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

📄 flashmac71x1.c

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

#include "Interface.h"
#include "Private.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iomac7111.h>
#include <inarm.h>


/*
** usefull for bitmask operations
*/
#define BIT0  ( 0x00000001 )
#define BIT1  ( 0x00000002 )
#define BIT2  ( 0x00000004 )
#define BIT3  ( 0x00000008 )
#define BIT4  ( 0x00000010 )
#define BIT5  ( 0x00000020 )
#define BIT6  ( 0x00000040 )
#define BIT7  ( 0x00000080 )
#define BIT8  ( 0x00000100 )
#define BIT9  ( 0x00000200 )
#define BIT10 ( 0x00000400 )
#define BIT11 ( 0x00000800 )
#define BIT12 ( 0x00001000 )
#define BIT13 ( 0x00002000 )
#define BIT14 ( 0x00004000 )
#define BIT15 ( 0x00008000 )
#define BIT16 ( 0x00010000 )
#define BIT17 ( 0x00020000 )
#define BIT18 ( 0x00040000 )
#define BIT19 ( 0x00080000 )
#define BIT20 ( 0x00100000 )
#define BIT21 ( 0x00200000 )
#define BIT22 ( 0x00400000 )
#define BIT23 ( 0x00800000 )
#define BIT24 ( 0x01000000 )
#define BIT25 ( 0x02000000 )
#define BIT26 ( 0x04000000 )
#define BIT27 ( 0x08000000 )
#define BIT28 ( 0x10000000 )
#define BIT29 ( 0x20000000 )
#define BIT30 ( 0x40000000 )
#define BIT31 ( 0x80000000 )


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


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


/*
** flash definition used from the flashloader
*/
struct FlashDef
{
  unsigned long DeviceID ;  /* Manufacturer_ID << 16 ) | Device_ID */
  unsigned short NumOfBanks ;  /* 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 */
} ;



/*
** flash commands
*/
#define FLASH_CMD_BLANK_CHECK ( 0x05 )
#define FLASH_CMD_PAGE_ERASE_VERIFY ( 0x06 )
#define FLASH_CMD_PROGRAM ( 0x20 )
#define FLASH_CMD_PAGE_ERASE ( 0x40 )
#define FLASH_CMD_MASS_ERASE ( 0x41 )
#define FLASH_ARRAY_PROGRAM_INTERFACE ( 0xFC100000UL )


/*
** some status bits
*/
#define CBEIF ( BIT7 )
#define CCIF ( BIT6 )
#define PVIOL ( BIT5 )
#define ACCERR ( BIT4 )
#define BLANK ( BIT2 )


/*
** internal identification numbers
*/
#define ID_MAC71x2 ( 0x01 )
#define ID_MAC71x1 ( 0x02 )
#define ID_MASK ( 0xFF )


/*
** Only 32-bit write operations are allowed to the program Flash memory space.
*/
typedef unsigned long flashunit ;


/* this is the FlashAddressTable array size */
#define MAX_NUM_OF_SECTORS ( 128 )


/* number of banks for MAC71x2 */
#define NUM_OF_BANKS_MAC71x2 ( 1 )
/* number of sectors for MAC71x2 */
#define NUM_OF_SECTORS_MAC71x2 ( 64 )
/* last sectors in banks */
const unsigned short BankOrg_MAC71x2[]=
{
  ( NUM_OF_SECTORS_MAC71x2 - 1 )
} ;
/* sector organization for MAC71x2 */
const struct SectorOrg SectorOrg_MAC71x2[] =
{
  { 64, 4 * 1024UL },  /* 64 x 4kbytes sectors */
} ;
/* device definition for for MAC71x2 */
const struct FlashDef FlashDef_MAC71x2 =
{
  0xA7007100 | ID_MAC71x2,
  NUM_OF_BANKS_MAC71x2,
  NUM_OF_SECTORS_MAC71x2,
  BankOrg_MAC71x2,
  SectorOrg_MAC71x2
} ;


/* number of banks for MAC71x1 */
#define NUM_OF_BANKS_MAC71x1 ( 1 )
/* number of sectors for MAC71x1 */
#define NUM_OF_SECTORS_MAC71x1 ( 128 )
/* last sectors in banks */
const unsigned short BankOrg_MAC71x1[]=
{
  ( NUM_OF_SECTORS_MAC71x1 - 1 )
} ;
/* sector organization for MAC71x1 */
const struct SectorOrg SectorOrg_MAC71x1[] =
{
  { 128, 4 * 1024UL },  /* 128 x 4kbytes sectors */
} ;
/* device definition for for MAC71x1 */
const struct FlashDef FlashDef_MAC71x1 =
{
  0xA7007100 | ID_MAC71x1,
  NUM_OF_BANKS_MAC71x1,
  NUM_OF_SECTORS_MAC71x1,
  BankOrg_MAC71x1,
  SectorOrg_MAC71x1
} ;


const struct FlashDef * const FlashDevices[] =
{
  &FlashDef_MAC71x2,
  &FlashDef_MAC71x1,
} ;


#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[MAX_NUM_OF_SECTORS] ;
/* the frequency input from the user in kHz */
__no_init static unsigned long FlashFsys ;
/* the "current" flash device */
static const struct FlashDef *FlashDevice ;


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

  ManID = PCT ;  /* Processor Core Type Register */
  DevID = REV ;  /* Device Revision Register */

  switch( DevID )
    {
    case 0x7130:  /* MAC71x2 0L61W */
      DevID = ( DevID & ~ID_MASK ) | ID_MAC71x2 ;
      break ;
    case 0x7110:  /* MAC71x1 0L49P */
    case 0x7111:  /* MAC71x1 1L49P */
    case 0x7120:  /* MAC71x1 0L47W */
    case 0x7121:  /* MAC71x1 1L47W */
      DevID = ( DevID & ~ID_MASK ) | ID_MAC71x1 ;
      break ;
    default:
      DevID = ( DevID & ~ID_MASK ) | ID_MASK ;
      break ;
    }

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


static unsigned char FlashPrepare( void )
{
  unsigned long PRDCLK ;
  unsigned char PRDIF8, DIV ;

  CFMMCR = ( 0x0 ) ;  /* disable flash interrupts */

  if( !( CFMCLKD & BIT7 ) )
    {
    if( ( 12800UL ) < FlashFsys / 2 )  /* setup F_NVMOP */
      {
      PRDIF8 = 1 ;
      PRDCLK = FlashFsys / 2 / 8 ;
      }
    else
      {
      PRDIF8 = 0 ;
      PRDCLK = FlashFsys / 2 ;
      }
    DIV = PRDCLK / 200 - 1 ;
    if( ( PRDCLK / ( DIV + 1 ) ) > 200 )
      {
      DIV++ ;
      }
    CFMCLKD = ( ( PRDIF8<<6 ) | DIV ) ;
    }
  CFMPROT = ( 0 ) ;  /* unprotect all logical sectors */
  CFMSACC = ( 0 ) ;  /* all logical sectors in unrestricted address space */

  if( !( ( CFMSEC & BIT1 ) && !( CFMSEC & BIT0 ) ) )
    {  /* oprartion caused some error or flash is secured */
    FlMessageBox( "Preparation error."  ) ;
    return( FLASH_ERROR ) ;
    }
  else
    {
    return( FLASH_OK ) ;
    }
}


static void FlashCleanup( void )
{
}


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

  SectorAddr = ( FlashAddressTable[Sector] & ~( sizeof( flashunit ) - 1 ) ) ;
  SectorAddr += FLASH_ARRAY_PROGRAM_INTERFACE - baseAddress ;

  while( !( CFMUSTAT & CBEIF ) )
    {  /* wait for the buffer to become empty */
    }
  if( CFMUSTAT & ( PVIOL|ACCERR ) ) CFMUSTAT |= ( PVIOL|ACCERR ) ;  /* clear ACCERR and PVIOL */
  /* buffer address and data */
  *( ( volatile flashunit * )SectorAddr ) = 0 ;
  if( CFMUSTAT & ACCERR )
    {  /* operartion caused access error */
    FlMessageBox( "Erase error."  ) ;
    return( FLASH_ERROR ) ;
    }
  else
    {
    CFMCMD = FLASH_CMD_PAGE_ERASE ;
    CFMUSTAT |= ( CBEIF ) ;  /* clear CBIEF, means start */
    if( CFMUSTAT & PVIOL )
      {  /* operartion caused protection violation */
      FlMessageBox( "Erase error."  ) ;
      return( FLASH_ERROR ) ;
      }
    else
      {
      while( !( CFMUSTAT & CCIF ) ) { }  /* wait for the operation to finish */
      return( FLASH_OK ) ;
      }
    }
}


static unsigned char FlashWriteUnit( unsigned long LoadAddr, flashunit Data )
{
  LoadAddr += FLASH_ARRAY_PROGRAM_INTERFACE - baseAddress ;

  while( !( CFMUSTAT & CBEIF ) ) { }  /* wait for the buffer to become empty */
  if( CFMUSTAT & ( PVIOL|ACCERR ) ) CFMUSTAT |= ( PVIOL|ACCERR ) ;  /* clear ACCERR and PVIOL */
  /* buffer address and data */
  *( ( volatile flashunit * )LoadAddr ) = Data ;
  CFMCMD = FLASH_CMD_PROGRAM ;
  CFMUSTAT |= ( CBEIF ) ;  /* clear CBIEF, means start */
  if( CFMUSTAT & PVIOL )
    {  /* oprartion caused protection violation */
    FlMessageBox( "Programming error."  ) ;
    return( FLASH_ERROR ) ;
    }
  else
    {
    while( !( CFMUSTAT & CCIF ) ) { }  /* wait for the operation to finish */
    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 baseAddress offset */
    FlashAddressTable[Sector] += baseAddress ;
    }
}


static void FlashWriteByte( unsigned long Addr, int Byte )
{
  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 */
      if( ( Addr >= baseAddress ) && ( Addr <= FlashAddressTable[FlashDevice->NumOfSectors - 1 ] ) )
        {  /* address is in flash area */
        if( Addr > FlashAddressTable[CurrentSector] )
          {  /* address is outside the current sector, so we have to enter a new one */
          while( Addr > 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[] )
{
  const char *ParameterStr ;
  unsigned char Count ;
  unsigned long DevID ;

  DevID = FlashIdentify( ) ;
  for( Count = 0 ; Count < NUM_OF_FLASH_DEVICES ; Count++ )
    {
    if( FlashDevices[Count]->DeviceID == DevID )
      {
      /* set current flash device */
      FlashDevice = FlashDevices[Count] ;
      break ;
      }
    }

  if( FlashDevice )
    {
    ParameterStr = FlFindOption( "--clock", 1, argc, argv ) ;
    ( ParameterStr ) ? ( FlashFsys = strtoul( ParameterStr, 0, 0 ) ) : ( FlashFsys = 8000UL ) ;
    /* build the address table based on the sector organization */
    FlashBuildAddressTable( ) ;
    /* init the flash */
    if( FLASH_OK != FlashPrepare( ) )
      {  /* preparation failed */
      FlErrorExit( ) ;
      }
    /* register the write function */
    FlRegisterWriteFunction( FlashWriteByte ) ;
    }
  else
    {
    FlMessageBox( "No MAC71x2/MAC71x1 detected." ) ;
    FlErrorExit( ) ;
    }
}


#if 0
int main( void )
{
  unsigned long Address ;

  FlashDriverInitialize( 0, 0 ) ;
  for( Address = 0x00000000 ; Address < 0x00000010 ; Address+=1 )
    {
    FlashWriteByte( Address, Address ) ;
    }
  FlashWriteByte( Address, -1 ) ;
  return( 0 ) ;
}
#endif

⌨️ 快捷键说明

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