📄 testnand.c
字号:
#include <stdio.h>
#include "systypes.h"
#include "regsdef.h"
//#include "mytest.h"
#define getch getchar
#define putch putchar
#define U8 UINT8
#define U16 UINT16
#define U32 UINT32
#define NAND_BASE 0x07000000 //virtual address
#define CLE_OFFSET (1<<23)
#define ALE_OFFSET (1<<22)
#define EnNandFlash()
#define DsNandFlash()
#define NFChipEn() (GPCR0 = 1<<10)
#define NFChipDs() (GPSR0 = 1<<10)
#define WrNFDat8(dat) (*(volatile U8 *)NAND_BASE = dat)
#define WrNFDat32(dat)
#define RdNFDat8() (*(volatile U8 *)NAND_BASE)
#define RdNFDat32()
#define WrNFCmd(cmd) (*(volatile U8 *)(NAND_BASE+CLE_OFFSET) = cmd)
#define WrNFAddr(addr) (*(volatile U8 *)(NAND_BASE+ALE_OFFSET) = addr)
#define WrNFDat(dat) WrNFDat8(dat)
#define RdNFDat() RdNFDat8() //for 8 bit nand flash, use byte access
#define RdNFStat()
#define NFIsBusy() (!NFIsReady())
#define NFIsReady() (GPLR2 & (1<<24))
//#define WIAT_BUSY_HARD 1
//#define ER_BAD_BLK_TEST
//#define WR_BAD_BLK_TEST
#define READCMD0 0
#define READCMD1 1
#define READCMD2 0x50
#define ERASECMD0 0x60
#define ERASECMD1 0xd0
#define PROGCMD0 0x80
#define PROGCMD1 0x10
#define QUERYCMD 0x70
#define RdIDCMD 0x90
static U16 NandAddr;
#ifdef WIAT_BUSY_HARD
#define WaitNFBusy() while(NFIsBusy())
#else
static U32 WaitNFBusy(void) // R/B 未接好?
{
U8 stat;
WrNFCmd(QUERYCMD);
do {
stat = RdNFDat();
//printf("%x\n", stat);
}while(!(stat&0x40));
WrNFCmd(READCMD0);
return stat&1;
}
#endif
static U32 ReadChipId(void)
{
U32 id;
NFChipEn();
WrNFCmd(RdIDCMD);
WrNFAddr(0);
while(NFIsBusy());
id = RdNFDat()<<8;
id |= RdNFDat();
NFChipDs();
return id;
}
static U16 ReadStatus(void)
{
U16 stat;
NFChipEn();
WrNFCmd(QUERYCMD);
stat = RdNFDat();
NFChipDs();
return stat;
}
static U32 EraseBlock(U32 addr)
{
U8 stat;
addr &= ~0x1f;
NFChipEn();
WrNFCmd(ERASECMD0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
if(NandAddr)
WrNFAddr(addr>>16);
WrNFCmd(ERASECMD1);
stat = WaitNFBusy();
NFChipDs();
#ifdef ER_BAD_BLK_TEST
if(!((addr+0xe0)&0xff)) stat = 1; //just for test bad block
#endif
//putch('.');
//printf("Erase block 0x%x %s\n", addr, stat?"fail":"ok");
return stat;
}
//addr = page address
static void ReadPage(U32 addr, U8 *buf)
{
U16 i;
NFChipEn();
WrNFCmd(READCMD0);
WrNFAddr(0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
if(NandAddr)
WrNFAddr(addr>>16);
WaitNFBusy();
for(i=0; i<512; i++)
buf[i] = RdNFDat();
NFChipDs();
}
static U32 WritePage(U32 addr, U8 *buf)
{
U32 i;
U8 stat;
NFChipEn();
WrNFCmd(PROGCMD0);
WrNFAddr(0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
if(NandAddr)
WrNFAddr(addr>>16);
for(i=0; i<512; i++)
WrNFDat(buf[i]);
// WrNFDat(0xff);
// WrNFDat(0xff);
// WrNFDat(0xff);
// WrNFDat(0xff);
// WrNFDat(0xff);
// WrNFDat(0xff);
// WrNFDat(0xff);
// WrNFDat(0xff);
WrNFCmd(PROGCMD1);
stat = WaitNFBusy();
NFChipDs();
#ifdef WR_BAD_BLK_TEST
if((addr&0xff)==0x17) stat = 1; //just for test bad block
#endif
return stat;
}
/************************************************************/
#define TEST_PAGE_NO 0x100
static int InitNandFlash(void)
{
U32 i;
i = ReadChipId();
printf("Read chip id is 0x%x\r\n", i);
if((i==0x9873)||(i==0xec75))
NandAddr = 0;
else if(i==0xec76)
NandAddr = 1;
else {
puts("Chip id error!\r\n");
return -1;
}
printf("Nand flash status = 0x%x\r\n", ReadStatus());
return 0;
}
void TestNand(void)
{
U32 i;
U8 buf[512];
printf("Test NAND FLASH.\r\n");
if(InitNandFlash()!=0)
return ;
if(EraseBlock(TEST_PAGE_NO)) {
printf("Erase block error!\r\n");
return ;
}
printf("\nWrite...\r\n");
for(i=0; i<64; i++)
{
buf[i] = i;
printf("%4x",i);
if(!((i+1)%16))printf("\r\n");
}
if(WritePage(TEST_PAGE_NO, buf)) {
printf("Write page error!\r\n");
return;
}
printf("\nRead...\r\n");
for(i=0; i<64; i++)
buf[i] = 0;
ReadPage(TEST_PAGE_NO, buf);
for(i=0; i<64; i++)
{
printf("%4x",buf[i]);
if(!((i+1)%16))printf("\r\n");
if(buf[i]!=(i&0xff)) {
printf("Check data error at 0x%03x!\r\n", i);
break;
}
}
printf("%s!\r\n", (i==64) ? "Success" : "Fail");
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -