📄 flash.c
字号:
/*****************************************
*
*
*****************************************/
#include <reg52.h>
#include <string.h>
#include <intrins.h>
#include <stdio.h>
#include <absacc.h>
#include "FlashRam.h"
unsigned char xdata eeprom[0x2000] _at_ 0x0000;
unsigned char xdata pageSel _at_ 0x6000;
unsigned char data FlashType; // Flash型号
unsigned long fAddr = 0;
extern void dog();
//=========================================
//
//=========================================
void Check_Toggle_Ready(unsigned int addr)
{
unsigned char data preTmp;
unsigned char data currTmp;
preTmp = eeprom[addr] & 0x40;
while(1)
{
currTmp = eeprom[addr] & 0x40;
if (preTmp == currTmp)
{
break;
}
preTmp = currTmp;
}
}
//=========================================
// 解锁SST28SF040A
//=========================================
void eepUnlock(void)
{
unsigned char data tmp;
tmp = eeprom[0x1823];
tmp = eeprom[0x1820];
tmp = eeprom[0x1822];
tmp = eeprom[0x0418];
tmp = eeprom[0x041B];
tmp = eeprom[0x0419];
tmp = eeprom[0x041A];
}
//=========================================
// 读取器件ID
// 成功: 返回1,否则返回0
//=========================================
char eepGetChipId(void)
{
unsigned char data cId[2];
pageSel = 0x00; // 页址
eeprom[0] = 0xff; // reset command
_nop_();
eeprom[0] = 0x90; // read id
_nop_();
cId[0] = eeprom[0];
cId[1] = eeprom[1];
eeprom[0] = 0xff;
if ((cId[0] == 0xbf) && (cId[1] == 0x04))
{
eepUnlock();
FlashType = cId[1];
return 1;
}
eeprom[0] = 0xf0; // 取消所有操作
_nop_();
_nop_();
eeprom[0x0555] = 0xAA;
eeprom[0x02AA] = 0x55;
eeprom[0x0555] = 0x90; // Software ID Entry Command
_nop_(); // Wait TIDA
_nop_();
cId[0] = eeprom[0x0000]; // Manufacturer’s ID = BFH
cId[1] = eeprom[0x0001]; // SST29SF040 Device ID = 13H
eeprom[0x0555] = 0xAA;
eeprom[0x02AA] = 0x55;
eeprom[0x0555] = 0xF0; // Software ID Entry Command
_nop_(); // Wait TIDA
if (cId[0] == 0xbf)
{
FlashType = cId[1];
return 1;
}
FlashType = NONE_FLASH;
return 0;
}
//=========================================
//
//=========================================
void eepEraseChip(void)
{
pageSel = 0;
switch(FlashType)
{
case SST28SF040A:
eeprom[0] = 0x30;
eeprom[0] = 0x30;
Check_Toggle_Ready(0);
break;
case SST29SF040:
eeprom[0x0555] = 0xAA;
eeprom[0x02AA] = 0x55;
eeprom[0x0555] = 0x80;
eeprom[0x0555] = 0xAA;
eeprom[0x02AA] = 0x55;
eeprom[0x0555] = 0x10;
Check_Toggle_Ready(0);
break;
default:
break;
}
}
//==================================================
// 擦除扇区
// input: 扇区起始地址
// output: 1=成功
//==================================================
char eepEraseSector(unsigned int addr)
{
unsigned char data try;
int data cnt, block_size;
unsigned data addr_mask;
try = 0;
while (try<3)
{
switch(FlashType)
{
case SST28SF040A:
addr_mask=0x1f00;
addr=addr&0x1f00;
block_size = 256;
eeprom[addr] = 0x20;
eeprom[addr] = 0xD0;
Check_Toggle_Ready(addr);
break;
case SST29SF040:
addr_mask=0x1f80;
addr=addr&0x1f80;
block_size=128;
eeprom[0x0555] = 0xAA;
eeprom[0x02AA] = 0x55;
eeprom[0x0555] = 0x80;
eeprom[0x0555] = 0xAA;
eeprom[0x02AA] = 0x55;
eeprom[addr] = 0x20;
Check_Toggle_Ready(addr);
break;
default:
return 0; // 失败
}
for (cnt=0; cnt<block_size; cnt++)
{
if (eeprom[addr&addr_mask + cnt] != 0xff) // 检查扇区是否全部擦空
{
break;
}
}
if ( cnt > block_size-1)
{
return 1;
}
++try; // 未擦空,重擦
}
return 0;
}
//=========================================
// 字节编程
// input: addr=地址
// dat=数据
// output: ---
//=========================================
void eepProgramByte(unsigned int addr,unsigned char dat)
{
switch(FlashType)
{
case SST28SF040A:
eeprom[addr] = 0x10; // AUTO_PGRM
eeprom[addr] = dat;
Check_Toggle_Ready(addr);
break;
case SST29SF040:
eeprom[0x0555] = 0xAA;
eeprom[0x02AA] = 0x55;
eeprom[0x0555] = 0xA0;
eeprom[addr] = dat;
Check_Toggle_Ready(addr);
break;
default:
break;
}
}
//=========================================
//
//=========================================
unsigned char eepReadByte(unsigned long addr)
{
pageSel = (unsigned char)(addr>>13);
return (eeprom[addr&0x1fff]);
}
//=========================================
//
//=========================================
void eepWriteRam(unsigned long addr,unsigned char dat)
{
bit _ea_save;
int block_size;
_ea_save = EA;
EA = 0;
switch (FlashType)
{
case SST28SF040A:
block_size=256;
break;
case SST29SF040:
block_size=128;
break;
default:
EA = _ea_save;
return;
}
pageSel = (unsigned char)(addr>>13); // 页选
if (eeprom[addr&0x1fff] != 0xff) // 数据不为空
{
int data cnt;
unsigned char xdata tmpBuffer[256];
unsigned int mask;
if (FlashType == SST28SF040A)mask=0x1f00;
else mask=0x1f80;
for (cnt=0; cnt<block_size; cnt++)
{
tmpBuffer[cnt] = eeprom[ addr&mask + cnt]; // 读
}
eepEraseSector(addr); // 擦除扇区
// DOG = !DOG;
dog();
if (FlashType == SST28SF040A)tmpBuffer[addr&0x00ff] = dat; // 改
else tmpBuffer[addr&0x007f] = dat;
for (cnt=0; cnt<block_size; cnt++)
{
eepProgramByte(addr&mask + cnt, tmpBuffer[cnt]); // 写
}
}
else // 直接写入
{
eepProgramByte(addr & 0x1fff, dat);
}
EA = _ea_save;
}
//=========================================
//
//=========================================
void eepWrite(unsigned long addr,unsigned char dat)
{
bit _ea_save;
unsigned char mask;
_ea_save = EA;
EA = 0;
pageSel = (unsigned char)(addr>>13); // 页选
if (FlashType==SST28SF040A)mask=0xff;
else mask=0x7f;
if ((addr&mask)==0)
{
eepEraseSector(addr); // 擦除扇区
}
dog();
eepProgramByte(addr & 0x1fff, dat);
EA = _ea_save;
}
int fopen(void)
{
fAddr = 0;
if (FlashType != NONE_FLASH)
return 1;
return -1;
}
int fread(unsigned char *buff, int len)
{
int rlen;
int cnt;
if (fAddr>0x7ffff)return -1;
rlen = 0;
for (cnt=0; cnt<len; cnt++)
{
++rlen;
buff[cnt] = eepReadByte(fAddr++);
if (fAddr>0x7ffff)break;
}
return rlen;
}
int fwrite(unsigned char *buff, int len)
{
int wlen;
int cnt;
if (fAddr>0x7ffff)return -1;
wlen = 0;
for (cnt=0; cnt<len; cnt++)
{
eepWrite(fAddr, buff[cnt]);
++wlen;
++fAddr;
if (fAddr>0x7ffff)break;
}
return wlen;
}
void fclose(void)
{
fAddr=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -