当前位置:首页 > > 充电吧
[导读]OK6410裸机简单的NAND FLASH驱动,只写了个简单的函数,读取一页 /**********************************************************


OK6410裸机简单的NAND FLASH驱动,只写了个简单的函数,读取一页


/*************************************************************************************************************
 * 文件名:		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<CONT|=(1<CONT&=~(1<CONT|=(1<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("rn1th=%02X ",temp);
	NANDADDR(temp);					//写入A0-A7;
	temp = (Addr >> 8) & 0x1f;	
	printf("rn2th=%02X ",temp);	
	NANDADDR(temp);					//写A8-A12,0,0,0
	temp = (Addr >> 13);
	printf("rn3th=%02X ",temp);			
	NANDADDR(temp);				
	temp = (Addr >> 21);//写A13-A20	
	printf("rn4th=%02X ",temp);		
	NANDADDR(temp);					//写A21-A28
	temp = (Addr >> 29) & 0x07;	
	printf("rn5th=%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;
}




本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