📄 sst39vf160.c
字号:
#include "../inc/def.h"
#include "../inc/config.h"
#include "../inc/utils.h"
#include "../inc/board.h"
#ifdef SST39VF160_SUPPORT
#define CMD_ADDR0 *((volatile U16 *)(0xaaaa+EXT_ROM_BASE))
#define CMD_ADDR1 *((volatile U16 *)(0x5554+EXT_ROM_BASE))
#define CHECK_DELAY 150000
static U16 state;
static U16 support;
static U32 chip_id;
static void SWPIDExit( void ) ;
/******************************************************************************
【功能说明】进入通用存储器接口(Common Flash memory Interface)查询
******************************************************************************/
static void CFIQueryEntry( void )
{
if ( state & 1 )
{
if ( state & 2 )
SWPIDExit();
else
return;
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x9898;
state |= 1;
}
/******************************************************************************
【功能说明】退出通用存储器接口(Common Flash memory Interface)查询
******************************************************************************/
static void CFIQueryExit( void )
{
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
/******************************************************************************
【功能说明】通过通用存储器接口(Common Flash memory Interface)来读取Flash数据
******************************************************************************/
void GetFlashCFI( unsigned short* DataPtr )
{
unsigned short i;
CFIQueryEntry();
for ( i = 0x10; i < 0x35; DataPtr++, i++ )
*DataPtr = *( unsigned short * ) ( i * 2 + EXT_ROM_BASE );
CFIQueryExit();
}
/******************************************************************************
【功能说明】进入存储器ID软件获取操作
******************************************************************************/
static void SWPIDEntry( void )
{
if ( state & 1 )
{
if ( state & 2 )
return;
else
CFIQueryExit();
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x9090;
state |= 3;
}
/******************************************************************************
【功能说明】退出存储器ID软件获取操作
******************************************************************************/
static void SWPIDExit( void )
{
CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
/******************************************************************************
【功能说明】获取Falsh的ID号
******************************************************************************/
unsigned int GetFlashID( void )
{
unsigned int i;
SWPIDEntry();
i = *( unsigned short * ) ( 0 + EXT_ROM_BASE );
i |= ( *( unsigned short * ) ( 2 + EXT_ROM_BASE ) ) << 16;
SWPIDExit();
return i;
}
/******************************************************************************
【功能说明】从Flash指定地址Readstart开始读取Size个字节的数据到DataPtr
******************************************************************************/
void FlashRead( void* DataPtr , U32 ReadStart , unsigned int Size )
{
int i;
// ReadStart += EXT_ROM_BASE;
// printf("FlashRead DataPtr = 0x%x\n", DataPtr );
// printf("FlashRead ReadStart = 0x%x\n", ReadStart );
for ( i = 0; i < Size / 2; i++ )
( ( U16 * ) DataPtr )[i] = ( ( U16 * ) ReadStart )[i];
if ( Size % 2 )
( ( U8 * ) DataPtr )[Size - 1] = ( ( U8 * ) ReadStart )[Size - 1] ;
}
/******************************************************************************
【功能说明】芯片整片擦除
******************************************************************************/
void ChipErase( void )
{
if ( state & 1 )
{
if ( state & 2 )
SWPIDExit();
else
CFIQueryExit();
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x8080;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x1010;
while ( 1 )
{
unsigned short i;
i = *( ( volatile unsigned short * ) ( EXT_ROM_BASE + 0x6666 ) ) & 0x40;
if ( i !=
*( ( volatile unsigned short * ) ( EXT_ROM_BASE + 0x6666 ) ) & 0x40 ) //D6 == D6
continue;
if ( *( ( volatile unsigned short * ) ( EXT_ROM_BASE + 0x8888 ) ) & 0x80 )
break; //D7 == 1
}
}
/******************************************************************************
【功能说明】擦除指定的扇区
******************************************************************************/
static int SectorErase( unsigned int sector )
{
unsigned short count;
int ok = -1 ;
if ( state & 1 )
{
if ( state & 2 )
SWPIDExit();
else
CFIQueryExit();
}
// printf("SectorErase sector = 0x%x\n", sector );
// sector += EXT_ROM_BASE;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x8080;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
*( volatile unsigned short * ) sector = 0x3030;
count = 60000;
while ( count-- )
{
unsigned short i;
i = *( ( volatile unsigned short * ) sector ) & 0x40;
if ( i != *( ( volatile unsigned short * ) sector ) & 0x40 ) //D6 == D6
continue;
if ( *( ( volatile unsigned short * ) sector ) & 0x80 )
{
ok = 0;
break; //D7 == 1
}
}
return ok ;
}
/******************************************************************************
【功能说明】将DataPtr指向的数据烧入Flash指定地址Progstart开始的地方,烧入长度WordCnt
******************************************************************************/
static int FlashProg( U32 ProgStart , U16* DataPtr , U32 WordCnt )
{
for ( ; WordCnt; ProgStart += 2, DataPtr++, WordCnt-- )
{
U32 tm;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0xa0a0;
*( volatile U16 * ) ProgStart = *DataPtr;
tm = CHECK_DELAY;
while ( 1 )
{
if ( ( ( *( volatile U16 * ) ProgStart ) ^ ( *( volatile U16 * )
ProgStart ) ) & ( 0x40 ) ) //D6 == D6
{
tm--;
if ( !tm )
return -1;
continue;
}
if ( ( *( volatile U16 * ) ProgStart ) == *DataPtr )
break; //D7 == D7
tm--;
if ( !tm )
return -1;
}
}
return 0;
}
/******************************************************************************
【功能说明】从指定扇区begin开始,将size个来自指针data的数据编程到Flash
******************************************************************************/
int SectorProg( unsigned int begin , unsigned short* data , unsigned int size )
{
unsigned int tmp = 0x1000 - ( begin & 0xfff );
if ( tmp > size )
tmp = size;
for ( ; size; )
{
SectorErase( begin & 0xfffff000 ); //4K Bytes boudary
FlashProg( begin , data , tmp / 2 );
size -= tmp;
begin += tmp;
data += tmp / 2;
tmp = ( size > 0x1000 ) ? 0x1000 : size;
}
return 0;
}
//*****************************************************************************
/******************************************************************************
【功能说明】从指定地址dst开始,将size个来自指针src的数据编程到Flash
******************************************************************************/
void NorFlashProg( U32 dst , U32 src , U32 size )
{
char buf[0x1000];
U32 tmp = 0x1000 - ( dst&0xfff );
int err;
if ( support )
{
if ( ( dst > ( EXT_ROM_BASE + EXT_ROM_SIZE ) ) ||
( dst < EXT_ROM_BASE ) ||
( dst & 1 ) )
{
printf( "Invalid flash address, the address is from 0x%x~0x%x, 16Bits aligned\n" ,
EXT_ROM_BASE , ( EXT_ROM_BASE + EXT_ROM_SIZE ) );
return;
}
if ( tmp > size )
tmp = size;
if ( tmp & 1 )
tmp++;
for ( ; size; )
{
if ( tmp < 0x1000 )
{
FlashRead( buf , ( dst & ~0xfff ) , 0x1000 ); //读取目标扇区前面的部分
memcpy( buf + ( dst & 0xfff ) , ( char * ) src , tmp ); //补足扇区后面的部分
}
else
{
memcpy( buf , ( char * ) src , 0x1000 );
}
err = SectorErase( dst & ~0xfff );
if ( err )
{
//4K Bytes boudary
printf( "\t\tErase 0x%x Fail!!!\n" , dst & ~0xfff );
return;
}
printf( "Program 0x%x %s\n" , dst & ~0xfff ,
FlashProg( dst & ~0xfff , ( U16 * ) buf , 0x1000 >> 1 ) ?
"\tFail!!! Error!!!" :
"Ok" );
size -= tmp;
dst += tmp;
src += tmp;
tmp = ( size > 0x1000 ) ? 0x1000 : size;
}
}
return;
}
//*****************************************************************************
/******************************************************************************
【功能说明】NorFlash初始化
******************************************************************************/
void NorFlashInit( void )
{
chip_id = GetFlashID();
support = 0;
if ( ( chip_id == 0x278200bf ) ||
( chip_id == 0x22c400c2 ) ||
( chip_id == 0x234b00bf ) )
support = 1;
}
//*****************************************************************************
/******************************************************************************
【功能说明】NorFlash状态报告
******************************************************************************/
void NorFlashStatusRep( void )
{
printf( "Nor Flash ID is: %x," , chip_id );
if ( support )
{
if ( chip_id == 0x278200bf )
printf( "SST39VF160 Found\n" );
if ( chip_id == 0x234b00bf )
printf( "SST39VF1601 Found\n" );
if ( chip_id == 0x22c400c2 )
printf( "MX29LV160 Found\n" );
}
else
printf( "Unknown Flash Type!\n" );
}
//*****************************************************************************
/******************************************************************************
【功能说明】NorFlash自测试
******************************************************************************/
void NorFlash_Test( void )
{
#define TEST_LENGTH ( 0x01000 )
#define TEST_ROM_START ( EXT_ROM_BASE+0x000000 )
#define TEST_ROM_END ( EXT_ROM_BASE+TEST_LENGTH )
U32 m, n ;
int err ;
U8 data[TEST_LENGTH] ;
NorFlashInit() ;
NorFlashStatusRep() ;
printf( "\nSector Erase Test\n\n" );
for ( m = TEST_ROM_START ; m < TEST_ROM_END ; m += 0x1000 )
{
err = SectorErase( m );
if ( err )
printf( "\tErase 0x%x Fail!!!\n" , m );
else
printf( "\tErase 0x%x OK!!!\n" , m );
}
//给要写入NorFlash的数组赋值
for ( m = 0 ; m < TEST_LENGTH ; m++ )
data[m] = 0xaa ;
printf( "write data : \n" );
for ( m = 0; m < ( TEST_LENGTH / 16 ); m ++ )
{
for ( n = 0; n < 16; n++ )
printf( "%02x " , data[m * 16 + n] ) ;
printf( "\n" );
}
printf( "\nProgram Flash Test\n\n" );
FlashProg( TEST_ROM_START , ( U16 * ) data , TEST_LENGTH ) ;
for ( m = 0 ; m < TEST_LENGTH ; m++ )
data[m] = 0 ;
FlashRead( data , TEST_ROM_START , TEST_LENGTH ) ;
printf( "\nread data from 0x%x :\n\n" , TEST_ROM_START );
for ( m = 0; m < ( TEST_LENGTH / 16 ); m ++ )
{
for ( n = 0; n < 16; n++ )
printf( "%02x " , data[m * 16 + n] ) ;
printf( "\n" );
}
printf( "\nPress ESC key to exit\n" );
while ( getkey() != ESC_KEY ) ;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -