[smart210] Nand Flash K9F4G08U0B 的配置与读写控制(二)

发布者:Leishan最新更新时间:2024-12-12 来源: cnblogs关键字:smart210  Nand  Flash  读写控制 手机看文章 扫描二维码
随时随地手机看文章

平台:smart210


CPU:s5pv210


目标:控制核心板上的Nand Flash,对其进行读写操作,本文为上文续篇,主要实现的是对nand flash进行读/写与块擦除操作


void nand_init(void)

{

    // 1. config nandflash controller 

    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. config memory port link to  nand flash 

    MP0_1CON = 0x22333322;

    MP0_2CON = 0x00002222;

    MP0_3CON = 0x22222222;

    // 3. reset

    nand_reset();

}


上文我们研究了NFCONF与NFCONT两个寄存器的设置,以及配置MP0_1,MP0_2,MP0_3的必要性,针对nand flash的初始化进行到了最后阶段,就是reset了。

可以得知Reset命令为FFh,这里#define NAND_CMD_RES 0xff


static void nand_reset(void)

{

    nand_select_chip(); //NFCONT bit1=0

    nand_send_cmd(NAND_CMD_RES);//NFCMMD=NAND_CMD_RES

    nand_wait_idle();//wait until NFSTAT bit4=1 means no busy

    nand_deselect_chip();//NFCONT bit1=1

}


对于nand_reset()函数,顺序依次是片选,命令,等待,解除片选。


接下来就是获取nand flash的id,这次的思路是片选,命令,地址,等待,读取,解除片选。


void nand_read_id(void)

{

    nand_id_info nand_id;

    nand_select_chip();

    nand_send_cmd(NAND_CMD_READ_ID);//发送读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 = %xrn',nand_id.IDm,nand_id.IDd);

    nand_deselect_chip();

}


这里应用到了nand_send_addr()函数,我们来分析一下这个函数


static void nand_send_addr(unsigned long addr)//send addr as column address and row address to send

{

    unsigned long i;

    unsigned long col, row;      

    col = addr % NAND_PAGE_SIZE;    //column :the address in a page 页内地址

    row = addr / NAND_PAGE_SIZE;    //row: the page address 页地址    

    

    NFADDR = col & 0xff;        // Column Address A0~A7          

    for(i=0; i<10; i++);            

    NFADDR = (col >> 8) & 0x0f;     // Column Address A8~A11      

    for(i=0; i<10; i++);

    

    NFADDR = row & 0xff;        // Row Address A12~A19        

    for(i=0; i<10; i++);

    NFADDR = (row >> 8) & 0xff;    // Row Address A20~A27    

    for(i=0; i<10; i++);

    NFADDR = (row >> 16) & 0xff;    // Row Address A28~A30    

    for(i=0; i<10; i++);

}


和(一)中的描述无误,我们把寻址地址拆成行列地址的形式发送出去。

获取到的id,可以根据下图判断是否正确,这块K9F1G08U0B所获取的Maker Code为0xec,Device Code为0xf1。而我们的芯片型号是K9F4G08U0B,具体细节会有所不同,我获取到的是Maker Code=0xec,Device Code=0x54。

获取id之后,证明nand flash处于正常工作状态,我们就能开始对其进行读/写以及块擦除工作了。首先是块擦除的流程图

根据流程图,操作顺序应该是 片选,块擦除命令1,块地址,块擦除命令2,等待,发读取状态命令确认块擦除完成。


之前说过了,row是用来描述页地址的,由于一个块有64页,所以特定的row值如0、64、128、192、256、320等就是块地址了。


unsigned char nand_erase(unsigned long block_num)

{

    unsigned long i = 0;

    unsigned long row = block_num * NAND_BLOCK_SIZE;

    nand_select_chip();

    nand_send_cmd(NAND_CMD_BLOCK_ERASE_1st);

    for(i=0; i<10; i++);    

    NFADDR = row & 0xff;    // Row Address A12~A19                            

    for(i=0; i<10; i++);

    NFADDR = (row >> 8) & 0xff;// Row Address A20~A27  

    for(i=0; i<10; i++);

    NFADDR = (row >> 16) & 0xff;    // Row Address A28~A30 

             

    NFSTAT = (NFSTAT)|(1<<4);

    nand_send_cmd(NAND_CMD_BLOCK_ERASE_2st);

    for(i=0; i<10; i++);

    nand_wait_idle();

    unsigned char status = read_nand_status();

    if (status & 1 )//一旦读取到状态异常,则认为该处为坏块,需要对坏块进行一些处理。

    {

        nand_deselect_chip();                        

        printf('masking bad block %drn', block_num);

        return -1;

    }

    else

    {

        nand_deselect_chip();

        return 0;

    }

}


完成了块擦除,接下来就是读写了,读的前提是写,没有写入数据的nand flash 自然就没有数据给我们读,所以我们首先来进行写操作(又叫页面编程 page program),下面是写操作流程图

写操作的一开始要先明确给出页地址和页内地址作为写的起始地址,由于nand flash采取的是整页读写的策略,所以我们只需要给定一次地址,就能源源不断地往该页写数据,实际上就是把一个缓冲数组的每个元素逐个逐个地给搬移到nand flash的特定页内,由于一开始给定的地址是寻址地址而非行列地址,所以遇到字节数大于2048的缓冲数组还得做特殊处理,下面这段程序用了巧妙的方式,以检查剩余缓冲区大小为主线,同时兼顾页面的剩余大小,哪个条件先达到就处理哪一种情况。


int copy_sdram_to_nand(unsigned char *sdram_addr, unsigned long nand_addr, unsigned long length)

{

    unsigned long i = 0;

    nand_select_chip();

    while(length)

    {

        nand_send_cmd(NAND_CMD_WRITE_PAGE_1st);

        nand_send_addr(nand_addr);

        unsigned long col = nand_addr % NAND_PAGE_SIZE;

        i = col;

        for(; i        {

            nand_write(*sdram_addr);

            sdram_addr++;

            nand_addr++;

        }

        NFSTAT = (NFSTAT)|(1<<4);

        nand_send_cmd(NAND_CMD_WRITE_PAGE_2st);

        nand_wait_idle();

    }

    unsigned char status = read_nand_status();

    if (status & 1 )

    {

        nand_deselect_chip();

        printf('copy sdram to nand failrn');

        return -1;

    }

    else

    {

        nand_deselect_chip();

        return 0;

    }

}


写操作的完成是为了读操作准备的,读操作和写操作的流程及其相似,主要原因是两者的模式都是基于sdram与nand flash的交互下完成的。

可以注意到,写操作命令1st和2nd携带了地址和数据,而读操作命令1st与2nd只携带了地址,接着就能顺着页面内的列地址读下去了。不管读写操作是从页面的哪个列地址开始的,最终都只能持续读写直到当前页面的最后一个字节,所以必要的时候还是需要重新计算行列地址,在新的页内内做读写操作。


int copy_nand_to_sdram(unsigned char *sdram_addr, unsigned long nand_addr, unsigned long length)

{

    unsigned long i = 0;

    nand_select_chip();

    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;

        for(; i        {

            *sdram_addr = nand_read();

            sdram_addr++;

            nand_addr++;

        }

    }


    unsigned char status = read_nand_status();

    if (status & 1 )

    {

        nand_deselect_chip();

        printf('copy nand to sdram failrn');

        return -1;

    }

    else

    {

        nand_deselect_chip();

        return 0;

    }

}


最终通过调用这两个函数,可以实现大数据的读写,sdram与nand flash的交互,一定程度体现了嵌入式设备RAM与ROM之间的关系,可编程的静态存储控制器与软件编程为动态存储与静态存储的沟通建立了桥梁。


关键字:smart210  Nand  Flash  读写控制 引用地址:[smart210] Nand Flash K9F4G08U0B 的配置与读写控制(二)

上一篇:[smart210] 定时器与PWM
下一篇:[smart210] Nand Flash K9F4G08U0B 的配置与读写控制(一)

推荐阅读最新更新时间:2026-03-20 13:58

非易失闪存技术NAND Flash内存设备的读写控制设计
    NOR Flash和NAND Flash是现在市场上两种主要的非易失闪存技术。Flash因为具有非易失性及可擦除性,在数码相机、手机、个人数字助理( PDA)、掌上电脑、MP3播放器等手持设备中得到广泛的应用。NAND Flash相对于NOR Flash具有更小的体积、更快的写入速度、更多次的可擦除次数以及更低廉的价格而得到了迅速发展。大容量的NAND Flash特别适合现在数码设备中大数据量的存储携带,可以降低成本,提高性能 。     1 系统设计     1.1 NAND Flash和NOR Flash的区别     1.1.1 接口差别     NOR Flash带有SRAM接口,有足够的地址引脚来寻址,可
[单片机]
Smart210学习记录------nor flash驱动
nor flash驱动与nand flash驱动的差别不大,只是设置不同的结构体而已,, nor flash驱动代码: #include linux/module.h #include linux/types.h #include linux/kernel.h #include linux/init.h #include linux/slab.h #include linux/device.h #include linux/platform_device.h #include linux/mtd/mtd.h #include linux/mtd/map.h #include linux/mtd/parti
[单片机]
S3C2440的内存情况在NAND FLASH或者NOR FLASH启动的情况下
1,从NANDFLASH启动时,在ARM上电时,ARM会自动把NANDFLASH前4K的内容拷贝到S3C2440内部SRAM中,同时把SRAM的地址映射到0X00000000。ARM上电后会从SRAM处开始运行。 2,从NOR FLASH启动时,因为NORFLASH接在bank0。地址映射是0X00000000。所以ARM上电后直接运行NORFLASH里的程序。此时S3C2440内部SRAM地址为0X40000000。 3,ARM上电启动都是从0X00000000开始运行。但是对于复位程序入口,ResetEntry的值在ARM上电运行时是0X00000000,在JTAG仿真时是0X30000000。这个值很关键,在拷贝程序
[单片机]
S3C2440的内存情况在<font color='red'>NAND</font> <font color='red'>FLASH</font>或者NOR <font color='red'>FLASH</font>启动的情况下
u-boot-2011.03在mini2440/micro2440上的移植 支持Nand Flash启动
7.1 创建nand_read.c 【注意】 本程序只能用于读取2K/页的Nand。本人的Micro2440上的Nand Flash为256M,型号为K9F2G08 $ touch board/samsung/micro2440/nand_read.c $ cat board/samsung/micro2440/nand_read.c #define rNFCONF (*(volatile unsigned *)0x4E000000) #define rNFCONT (*(volatile unsigned *)0x4E000004) #define rNFCMD (*(volatile unsigned *)0x4E00
[单片机]
s3c2440 移值u-boot-2016.03 第4篇 支持NAND flash 识别
1, /include/configs/smdk2440.h 中添加 #define CONFIG_CMD_NAND 编译 drivers/mtd/nand/built-in.o: In function `nand_init_chip': /u-boot-2016.03/drivers/mtd/nand/nand.c:76: undefined reference to `board_nand_init' 发现是少了文件 /drivers/mtd/nand/s3c2410_nand.c 复制为 /drivers/mtd/nand/s3c2440_nand.c 打开 里面的 所有 2410 换为 2440 dri
[单片机]
s3c2440 移值u-boot-2016.03 第4篇 支持<font color='red'>NAND</font> <font color='red'>flash</font> 识别
U-Boot在FL2440上移植(三)----支持NAND Flash
一 支持NAND Flash 1. 首先在配置文件 include/config/fl2440.h 的宏 CONFIG_COMMANDS 中增加 CFG_CMD_NAND, #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_CACHE | CFG_CMD_NAND | 2.在配置文件 include/configs/fl2440.h 中增加如下3个宏 #define CFG_NAND_BASE 0 //无实际意义:基地址,在board_nand_init中重新定义 #define CFG_MAX_NAND_DEVICE 1 //NAND Flash设备数目为1
[单片机]
Linux2.6.32移植到MINI2440(2)添加Nand Flash驱动,修改分区
开发环境: 主机:fedora 14 虚拟机:vmware workstation 10 交叉编译工具:arm-linux-gcc 4.3.2 开发板:mini2440(2m nor ,64m sdram,256m nand) 一、添加头文件 在/arch/arm/mach-s3c2440/mach-mini2440.c中 vim mach_mini2440.c 添加进去如下头文件: #include linux/mtd/partitions.h #include linux/mtd/nand_ecc.h #include linux/mtd/mt
[单片机]
U-boot-2014.04移植到MINI2440(7) nand flash datasheet及arm9控制寄存器分析
我的MINI2440上有一个256M的nand flash,后面我们需要从nand启动u-boot,然后引导加载内核,再挂载根文件系统,这里先对其做一个较为细致的认识。主要是硬件管脚定义,控制方式,处理器的控制寄存器对其做一个了解,因为现在市面上nand的用途比较广泛,数码相机,mp3都要使用,进入正题。 一.nand flash datasheeet 在移植好的u-boot下输入nand info会出现下面的信息: Device 0: NAND 256MiB 3,3V 8-bit, sector size 128 KiB 这说明nand大小为256M,工作电压3.3v,数据总线为8位,扇区大小为128K。首先我们
[单片机]
U-boot-2014.04移植到MINI2440(7) <font color='red'>nand</font> <font color='red'>flash</font> datasheet及arm9<font color='red'>控制</font>寄存器分析
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved