📄 sst39vf160.c
字号:
/****************************************************************************
【文 件 名 称】SST39VF160.c
【功 能 描 述】FS44B0XP教学平台Nor Flash
【程 序 版 本】2.0
【创建及创建日期】优龙公司/2005-5-1
【修改及修改日期】2005-5-19
****************************************************************************/
//头文件定义
#include "def.h"
#include "board.h"
#include "SST39VF160.h"
#define CMD_ADDR0 *((volatile U16 *)(0x5555*2+ROM_BASE))
#define CMD_ADDR1 *((volatile U16 *)(0x2aaa*2+ROM_BASE))
#define CHECK_DELAY 150000
static U16 state;
static U16 support;
static U32 chip_id;
extern void memcpy(void *s1,const void *s2,int n);
/********************************************************************
Function name: memcpy
Parameter :
Description : 内存拷贝函数,将大小为n的数据从s2拷贝到s1中
Return : void
Argument :
Autor & date :
*********************************************************************/
/*
void memcpy(void *s1, const void *s2, int n)
{
int i;
for (i = 0; i < n; i++)
((char *)(s1))[i] = ((const char *)(s2))[i];
}
*/
/********************************************************************
Function name: CFIQueryExit
Parameter : void
Description : CFI查询退出
Return : void
Argument :
Autor & date :
*********************************************************************/
static void CFIQueryExit(void)
{
outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
outportw(0xf0f0, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
/********************************************************************
Function name: SWPIDExit
Parameter : void
Description : 软件ID的退出
Return : void
Argument :
Autor & date :
*********************************************************************/
static void SWPIDExit(void)
{
outportw(0xf0f0, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
/********************************************************************
Function name: SWPIDEntry
Parameter : void
Description : 软件ID的入口
Return : void
Argument :
Autor & date :
*********************************************************************/
static void SWPIDEntry(void)
{
if(state&1)
{
if(state&2)
return;
else
CFIQueryExit();
}
outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
outportw(0x9090, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0x9090;
state |= 3;
}
/********************************************************************
Function name: GetFlashID
Parameter : void
Description : 读取Nor Flash的ID号
Return : 返回Nor Flash的ID号
Argument :
Autor & date :
*********************************************************************/
static U32 GetFlashID(void)
{
U32 i;
SWPIDEntry();
i = inportw(ROM_BASE);
i |= inportw(ROM_BASE+2)<<16;
SWPIDExit();
return i;
}
/********************************************************************
Function name: FlashRead
Parameter : ReadStart : 目的地址
*DataPtr : 源地址
Size : 要写入的数据长度的大小
Description : 从Flash指定地址Readstart开始读取Size个数据到DataPtr
Return : void
Argument :
Autor & date :
*********************************************************************/
void FlashRead(unsigned int ReadStart, unsigned short *DataPtr, unsigned int Size)
{
int i;
ReadStart += ROM_BASE;
for(i=0; i<Size/2; i++)
*(DataPtr+i) = *((unsigned short *)ReadStart+i);
}
/********************************************************************
Function name: SectorErase
Parameter : sector : 要擦除的扇区地址
Description : 擦除sector地址的扇区
Return : 返回0或非0数值
Argument : 返回0:烧写成功 返回非0:烧写不成功
Autor & date :
*********************************************************************/
int SectorErase(U32 sector)
{
U32 tm, d1 ,d2;
if(state&1) {
if(state&2)
SWPIDExit();
else
CFIQueryExit();
}
sector += ROM_BASE;
outportw(0xaaaa, ROM_BASE+0xaaaa);
outportw(0x5555, ROM_BASE+0x5554);
outportw(0x8080, ROM_BASE+0xaaaa);
outportw(0xaaaa, ROM_BASE+0xaaaa);
outportw(0x5555, ROM_BASE+0x5554);
outportw(0x3030, sector);
d2 = inportw(sector);
tm = CHECK_DELAY;
while(1) {
tm--;
if(!tm)
return -1;
d1 = d2;
d2 = inportw(sector);
if((d1^d2)&(1<<6)) {
continue;
}
if(inportw(sector)==0xffff) {
return 0;
}
}
}
/********************************************************************
Function name: FlashProg
Parameter : ProgStart : 目的地址
*DataPtr : 源地址
WorkCnt : 要写入的数据长度的大小
Description : 将大小为size的数据从src地址写到dst地址
Return : 返回0或非0数值
Argument : 返回0:烧写成功 返回非0:烧写不成功
Autor & date :
*********************************************************************/
static int FlashProg(U32 ProgStart, U16 *DataPtr, U32 WordCnt)
{
ProgStart += ROM_BASE;
for( ; WordCnt; ProgStart+=2, DataPtr++, WordCnt--) {
U32 tm;
outportw(0xaaaa, ROM_BASE+0xaaaa);
outportw(0x5555, ROM_BASE+0x5554);
outportw(0xa0a0, ROM_BASE+0xaaaa);
outportw(*DataPtr, ProgStart);
tm = CHECK_DELAY;
while(1) {
if((inportw(ProgStart)^inportw(ProgStart))&(0x40)) { //D6 == D6
tm--;
if(!tm)
return -1;
continue;
}
if(inportw(ProgStart)==*DataPtr)
break; //D7 == D7
tm--;
if(!tm)
return -1;
}
}
return 0;
}
/********************************************************************
Function name: NorFlashProg
Parameter : dst : 目的地址
src : 源地址
size: 要写入的数据长度的大小
Description : 将大小为size的数据从src地址写到dst地址
Return : void
Argument :
Autor & date :
*********************************************************************/
void NorFlashProg(U32 dst, U32 src, U32 size)
{
char buf[0x1000];
U32 tmp = 0x1000-(dst&0xfff);
int err;
if(support) {
if((dst>ROM_SIZE)||(dst&1)) {
printf("Invalid flash address, the address is from 0~0x%x, 16Bits aligned\n", ROM_SIZE);
return;
}
if(tmp>size)
tmp = size;
if(tmp&1)
tmp++;
for(; size;) {
if(tmp<0x1000) {
NorFlashRead(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;
}
/*
void NorFlashProg(U32 dst, U32 src, U32 size)
{
char buf[0x1000];
U32 tmp = 0x1000-(dst&0xfff);
int err;
if(support) {
if((dst>ROM_SIZE)||(dst&1)) {
Uart_Printf("Invalid flash address, the address is from 0~0x%x, 16Bits aligned\n", ROM_SIZE);
return;
}
if(tmp>size)
tmp = size;
if(tmp&1)
tmp++;
for(; size;) {
if(tmp<0x1000) {
NorFlashRead(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
Uart_Printf("\t\tErase 0x%x Fail!!!\n", dst&~0xfff);
return;
}
Uart_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;
}
*/
/********************************************************************
Function name: NorFlashInit
Parameter : void
Description : 初始化Nor Flash
Return : void
Argument :
Autor & date :
*********************************************************************/
void NorFlashInit(void)
{
chip_id = GetFlashID();
support = 0;
if( (chip_id==0x278200bf)||(chip_id==0x22c400c2)||(chip_id==0x234b00bf) )
support = 1;
}
/********************************************************************
Function name: NorFlashStatusRep
Parameter : void
Description : 读取Nor Flash的相关信息
Return : void
Argument :
Autor & date :
*********************************************************************/
void NorFlashStatusRep(void)
{
printf("Nor Flash ID is : %x\n", 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");
}
/********************************************************************
Function name: ProgNorFlash
Parameter : void
Description : 读写函数
Return : void
Argument :
Autor & date : void
*********************************************************************/
void ProgNorFlash(void)
{
NorFlashInit();
NorFlashStatusRep();
if(support) {
if(download_len>0)
{
NorFlashProg((U32)0x10000,download_addr, download_len);
}
}
}
/********************************************************************
Function name: UpdateBootLoader
Parameter : void
Description : 更新BootLoader
Return : void
Argument :
Autor & date : void
*********************************************************************/
void UpdateBootLoader(void)
{
NorFlashInit();
NorFlashStatusRep();
if(support){
if(download_len>0)
{
NorFlashProg(0x0,download_addr,download_len);
}
}
}
/*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -