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

📄 main.c

📁 一份对nandflash ks9f1208读写操作的源代码 本人已经测试通过
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZHIYUAN electronics Co.,LTD.
**                                     
**                                 http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: main.c
** Last modified Date: 
** Last Version: 
** Description: 
**
**------------------------------------------------------------------------------------------------------
** Created By: 
** Created date: 
** Version: 
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include  "config.h"


// NAND Flash操作宏函数
#define   NF_CMD(cmd)		rNFCMD = cmd
#define   NF_ADDR(addr)		rNFADDR = addr
#define   NF_nFCE_L()		rNFCONF = rNFCONF & (~(1<<11))
#define   NF_nFCE_H()		rNFCONF = rNFCONF | (1<<11)
#define   NF_RSTECC()		rNFCONF = rNFCONF | (1<<12)
#define   NF_RDDATA()		(rNFDATA)
#define   NF_WRDATA(data)	rNFDATA = data
#define   NF_WAITRB()		while( !(rNFSTAT&0x01) )


// NAND Flash控制器命令字定义
#define   CMD_READ0			0x00 
#define   CMD_READ1			0x01
#define   CMD_PAGEPROG		0x10
#define   CMD_READOOB		0x50
#define   CMD_ERASE1		0x60
#define   CMD_STATUS		0x70
#define   CMD_SEQIN			0x80
#define   CMD_READID		0x90
#define   CMD_ERASE2		0xD0
#define   CMD_RESET			0xFF


//add by lgh
#define   rNF_ECC0           (*(volatile unsigned char *)0x4e000014)
#define   rNF_ECC1           (*(volatile unsigned char *)0x4e000015)
#define   rNF_ECC2           (*(volatile unsigned char *)0x4e000016)
#define   MAX_BLOCK_NUM     4096
#define   PAGE0             0
#define   PAGE1             1

uint8 eccbuf[3]={0,0,0};
/*********************************************************************************************************
** Function name: DelayNS
** Descriptions: 长软件延时。
**              延时时间与系统时钟有关。
** Input: dly	延时参数,值越大,延时越久
** Output: 无
** Created by: 黄绍斌
** Created Date: 2005-12-31 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void  DelayNS(uint32  dly)
{  
	uint32  i;

   	for(; dly>0; dly--) 
       for(i=0; i<50000; i++);
}

/*********************************************************************************************************
** Function name: NF_Init
** Descriptions: 初始化NAND Flash控制器
** Input: 无
** Output: 无
** Created by: 黄绍斌
** Created Date: 2006-01-05 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void  NF_Init(void)
{
	// NAND Flash控制器的I/O设置
	rGPACON = rGPACON | (0x2F<<17);   //设置为nandflash控制引脚
	
	// NAND Flash控制器配置
	rNFCONF = (1<<15) | 	// 使能NAND Flash控制器
			  (1<<12) | 	// 初始化ECC
			  (0<<11) |		// nFCE = H (片选)
			  (2<<8)  | 	// CLE、ALE延时时间为30nS,HCLK=100MHz
			  (4<<4)  |		// TWRPH0为50nS
			  (2<<0);		// TWRPH1为30nS

	// 复位NAND Flash
	NF_nFCE_L();			// 片选有效
	NF_CMD(CMD_ERASE2);		// 发送复位命令
	NF_WAITRB();			// 等待操作完成
	NF_nFCE_H();			// 取消选择
}

/*********************************************************************************************************
** Function name: NF_ReadID
** Descriptions: 读取器件ID (ID Read1)
** Input: 无
** Output: 返回值即时读出的4字节ID信号 (先读出的数据放在最高字节处)
** Created by: 黄绍斌
** Created Date: 2006-01-05 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint32  NF_ReadID(void)
{	
	uint32  id;
	
	// 发送命令和地址
	NF_nFCE_L();			// 片选有效			
	NF_CMD(CMD_READID);		// 发送读ID命令
	NF_ADDR(0);				// 发送地址0
	
	// 读取ID信息
	id = NF_RDDATA();          //manufacture ID
	id = id<<8;           
	id = id | NF_RDDATA();     //device code
	id = id<<8;            
	id = id | NF_RDDATA();     //A5H
	id = id<<8;                //C0H
	id = id | NF_RDDATA();	
	NF_nFCE_H();			// 取消选择			
	
	return(id);
}
/*********************************************************************************************************
** Function name: NF_EraseBlock
** Descriptions:  块擦除操作
** Input: block:  擦除某个块 (不算空闲区,即64MB的地址)
** Output: 擦除成功返回TRUE,否则返回FALSE
** Created by:刘国华
** Created Date: 2007-08-14 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8  NF_EraseBlock(uint32 block)
{
	uint32 block_page;                  //块地址
	uint8 bak;

	block_page=block<<5;//    block 00000 (A8 0000 0000:not send),所以左移5位  
	// 发送命令和地址
	NF_nFCE_L();		
	NF_CMD(CMD_ERASE1);					// 发送块擦除命令0x60
	//注意只送了3个周期
	NF_ADDR(block_page&0xff);	        // 发送地址A9--A16
	NF_ADDR((block_page>>8) & 0xff);	// 发送地址A17--A24
	NF_ADDR((block_page>>16)& 0xff);	// 发送地址A25	
	NF_CMD(CMD_ERASE2);	                // 0xd0
	NF_WAITRB();						// 等待操作完成
	
	NF_CMD(CMD_STATUS);					// 发送读取状态命令0x70
	bak = NF_RDDATA();
	NF_nFCE_H();
	
	if(bak&0x01) 
	    return(FALSE);	   //erase fail
	else  
	    return(TRUE);	   //erase success	 
}
/*********************************************************************************************************
** Function name: NF_WritePage
** Descriptions:  写一页数据
** Input: block:  块号
		  page    页号
** Output       :          
** Created by:刘国华
** Created Date: 2007-08-14 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 NF_WritePage(uint32 block,uint8 page,uint8 *buf)
{
	uint32 blockpage=(block<<5)+page;//
	uint32 i;
	uint8 status;
	NF_RSTECC();                     //ECC使能
	NF_nFCE_L();	
	NF_CMD(CMD_READ0);               //从0x00位置开始写一页
	NF_CMD(CMD_SEQIN);               //0x80
	NF_ADDR(0x00);                   //A7-A0为0x00
	NF_ADDR(blockpage&0x000000ff);   //A9-A16
	NF_ADDR((blockpage>>8)&0x000000ff);//A17-A24
	NF_ADDR((blockpage>>16)&0x000000ff);  //A25
	//写入字节的数据
	for(i=0;i<512;i++)
	{
		NF_WRDATA(*buf++); 
	}    
	
	//写OOB区数据,只写前面的三个为了测试
	/*
	eccbuf[0]=rNF_ECC0;
	eccbuf[1]=rNF_ECC1;
	eccbuf[2]=rNF_ECC2;         //两种方法都可以
	*/
	i=rNFECC;
	eccbuf[0]=i&0xff;
	eccbuf[1]=(i>>8)&0xff;
	eccbuf[2]=(i>>16)&0xff;
	Uart_Printf("W_EEC0:0x%x,W_EEC1:0x%x,W_EEC2:0x%x\n",eccbuf[0],eccbuf[1],eccbuf[2]);
	for(i=0;i<3;i++)
	{
		NF_WRDATA(eccbuf[i]);
	}
	
	NF_CMD(CMD_PAGEPROG);
	NF_WAITRB();	
	
	NF_CMD(CMD_STATUS);
	status=NF_RDDATA();
	
	if(status&0x01)
	{
		NF_nFCE_H();
		return FALSE;
	}
	else
	{
		NF_nFCE_H();
		return TRUE;
	}
	                           
}

/*********************************************************************************************************
** Function name: NF_ReadPage
** Descriptions:  读一页数据
** Input: block:  块号 (0-4095)
		  page    页号(0-31)
** Output       :          
** Created by:刘国华
** Created Date: 2007-08-14 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 NF_ReadPage(uint32 block,uint8 page,uint8 *buf_ret)
{
	
	uint32 blockpage=(block<<5)+page;//
	uint32 i;
	uint8 r_ecc0,r_ecc1,r_ecc2;
	NF_RSTECC();                     //ECC使能
	NF_nFCE_L();	
	NF_CMD(CMD_READ0);               //从0x00位置开始写一页
	NF_ADDR(0x00);                   //A7-A0为0x00
	NF_ADDR(blockpage&0x000000ff);   //A9-A16
	NF_ADDR((blockpage>>8)&0x000000ff);//A17-A24
	NF_ADDR((blockpage>>16)&0x000000ff);  //A25
	NF_WAITRB();
	
	for(i=0;i<512;i++)
	{
		*buf_ret++=NF_RDDATA();
	}
	
	//读取该页的3个字节ECC(写的时候的ECC)
	for(i=0;i<3;i++)
	{
		eccbuf[i]=NF_RDDATA();
	}
	
	NF_nFCE_H();
	
	//读出此时的ECC校验码(读出数据后产生的ECC)
	r_ecc0=rNF_ECC0;
	r_ecc1=rNF_ECC1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -