📄 flashat49bv162.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 + -