⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashat49bv162.c

📁 很好的资料
💻 C
字号:
//*--------------------------------------------------------------------------------------
//*      ATMEL Microcontroller Software Support  -  ROUSSET  -
//*--------------------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*--------------------------------------------------------------------------------------
//* File Name               : FlashAT49BV162.c
//* Object                  : FLASH programmer for SAM7A3 product
//*
//* Creation                : JPP  01/Jul/2005
//*--------------------------------------------------------------------------------------
#include "Interface.h"
#include "Private.h"
#include <stdio.h>

 #define AT91_TRACE
/*
** flash functions return value
*/
#define FLASH_ERROR ( 0 )
#define FLASH_OK ( 1 )

/*
** define flash command codes
*/
// AT49BV1604A/AT49BV1604AT/AT49BV162A
#define FLASH_A_SEQ_ADD1 ( 0x555 )
#define FLASH_A_SEQ_ADD2 ( 0xAAA )
// AT49BV1604/AT49BV1604T
#define FLASH_SEQ_ADD1 ( 0x5555 )
#define FLASH_SEQ_ADD2 ( 0x2AAA )
// AT49BV1604A/AT49BV1604AT/AT49BV1604/AT49BV1604T
#define FLASH_CODE1 ( 0xAA )
#define FLASH_CODE2 ( 0x55 )
#define ID_IN_CODE ( 0x90 )
#define ID_OUT_CODE ( 0xF0 )
#define WRITE_CODE ( 0xA0 )
#define ERASE_SECTOR_CODE1 ( 0x80 )
#define CHIP_SECTOR_CODE1 ( 0x10 )
#define ERASE_SECTOR_CODE2 ( 0x30 )

/*
** minimum writeable unit for this flash
*/
typedef unsigned short flashunit ;

/*
** sector organization
*/
struct SectorOrg
{
  unsigned short SectorCount ;  /* how many sectors ... */
  unsigned long SectorSize ;  /* ... of what size */
} ;

/*
** flash definition used for the flashloader
*/
struct FlashDef
{
  unsigned long deviceID ;  /* Manufacturer_ID << 16 ) | Device_ID */
  int variant; /* flash variant, ie. A, B, ... */
  unsigned short dumOfBanks ;  /* number of physical banks in total */
  unsigned short numOfSectors ;  /* number of physical sectors in total */
  const unsigned short *lastSectorInBank ;  /* pointer to arrays with last sectors in banks */
  const struct SectorOrg *sectorTable ;  /* sector organization */
  char  name[20];

} ;

// ===================================
// AT49BV162A
// ===================================

// Bank organization.
const unsigned short bankOrg_AT49BV162A[]=
{
  39 - 1 // last sectors in banks
};

// Sector organization.
const struct SectorOrg sectorOrg_AT49BV162A[] =
{
  { 8,  8 * 1024},  //  8 x  8 kbytes sectors
  {31, 64 * 1024},  // 31 x 64 kbytes sectors
};

// Device definition.
const struct FlashDef flashDef_AT49BV162A =
{
  0x001F00C0,  // device ID
  'A', // variant
  1, // number of banks
  39, // bumber of sectors
  bankOrg_AT49BV162A,
  sectorOrg_AT49BV162A,
  "AT49BV162A\n"
};
// ===================================
// AT49BV162AT
// ===================================

// Bank organization.
const unsigned short bankOrg_AT49BV162AT[]=
{
  39 - 1 // last sectors in banks
};

// Sector organization.
const struct SectorOrg sectorOrg_AT49BV162AT[] =
{
  {31, 64 * 1024},  // 31 x 64 kbytes sectors
  { 8,  8 * 1024},  //  8 x  8 kbytes sectors
};

// Device definition.
const struct FlashDef flashDef_AT49BV162AT =
{
  0x001F00C2,  // device ID
  'A', // variant
  1, // number of banks
  39, // bumber of sectors
  bankOrg_AT49BV162AT,
  sectorOrg_AT49BV162AT,
  "AT49BV162AT\n"
};


const struct FlashDef * const flashDevices[] =
{
  &flashDef_AT49BV162A,
  &flashDef_AT49BV162AT
};

static char message[80];

#define NUM_OF_FLASH_DEVICES ( sizeof( flashDevices ) / sizeof( struct FlashDef * ) )


/* will be filled with high address of the sectors */
__no_init static unsigned long flashAddressTable[40] ;
/* the "current" flash device */
static const struct FlashDef *flashDevice ;

static unsigned long flashBase;
static unsigned long flashOffset = 0;
static unsigned long flashSeqAdd1;
static unsigned long flashSeqAdd2;
static int userMode = 0;


static unsigned long FlashIdentify( void )
{
  unsigned short ManID ;
  unsigned short DevID ;

  /* enter software product identification mode */
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = FLASH_CODE1 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd2 ) = FLASH_CODE2 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = ID_IN_CODE ;

  /* read manufacturer and device code from the device */
  ManID  = *( ( volatile flashunit * )flashBase + flashOffset) ;
  DevID = *( ( volatile flashunit * )flashBase + flashOffset + 1 ) ;

  /* exit software product identification mode */
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = FLASH_CODE1 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd2 ) = FLASH_CODE2 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = ID_OUT_CODE ;

#ifdef AT91_TRACE
   sprintf(message,"Man ID: 0x%X\n",ManID);
   FlMessageLog(message);
   sprintf(message,"Flash ID: 0x%X\n",DevID);
   FlMessageLog(message);
#endif
  return( ( ( unsigned long )ManID << 16 ) | DevID ) ;
}

static unsigned char FlashPrepare( void )
{
#ifdef AT91_TRACE_ALL
   FlMessageLog("-I- FlashPrepare\n");
#endif
  /* nothing to prepare */
  return( FLASH_OK ) ;
}

static void FlashCleanup( void )
{
#ifdef AT91_TRACE
   FlMessageLog("-I- Flash Written\n");
#endif
  /* nothing to clean up */
}


static unsigned char FlashEraseSector( unsigned long Sector )
{
  unsigned long SectorAddr ;

  SectorAddr = ( flashAddressTable[Sector] & ~( sizeof( flashunit ) - 1 ) ) ;
  if (userMode)
  {
    SectorAddr -= 0x100000;
  }
#ifdef AT91_TRACE
  sprintf(message,"-I- Sector: 0x%X\n",SectorAddr);
  FlMessageLog(message);
#endif

  /* enter sector erase sequence codes */
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = FLASH_CODE1 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd2 ) = FLASH_CODE2 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = ERASE_SECTOR_CODE1 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = FLASH_CODE1 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd2 ) = FLASH_CODE2 ;
  *( volatile flashunit * )SectorAddr = ERASE_SECTOR_CODE2 ;

  while( *( ( volatile flashunit * )SectorAddr ) != *( ( volatile flashunit * )SectorAddr ) )
    {  /* use the toggle function for bussy check */
    }
  return( FLASH_OK ) ;
}


static unsigned char FlashWriteUnit( unsigned long LoadAddr, flashunit Data )
{
#ifdef AT91_TRACE_ALL
	 sprintf(message,"-I- Flash add  0x%X\n",LoadAddr);
	 FlMessageLog(message);
#endif
	/* enter programming code sequence */
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = FLASH_CODE1 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd2 ) = FLASH_CODE2 ;
  *( ( volatile flashunit * )flashBase + flashOffset + flashSeqAdd1 ) = WRITE_CODE ;
  *( ( volatile flashunit * )LoadAddr ) = Data ;

  while( *( ( volatile flashunit * )LoadAddr ) != *( ( volatile flashunit * )LoadAddr ) )
    {  /* use the toggle function for bussy check */
    }
  return( FLASH_OK ) ;
}


static void FlashBuildAddressTable( void )
{
  unsigned int Block = 0 ;
  unsigned int Sector = 0, SectorInBlock = 0 ;
  unsigned long WorkAddr = 0 ;

  while( Sector < flashDevice->numOfSectors )
  {  /* based on SectorOrg write high sector addresses in the address table */
    WorkAddr += flashDevice->sectorTable[Block].SectorSize ;
    flashAddressTable[Sector] = WorkAddr - 1 ;
    if( ++SectorInBlock < flashDevice->sectorTable[Block].SectorCount )
    {
    }
    else
    {
      SectorInBlock = 0 ;
      Block++ ;
    }
    Sector++ ;
  }

  for( Sector = 0 ; Sector < flashDevice->numOfSectors ; Sector++ )
  {  /* add the flashBase offset */
    flashAddressTable[Sector] += flashBase ;
  }
}


