⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testnand.c

📁 pxa270 NAND flash驱动程序
💻 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 + -