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