• NandFlash读写


    1.NandFlash分类

    根据物理结构上的区别,NandFlash主要分为如下两类:
    •SLC (Single Level Cell): 单层式存储
    •MLC (Multi Level Cell): 多层式存储
    SLC在存储格上只存一位数据,而MLC则存放两位数据。

    2.MLC与SLC对比

    价格:由于MLC采用了更高密度的存储方式,因此同容量的MLC价格上远低于SLC.
    访问速度:SLC的访问速度一般要比MLC快3倍以上.
    使用寿命:SLC能进行10万次的擦写,MLC能进行1万次
    功耗:MLC功耗比SLC高15%左右

    3.NandFlash初始化

    3.1 设置时间参数TACLS 、TWRPH0、TWRPH1 

    3.2 使能NandFlash

    3.3 NandFlash复位

    3.3.1 选中芯片

    3.3.2 清除RnB

    3.3.3 发出复位信号(0xff)

    3.3.4 等待就绪

    3.3.5 取消选中

     4.按页读取NandFlash的值

     

    步骤:

    1.选中芯片;2.清除RnB;3.发出命令0x00;4.发送列地址;5.发送行地址;6.发出命令0x30;7.等待就绪;8.读数据 ;9.取消片选

    5.向NandFlash写入数据

    5.1 擦除(写之前要进行擦除)

    步骤:

    1.选中芯片;2.清除RnB;3.发出命令0x60;4.发送行地址(3个周期);5.发送命令D0;6.等待RnB;7.发送命令70;8.读取擦除结果;9.取消片选

     5.2 写入数据

    步骤:

    1.选中芯片;2.清除RnB;3.发出命令0x80;4.发送列地址(2个周期);5.发送行地址(3个周期);6.写入数据;7.发送命令0x10;8.等待RnB;9.发送命令70;10.读取写入结果;10.取消片选

    6.代码

    nand.c

      1 /*
      2 tiny6410用的nandflash为 一页2K
      3 */
      4 
      5 
      6 #define NFCONF             (*((volatile unsigned long*)0x70200000))
      7 #define NFCONT             (*((volatile unsigned long*)0x70200004))
      8 #define NFCMMD             (*((volatile unsigned char*)0x70200008))
      9 #define NFSTAT             (*((volatile unsigned char*)0x70200028))
     10 #define NFADDR             (*((volatile unsigned char*)0x7020000c))
     11 #define NFDATA             (*((volatile unsigned char*)0x70200010))
     12 
     13 void select_ship(void)
     14 {
     15     NFCONT &= ~(1<<1);    
     16 }
     17 
     18 void delselect_ship(void)
     19 {
     20     NFCONT |= (1<<1);
     21 }
     22 
     23 void clean_RnB()
     24 {
     25     NFSTAT |= (1<<4);
     26 } 
     27 void nand_cmd(unsigned char cmd)
     28 {
     29     NFCMMD = cmd;   
     30 }
     31 
     32 void wait_RnB(void)
     33 {
     34     while(!(NFSTAT & 0x1));
     35 }
     36 
     37 void nand_addr(unsigned char addr)
     38 {
     39     NFADDR = addr;
     40 }
     41 
     42 void nand_reset(void)
     43 {
     44     /* 选中 */
     45     select_ship();
     46     
     47     /* 清除RnB */
     48     clean_RnB();
     49     
     50     /* 发出复位信号 */
     51     nand_cmd(0xff);
     52     
     53     /* 等待就绪 */
     54     wait_RnB();
     55     
     56     /* 取消选中 */
     57     delselect_ship();
     58 }
     59 
     60 void nand_init(void)
     61 { 
     62 
     63     
     64     /* 设置时间参数 */
     65 #define TACLS  7
     66 #define TWRPH0 7
     67 #define TWRPH1 7
     68     
     69     NFCONF &= ~((7<<12)|(7<<8)|(7<<4));
     70     NFCONF |= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
     71     
     72     /* 使能 nandflash controller*/
     73     NFCONT = 1 | (1<<1);
     74     
     75     
     76     
     77     /* 复位 */
     78     nand_reset();
     79 }
     80 
     81 void NF_PageRead(unsigned long addr,unsigned char* buff)
     82 {
     83     int i;
     84     
     85     
     86     /* 选中芯片 */
     87     select_ship();
     88     
     89     /* 清除RnB */
     90     clean_RnB();
     91     
     92     /* 发出命令0x00 */
     93      nand_cmd(0x00);
     94         
     95      /* 发出列地址 */
     96     nand_addr(0x00);
     97     nand_addr(0x00);
     98 
     99     /* 发出行地址 */
    100     nand_addr(addr&0xff);
    101     nand_addr((addr >>8 ) & (0xff));
    102     nand_addr((addr >>16 ) & (0xff));
    103         
    104     /* 发出命令0x30 */
    105      nand_cmd(0x30);
    106         
    107     /* 等待就绪 */
    108      wait_RnB();
    109         
    110     /* 读数据 */
    111      for(i = 0; i<1024*2; i++)
    112     {
    113         *buff++ = NFDATA;
    114     }
    115         
    116       
    117      /* 取消片选 */
    118      
    119      delselect_ship();
    120      
    121 }
    122 
    123 
    124 int NF_Erase(unsigned long addr)
    125 {
    126     int ret;
    127     
    128     //选中flash芯片
    129     select_ship();
    130     
    131     //清除RnB
    132     clean_RnB();
    133     
    134     //发送命令60
    135     nand_cmd(0x60);
    136     
    137     //发送行地址(3个周期)
    138     nand_addr(addr&0xff);
    139         nand_addr((addr >>8 ) & (0xff));
    140         nand_addr((addr >>16 ) & (0xff));
    141     
    142     //发送命令D0
    143     nand_cmd(0xD0);
    144     
    145     //等待RnB
    146     wait_RnB();
    147     
    148     //发送命令70
    149     nand_cmd(0x70);
    150     
    151     //读取擦除结果
    152     ret = NFDATA;
    153     
    154     //取消选中flash芯片
    155     delselect_ship();
    156     
    157     return ret;
    158 }
    159 
    160 int NF_WritePage(unsigned long addr,unsigned char* buff)
    161 {
    162     int ret,i;
    163     
    164     //选中flash芯片
    165     select_ship();
    166     
    167     //清除RnB
    168     clean_RnB();
    169     
    170     //发送命令80
    171     nand_cmd(0x80);
    172     
    173     //发送列地址(2个周期)
    174     nand_addr(0x00);
    175         nand_addr(0x00);
    176     
    177     //发送行地址(3个周期)
    178     nand_addr(addr&0xff);
    179         nand_addr((addr >>8 ) & (0xff));
    180         nand_addr((addr >>16 ) & (0xff));
    181     
    182     //写入数据
    183     for(i=0;i<1024*2;i++)
    184     {
    185         NFDATA = buff[i];    
    186     }
    187     
    188     //发送命令10
    189     nand_cmd(0x10);
    190     
    191     //等待RnB
    192     wait_RnB();
    193     
    194     //发送命令70
    195     nand_cmd(0x70);
    196     
    197     //读取写入结果
    198     ret = NFDATA;
    199     
    200     //取消选中flash芯片
    201     delselect_ship();
    202     
    203     return ret;
    204 }
    nand.c

    nand_to_ram

    汇编和C语言的参数传递,不超过4个的时候,直接用r0--r3传递,且顺序和从函数的形参一致

     1 copy_to_ram:
     2     mov r0,#0
     3     ldr r1,=_start
     4     ldr r2,=bss_end
     5     
     6     sub r2,r2,r1
     7     mov ip,lr
     8     bl nand_to_ram
     9     
    10     mov lr,ip
    11     
    12     
    13     mov pc,lr
    start.S
     1 void nand_to_ram(unsigned long start_addr,unsigned char* sdram_addr,int size)
     2 {
     3         int i;
     4                
     5     for( i=(start_addr >>11); size>0;)
     6     {
     7         NF_PageRead(i,sdram_addr);    
     8         size -= 2048;
     9         sdram_addr += 2048;
    10         i++;
    11     }
    12         
    13 }
    nand_to_ram
  • 相关阅读:
    23种设计模式(转载)
    RabbitMQ JAVA客户端调用
    JavaScript中的this
    RedisDesktopManager 踩坑之旅
    webmagic使用手册
    Maven 手动添加本地jar包
    根据端口号查询 进程 并杀掉进程
    从经典面试题看java中类的加载机制
    Java线程的5种状态及切换(透彻讲解)
    JVM 类加载机制详解
  • 原文地址:https://www.cnblogs.com/boyiliushui/p/6002783.html
Copyright © 2020-2023  润新知