📄 nand.c
字号:
#include <windows.h>
#include "s2450ADDR.h"
#include "option.h"
#define NF_CMD(cmd) {rNFCMD=cmd;}
#define NF_ADDR(addr) {rNFADDR=addr;}
#define NF_FCE 0 // 0:FCE0, 1:FCE1, In steploader, NAND cs has to be FCE0.
#define CMD_READ 0x00 // Read
#define CMD_READ1 0x01 // Read1
#define CMD_READ2 0x50 // Read2
#define CMD_READ3 0x30 // Read3
#define CMD_RDO 0x05 // Random Data Output
#define CMD_RDO2 0xE0 // Random Data Output
#if NF_FCE==0
#define NF_nFCE_L() {rNFCONT &= ~(1 << 1);}
#define NF_nFCE_H() {rNFCONT |= (1 << 1);}
#else if NF_FCE==1
#define NF_nFCE_L() {rNFCONT &= ~(1 << 2);}
#define NF_nFCE_H() {rNFCONT |= (1 << 2);}
#endif
#define NF_RSTECC() {rNFCONT |= ((1<<5)|(1<<4));}
#define NF_MECC_UnLock() {rNFCONT &= ~(1<<7);}
#define NF_MECC_Lock() {rNFCONT |= (1<<7);}
#define NF_SECC_UnLock() {rNFCONT &= ~(1<<6);}
#define NF_SECC_Lock() {rNFCONT |= (1<<6);}
#define NF_CLEAR_RB() {rNFSTAT |= (1 << 4);}
//#define NF_DETECT_RB() {while(!(rNFSTAT&(1<<4)));}
#define NF_DETECT_RB() { while((rNFSTAT&0x11)!=0x11);} // RnB_Transdetect & RnB
#define NF_WAITRB() {while (!(rNFSTAT & (1 << 0)));}
#define NF_RDDATA() (rNFDATA)
#define NF_RDDATA8() (unsigned char)(rNFDATA8)
#define NF_RDDATA32() (rNFDATA32)
#define NF_WRDATA(data) {rNFDATA=data;}
#define NF_RDMECC0() (rNFMECC0)
#define NF_RDMECC1() (rNFMECC1)
#define NF_RDMECCD0() (rNFMECCD0)
#define NF_RDMECCD1() (rNFMECCD1)
#define NF_WRMECCD0(data) {rNFMECCD0 = (data);}
#define NF_WRMECCD1(data) {rNFMECCD1 = (data);}
#define ID_K9S1208V0M 0xec76
// HCLK=100Mhz
#define TACLS 7 // 1-clk(0ns)
#define TWRPH0 7 // 3-clk(25ns)
#define TWRPH1 7 // 1-clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns
BOOL bLARGEBLOCK;
void Uart_SendBYTE(BYTE d, BOOL cr);
void __RdPage512(BYTE *bufPt);
typedef enum {
ECC_CORRECT_MAIN = 0, // correct Main ECC
ECC_CORRECT_SPARE1 = 1, // correct Main ECC
ECC_CORRECT_SPARE2 = 2, // correct Main ECC
} ECC_CORRECT_TYPE;
BOOL ECC_CorrectData(unsigned int sectoraddr, UINT8* pData, UINT32 nRetEcc, ECC_CORRECT_TYPE nType)
{
DWORD nErrStatus;
DWORD nErrDataNo;
DWORD nErrBitNo;
UINT32 nErrDataMask;
UINT32 nErrBitMask = 0x7;
BOOL bRet = TRUE;
if (nType == ECC_CORRECT_MAIN ||nType == ECC_CORRECT_SPARE1 || nType == ECC_CORRECT_SPARE2)
{
nErrStatus = 0;
nErrDataNo = 7;
nErrBitNo = 4;
nErrDataMask = 0x7ff;
}
else
{
return FALSE;
}
switch((nRetEcc>>nErrStatus) & 0x3)
{
case 0: // No Error
bRet = TRUE;
break;
case 1: // 1-bit Error(Correctable)
// Uart_SendString("ECC 1bit error ");
(pData)[(nRetEcc>>nErrDataNo)&nErrDataMask] ^= (1<<((nRetEcc>>nErrBitNo)&nErrBitMask));
bRet = TRUE;
break;
case 2: // Multiple Error
// Uart_SendString("ECC Multiple error ");
// Uart_SendDWORD(sectoraddr,1);
bRet = FALSE;
break;
case 3: // ECC area Error
// Uart_SendString("ECC area error\n");
default:
bRet = FALSE;
break;
}
return bRet;
}
int NF_ReadPage(UINT32 block,UINT32 sector,UINT8 *buffer)
{
register UINT8 * bufPt=buffer;
unsigned int RowAddr, ColAddr;
DWORD MECCBuf, rddata1, rddata2;
UINT32 nRetEcc;
int nRet = FALSE;
int nSectorLoop;
NF_nFCE_L();
for (nSectorLoop = 0; nSectorLoop < (bLARGEBLOCK==TRUE?4:1); nSectorLoop++)
{
ColAddr = nSectorLoop * 512;
NF_CMD(CMD_READ); // Read command
if (bLARGEBLOCK == TRUE)
{
RowAddr = (block<<6) + sector;
NF_ADDR((ColAddr) &0xff); // 1st cycle
NF_ADDR((ColAddr>>8)&0xff); // 2nd cycle
NF_ADDR((RowAddr) &0xff); // 3rd cycle
NF_ADDR((RowAddr>>8)&0xff); // 4th cycle
if (LB_NEED_EXT_ADDR)
NF_ADDR((RowAddr>>16)&0xff); // 5th cycle
}
else
{
RowAddr = (block<<5) + sector;
NF_ADDR((ColAddr) &0xff); // 1st cycle
NF_ADDR((RowAddr) &0xff); // 2nd cycle
NF_ADDR((RowAddr>>8)&0xff); // 3rd cycle
if (SB_NEED_EXT_ADDR)
NF_ADDR((RowAddr>>16)&0xff); // 4th cycle
}
NF_CLEAR_RB();
NF_CMD(CMD_READ3); // Read command
NF_DETECT_RB();
//NF_WAITRB();
NF_RSTECC(); // Initialize ECC
NF_MECC_UnLock();
__RdPage512(bufPt+nSectorLoop*512); // Read 512 bytes.
NF_MECC_Lock();
if (bLARGEBLOCK == TRUE)
{
ColAddr = 2048;
NF_CMD(CMD_RDO); // Random Data Output In a Page, 1st Cycle
NF_ADDR((ColAddr) &0xff); // 1st cycle
NF_ADDR((ColAddr>>8)&0xff); // 2nd cycle
NF_CMD(CMD_RDO2); // Random Data Output In a Page. 2nd Cycle
}
rddata1 = NF_RDDATA32(); // check bad block
rddata2 = NF_RDDATA32();
if (bLARGEBLOCK == TRUE)
{
if (((rddata1 & 0xff) != 0xff) && (((rddata2>>8) & 0xff) != 0x03)) return nRet; // bad block && !(OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY)
}
else if ((((rddata2>>8) & 0xff) != 0xff) && ((rddata2 & 0xff) != 0x03)) return nRet; // bad block && !(OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY)
if (bLARGEBLOCK == TRUE)
{
ColAddr = 2048 + 8 + nSectorLoop*4;
NF_CMD(CMD_RDO); // Random Data Output In a Page, 1st Cycle
NF_ADDR((ColAddr) &0xff); // 1st cycle
NF_ADDR((ColAddr>>8)&0xff); // 2nd cycle
NF_CMD(CMD_RDO2); // Random Data Output In a Page. 2nd Cycle
}
MECCBuf = NF_RDDATA32();
NF_WRMECCD0( ((MECCBuf&0x0000ff00)<<8) | ((MECCBuf&0x000000ff) ) );
NF_WRMECCD1( ((MECCBuf&0xff000000)>>8) | ((MECCBuf&0x00ff0000)>>16) );
nRetEcc = rNFECCERR0;
nRet = ECC_CorrectData(RowAddr, bufPt+nSectorLoop*512, nRetEcc, ECC_CORRECT_MAIN);
if (!nRet) return nRet;
}
NF_nFCE_H();
return nRet;
}
DWORD ReadFlashID(void)
{
BYTE Mfg, Dev, i;
volatile int ReadID;
UINT32 nRet;
bLARGEBLOCK = FALSE;
nRet = TRUE;
NF_nFCE_L();
NF_CMD(0x90); // Send flash ID read command.
NF_ADDR(0);
for (i=0; i<10; i++);
Mfg = NF_RDDATA8(); // Maker code
Dev = NF_RDDATA8(); // Devide code(K9S1208V:0x76), (K9K2G16U0M:0xca)
NF_nFCE_H();
if (Mfg == (UINT8)0xEC)
{
if (Dev >= (UINT8)0xA0)
bLARGEBLOCK = TRUE;
}
else if (Mfg == (UINT8)0x98)
{
}
else
{
nRet = FALSE;
}
ReadID = (DWORD)((Mfg<<8)+Dev);
// Uart_SendString("FlashID :");
// Uart_SendDWORD(ReadID,1);
// return ((DWORD)(Mfg<<8)+Dev);
return nRet;
}
void NF_Reset(void)
{
volatile int i;
NF_nFCE_L();
NF_CLEAR_RB();
NF_CMD(0xFF); //reset command
for(i=0;i<10;i++); //tWB = 100ns. //??????
NF_DETECT_RB();
NF_nFCE_H(); // Deselect the flash chip.
}
void NF_Init(void)
{
rNFCONF = (TACLS << 12) | /* CLE & ALE = HCLK * (TACLS + 1) */
(TWRPH0 << 8) | /* TWRPH0 = HCLK * (TWRPH0 + 1) */
(TWRPH1 << 4) |
(0<<0);
rNFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0);
rNFSTAT = (1<<4);
NF_Reset();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -