📄 flash.c
字号:
/*----------Copyright 2006-2010 武汉菱电汽车电子有限公司-----------------------
* 项目名称: 汽车诊断仪
* 开发工具: uV2 Keil C51
* 程序名称: flash.c
* 作者: 朱坤
* 写作时间: 2006/03/02
*
* 程序说明:
* 提供操作 Flash 的基本功能
* 1、复位flash:void ResetFlash(void)
* 2、擦除扇区: bit EraseSector(u16 wSA)
* 3、全片擦除: bit EraseFlash(void)
* 4、读Flash: u8 ReadFlash(u16 wPA)
* 5、编程Flash:bit WriteFlash(u16 wPA, u8 uPD)
* 6、初始化: void InitFlash(void)
* 返回 TRUE 表示操作成功,FLASE 表示操作失败
*
* 修改记录:
*
*---------------------------------------------------------------------------*/
//#pragma SRC
//#pragma SMALL
//#pragma OPTIMIZE(SIZE)
#include "flash.h"
/*-----------------------------------------------------------------------------
* Read 1 RA RD
* Reset 1 XXX F0
* Autoselect
* Manufacturer ID
* Word 4 555 AA 2AA 55 555 90 X00 01
* Byte AAA 555 AAA
* Device ID(Top Boot Block)
* Word 4 555 AA 2AA 55 555 90 X01 22D2
* Byte AAA 555 AAA X02 D2
* Device ID(Bottom Boot Block)
* Word 4 555 AA 2AA 55 555 90 X01 22D8
* Byte AAA 555 AAA X02 D8
* Sector Protect Verify
* Word 4 555 AA 2AA 55 555 90 (SA) X02 XX00
* XX01
* Byte AAA 555 AAA (SA) X04 00
* 01
* CFI Query (Note 10)
* Word 1 555 98
* Byte AAA
* Program
* Word 4 555 AA 2AA 55 555 A0 PA PD
* Byte AAA 555 AAA
* Unlock Bypass
* Word 3 555 AA 2AA 55 555 20
* Byte AAA 555 AAA
* Unlock Bypass Program 2 XXX A0 PA PD
* Unlock Bypass Reset 2 XXX 90 XXX 00
* Chip Erase
* Word 6 555 AA 2AA 55 555 80 555 AA 2AA 55 555 10
* Byte AAA 555 AAA AAA 555 AAA
* Sector Erase
* Word 6 555 AA 2AA 55 555 80 555 AA 2AA 55 SA 30
* Byte AAA 555 AAA AAA 555
* Erase Suspend 1 XXX B0
* Erase Resume 1 XXX 30
* --------------------------------------------------------------------------*/
/* 检查操作是否完成 */
BOOLEAN ToggleBitI(void)
{
u8 uData1,uData2;
//u8 i;
uData1 = XBYTE[Addr_Flash];
//i = 255;
//while(i--){
while(1){
WD_Refresh(); /* 刷新看门狗 */
uData2 = XBYTE[Addr_Flash];
if (((uData1 ^ uData2) & 0x40) == 0){ /* D6 */
return TRUE;
} else if ((uData2 & 0x20) == 0x20){ /* D5 */
uData1 = XBYTE[Addr_Flash];
uData2 = XBYTE[Addr_Flash];
if (((uData1 ^ uData2) & 0x40) == 0){ /* D6 */
return TRUE;
} else { /* 操作错误 */
ResetFlash(); /* 复位 */
return FALSE;
}
}
uData1 = uData2;
}
return FALSE;
}
/* Program
* Byte 4 AAA AA 555 55 AAA A0 PA PD
* 这儿假设已经设置 Flash 的页地址 */
BOOLEAN WriteFlash(u16 wPA, u8 uPD)
{
XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
XBYTE[Addr_Flash|0x555] = 0x55;
XBYTE[Addr_Flash|0x0AAA] = 0x0A0;
XBYTE[wPA] = uPD;
/* 检查是否完成 */
ToggleBitI();
if (XBYTE[wPA] == uPD){
return TRUE;
}
return FALSE;
}
/* Sector Erase
* Byte 6 AAA AA 555 55 AAA 80 AAA AA 555 55 SA 30
* 这儿假设已经设置 Flash 的页地址 */
BOOLEAN EraseSector(u16 wSA)
{
XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
XBYTE[Addr_Flash|0x555] = 0x55;
XBYTE[Addr_Flash|0x0AAA] = 0x80;
XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
XBYTE[Addr_Flash|0x555] = 0x55;
if ((wSA & 0x7fff)!= 0){
XBYTE[wSA] = 0x30;
} else {
XBYTE[Addr_Flash|0xAAA] = 0x10;
}
/* 检查是否完成 */
return ToggleBitI();
}
/* 初始化
* Autoselect
* Manufacturer ID
* Word 4 555 AA 2AA 55 555 90 X00 01
* Byte AAA 555 AAA
* Device ID(Top Boot Block AM29F160D)
* Word 4 555 AA 2AA 55 555 90 X01 22D2
* Byte AAA 555 AAA X02 D2
* Device ID(Bottom Boot Block AM29F160D)
* Word 4 555 AA 2AA 55 555 90 X01 22D8
* Byte AAA 555 AAA X02 D8
* Sector Protect Verify
* Word 4 555 AA 2AA 55 555 90 (SA) X02 XX00
* XX01
* Byte AAA 555 AAA (SA) X04 00
* 01 */
u16 InitFlash(void)
{
u16 i;
XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
XBYTE[Addr_Flash|0x555] = 0x55;
XBYTE[Addr_Flash|0x0AAA] = 0x90;
i = (XBYTE[Addr_Flash|0x02] * 256) + XBYTE[Addr_Flash|0x00];
ResetFlash(); /* 复位 */
return i;
}
/* Chip Erase
* Byte 6 AAA AA 555 55 AAA 80 AAA AA 555 55 AAA 10 */
/*
bit EraseFlash(void)
{
XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
XBYTE[Addr_Flash|0x555] = 0x55;
XBYTE[Addr_Flash|0x0AAA] = 0x80;
XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
XBYTE[Addr_Flash|0x555] = 0x55;
XBYTE[Addr_Flash|0xAAA] = 0x10;
// 检查是否完成
return ToggleBitI();
}
*/
/* 编程 Flash
* dPA: 编程起始地址[注意: 线性地址,不考虑分区]
* upPD: 被编程的数据指针, 数据限定在外存[xdata]当前页内
* uLen: 被编程的数据字节数[若为 0,则不执行编程操作]
*
* 本过程没有检查 Flash 地址是否超过允许范围,
* 也没有检测被编程的数据字节数是否超出允许范围,
* 所有参数都需要调用者保证合法。 */
/*
bit ProgramFlash(FourBytes dAddr, u8 xdata *upPD, u16 uLen)
{
u8 uPage;
u8 uOldPage;
bit bResult;
// 设置 Flash 的页地址
uOldPage = GetCurrentBank();
uPage = dAddr.b_form.hl << 1;
if ((dAddr.b_form.lh & 0x80) != 0x00){
uPage++;
}
SwitchBank(uPage);
// 数据最大长度不允许超过 16K
bResult = TRUE;
if ((uLen > Len_SRAM) ||
(upPD < (u8 xdata *)Addr_SRAM)||
((upPD+uLen) >= (u8 xdata *)(Addr_SRAM+Len_SRAM))){
bResult = FALSE;
}
while(bResult && (uLen-- != 0x0000)){
// 如果到了扇区[Sector]的开头位置,擦除扇区
// 我只支持 Bottom Boot Block 型的 flash
if ((dAddr.b_form.ll == 0x00) &&
((dAddr.b_form.lh == 0x00) ||
((dAddr.b_form.hl == 0x00) &&
((dAddr.b_form.lh == 0x40) ||
(dAddr.b_form.lh == 0x60) ||
(dAddr.b_form.lh == 0x80))))){
bResult = EraseSector(dAddr.w_form.lo|Addr_Flash);
}
if (bResult){
bResult = WriteFlash(dAddr.w_form.lo|Addr_Flash, *upPD++);
// 如果到了分区[BANK]的开头,切换分区
if ((dAddr.w_form.lo & 0x7fff) == 0x7fff){
SwitchBank(++uPage);
}
}
dAddr.d_form++;
}
// 恢复 Flash 当前活动页
SwitchBank(uOldPage);
return bResult;
}
*/
/*----------Copyright 2006-2010 武汉菱电汽车电子有限公司---------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -