📄 flash.c
字号:
/*------------------------------------------------------------------*/
/*模块名称:flash.c */
/*模块功能:flash底层驱动程序 */
/*编写日期:2004年9月 */
/*编写者: zxd */
/*------------------------------------------------------------------*/
#include "../ucos_ii/includes.h"
/*------------------------------------------------------------------*/
/*函数名称:FlashisEmpty() */
/*函数功能:检查flash是否为空 */
/*输入说明:base--flash基址;sector--检查的扇区 */
/*输出说明:为空时返回TRUE */
/*------------------------------------------------------------------*/
BOOL FlashisEmpty(u_int base, u_char sector)
{
u_int c, offset;
u_int aa;
u_int SECTOR_SIZE;
if (sector >= SECTOR_NUM)
return FALSE;
if(sector<8) //前8个扇区
{
SECTOR_SIZE = 0x1000;
offset = sector*SECTOR_SIZE;
}
else if(sector<39) //后31个扇区
{
SECTOR_SIZE = 0x8000;
offset = 8*0x1000 + (sector-8)*SECTOR_SIZE;
}
else //整片flash
{
SECTOR_SIZE = 0x100000;
offset = 0;
}
IDExit(base);
for(c=0; c<SECTOR_SIZE; c++,offset++)
{
aa = REG16(base+(offset<<1));
if(aa != 0xffff)
return FALSE;
}
return TRUE;
}
/*------------------------------------------------------------------*/
/*函数名称:FlashErase() */
/*函数功能:扇区擦除,不成功重擦,最多擦三遍 */
/*输入说明:base--flash基址;sector--扇区 */
/*输出说明:成功返回TRUE */
/*------------------------------------------------------------------*/
BOOL FlashErase(u_int base,u_char sector)
{
BOOL rc = TRUE, flag = FALSE;
u_char i;
u_int offset;
if (sector > SECTOR_NUM)
return FALSE;
if(sector<8) //前8个扇区
{
offset = sector*0x1000;
}
else if(sector<39) //后31个扇区
{
offset = 8*0x1000 + (sector-8)*0x8000;
}
else //整片flash
{
offset = 0;
flag = TRUE;
}
for (i=0; i<2; i++)
{
if (rc)
{
rc = FlashisEmpty(base, sector);
if (rc)
{
IDExit(base);
return (TRUE);
}
}
rc = FlashEraseCore(base, offset, flag);
}
IDExit(base);
return (FALSE);
}
/*------------------------------------------------------------------------
Procedure: FlashEraseCore ID:1
Purpose: 扇区擦除[可以代替整片擦除,时间相同,更灵活]
Input: base:基址;sector:扇区号[从0计数].
Output: 0: 成功
Errors:
------------------------------------------------------------------------*/
BOOL FlashEraseCore(u_int base, u_int offset, BOOL flag)
{
flash_word value, value_new;
REG16(base+(0x555<<1)) = (0xAAAA);
REG16(base+(0xAAA<<1)) = (0x5555);
REG16(base+(0x555<<1)) = (0x8080);
REG16(base+(0x555<<1)) = (0xAAAA);
REG16(base+(0xAAA<<1)) = (0x5555);
if (flag)
REG16(base+(0x555<<1)) = (0x1010);
else
REG16(base+(offset<<1)) = (0x3030);
value = REG16(base+(offset<<1));
while(1)
{
value_new = REG16(base+(offset<<1));
if((value & 0x44) == (value_new & 0x44))
break;
if (value_new & (DQ5 | DQ3))
{
value = REG16(base+(offset<<1));
value_new = REG16(base+(offset<<1));
if((value & 0x44) == (value_new & 0x44))
break;
else
{
IDExit(base);
return FALSE;
}
}
value = value_new;
}
IDExit(base);
return TRUE;
}
/*------------------------------------------------------------------------
Procedure: FlashWrite ID:1
Purpose: 写入[不考虑扇区擦除]
Input: base:基址;offset:偏移地址.
Output:
Errors:
------------------------------------------------------------------------*/
int FlashWrite(u_int base,u_int offset, u_char *pbuf, u_int count)
{
u_int dd, c, rc;
u_short val, tmp;
flash_word value, value_new;
rc = 0;
dd = (count + 1) / 2;
for (c=0; c<dd; c++,offset+=2)
{
if ((count%2) && (c == (dd-1)))
{
val = *(pbuf+rc) | 0xFF00;
rc++;
}
else
{
val = *(pbuf+rc) | (*(pbuf+rc+1))<<8;
rc+=2;
}
REG16(base+(0x555<<1)) = 0xAAAA;
tmp++;
tmp++;
REG16(base+(0xAAA<<1)) = 0x5555;
tmp++;
tmp++;
REG16(base+(0x555<<1)) = 0xA0A0;
tmp++;
tmp++;
REG16(base+(offset)) = val;
tmp++;
tmp++;
value = REG16(base+(offset));
tmp++;
tmp++;
tmp++;
tmp++;
while(1)
{
value_new = REG16(base+(offset));
if((value & DQ6) == (value_new & DQ6))
break;
if (value_new & (DQ5 | DQ3))
{
value = REG16(base+(offset));
tmp++;
tmp++;
tmp++;
tmp++;
value_new = REG16(base+(offset));
if((value & DQ6) == (value_new & DQ6))
break;
else
{
IDExit(base);
return -1;
}
}
value = value_new;
}
//校验
IDExit(base);
value = REG16(base+(offset));
if (val != value)
return -1;
}
return rc;
}
/*------------------------------------------------------------------------
Procedure: Flashread ID:1
Purpose: 读出[不考虑扇区擦除]
Input: base:基址;offset:偏移地址.
Output:
Errors:
------------------------------------------------------------------------*/
int FlashRead(u_int base,u_int offset, u_char *pbuf, u_int count)
{
u_int i, rc;
u_short val;
IDExit(base);
rc = 0;
for(i=0; i<(count/2)*2; i+=2,offset+=2)
{
rc += 2;
val = REG16(base+(offset));
*(pbuf+i) = (u_char)(val & 0xFF);
*(pbuf+i+1) = (u_char)((val & 0xFF00) >>8);
}
if (count%2)
{
rc++;
val = REG16(base+(offset));
*(pbuf+i) = (u_char)(val & 0xFF);
}
return rc;
}
/*------------------------------------------------------------------*/
/*函数名称:IDExit() */
/*函数功能:退出相关操作进入正常读模式 */
/*输入说明:base--flash基址 */
/*------------------------------------------------------------------*/
void IDExit(u_int base)
{
REG16(base+(0x555)) = (0xAAAA);
REG16(base+(0xAAA)) = (0x5555);
REG16(base+(0x555)) = (0xF0F0);
}
/*------------------------------------------------------------------*/
/*函数名称:SetCFG() */
/*函数功能:设置flash模式 */
/*输入说明:base--flash基址 */
/*------------------------------------------------------------------*/
void SetCFG(u_int base)
{
REG16(base+(0x555)) = (0xAAAA);
REG16(base+(0xAAA)) = (0x5555);
REG16(base+(0x555)) = (0xD0D0);
REG16(base) = (0x0101);
IDExit(base);
}
/*------------------------------------------------------------------*/
/*函数名称:Read_Manufactuer_Code() */
/*函数功能:读出falsh出厂信息 */
/*输入说明:base--flash基址 */
/*------------------------------------------------------------------*/
int Read_Manufactuer_Code(u_int base)
{
int Manufactuer,Code;
REG16(base+(0x555<<1)) = (0xAAAA);
REG16(base+(0xAAA<<1)) = (0x5555);
REG16(base+(0x555<<1)) = (0x9090);
Manufactuer = REG16(base);
Code = REG16(base + 2);
REG16(base) = (0xF0F0);
return (Manufactuer + (Code<<8));
}
void ReadCFI(u_int base, INT16U* pData)
{
INT16U i;
REG16(base+(0x55<<1)) = (0x9898);
for (i=0; i<37; i++)
{
pData[i] = REG16(base + ((i+0x10)<<1));
}
IDExit(base);
}
int SectorCpy(u_char DSector, u_char SSector)
{
u_int size;
u_int saddr, daddr;
if (((SSector<8) && (DSector>=8)) || ((SSector>=8) && (DSector<8)))
return (0);
if (SSector<8)
{
size = 0x2000;
saddr = SSector * 0x2000;
daddr = DSector * 0x2000;
}
else
{
size = 0x10000;
saddr = SSector * 0x10000;
daddr = DSector * 0x10000;
}
return (FlashCpy(daddr, saddr, size));
}
int FlashCpy(u_int Daddr, u_int Saddr, u_int count)
{
u_int offset;
u_int i, base;
u_short tmp;
flash_word val, value, value_new;
base = FLASH_BASE;
IDExit(base);
offset = 0;
for(i=0; i<(count+1)/2; i++,offset+=2)
{
IDExit(base);
val = REG16(base + Saddr +(offset));
REG16(base+(0x555<<1)) = 0xAAAA;
tmp++;
REG16(base+(0xAAA<<1)) = 0x5555;
tmp++;
REG16(base+(0x555<<1)) = 0xA0A0;
tmp++;
REG16(base + Daddr + offset) = val;
tmp++;
REG16(base) = 0x3030;
tmp++;
value = REG16(base + Daddr + offset);
tmp++;
tmp++;
tmp++;
tmp++;
while(1)
{
value_new = REG16(base + Daddr + offset);
if((value & 0x40) == (value_new & 0x40))
break;
if (value_new & (DQ5 | DQ3))
{
value = REG16(base + Daddr + offset);
tmp++;
tmp++;
tmp++;
tmp++;
value_new = REG16(base + Daddr + offset);
if((value & 0x40) == (value_new & 0x40))
break;
else
{
IDExit(base);
return -1;
}
}
value = value_new;
}
IDExit(base);
}
return (offset);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -