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

📄 flashat91ebxx.c

📁 FlashAT91EBxx 读写程序 FlashAT91EBxx 读写程序
💻 C
字号:
/**************************************************
 * Copyright 2004-2005 IAR Systems. All rights reserved.
 *
 * $Revision: 1.3 $
 **************************************************/

#include "Interface.h"
#include "Private.h"
#include <stdio.h>


/*
** 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 */
} ;


// ===================================
// AT49BV1614A/AT49BV162A
// ===================================

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

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

// Device definition.
const struct FlashDef flashDef_AT49BV1614A =
{
  0x001F00C0,  // device ID
  'A', // variant
  1, // number of banks
  39, // bumber of sectors
  bankOrg_AT49BV1614A,
  sectorOrg_AT49BV1614A
};

// ===================================
// AT49BV1614AT
// ===================================

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

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

// Device definition.
const struct FlashDef flashDef_AT49BV1614AT =
{
  0x001F00C2,  // device ID
  'A', // variant
  1, // number of banks
  39, // bumber of sectors
  bankOrg_AT49BV1614AT,
  sectorOrg_AT49BV1614AT
};

// ===================================
// AT49BV1614
// ===================================

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

// Sector organization.
const struct SectorOrg sectorOrg_AT49BV1614[] =
{
  { 8,  8 * 1024},  //  8 x  8 kbytes sectors
  { 2, 32 * 1024},  //  2 x 32 kbytes sectors
  {30, 64 * 1024},  // 30 x 64 kbytes sectors
};

// Device definition.
const struct FlashDef flashDef_AT49BV1614 =
{
  0x001F00C0,  // device ID
  0, // variant
  1, // number of banks
  40, // bumber of sectors
  bankOrg_AT49BV1614,
  sectorOrg_AT49BV1614
};

// ===================================
// AT49BV1614T
// ===================================

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

// Sector organization.
const struct SectorOrg sectorOrg_AT49BV1614T[] =
{
  {30, 64 * 1024},  // 30 x 64 kbytes sectors
  { 2, 32 * 1024},  //  2 x 32 kbytes sectors
  { 8,  8 * 1024},  //  8 x  8 kbytes sectors
};

// Device definition.
const struct FlashDef flashDef_AT49BV1614T =
{
  0x001F00C2,  // device ID
  0, // variant
  1, // number of banks
  40, // bumber of sectors
  bankOrg_AT49BV1614T,
  sectorOrg_AT49BV1614T
};


const struct FlashDef * const flashDevices[] =
{
  &flashDef_AT49BV1614A,
  &flashDef_AT49BV1614AT,
  &flashDef_AT49BV1614,
  &flashDef_AT49BV1614T,
};


#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 ;

  return( ( ( unsigned long )ManID << 16 ) | DevID ) ;
}


static unsigned char FlashPrepare( void )
{
  /* nothing to prepare */
  return( FLASH_OK ) ;
}


static void FlashCleanup( void )
{
  /* nothing to clean up */
}


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

  SectorAddr = ( flashAddressTable[Sector] & ~( sizeof( flashunit ) - 1 ) ) ;

  if (userMode)
  {
    SectorAddr -= 0x100000;
  }

  /* 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 )
{
  /* 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 */
            FlErrorExit( ) ;
          }
          EraseSector = 0 ;  /* erase is done */
        }
        if( FLASH_OK != FlashWriteUnit( ( Addr & ~( sizeof( flashunit ) - 1 ) ), Data ) )
        {  /* 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;

  // 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;
  }

  flashBase = FlGetBaseAddress();
  if (flashBase == 0xffffffff)
  {
    // Use the flash base address configured by the .mac file.
    flashBase = 0x1000000;
  }

  // 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] ;
      break ;
    }
  }

  if( flashDevice )
  {
    /* build the address table based on the sector organization */
    FlashBuildAddressTable( ) ;
    /* init the flash */
    if( FLASH_OK != FlashPrepare( ) )
    {  /* preparation failed */
      FlErrorExit( ) ;
    }
    FlRegisterWriteFunction( FlashWriteByte ) ;
  }
  else
  {
    FlMessageBox("No AT49BV16x4 detected.");
    FlErrorExit( ) ;
  }
}

⌨️ 快捷键说明

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