📄 sst39vf160.c
字号:
sectorAddr = sectorAddr + flashSectorSize;
}
if (sectorAddr == (blockAddr + flashBlockSize)) {
blockAddr = blockAddr + flashBlockSize;
}
}
if (sectorAddr < endPoint) {
while ((blockAddr + flashBlockSize) <= endPoint) {
eraseChip(ERASE_BLOCK, blockAddr, 1);
blockAddr = blockAddr + flashBlockSize;
}
sectorAddr = blockAddr;
while (sectorAddr < endPoint) {
eraseChip(ERASE_SECTOR, sectorAddr, 1);
sectorAddr = sectorAddr + flashSectorSize;
}
}
sectorAddr = getSectorAddr(aAddr); //重新获取数据
blockAddr = getBlockAddr(aAddr);
//恢复扇区开始处的数据
tmpAddr = sectorAddr;
tmpData = flashStaDataBack;
for (uIndex = 0; uIndex < uBakStaDataCnt; uIndex ++) {
uRetCode = writeFlashWord(tmpAddr , *tmpData);
if (FLASH_OK != uRetCode) {
goto ENDPROC;
}
tmpAddr = tmpAddr + 1;
tmpData = tmpData + 1;
}
//写数据
uTmpAddr = aAddr;
tmpData = aData;
for (uIndex = 0; uIndex < aLength; uIndex ++) {
tmpAddr = GetAddr(uTmpAddr);
uRetCode = writeFlashWord(tmpAddr, *tmpData);
if (FLASH_OK != uRetCode) {
break;
}
uTmpAddr = uTmpAddr + 1;
tmpData = tmpData + 1;
}
//恢复扇区末尾处的数据
tmpAddr = endPoint;
tmpData = flashEndDataBack;
for (uIndex = 0; uIndex < uBakEndDataCnt; uIndex ++) {
uRetCode = writeFlashWord(tmpAddr , *tmpData);
if (FLASH_OK != uRetCode) {
goto ENDPROC;
}
tmpAddr = tmpAddr + 1;
tmpData = tmpData + 1;
}
ENDPROC:
return uRetCode;
}
uint16 readFlashBuff(uint16 aAddr, uint16 *aData, uint16 aLength)
{
uint16 uIndex = 0;
uint16 *pTmpData;
volatile uint16 *addr;
pTmpData = aData;
for (uIndex = 0; uIndex < aLength; uIndex ++) {
addr = GetAddr(aAddr);
*pTmpData = *addr;
pTmpData = pTmpData + 1;
aAddr = aAddr + 1;
}
return uIndex;
}
void preEraseChip(void)
{
volatile uint16 *addr;
addr = GetAddr(0x5555);
addr[0] = 0xAAAA; // 第一个写周期,地址0x5555,数据0xAA
addr = GetAddr(0x2AAA);
addr[0] = 0x5555; // 第二个写周期,地址0x2aaa,数据0x55
addr = GetAddr(0x5555);
addr[0] = 0x8080; // 第三个写周期,地址0x5555,数据0x80
addr = GetAddr(0x5555);
addr[0] = 0xAAAA; // 第四个写周期,地址0x5555,数据0xAA
addr = GetAddr(0x2AAA);
addr[0] = 0x5555; // 第五个写周期,地址0x2aaa,数据0x55
}
uint16 eraseChip(eraseType aFlag,volatile uint16 *aAddr, uint16 aNumber)
{
uint16 uIndex = 0;
uint16 temp1 = 0;
uint16 temp2 = 0;
volatile uint16 *tmpAddr = 0;
uint8 uRetCode = FLASH_OK;
volatile uint16 *addr;
switch (aFlag)
{
case ERASE_ALL: //擦除芯片
preEraseChip();
addr = GetAddr(0x5555);
addr[0] = 0x1010; // 第六个写周期,地址0x5555,数据0x10
while (1) { // 等待操作完成 (若擦除操作没有完成,每次读操作DQ6会跳变)
temp1 = *addr;
temp2 = *addr;
if (temp1 == temp2) {
if (temp1 != 0xFFFF) {
uRetCode = FLASH_NG;
}
break;
}
}
break;
case ERASE_BLOCK: //删除块
tmpAddr = aAddr;
for (uIndex = 0; uIndex < aNumber; uIndex++) {
tmpAddr = tmpAddr + (uIndex * flashBlockSize);
preEraseChip();
tmpAddr[0] = 0x5050; // 第六个写周期,地址:要删扇区块地址数据0xXX500
while (1) { // 等待操作完成 (若擦除操作没有完成,每次读操作DQ6会跳变)
temp1 = *tmpAddr;
temp2 = *tmpAddr;
if (temp1 == temp2) {
break;
}
}
}
break;
case ERASE_SECTOR: //删除扇区
tmpAddr = aAddr;
for (uIndex = 0; uIndex < aNumber; uIndex++) {
tmpAddr = tmpAddr + (uIndex * flashSectorSize);
preEraseChip();
tmpAddr[0] = 0x3030; // 第六个写周期,地址:要删除块地址,数据0xXX30
while (1) { // 等待操作完成 (若擦除操作没有完成,每次读操作DQ6会跳变)
temp1 = *tmpAddr;
temp2 = *tmpAddr;
if (temp1 == temp2) {
break;
}
}
}
break;
}
return uRetCode;
}
//进入查询入口命令状态(CFI)
void enterCFISatus(void)
{
volatile uint16 *addr;
uint16 i,k;
addr = GetAddr(0x5555); // 第一个写周期,地址5555H,数据XXAAH
addr[0] = 0xAAAA;
addr = GetAddr(0x2AAA); // 第二个写周期,地址2AAAH,数据XX55H
addr[0] = 0x5555;
addr = GetAddr(0x5555); // 第三个写周期,地址5555H,数据XX98H
addr[0] = 0x9898;
for (i = 0; i < 500; i++) { //等待 TIDA //TODO
for (k = 0; k < 100; k++) {
}
}
}
//进入正常工作模式
void enterNormalSatus(void)
{
volatile uint16 *addr;
uint16 i,k;
addr = GetAddr(0x5555); // 第一个写周期,地址5555H,数据XXAAH
addr[0] = 0xAAAA;
addr = GetAddr(0x2AAA); // 第二个写周期,地址2AAAH,数据XX55H
addr[0] = 0x5555;
addr = GetAddr(0x5555); // 第三个写周期,地址5555H,数据XX98H
addr[0] = 0xF0F0;
for (i = 0; i < 500; i++) { //等待 TIDA //TODO
for (k = 0; k < 100; k++) {
}
}
}
uint16 readCFI(uint16 aAddr)
{
volatile uint16 *tmpAddr;
tmpAddr = GetAddr(aAddr);
return tmpAddr[0];
}
/****************************************************************************
* 名称:main()
* 功能:SST39VF160擦除、编程操作。
****************************************************************************/
uint16 first, second, third, fourth;
uint16 mytest[64];
uint16 game[16];
int main(void)
{
uint16 i;
uint8 err = 0;
uint8 *tmp;
volatile uint16 *addr;
eraseType flags = ERASE_SECTOR;
PINSEL0 = 0x00000000; // 设置管脚连接GPIO
IO0DIR = BEEPCON; // 设置I/O为输出
flashInitial();
// eraseChip(flags, 0x00, 1); // FLASH全片擦除
// 校验是否真正擦除。若发现有非0xFFFF的存储单元,设置err=1
addr = GetAddr(0);
for(i=0; i<100; i++)
{ if(0xFFFF != (*addr)) err = 1;
addr++;
}
tmp = (uint8 *)game;
for (i = 0 ; i < 16 * 2 ; i++) {
*tmp = 'C';
tmp++;
}
writeFlashBuff(0x00, game, 16 * 2);
i = readFlashBuff(0x10, mytest, 16);
// writeFlashWord(0, 0x55BB); // 向FLASH的0地址写入0x55AA
//
// writeFlashWord(2, 0xDDDD);
// writeFlashWord(0, 0xDDDD);
addr = GetAddr(0);
if(0x55AA != (*addr)) err = 1; // 读出校验,若数据错误则设置err=1
if(0==err)
{ IO0CLR = BEEPCON; // BEEPCON = 0
DelayNS(20);
IO0SET = BEEPCON; // BEEPCON = 1
DelayNS(20);
}
else
{
while(1)
{
IO0CLR = BEEPCON; // BEEPCON = 0
DelayNS(10);
IO0SET = BEEPCON; // BEEPCON = 1
DelayNS(10);
}
}
while(1);
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -