📄 kw_nand.c
字号:
/**************************************************************************************
Copyright (C), 1988-1999, Xi'an Keyway Control & Measurement Technology Co., Ltd
FileName: kw_nand.c
Description :nandflash 接口模块。
Version :1.0
Function List :
History: // 历史修改记录
<author> <time> <version > <desc>
LigangWang 07/08/08 1.0 build this moudle
*************************************************************************************/
#include "globals.h"
BYTE xdata gPageBuff[512]; //页缓冲区,用于临时备份数据
/*************************************************************************************
Function: NM_ReadPage
Description: 读取指定LBA地址数据到EP6的缓冲区中,并完成数据校验
Called By:
Input: rdLBA @ DWORD: LBA地址
Output: N/A
Return: void
Others:
*************************************************************************************/
void NM_ReadPage(DWORD rdLBA)
{
dwLBA = rdLBA; //LBA地址到全局LBA地址,Log2Phy函数用
directionIn =1; //读写标志,Log2Phy函数用
Log2Phy(); //将LBA地址转换成物理Flash地址
Fifo6In(); //设置EP6的端点缓冲为输入方式
NandSetAdd(cNAND_READ_DATA, dwLBA&3); //设置读地址,地址由Log2Phy转换
P_ECCRESET=0; //复位ECC产生器
P_GPIFTCB1=MSB(528),P_GPIFTCB0= LSB(528), //设置GPIF读取数量
GPIFTRIG = 0x04 | cEP6; //启动GPIF
AUTOPTR1H = MSB(cEP6FIFO); //设置自动指针到EP6缓冲
AUTOPTR1L = LSB(cEP6FIFO);
while (P_GPIFTCB1); //等待首256字节读取完成
ecc0[0] = P_ECC1B0[0]; //保存首256字节的ECC
ecc0[1] = P_ECC1B0[1];
ecc0[2] = P_ECC1B0[2];
while (!gpifIdle());
ecc0[3] = P_ECC1B0[3]; //保存后256字节的ECC
ecc0[4] = P_ECC1B0[4];
ecc0[5] = P_ECC1B0[5];
ecc1[0] = P_XAUTODAT1; //保存ECC产生器中产生的ECC
ecc1[1] = P_XAUTODAT1;
ecc1[2] = P_XAUTODAT1;
ecc1[3] = P_XAUTODAT1;
ecc1[4] = P_XAUTODAT1;
ecc1[5] = P_XAUTODAT1;
bErr = 0;
CheckECC(); //检查ECC
return;
}
/*************************************************************************************
Function: NM_WritePages
Description: 写EP6的缓冲区中的数据到指定LBA地址的扇区中
Called By:
Input: wrLBA @ DWORD: LBA地址
Output: N/A
Return: void
Others:
*************************************************************************************/
void NM_WritePages(DWORD wrLBA)
{
WORD xdata i;
dwLBA = wrLBA; //LBA地址到全局LBA地址,Log2Phy函数用
gSectorcount = 1; //写扇区数量
directionIn =0; //读写标志,Log2Phy函数用
for(i = 0; i<512; i++) //备份当前缓存区数据
gPageBuff[i] = EP6FIFOBUF[i];
Log2Phy(); //LBA地址转换物理地址
P_FIFORESET = 0x80; //设置EP6缓冲区为输出方式
P_FIFORESET = 6;
P_EP6CFG = EP6CFG_OUT_DEFAULT;
for(i = 0; i<512; i++) //读取数据
EP6FIFOBUF[i] = gPageBuff[i];
EP6BCH = MSB(512); //设置缓冲区数据量
_nop_();
EP6BCL = LSB(512);
_nop_();
NandSetAdd(cNAND_WRITE_DATA, (xLBA3 & 3)); //设置写地址
P_ECCRESET =LSB(cNAND_DSIZE);
FifoWr(cEP6, 512-1); //写数据
WriteRedundant(); //写ECC码及LBA地址
NandSendCmd(cNAND_PROGRAM_PAGE); //编程,写入数据
dwLBA++; //因为写如数据为新块,故须复制当前块剩余页
gPartialCpy = xLBA3;
if((dwLBA & 3) == 0)
{
xPhyAdd++; xSrcAdd++;
}
if(gPartialCpy)
{
gPartialCpy = 0 - gPartialCpy;
if(gPartialCpy)
{
NAND_PCPY(gPartialCpy, xLBA3);
gPartialCpy = 0;
nEraseBlock();
DISABLE_NAND();
}
}
else
{
nEraseBlock();
DISABLE_NAND();
}
}
/*************************************************************************************
Function: NM_WritePagesFromBuff
Description: 写pBuffer中的数据到指定地址,该地址扇区Start前字节保持不变
Called By:
Input: wrLBA @ DWORD: LBA地址
pBuffer @ BYTE* : 数据指针
Start @ WORD: 扇区你偏移
Length @ WORD: 数据长度
Output: N/A
Return: void
Others:
*************************************************************************************/
void NM_WritePagesFromBuff(DWORD wrLBA,BYTE * pBuffer,WORD Start, WORD Length)
{
WORD xdata i;
dwLBA = wrLBA; //LBA地址到全局LBA地址,Log2Phy函数用
gSectorcount = 1; //写扇区数量
directionIn =0; //读写标志,Log2Phy函数用
for(i = 0; i<Start; i++) //备份当前缓存区数据
gPageBuff[i] = EP6FIFOBUF[i];
Log2Phy(); //LBA地址转换物理地址
P_FIFORESET = 0x80; //设置EP6缓冲区为输出方式
P_FIFORESET = 6;
P_EP6CFG = EP6CFG_OUT_DEFAULT;
for(i = 0; i<Start; i++) //保持源Start个数据不变
EP6FIFOBUF[i] = gPageBuff[i];
for(i = Start;i<(Start+Length);i++) //复制剩余length个数到EP6缓冲
{
EP6FIFOBUF[i] = *pBuffer;
pBuffer ++;
}
EP6BCH = MSB(512); //设置数据长度
_nop_();
EP6BCL = LSB(512);
_nop_();
NandSetAdd(cNAND_WRITE_DATA, (xLBA3 & 3)); //设置写物理地址
P_ECCRESET =LSB(cNAND_DSIZE); //复位ECC产生器
FifoWr(cEP6, 512-1); //写数据
WriteRedundant(); //写ECC和LBA地址
NandSendCmd(cNAND_PROGRAM_PAGE); //编程,写入
dwLBA++; //因为写如数据为新块,故须复制当前块剩余页
gPartialCpy = xLBA3;
if((dwLBA & 3) == 0)
{
xPhyAdd++; xSrcAdd++;
}
if(gPartialCpy)
{
gPartialCpy = 0 - gPartialCpy;
if(gPartialCpy)
{
NAND_PCPY(gPartialCpy, xLBA3);
gPartialCpy = 0;
nEraseBlock();
DISABLE_NAND();
}
}
else
{
nEraseBlock();
DISABLE_NAND();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -