📄 nand.c
字号:
#include <windows.h>
#include "s2443ADDR.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.
// For flash chip that is bigger than 32 MB, we need to have 4 step address
#define NEED_EXT_ADDR 1
#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_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
void Uart_SendBYTE(BYTE d, BOOL cr);
void __RdPage512(BYTE *bufPt);
int NF_ReadPage(UINT32 block,UINT32 page,UINT8 *buffer)
{
volatile int i;
register UINT8 * bufPt=buffer;
unsigned int blockPage;
ULONG MECC, tmp1, tmp2;
blockPage=(block<<8)+page;
NF_RSTECC(); // Initialize ECC
NF_nFCE_L();
NF_CLEAR_RB();
NF_CMD(0x00); // Read command
NF_ADDR(0); // Column = 0
NF_ADDR(blockPage&0xff); //
NF_ADDR((blockPage>>8)&0xff); // Block & Page num.
NF_ADDR((blockPage>>16)&0xff); //
NF_DETECT_RB();
NF_MECC_UnLock();
__RdPage512(bufPt); // Read 512 bytes.
NF_MECC_Lock();
tmp1 = NF_RDDATA32();
tmp2 = NF_RDDATA32();
MECC = NF_RDDATA32();
NF_WRMECCD0( ((MECC&0xff00 )<<8) | (MECC&0xff ) );
NF_WRMECCD1( ((MECC&0xff000000)>>8) | ((MECC&0xff0000)>>16) );
NF_nFCE_H();
if(rNFECCERR0 & 0x3)
{
Uart_SendString("Read data:\n");
for(i=0; i<512; i++) {
if(!(i%16)) Uart_SendString("\n");
Uart_SendBYTE(bufPt[i],0);
}
Uart_SendString("<ECC ERROR... RD:");
Uart_SendDWORD(MECC,0);
Uart_SendString(" MECC0 Reg:");
Uart_SendDWORD(NF_RDMECC0(),1);
Uart_SendString("\nECC ERROR block:");
Uart_SendDWORD(block,0);
Uart_SendString(",page:");
Uart_SendDWORD(page,1);
Uart_SendString(">\n");
return 0;
}
else
return 1;
}
static DWORD ReadFlashID(void)
{
BYTE Mfg, Dev, i;
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();
return ((DWORD)(Mfg<<8)+Dev);
}
void NF_Reset(void)
{
volatile int i, ReadID;
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.
// Get manufacturer and device codes.
ReadID = ReadFlashID();
if (ReadID != 0xEC76 && ReadID != 0x9876 && ReadID != 0x9879)
{
Uart_SendString("ID read Error RD:");
Uart_SendDWORD(ReadID,1);
Uart_SendString("!\n");
}
}
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 + -