OK6410裸机简单的NAND FLASH驱动

OK6410裸机简单的NAND FLASH驱动,只写了个简单的函数,读取一页OK6410裸机简单的NAND FLASH驱动_第1张图片


/*************************************************************************************************************
 * 文件名:		NandFlash.c
 * 功能:		S3C6410 NandFlash底层驱动函数
 * 作者:		陈鹏
 * 创建时间:	2012年3月31日21:34
 * 最后修改时间:2012年3月31日
 * 详细:		NandFlash底层驱动函数,
 				板载NAND FLASH信息:2GB,MLC K9G4G08(K9GAG08U0D,页大小4KB,4bit纠正)
*************************************************************************************************************/
#include "s3c6410_system.h"
#include "NandFlash.h"
#include "s3c6410_map.h"

//配置
//CONF
#define ECCType		1	//ECC类型选择,0:SLC(1位修正);1:MLC(4位修正)
#define TACLS		5	//CLE & ALE持续时间(0-7)(= HCLK * TACLS)
#define TWRPH0		5	//TWRPH0持续时间(0-7)(= HCLK * (TWRPH0 + 1))
#define TWRPH1		5	//TWRPH1持续时间(0-7)(= HCLK * (TWRPH1 + 1))
#define AdvFlash	1	//预先NAND flash 存储器启动;0:支持512字节/页;1:支持2KB/页
#define AddrCycle	1	//NAND Flash存储器地址周期,0: 0:3地址周期,1:4地址周期;1: 0:4地址周期,1:5地址周期
//CONT
#define SoftLock	0	//软件锁配置,0:禁用锁,1:使能锁
#define MainECCLock	1	//锁存主区ECC生成:0:开启主区ECC;1:锁存主区ECC
#define SpareECCLock	1	//锁存备用区ECC生成;0:开启备用区ECC,1:锁存备用区ECC,备用区ECC 状态寄存器是NFSECC(0x7020003C)
#define RegNCE1		1	//NAND Flash 存储器nGCS[3]信号控制:0:强制nGCS[3]为低(使能片选);1:强制nGCS[3]为高(禁用片选)注:即使Reg_nCE1 和 Reg_nCE0 同时被设置为0,它们之中也只有一个被声明
#define MODE		1	//NAND Flash 控制器操作模式:0:NAND Flash 控制器禁用(不工作)1:NAND Flash 控制器使能

//NAND FLASH操作宏
#define NANDCMD(cmd)	(NAND->CMMD = (cmd))	//向NAND flash写入命令
#define NANDADDR(addr)	(NAND->ADDR = (addr))	//向NAND flash写入地址
#define NANDDATA		(NAND->DATA)			//向NAND flash读写数据
#define NF_nCS3_L		(NAND->CONT&=~(1<<2))
#define NF_nCS3_H		(NAND->CONT|=(1<<2))
#define NF_nCS2_L		(NAND->CONT&=~(1<<1))		//片选
#define NF_nCS2_H		(NAND->CONT|=(1<<1))
#define NF_RnB			(NAND->STAT & BIT0)			//0:存储器忙,1:空闲

//NAND FLASH信息宏
#define FLASH_MAX_ADDR 		0x80000000	//FLASH最大能够达到的地址,是2GB
#define FLASH_BLOCK_SIZE 	0x20000		//FLASH块大小,为512KB
#define FLASH_PAGE_SIZE 	0x1000		//FLASH页大小,为4KB
//ECC 8BIT 512B


//NAND FLASH	命令定义
#define NAND_READ_1th			0x00				//读数据区,第一个访问周期
#define NAND_READ_2th			0x30				//读数据区,第二个访问周期	
#define NAND_READ_ID			0x90				//读NAND ID
#define NAND_READ_STATUS1		0x70				//读状态1
#define NAND_READ_STATUS2		0xf1				//读状态2
#define NAND_RESET				0xff				//复位


/*************************************************************************************************************************
*函数        :	void NnadFlashWait(void)
*功能        :	等待操作完成
*参数        :	无
*返回        :	无
*依赖        : 	无
*作者        :	陈鹏
*时间        :	20120331
*最后修改时间:	20120331
*说明        :	低电平操作忙
*************************************************************************************************************************/
void NnadFlashWait(void)
{
	while(NF_RnB == 0);  //等待写完成  为低表示忙
}


/*************************************************************************************************************************
*函数        :	static void NandFlashWrite5BitAddr(vu32 Addr)
*功能        :	向NAND FLASH写入4字节的地址
*参数        :	地址
*返回        :	无
*依赖        : 	无
*作者        :	陈鹏
*时间        :	20120331
*最后修改时间:	20120331
*说明        :	写NAND地址,地址共32bit,分5次写入
*************************************************************************************************************************/
static void NandFlashWrite5BitAddr(vu32 Addr)
{
	vu8 temp;
	
	temp = Addr & 0xff;				//取低8位地址
	printf("\r\n1th=%02X ",temp);
	NANDADDR(temp);					//写入A0-A7;
	temp = (Addr >> 8) & 0x1f;	
	printf("\r\n2th=%02X ",temp);	
	NANDADDR(temp);					//写A8-A12,0,0,0
	temp = (Addr >> 13);
	printf("\r\n3th=%02X ",temp);			
	NANDADDR(temp);				
	temp = (Addr >> 21);//写A13-A20	
	printf("\r\n4th=%02X ",temp);		
	NANDADDR(temp);					//写A21-A28
	temp = (Addr >> 29) & 0x07;	
	printf("\r\n5th=%02X ",temp);				
	NANDADDR(temp);					//写A29-A31,0,0,0,0,0
}



/*************************************************************************************************************************
*函数        :	void NandFlashReset(void)
*功能        :	NandFlash复位
*参数        :	无
*返回        :	无
*依赖        : 	无
*作者        :	陈鹏
*时间        :	20120331
*最后修改时间:	20120331
*说明        :	写入复位命令等待复位完成
*************************************************************************************************************************/
void NandFlashReset(void)
{
	NANDADDR(0x00);		//地址复位
	NANDCMD(NAND_RESET);		//写入复位命令
	NnadFlashWait();	//等待操作完成
}



/*************************************************************************************************************************
*函数        :	void NandFlashInit(void)
*功能        :	NandFlash初始化函数
*参数        :	无
*返回        :	无
*依赖        : 	无
*作者        :	陈鹏
*时间        :	20120331
*最后修改时间:	20120331
*说明        :	用于初始化NAND
*************************************************************************************************************************/
void NandFlashInit(void)
{
//	rGPPCON &= ~(3 << 14);		//GPIOP7输入
	NAND->CONF = (ECCType << 24) + (TACLS << 12) + (TWRPH0 << 8) + (TWRPH1 << 4) + (AdvFlash << 3) + BIT2 + (AddrCycle << 1);	//配置NAND FLASH
	NAND->CONT = (SoftLock << 16) + (MainECCLock << 7) + (SpareECCLock << 6) + (RegNCE1 << 2) + (MODE << 0);//初始化控制寄存器
	NandFlashReset();	//复位NAND FLASH
}


/*************************************************************************************************************************
*函数        :	u32 NandFlashReadStatus(void)
*功能        :	读取NandFlash状态
*参数        :	无
*返回        :	状态参数
*依赖        : 	无
*作者        :	陈鹏
*时间        :	20120331
*最后修改时间:	20120331
*说明        :	读取状态
*************************************************************************************************************************/
u32 NandFlashReadStatus(void)
{
	NF_nCS2_L;
	NANDCMD(NAND_READ_STATUS1);		//写查询命令
	NnadFlashWait();	//等待操作完成
	NF_nCS2_H;
	return NANDDATA;	//返回状态信息
}


/*************************************************************************************************************************
*函数        :	u32 NandFlashReadStatus1(void)
*功能        :	读取NandFlash状态1
*参数        :	无
*返回        :	状态参数
*依赖        : 	无
*作者        :	陈鹏
*时间        :	20120331
*最后修改时间:	20120331
*说明        :	读取状态1
*************************************************************************************************************************/
u32 NandFlashReadStatus1(void)
{
	NF_nCS2_L;
	NANDCMD(NAND_READ_STATUS2);		//写查询命令1
	NnadFlashWait();	//等待操作完成
	NF_nCS2_H;
	return NANDDATA;	//返回状态信息
}


/*************************************************************************************************************************
*函数        :	void NandFlashReadID(u8 *pbuff)
*功能        :	读取NandFlash ID
*参数        :	缓冲区指针
*返回        :	无
*依赖        : 	无
*作者        :	陈鹏
*时间        :	20120331
*最后修改时间:	20120720
*说明        :	读取ID,注意ID为6字节,ECH,DeviceCode,3rd cyc,4th cyc,5th cyc,6th cyc,读一次是32BIT,4	字节
*************************************************************************************************************************/
void NandFlashReadID(u8 *pbuff)
{
	u8 i;
	u32 buff[2];
	u8 *p = (u8 *)buff;
	
	NF_nCS2_L;
	NANDCMD(NAND_READ_ID);	//写读取ID命令	
	NANDADDR(0x00);			//地址复位
	NnadFlashWait();		//等待操作完成
	//读取2次,共8字节
	for(i = 0;i < 2;i ++)	
		buff[i] = NANDDATA;
	NF_nCS2_H;
	
	//复制前面的6字节ID
	for(i = 0;i < 6;i ++)
		pbuff[i] = p[i];
}


/*************************************************************************************************************************
*函数        :	u8 NandFlashReadOneSector(u32 Addr,u8 *pBuff)
*功能        :	读取nand flash一页
*参数        :	Addr:页地址,pBuff:缓冲区指针;
*返回        :	状态
*依赖        : 	底层操作函数
*作者        :	陈鹏
*时间        :	20120401
*最后修改时间:	20120401
*说明        :	读取一页,一页4KB,注意缓冲区不要越界,读一次是32BIT,4	字节
*************************************************************************************************************************/
u8 NandFlashReadOneSector(u32 Addr,u8 *pBuff)
{
	u32 i;
	u32 *p = (u32 *)pBuff;
	u32 cnt = FLASH_PAGE_SIZE / 4;	//读取次数,每次读取4字节
	
	if(Addr > FLASH_MAX_ADDR)	//地址超出范围返,返回错误代码1,地址越界
		return 1;
	NF_nCS2_L;
	//如果跨页的,则写读数据命令
	NANDCMD(NAND_READ_1th);
	NandFlashWrite5BitAddr(Addr);
	NANDCMD(NAND_READ_2th);
	NnadFlashWait(); //等待数据读回
	for(i = 0;i < cnt;i++)
	{
		p[i] = NANDDATA;  //读一字节数据
	}
	NF_nCS2_H;
	return 0;
}











你可能感兴趣的:(c,工作,cmd,Flash,存储,n2)