📄 bootflash.c
字号:
/****************************************************************************
** File Name:Flash.c
** Function: The Flash(Now Only include AMD and SST type) driver
** Author:Tiny
** Date: Des.4 2002
** Ver:V1.0
** Modify:
** 2003.12.19 Zhouyuhui 增加获取BOOT类型和电压的函数
** 2004.05.10 FANLIHAN MODIFY
****************************************************************************/
#include "vxWorks.h"
#define _BOOTFLASH_BASE 0xFFF80000
#define _BOOTFLASH_SIZE 0x80000
/*zhou yuhui add boot flash type*/
#define FUJTU29F040C 1
#define AM29F040B 2
#define AM29LV040B 3
#define SST39VF040 4
#define SST39SF040 5
#define NOTSUPPORT 100
static unsigned short __AMD_ID[] = {
0x04A4, /*Fuj 29f040c */
0x01A4, /*AMD 29f040b */
0x014F /*AMD 29lv040 */
};
#define AMD_NUM (sizeof(__AMD_ID)/sizeof(unsigned short))
static unsigned short __SST_ID[] = {
0xBFD7, /*SST 39VF040 */
0xBFB7 /*SST 39SF040 */
};
#define SST_NUM (sizeof(__SST_ID)/sizeof(unsigned short))
#define __AMD_TYPE 1
#define __SST_TYPE 2
#define __UNKNOW_TYPE -1
static int Flash_Type;
int Boot_Type=0;
int Voltage_Type=0;
IMPORT STATUS taskDelay(int ticks);
/*extern void sndsCacheDisable(void);
extern void sndsCacheEnable( int cachesiz );*/
#ifndef SNDS_CACHE_8K
#define SNDS_CACHE_8K 0x10
#endif
/*-------------------------------------------------------------------*/
/* Local function prototypes */
/*-------------------------------------------------------------------*/
static unsigned char ReadReg(volatile unsigned char *Addr);
static void WriteReg(volatile unsigned char *Addr, unsigned char val);
int GetBootFlashType(unsigned long base);
static int EraseChip(unsigned long BaseAddr);
int FlashPrg(unsigned long BaseAddr, unsigned long Offset, unsigned char *BufAddr, unsigned int DataLen);
/*********************************************************************/
/* ReadReg : Read a value from an 8-bit memory-mapped register */
/* */
/* INPUTS: Addr: Address of register to read from */
/* */
/* OUTPUTS: register value */
/* */
/*********************************************************************/
static unsigned char ReadReg(volatile unsigned char *Addr) {
return (*(volatile unsigned char *)Addr);
}
/********************************************************************/
/* WriteReg : Write a value to an 8-bit register */
/* */
/* INPUTS : Addr : Address of register to write to */
/* val : Value to write */
/* */
/* OUTPUTS : None */
/* */
/********************************************************************/
static void WriteReg(volatile unsigned char *Addr, unsigned char val) {
*(volatile unsigned char *)Addr = val;
return;
}
/********************************************************************/
/* GetBootFlashType : Get the Flash Type */
/* */
/* INPUTS : base :the flash base address */
/* */
/* OUTPUTS : correct flash type or Error */
/* */
/********************************************************************/
int GetBootFlashType(unsigned long base)
{
unsigned short mid;
unsigned char li,hi;
unsigned int i;
WriteReg((volatile unsigned char *)(base + 0x555),0xAA);
WriteReg((volatile unsigned char *)(base + 0x2AA),0x55);
WriteReg((volatile unsigned char *)(base + 0x555),0x90);
/* 060706 lyf:
* A delay is necessary!
*/
taskDelay (1);
li = ReadReg((volatile unsigned char *)base);
hi = ReadReg((volatile unsigned char *)(base + 1));
mid = (li<<8)|hi;
for(i=0;i<AMD_NUM;i++)
{
if(__AMD_ID[i] == mid)
{
WriteReg((unsigned char *)(base),0xF0);
Boot_Type = (i+1);
return __AMD_TYPE;
}
}
WriteReg((volatile unsigned char *)(base + 0x5555),0xAA);
WriteReg((volatile unsigned char *)(base + 0x2AAA),0x55);
WriteReg((volatile unsigned char *)(base + 0x5555),0x90);
li = ReadReg((volatile unsigned char *)base);
hi = ReadReg((volatile unsigned char *)(base + 1));
mid = (li<<8)|hi;
for(i=0;i<SST_NUM;i++)
{
if(__SST_ID[i] == mid)
{
WriteReg((volatile unsigned char *)(base),0xF0);
Boot_Type = (i+4);
return __SST_TYPE;
}
}
Boot_Type = 100;
WriteReg((volatile unsigned char *)(base),0xF0);
return __UNKNOW_TYPE;
}
/********************************************************************/
/* FlashBlankCheck : check the Flash blank error */
/* */
/* INPUTS : base :the flash base address */
/* */
/* OUTPUTS : correct 0 or Error -1 */
/* */
/********************************************************************/
static int FlashBlankCheck(unsigned long base)
{
int i = 0;
for(i=0;i<_BOOTFLASH_SIZE;i++)
{
if(*(unsigned char *)(base + i) != 0xFF)
return -1;
}
return 0;
}
/********************************************************************/
/* CheckAddSum : calculate the sum */
/* */
/* INPUTS : base :the flash base address */
/* size :the memory size */
/* */
/* OUTPUTS : sum */
/* */
/********************************************************************/
static unsigned short CheckAddSum(unsigned long base,int size)
{
unsigned short Sum = 0;
int i;
if(((size % 2) == 0))
{
size = size/2;
for(i = 0;i< size;i++)
Sum += *(unsigned short *)(base + i*2);
return Sum;
}
else
{
size = size/2;
for(i = 0;i< size;i++)
Sum += *(unsigned short *)(base + i*2);
Sum += (*(unsigned char *)(base + size*2))<<8 ;
return Sum;
}
}
/*****************************************************
**Return
** 0:Ok
** -1:The ic isn't amdflash or sst
**-2:can't erase
**-3:can't program
******************************************************/
#define FLASH_OK 0
#define FLASH_ID_ERR -1
#define FLASH_ERASE_ERR -2
#define FLASH_PRAG_ERR -3
/********************************************************************/
/* WriteToBootFlash : flush the flash */
/* */
/* INPUTS : src :data begin */
/* len :data size */
/* */
/* OUTPUTS : correct or error */
/* */
/********************************************************************/
int WriteToBootFlash(unsigned char *src,int len)
{
int rc;
unsigned short SumCheckSrc = 0;
unsigned short SumCheckDes = 0;
/*sndsCacheDisable();*/
Flash_Type = rc = GetBootFlashType(_BOOTFLASH_BASE);
if(__UNKNOW_TYPE == rc)
{
/*sndsCacheEnable(SNDS_CACHE_8K);*/
return FLASH_ID_ERR; /*Not find the valid Flash -1*/
}
rc = EraseChip(_BOOTFLASH_BASE);
if(rc < 0 )
{
/*sndsCacheEnable(SNDS_CACHE_8K);*/
return FLASH_ERASE_ERR;
}
rc = FlashBlankCheck(_BOOTFLASH_BASE);
if(rc < 0 )
{
/*sndsCacheEnable(SNDS_CACHE_8K);*/
return FLASH_ERASE_ERR;
}
SumCheckSrc = CheckAddSum((unsigned long)src,len);
rc = FlashPrg(_BOOTFLASH_BASE,0,src,len) ;
if(rc < 0 )
{
/*sndsCacheEnable(SNDS_CACHE_8K);*/
return FLASH_PRAG_ERR;
}
SumCheckDes = CheckAddSum(_BOOTFLASH_BASE,len);
if(SumCheckDes != SumCheckSrc)
{
/*sndsCacheEnable(SNDS_CACHE_8K);*/
return FLASH_PRAG_ERR;
}
/*sndsCacheEnable(SNDS_CACHE_8K);*/
return FLASH_OK;
}
/********************************************************************/
/* EraseChip : Erases FLASH */
/* */
/* INPUTS : BaseAddr : Base address of FLASH to be erased */
/* Offset : Offset from base to start erasing. */
/* DataLen : Number of bytes to be written */
/* */
/* OUTPUTS : Success(0) or failure (-1) */
/* */
/********************************************************************/
static int EraseChip(unsigned long BaseAddr)
{
int i ;
if (__AMD_TYPE == Flash_Type )
{
WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xAA);
WriteReg((volatile unsigned char *)(BaseAddr + 0x2AA), 0x55);
WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0x80);
WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xAA);
WriteReg((volatile unsigned char *)(BaseAddr + 0x2AA), 0x55);
WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0x10);
}
else if(__SST_TYPE == Flash_Type)
{
WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xAA);
WriteReg((volatile unsigned char *)(BaseAddr + 0x2AAA), 0x55);
WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0x80);
WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xAA);
WriteReg((volatile unsigned char *)(BaseAddr + 0x2AAA), 0x55);
WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0x10);
}
else
return(-1);
i = 1000;
while (i--)
{
taskDelay(1);
/* poll until the erase is complete */
if ((ReadReg((volatile unsigned char *)BaseAddr) & 0x80) != 0)
{
break;
}
if ((ReadReg((volatile unsigned char *)BaseAddr) & 0x20) != 0)
{
if ((ReadReg((volatile unsigned char *)BaseAddr) & 0x80)!=0)
{
break;
}
else
{
return(-2);
}
}
}
taskDelay(100);
WriteReg((volatile unsigned char *)(BaseAddr), 0xF0);
return(0);
}
void FB_DELAY(unsigned long nusecs)
{
unsigned long j, k, i=0x1234;
while(nusecs--)
{
for (j=0; j<30; j++)
k = j * i;
k = k + 1;
}
}
/*******************************************************************/
/* FlashPrg : This function is used to store data in the FLASH. */
/* */
/* INPUTS : BaseAddr : Base address of FLASH */
/* Offset : Offset from base to start programming */
/* BufAddr : Pointer to buffer which contains data */
/* DataLen : Number of bytes to be written */
/* */
/* OUTPUTS : Write operation successful (0) or not (-1) */
/* */
/*******************************************************************/
int FlashPrg(unsigned long BaseAddr, unsigned long Offset, unsigned char *BufAddr, unsigned int DataLen)
{
unsigned int i, retry;
unsigned char *start;
unsigned char data, status;
i=0;
start = (unsigned char *)(BaseAddr + Offset);
while(1)
{
data = status = BufAddr[i];
status ^= 0xFF;
status &= 0x80;
if (data != 0xFF)
{
if (__AMD_TYPE == Flash_Type)
{
WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xAA);
WriteReg((volatile unsigned char *)(BaseAddr + 0x2AA), 0x55);
WriteReg((volatile unsigned char *)(BaseAddr + 0x555), 0xA0);
}
else if(__SST_TYPE == Flash_Type)
{
WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xAA);
WriteReg((volatile unsigned char *)(BaseAddr + 0x2AAA), 0x55);
WriteReg((volatile unsigned char *)(BaseAddr + 0x5555), 0xA0);
}
else
return(-1);
/* Write data to the next ROM address */
*start = data;
retry = 50;
while (retry--)
{
if ((ReadReg((volatile unsigned char *)start) & 0x80) != status)
break;
else
FB_DELAY(1);
}
if (!retry)
return(-2);
}
/* Increment to the next ROM address and the next byte of data. */
i++;
start++;
/* Exit when finished. */
if (i == DataLen)
break;
}
*start = 0xF0;
return(0);
}
void GetVoltage()
{
unsigned char BtType;
BtType = Boot_Type;
switch(BtType)
{
case FUJTU29F040C:
Voltage_Type = 2;
break;
case AM29F040B:
Voltage_Type = 2;
break;
case AM29LV040B:
Voltage_Type = 1;
break;
case SST39VF040:
Voltage_Type = 1;
break;
case SST39SF040:
Voltage_Type = 2;
break;
default:
Voltage_Type = 100;
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -