加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

嵌入式bootloader开发之八----NAND Flash读写擦除操作实现(Tiny

发布时间:2020-12-15 17:51:34 所属栏目:百科 来源:网络整理
导读:概要: ? ? ? ? ?本节主要记录开发Tiny6410自带的NAND FLASH的过程,实现了NAND FLASH的擦除,读写数据功能,但都只是简单的实现而已,并没有做精细而完整的实现,毕竟只是想学原理。 前言: ? ? 工欲善其事,必先利其器。在做开发之前,必须保证良好的环境

概要:

? ? ? ? ?本节主要记录开发Tiny6410自带的NAND FLASH的过程,实现了NAND FLASH的擦除,读写数据功能,但都只是简单的实现而已,并没有做精细而完整的实现,毕竟只是想学原理。


前言:

? ? 工欲善其事,必先利其器。在做开发之前,必须保证良好的环境和设备,笔者所使用的tiny6410光盘中自带的uboot版本比较老,而且其并不支持MLC2的读写操作,但是之前并不知道,写了很多次,但是总是写不到NAND FLASH中去,还以为是NAND FLASH设备的坏块太多,各种原因各种奇葩猜想,还好,最后时刻想起了友善之臂的官网,无意间看到了uboot的某一版的发行注释中写着实现了MLC2的读写,啊。。。。。有点怒了。。。。竟然是使用的uboot的问题,立即马上下载,然后烧录进去,重写NAND FLASH,写入成功!!!

为了方便,现将新版的uboot和System.map文件共享出来,版权属于友善之臂公司。

uboot-ram256M nand-flash版:uboot

System.map文件:System.map


详细的有关NAND FLASH设备的介绍以及一些常识请自行百度或者直接查阅S3C6410数据手册和相应的NAND FLASH数据手册,本文中以Tiny6410中使用的三星公司产的MLC的NAND FLASH芯片K9GAG08U0E(2GB MLC)为例。

具体NAND FLASH的接口电路如下:


LDATA0~LDATA7是I/O口,传输数据、命令或者地址

FWEn:NAND FLASH写数据信号,低有效

FREn:NAND FLASH读数据信号,低有效

FCLE:命令锁存信号

FALE:地址锁存信号

RnB:忙或准备好状态标志位


S3C6410本身集成有NAND FLASH控制器,若要使用只需进行相应的配置即可。

相关的寄存器如下:

//nand flash K9GAG08U0E
#define Base 0x70200000
#define NFCONF (*(volatile unsigned long *)(Base + 0x00))
#define NFCONT (*(volatile unsigned long *)(Base + 0x04 ))
#define NFCMMD (*(volatile unsigned char *)(Base + 0x08 ))
#define  NFADDR (*(volatile unsigned char *)(Base + 0x0c))
#define  NFDATA (*(volatile unsigned char *)(Base + 0x10))
#define  NFSTAT (*(volatile unsigned long *)(Base + 0x28))


NAND FLASH controller的初始化主要有:

1.初始化NFCONF,配置TACLS 、TWRPH0、TWRPH1 等。

2.初始化NFCONT,使能NAND FLASH控制器



具体代码如下:

void nand_init(){
        reset();//无关紧要,要不要都可以

        NFCONF &=~((0x7<<4)|(0x7<<8)|(0x7<<12)|(1<<30));
        NFCONF |=((TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4));

        NFCONT |= 1 ;// enable controller

}


读操作的流程如下:

1.片选有效

2.发送命令0x00H

3.发送地址信号

4.发送命令0x30h

5.检测ready/busy状态标志位,若不忙,读取指定字节的数据

6.拉高片选信号,使无效

具体代码实现如下:

void nand_read(unsigned long addr,char *buf,int len)
{

        NFCONT &= ~(1<<1);//片选有效
        NFCMMD = 0x00;  //read 1 circle
        get_addr(addr); 
        NFCMMD = 0x30;//read 2 circle
        volatile int i;  
        while(!(NFSTAT & 1))    //wait until ready
                ;
        for(i=0;i<PAGE_SIZE;++i)//read a page
                buf[i]=NFDATA;
        NFCONF |= (1<<1);//拉高
}

写操作的流程如下:

1.片选有效

2.发送命令0x80

3.发送地址信号

4.发送命令0x10

5.检测ready/busy状态标志位,若不忙,读取指定字节的数据

6.拉高片选信号,使无效

具体代码实现如下:

void nand_write(unsigned long addr,int len)
{
        volatile int i;  
        NFCONT &= ~(1<<1);//片选有效
        NFCMMD = 0x80;  //write 1 circle
        get_addr(addr);
        for(i=0;i<len;++i)//write a page
                NFDATA=buf[i];
        for(i=len;i<PAGE_SIZE;++i)
                NFDATA = 0xff;

      NFCMMD = 0x10;//write 2 circle
        while(!(NFSTAT & 1))    //wait until ready
                ;
        show("nand write ok!n");

        NFCONF |= (1<<1);//拉高
}

擦除操作的流程如下:

1.片选有效

2.发送命令0x60

3.发送地址信号(注意这里的地址是页号

4.发送命令0xd0

5.检测ready/busy状态标志位,若不忙,读取指定字节的数据

6.拉高片选信号,使无效

void nand_erase(unsigned long addr)
{

        volatile int i,row;
        NFCONT &= ~(1<<1);//片选有效
        NFCMMD = 0x60;  //write 1 circle

        row = addr / PAGE_SIZE;
        NFADDR = row &0xff;
        NFADDR =(row>>8) &0xff;
        NFADDR = (row>>16) & 0xff;

        NFCMMD = 0xd0;//write 2 circle
        while(!(NFSTAT & 1))    //wait until ready
                ;
        show("nand erase ok!n");

        NFCONF |= (1<<1);//拉高
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读