static void FlashWriteByte( unsigned long Addr, int Byte )
{
  unsigned long realAddr; // Address as seen by flash device.
  static unsigned short CurrentSector = 0 ;  /* start in sector 0 */
  static union
  {  /* since we receive bytes we need to buffer them */
    flashunit Data ;
    unsigned char Buffer[sizeof( flashunit )] ;
  } ;
  /*
  ** init LastAddr with -1 to have a proper LastAddr when
  ** the very first address is within the first flashunit but not 0x0
  */
  static unsigned long LastAddr = ( unsigned long )-1 ;
  static unsigned char Buffered = 0 ;
  static unsigned char EraseSector = 1 ;

  if( ( 0 == Buffered ) && ( ( Addr - LastAddr ) >= sizeof( flashunit ) ) )
  {  /* skip spaces larger one flashunit only if buffer is currently empty */
    LastAddr = ( Addr & ~( sizeof( flashunit ) - 1 ) ) - 1 ;
  }
  while( ( ( -1 != Byte ) && ( ( Addr - LastAddr ) > 1 ) ) || ( ( -1 == Byte ) && ( 0 < Buffered ) ) )
  {  /* in case there is some gap within one flashunit, fill it with 0xFFs */
    FlashWriteByte( LastAddr + 1, 0xFF ) ;
  }

  if( -1 == Byte )
  {  /* flashloader is asked to quit */
    FlashCleanup( ) ;
  }
  else
  {  /* data to be buffered */
    Buffer[Buffered] = Byte ;
    Buffered++ ;
    if( Buffered == sizeof( flashunit ) )
      {  /* write buffer is full */
        realAddr = Addr;
        if (userMode)
        {
          realAddr += 0x100000;
        }
        if( ( realAddr >= flashBase ) && ( realAddr <= flashAddressTable[flashDevice->numOfSectors - 1 ] ) )
        {  /* address is in flash area */
          if( realAddr > flashAddressTable[CurrentSector] )
          {  /* address is outside the current sector, so we have to enter a new one */
            while( realAddr > flashAddressTable[CurrentSector] )
            {  /* skip sectors until we are in the right one */
              CurrentSector++ ;
            }
            EraseSector = 1 ;  /* we need to erase the now entered sector */
          }
          else
          {  /* address is in the current sector */
          }
          if( EraseSector )
          {  /* erase sector is required before the data can be written */
            if( FLASH_OK != FlashEraseSector( CurrentSector ) )
            {  /* erasing sector failed */
              FlMessageBox( "Erasing sector failed");
              FlErrorExit( ) ;
            }
            EraseSector = 0 ;  /* erase is done */
          }
          if( FLASH_OK != FlashWriteUnit( ( Addr & ~( sizeof( flashunit ) - 1 ) ), Data ) )
          {  /* writing data failed */
            FlMessageBox( "Writing data failed");
            FlErrorExit( ) ;
          }
        }
        else
        {  /* address is not in flash area, maybe it is RAM */
          /* *( flashunit * )Addr = Data ; might be too dangerous */
        }
        Buffered = 0 ;  /* buffer is free again */
      }
      LastAddr = Addr ;
    }
}


void FlashDriverInitialize( int argc, char const* argv[] )
{
  unsigned char count;
  unsigned long dev_id;
  int flash_variant;
  const char *str;
   FlMessageLog("-I- Flash Driver Version 1.1 20/Jun/2005\n");

#ifdef AT91_TRACE_ALL
   FlMessageLog("-I- FlashDriverInitialize \n");
#endif

  // The --user option supports mapping the top half of the flash to 0x1000000.
  str = FlFindOption("--user", 0, argc, argv);
  if (str)
  {
    userMode = 1;
    flashOffset = 0x100000;
  }
  // get the param
  flashBase = FlGetBaseAddress();
#ifdef AT91_TRACE_ALL
  sprintf(message,"-I- flashBase: 0x%X\n",flashBase);
  FlMessageLog(message);
#endif
  if (flashBase == 0xffffffff)
  {
    FlMessageBox( "Wrong Base address set the Parameter.");
    FlErrorExit( ) ;
  }

#ifdef AT91_TRACE
  sprintf(message,"-I- flashBase: 0x%X\n",flashBase);
  FlMessageLog(message);
#endif

  // Try AT49BV1604A/AT49BV1604AT.
  flashSeqAdd1 = FLASH_A_SEQ_ADD1;
  flashSeqAdd2 = FLASH_A_SEQ_ADD2;
  flash_variant = 'A';
  dev_id = FlashIdentify();

  if ((dev_id & 0xffff0000) != 0x001f0000)
  {
    // Try AT49BV1604/AT49BV1604T.
    flashSeqAdd1 = FLASH_SEQ_ADD1;
    flashSeqAdd2 = FLASH_SEQ_ADD2;
    flash_variant = 0;
    dev_id = FlashIdentify();
  }

  if ((dev_id & 0xffff0000) != 0x001f0000)
  {
    FlMessageBox( "Wrong manufacturer ID.");
    FlErrorExit( ) ;
  }

  for(count = 0; count < NUM_OF_FLASH_DEVICES; count++ )
  {
    if (flashDevices[count]->deviceID == dev_id &&
        flashDevices[count]->variant == flash_variant)
    {
      /* set current flash device */
      flashDevice = flashDevices[count] ;
#ifdef AT91_TRACE
      sprintf(message,"-I- flash: %s\n", flashDevices[count]->name);
      FlMessageLog(message);
#endif
      break ;
    }
  }

  if( flashDevice )
  {
    /* build the address table based on the sector organization */
    FlashBuildAddressTable( ) ;
    /* init the flash */
    if( FLASH_OK != FlashPrepare( ) )
    {  /* preparation failed */
      FlMessageBox( "Preparation failed");
      FlErrorExit( ) ;
    }
    FlMessageLog("-I- AT49BV device detected.");
    FlRegisterWriteFunction( FlashWriteByte ) ;
  }
  else
  {
    FlMessageBox("No AT49BV device detected.");
    FlErrorExit( ) ;
  }
#ifdef AT91_TRACE_ALL
   FlMessageLog("-I- FlashDriverInitialize End\n");
#endif

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -