关于NAND Flash
S5PV210的NAND Flash控制器有如下特点:
1) 支持512byte,2k,4k,8k的页大小
2) 通过各种软件模式来进行NAND Flash的读写擦除等
3) 8bit的总线
4) 支持SLC和MCL的NAND Flash
5) 支持1/4/8/12/16bit的ECC
6) 支持以字节/半字/字为单位访问数据/ECC寄存器,以字为单位访问其他寄存器。
注意:在此使用的TQ210的NAND Flash类型为SLC,大小为1G,型号为K9K8G08U0A。所以本章的内容是针对SLC类型的NAND Flash(包括256M/512M/1GB等),并不适用MLC类型的NAND Flash。

程序例子:(完整代码见链接)
代码多了nand.c这个文件,里面包含了对NAND Flash的相关操作。
/*nand.c*/
<1> NAND Flash初始化函数nand_init(),代码如下

void nand_init(void)
{
// 1. 配置NAND Flash
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0);
NFCONT =(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x3<<1)|(1<<0);
// 2. 配置引脚
MP0_1CON = 0x22333322;
MP0_2CON = 0x00002222;
MP0_3CON = 0x22222222;
// 3. 复位
nand_reset();
}

共3个步骤:
第一步 配置NAND Flash
主要是设置NFCONF和NFCONT两个寄存器

NFCONF寄存器
AddrCycle = 1,When page size is 2K or 4K, 1 = 5 address cycle,TQ210的NAND Flash的页大小为2k,所有是5个地址周期(手册);
PageSize = 0,When MLCFlash is 0, the value of PageSize is as follows: 0 = 2048 Bytes/page,TQ210使用的是SLC NAND Flash且每页大小为2k;
MLCFlash = 0,在此使用的是SLC NAND Flash;
TWRPH1/TWRPH0/TACLS是关于访问时序的设置,需对照NAND Flash芯片手册设置,这里不再详细解释,分别取TWRPH1=1,TWRPH0=4,TACLS=1;
ECCType0/MsgLength,我们的裸机代码没有使用到ECC,所有不用设置这两个标志。

MODE = 1,使能NAND Flash控制器;
Reg_nCE0 = 1,取消片选,需要操作NAND Flash时再发片选;
Reg_nCE1 = 1, 取消片选,需要操作NAND Flash时再发片选;
InitMECC/InitSECC/SECCLock/MECCLock,我们的裸机代码不涉及ECC,这4个标志位随便设置即可;
RnB_TransMode = 0,Detect rising edge,RnB是NAND Flash的状态探测引脚,我们使用上升沿触发;
EnbRnBINT = 0 ,禁止RnB中断;
EnbIllegalAccINT = 0,禁止Illegal access 中断 ;
EnbMLCDecInt/EnbMLCEncInt为MCL相关,不用设置;
LOCK = 0,我们没有用到Soft Lock,所以禁止Soft Lock;
LockTight = 0,我们没有用到Lock-tight,所有禁止Lock-tight;
MLCEccDirection,MLC相关,可不用设置
第二步 配置引脚
用于NAND Flash相关功能;
第三步 复位
复位函数nand_reset的相关代码如下:

static void nand_reset(void)
{nand_select_chip();nand_send_cmd(NAND_CMD_RES);nand_wait_idle();nand_deselect_chip();
}

NAND Flash的复位操作共4个步骤:
1) 发片选,实质就是NFCONT &= ~(1<<1);往NFCONT的bit[1]写0;
2) 发命令复位命令NAND_CMD_RES (0xff);实质就是NFCMMD = cmd;将命令写到NFCMMD寄存器;完整的NAND Flash命令信息见下图:

3) 等待NAND Flash 就绪;实质就是while( !(NFSTAT & (BUSY<<4)) ),读NFSTAT的bit[4]检查NAND Flash是否就绪;
4) 取消片选,实质就是NFCONT |= (1<<1); 往NFCONT的bit[1]写1;

<2> NAND Flash读ID函数nand_read_id(),代码如下

void nand_read_id(void)
{nand_id_info nand_id;// 1. 发片选nand_select_chip();// 2. 读IDnand_send_cmd(NAND_CMD_READ_ID);nand_send_addr(0x00);nand_wait_idle();nand_id.IDm = nand_read();nand_id.IDd = nand_read();nand_id.ID3rd = nand_read();nand_id.ID4th = nand_read();nand_id.ID5th = nand_read();printf("NANDFlash: makercode = %x,devicecode = %x\r\n",nand_id.IDm,nand_id.IDd);nand_deselect_chip();
}

NAND Flash 读ID操作
根据上图,NAND Flash的读ID操作共4个步骤:
第一步 发片选;
第二步 发读ID命令NAND_CMD_READ_ID(0x90);
第三步 发地址0x00;调用函数nand_send_addr();
第四步 等待NAND Flash 就绪;
第五步 读ID;调用了nand_read()函数,实质就是读NFDATA寄存器;
下面解释一下函数nand_send_addr(),核心代码如下:

nand_send_addr()
{// 列地址,即页内地址col = addr % NAND_PAGE_SIZE;// 行地址,即页地址row = addr / NAND_PAGE_SIZE;// Column Address A0~A7NFADDR = col & 0xff;for(i=0; i<10; i++);// Column Address A8~A11NFADDR = (col >> 8) & 0x0f;for(i=0; i<10; i++);// Row Address A12~A19NFADDR = row & 0xff;for(i=0; i<10; i++);// Row Address A20~A27NFADDR = (row >> 8) & 0xff;for(i=0; i<10; i++);// Row Address A28~A30NFADDR = (row >> 16) & 0xff;for(i=0; i<10; i++);
} 

首先根据页大小来获取页地址和页内偏移地址,然后通过5个周期将地址发送出去,实质就是写NFADDR寄存器,具体每个周期如何发送,查阅NAND Flash芯片手册可知,见下图:

发送地址后,就可以连续读出5个ID了,其中第一个是MAKDER CODE, 第二个是DEVICE CODE。

<3> NAND Flash擦除函数nand_erase(),核心代码如下:

nand_erase()
{// 获得row地址,即页地址unsigned long row = block_num * NAND_BLOCK_SIZE;// 1. 发出片选信号nand_select_chip();// 2. 擦除:第一个周期发命令0x60,第二个周期发块地址,第三个周期发命令0xd0 nand_send_cmd(NAND_CMD_BLOCK_ERASE_1st);for(i=0; i<10; i++);// Row Address A12~A19NFADDR = row & 0xff;for(i=0; i<10; i++);// Row Address A20~A27NFADDR = (row >> 8) & 0xff;for(i=0; i<10; i++);// Row Address A28~A30NFADDR = (row >> 16) & 0xff;NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_BLOCK_ERASE_2st);for(i=0; i<10; i++);// 3. 等待就绪nand_wait_idle();// 4. 读状态unsigned char status = read_nand_status();
}

根据上图,NAND Flash的擦除操作共6个步骤:
第一步 发片选;
第二步 发擦除命令1 NAND_CMD_BLOCK_ERASE_1(0x60);
第三步 发页地址,只需发页地址;
第四步 发擦除命令2 NAND_CMD_BLOCK_ERASE_2st(0xD0);
第五步 等待NAND Flash就绪;
第六步 读状态,判断擦除是否成功。若擦除失败,则打印是坏块再取消片选;否则直接直接取消片选即可。读状态调用了函数read_nand_status(),它的实质就是nand_send_cmd(NAND_CMD_READ_STATUS);ch = nand_read();先发读状态命令NAND_CMD_READ_STATUS,然后再读状态值。

<4> NAND Flash读函数copy_nand_to_sdram(),从NAND Flash中读数据到DRAM,核心代码如下:

copy_nand_to_sdram()
{// 1. 发出片选信号 nand_select_chip();// 2. 从nand读数据到sdram,第一周期发命令0x00,第二周期发地址nand_addr,第三个周期发命令0x30,可读一页(2k)的数据while(length){nand_send_cmd(NAND_CMD_READ_1st);nand_send_addr(nand_addr);NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_READ_2st);nand_wait_idle();// 列地址,即页内地址unsigned long col = nand_addr % NAND_PAGE_SIZE;i = col;// 读一页数据,每次拷1byte,共拷2048次(2k),直到长度为length的数据拷贝完毕for(; i<NAND_PAGE_SIZE && length!=0; i++,length--){*sdram_addr = nand_read();sdram_addr++; nand_addr++;}}// 3. 读状态unsigned char status = read_nand_status();
}

NAND Flash 读操作
根据上图,NAND Flash的读操作共7个步骤:
第一步 发片选;
第二步 发读命令1 NAND_CMD_READ_1st(0x00);
第三步 发地址,调用函数nand_send_cmd(),发5个地址周期;
第四步 发读命令2 NAND_CMD_READ_2st(0xD0);
第五步 等待NAND Flash就绪;
第六步 从页内偏移地址开始读,读到页结尾即结束,每次读1byte;
第七步 读状态,判断是否读成功。

<5> NAND Flash写函数copy_sdram_to_nand (),从DRAM写数据到NAND Flash,核心代码如下:

copy_sdram_to_nand()
{// 1. 发出片选信号nand_select_chip();// 2. 从sdram读数据到nand,第一周期发命令0x80,第二周期发地址nand_addr,第三个周期写一页(2k)数据,第四周期发0x10while(length){nand_send_cmd(NAND_CMD_WRITE_PAGE_1st);nand_send_addr(nand_addr);// 列地址,即页内地址unsigned long col = nand_addr % NAND_PAGE_SIZE;i = col;// 写一页数据,每次拷1byte,共拷2048次(2k),直到长度为length的数据拷贝完毕for(; i<NAND_PAGE_SIZE && length!=0; i++,length--){nand_write(*sdram_addr);sdram_addr++;nand_addr++;}NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_WRITE_PAGE_2st);nand_wait_idle();}// 3. 读状态unsigned char status = read_nand_status();
}

根据上图,NAND Flash的写操作共7个步骤:
第一步 发片选;
第二步 发写命令1 NAND_CMD_WRITE_PAGE_1st (0x80);
第三步 发地址地址,调用函数nand_send_cmd(),发5个地址周期;
第四步 发读命令2 NAND_CMD_WRITE_PAGE_2st (0x10);
第五步 等待NAND Flash就绪;
第六步 从页内偏移地址开始写,读到页结尾即结束,每次写1byte;
第七步 读状态,判断是否读成功。

2. main.c
在main.c中,首先会调用nand_init()来初始化NAND Flash,然后打印一个菜单,提供4种选择测试NAND Flash:
读ID功能(nand_read_id());
擦除功能(nand_erase());
读功能(copy_nand_to_sdram());
写功能(copy_sdram_to_nand());

完整代码下载链接:http://download.csdn.net/detail/klcf0220/5636167

Nand flash(三)寄存器及硬件初始化分析相关推荐

  1. Nand flash(一)硬件实现机制

    Flash全名叫做Flash Memory,属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Volatile Memory Device). ...

  2. nand flash 扇区的管理以及初始化

    (1)首先需要了解NAND FLASH的结构.如图: 以镁光MT29F4G08BxB Nand Flash为例,这款Flash(如上图)以4个扇区(sector)组成1个页(page),64个页(pa ...

  3. K9F1208U0M 64M nand flash 手册阅读以及相关驱动程序分析

    首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的.教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈-我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转 ...

  4. K9F1208U0M(64M nand flash)手册阅读以及相关驱动程序分析

    作者:wogoyixikexie@gliet 以前一直使用别人成功的FMD,早几天对一些细节以及编程方法一无所知,同时也有很多人问我flash相关问题,我好想在论坛指点江山,给养技术,可是感觉有些东西 ...

  5. Nand flash 三种类型SLC,MLC,TLC

    转载自:http://diy.pconline.com.cn/750/7501340.html 从前,大家谈TLC色变:如今,TLC攻占SSD半壁江山.是的,这个世界就是这么奇妙. 虽然TLC早已占据 ...

  6. Nand flash 三种类型SLC,MLC,TLC【转】

    转自:https://blog.csdn.net/fc34235/article/details/79584758 转载自:http://diy.pconline.com.cn/750/7501340 ...

  7. SQL Server数据库性能优化(三)之 硬件瓶颈分析

    参考文献 http://isky000.com/database/mysql-performance-tuning-hardware 由于对DBA 工作了解不多    所以只从网上简单的看了下  硬件 ...

  8. nand flash 个人觉得写得比较好的文章

    [详解]如何编写Linux下Nand Flash驱动 版本:v2.2.1 Crifan Li 摘要 本文先解释了Nand Flash相关的一些名词,再从Flash硬件机制开始,介绍到Nand Flas ...

  9. nand flash 经典 全面 ------如何编写Linux下Nand Flash驱动

    Crifan Li 摘要 本文先解释了Nand Flash相关的一些名词,再从Flash硬件机制开始,介绍到Nand Flash的常见的物理特性,且深入介绍了Nand Flash的一些高级功能,然后开 ...

最新文章

  1. U盘启动盘制作方法 2种绝招轻松搞定
  2. 有多少用户痛点,你是听回来的,而不是经过深思过后找出来的
  3. 服务的心跳机制与断线重连,Netty底层是怎么实现的?
  4. Java无线数据增值业务概述
  5. phpmyadmin安全预防
  6. 亿阳防火墙-命令行指令参考手册
  7. 图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)(纯C++)
  8. 【STM32F429的DSP教程】第13章 DSP快速计算函数-三角函数和平方根
  9. oracle 索引优化
  10. 单精度和双精度的区别
  11. 【每日一题】一起冲击蓝桥杯吧——Day09【蓝桥真题一起练】
  12. Android开发笔记01-TextView01
  13. 乔布斯辞世 盖茨等朋友、对手纷纷表示怀念哀悼
  14. FleaPHP 的 Ajax 支持和 WebControls
  15. SSH用法及命令详解
  16. vsftpd failed - probably invalid config.
  17. 使用 Redis 实现 Feed 流
  18. 发布golang第三方包
  19. html%3ca%3e标签中有变量,经过代码审计找出网站中的XSS漏洞实战(三)
  20. 架构师成长营-年度成长计划

热门文章

  1. 【Delphi练习】简易计算器(升级版)
  2. 【代码随想录 | day06】(JavaScript) 哈希表理论基础以及相关算法题
  3. 记录一下最近找到的好玩的东西
  4. 自制聊天机器人实现与chatgpt或微信好友对话【附代码】
  5. padStart()与padEnd()
  6. 我怎么才可以追到我喜欢的女孩子?
  7. (附源码)SSM校园疫情防控志愿服务JAVA计算机毕业设计项目
  8. 明胶纳米颗粒GNPs,50-100nm,呈光滑球形,颗粒尺寸分布较为均匀/齐岳生物
  9. Linux Shell脚本讲解
  10. win7安装vs2015问题总结