在线问答
直播中

mrbushy

9年用户 77经验值
擅长:可编程逻辑 嵌入式技术 处理器/DSP 光电显示 控制/MCU EDA/IC设计
私信 关注

【OK210试用体验】+ 《NANDFLASH配置源码分析》

本帖最后由 mrbushy 于 2015-9-16 22:40 编辑

一、仍然先把源码贴出来再分析/*
* Nand Interface Init for SMDKC110
*/
nand_asm_init:

        /* Setting GPIO for NAND */
        /* This setting is NAND initialze code at booting time in iROM. */

        ldr        r0, =ELFIN_GPIO_BASE

        ldr        r1, [r0, #MP01CON_OFFSET]
        bic        r1, r1, #(0xf<<8)
        orr        r1, r1, #(0x3<<8)
        str        r1, [r0, #MP01CON_OFFSET]

        ldr        r1, [r0, #MP01PUD_OFFSET]
        bic        r1, r1, #(0x3<<4)
        str        r1, [r0, #MP01PUD_OFFSET]

        ldr        r1, [r0, #MP03CON_OFFSET]
        bic        r1, r1, #0xFFFFFF
        ldr        r2, =0x22222222
        orr        r1, r1, r2
        str        r1, [r0, #MP03CON_OFFSET]

        ldr        r1, [r0, #MP03PUD_OFFSET]
        ldr        r2, =0x3fff
        bic        r1, r1, r2
        str        r1, [r0, #MP03PUD_OFFSET]

        ldr        r0, =ELFIN_NAND_BASE

        ldr        r1, [r0, #NFCONF_OFFSET]
        ldr        r2, =0x777F
        bic        r1, r1, r2
        ldr        r2, =NFCONF_VAL
        orr        r1, r1, r2
        str        r1, [r0, #NFCONF_OFFSET]

        ldr        r1, [r0, #NFCONT_OFFSET]
        ldr        r2, =0x707C7
        bic        r1, r1, r2
        ldr        r2, =NFCONT_VAL
        orr        r1, r1, r2
        str        r1, [r0, #NFCONT_OFFSET]

        ldr        r1, [r0, #NFCONF_OFFSET]
        orr        r1, r1, #0x70
        orr        r1, r1, #0x7700
        str     r1, [r0, #NFCONF_OFFSET]

        ldr        r1, [r0, #NFCONT_OFFSET]
        orr        r1, r1, #0x03
        str     r1, [r0, #NFCONT_OFFSET]

        mov        pc, lr
boardsamsungOK210lowlevel_init.S中找到
u-boot-2011.06-2013-05-30includeconfigsOK210.h中查找到
#define MP01CON_OFFSET                         0x2E0
#define MP01DAT_OFFSET                         0x2E4
#define MP01PUD_OFFSET                         0x2E8
#define MP01DRV_SR_OFFSET                 0x2EC
#define MP01CONPDN_OFFSET                 0x2E0
#define MP01PUDPDN_OFFSET                 0x2E4

#define MP02CON_OFFSET                  0x300
#define MP02DAT_OFFSET                  0x304
#define MP02PUD_OFFSET                  0x308
#define MP02DRV_SR_OFFSET               0x30c
#define MP02CONPDN_OFFSET               0x310
#define MP02PUDPDN_OFFSET               0x314

#define MP03CON_OFFSET                  0x320
#define MP03DAT_OFFSET                  0x324
#define MP03PUD_OFFSET                  0x328
#define MP03DRV_SR_OFFSET               0x32c
#define MP03CONPDN_OFFSET               0x330
#define MP03PUDPDN_OFFSET               0x334
#define NFCONF_VAL        (7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0)
#define NFCONT_VAL      (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x2<<1)|(1<<0)
#define MP03CON_VAL        (1<<29)|(1<<25)|(1<<21)|(1<<17)|(1<<13)|(1<<9)|(1<<5)|(1<<1)

/*
* Nand flash controller
*/
#define ELFIN_NAND_BASE                        0xB0E00000
#define ELFIN_NAND_ECC_BASE                0xB0E20000

#define NFCONF_OFFSET                   0x00
#define NFCONT_OFFSET                   0x04
#define NFCMMD_OFFSET                   0x08
#define NFADDR_OFFSET                   0x0c
#define NFDATA_OFFSET                        0x10
#define NFMECCDATA0_OFFSET              0x14
#define NFMECCDATA1_OFFSET              0x18
#define NFSECCDATA0_OFFSET              0x1c
#define NFSBLK_OFFSET                   0x20
#define NFEBLK_OFFSET                   0x24
#define NFSTAT_OFFSET                   0x28
#define NFESTAT0_OFFSET                 0x2c
#define NFESTAT1_OFFSET                 0x30

#define NFCONF                                (ELFIN_NAND_BASE+NFCONF_OFFSET)
#define NFCONT                                (ELFIN_NAND_BASE+NFCONT_OFFSET)
#define NFCMMD                                (ELFIN_NAND_BASE+NFCMMD_OFFSET)
#define NFADDR                           (ELFIN_NAND_BASE+NFADDR_OFFSET)
#define NFDATA                          (ELFIN_NAND_BASE+NFDATA_OFFSET)
#define NFMECCDATA0                     (ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
#define NFMECCDATA1                     (ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
#define NFSECCDATA0                      (ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
#define NFSBLK                          (ELFIN_NAND_BASE+NFSBLK_OFFSET)
#define NFEBLK                           (ELFIN_NAND_BASE+NFEBLK_OFFSET)
#define NFSTAT                           (ELFIN_NAND_BASE+NFSTAT_OFFSET)
#define NFESTAT0                         (ELFIN_NAND_BASE+NFESTAT0_OFFSET)
#define NFESTAT1                         (ELFIN_NAND_BASE+NFESTAT1_OFFSET)
#define NFMECC0                          (ELFIN_NAND_BASE+NFMECC0_OFFSET)
#define NFMECC1                          (ELFIN_NAND_BASE+NFMECC1_OFFSET)
#define NFSECC                           (ELFIN_NAND_BASE+NFSECC_OFFSET)
#define NFMLCBITPT                           (ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)





二.配置原理分析
初始化Nand Flash
在u-boot中,Nand的低级初始化在lowlevel_init.S中的nand_asm_init函数中。打开原理图,配置各个功能引脚----状态引脚R/B1, 读使能引用脚/RE, 片选信号/CE1, 命令使能引脚CLE ,地址使能引脚ALE, 写使能引脚WE
1.png

2.png

搜索各个引脚的值,比如R/B1接在Xm0FRnB0上,搜索Xm0FRnB0,发现Xm0FRnB0和ONDXL_INT0/MP03_4共用一个引脚。
1.配置片选信号引脚
查找到nCE接在复用引脚Xm0CSn2/NFCSn0/MP01_2上,打开S5PV210芯片手册,P185页查找到MP0_1 Control Registe,MP0_1CON[2]的配置如下:


3.png





所以,只需将NFCSN0配置成011,才能识别成Nand Flash。
*
* Nand Interface Init for SMDKC110
*/
nand_asm_init:

        /* Setting GPIO for NAND */
        /* This setting is NAND initialze code at booting time in iROM. */

        ldr        r0, =ELFIN_GPIO_BASE

        ldr        r1, [r0, #MP01CON_OFFSET]
        bic        r1, r1, #(0xf<<8)    // 将MP0_1 Control Register 的第8.9.10.11位清零
        orr        r1, r1, #(0x3<<8)   //MP0_1 Control Register 的第8.9.10.11位写0x3(0011)
        str        r1, [r0, #MP01CON_OFFSET]
将Port Group MP0_1 Control Register 的4-5位全部清为0


4.png
        ldr        r1, [r0, #MP01PUD_OFFSET]
        bic        r1, r1, #(0x3<<4)
        str        r1, [r0, #MP01PUD_OFFSET]
配置CLE/ALE/nWE/nRE/R/nB引脚
除了nCE引脚,其余的几个引脚都是复用的MP0,查找MP03,P189,Port Group MP0_3 Control Register,配置如下:
Port Group MP0_3 Control Register (MP0_3CON, R/W, Address = 0xE020_0320)
5.png

6.png

图中红框中的NF应该是nandflash 的缩写。
先将0-23位全部清零,然后全部置为0010,也就是全部置为2
    ldr        r1, [r0, #MP03CON_OFFSET]
        bic        r1, r1, #0xFFFFFF
        ldr        r2, =0x22222222
        orr        r1, r1, r2
        str        r1, [r0, #MP03CON_OFFSET]

        ldr        r1, [r0, #MP03PUD_OFFSET]
        ldr        r2, =0x3fff
        bic        r1, r1, r2
        str        r1, [r0, #MP03PUD_OFFSET]
将Port Group MP0_3 Control Register的0-23位全部清为0
Port Group MP0_3 Control Register (MP0_3PUD, R/W, Address = 0xE020_0328)
7.png

    ldr        r1, [r0, #MP03PUD_OFFSET]
        ldr        r2, =0x3fff
        bic        r1, r1, r2
        str        r1, [r0, #MP03PUD_OFFSET]


2.配置Nandf Flash控制器的寄存器NFCONF
Nand Flash Configuration Register (NFCONF, R/W, Address = 0xB0E0_0000)
先看前四位[3:0]
8.png

[0]位保留,置为0。
[1]用来配置页的一个地址周期是,MT29F8G08ABABA是每页4K,那么地址周期是多少,再去看MT29F8G08ABABA的芯片手册,看到第P16页
9.png

示地址周期为5th,所以[1]配为1
先看[3],这里是配置是SLC还是MCL,根据芯片名称,这款MT29F8G08ABABA是SLC存储,所以[3]配为0
再来看[2],K9F2G08UOBSingle-level cell (SLC) technology,PageSize是4,[2]中没有相应的选项....但是源码中是选1
10.png 这里需要配置TACLS, TWRPH0, TWRPH1
查看一下s5pv210芯片手册上的NAND FLASH MEMORY TIMING, P693-P694
11.png

TACLS:当将CLE和ALE拉高以后,再过多少时间才能发出写使能信号(nWE)
TWRPH0:nWE使能持续时间,信号被拉低的时间
TWRPH1:当将CLE和ALE拉高以后,WE使能,这时,后面开始发数据,这就是数据起作用的时间(Data hold time)
查看MT29F8G08ABABA的芯片手册18页
17.png



查看1页知MT29F8G08ABABA是基于timing mode 4 的


14.png

查看103页
15.png
16.png












这里S5PV210的NandFlash的HCLK频率为133MHz(P522页),NFCON属于HCLKD0 = 133MHz,T = 1/133 = 7.5ns
18.png
查看210芯片手册708页
19.png
在210芯片手册693页下有一句话
Figure 4-2 CLE and ALE Timing (TACLS=1, TWRPH0=0, TWRPH1=0)
所以
TACLS:配置0,算出时间为7.5*(0+1)= 7.5ns
TWRPH0:配置1,算出时间为7.5*(1+1)= 15ns
TWRPH1:配置0,算出时间为7.5*(0+1)= 7.5ns
通过实际的测试,如果配置成最小值,Nand Flash会出现无法读写的情况,这里我们还是参考提供的Nand Flash的裸机的参考代码,将这三位配成7--7--7
TACLS:配置0,算出时间为7.5*(7+1)= 60ns
TWRPH0:配置1,算出时间为7.5*(7+1)= 60ns
TWRPH1:配置0,算出时间为7.5*(7+1)= 60ns



  ldr        r0, =ELFIN_NAND_BASE

        ldr        r1, [r0, #NFCONF_OFFSET]
        ldr        r2, =0x777F
        bic        r1, r1, r2
        ldr        r2, =NFCONF_VAL  /#define NFCONF_VAL        (7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0)
        orr        r1, r1, r2
        str        r1, [r0, #NFCONF_OFFSET]

3.配置CONTROL REGISTER

(NFCONT, R/W, ADDRESS = 0XE720_0004)
查看210芯片手册709-710页
20.png

21.png
第[0]位,让NAND Flash控制器Enable,这里设置为1。使能意思就是生效的意思第二位是1Force nRCS[0] to High (Disable chip select)剩下的几位按源码配置


        ldr        r1, [r0, #NFCONT_OFFSET]
        ldr        r2, =0x707C7
        bic        r1, r1, r2
        ldr        r2, =NFCONT_VAL /#define NFCONT_VAL      (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x2<<1)|(1<<0)
        orr        r1, r1, r2
        str        r1, [r0, #NFCONT_OFFSET]



        ldr        r1, [r0, #NFCONF_OFFSET]
        orr        r1, r1, #0x70
        orr        r1, r1, #0x7700                  /这一步上面已经做过相同配置不知为何又写一遍,看了其他版本的uboot并没有重复,也许是后来改的人直接在这个源码中添加了内容没有删减也不得而知。。。。
        str     r1, [r0, #NFCONF_OFFSET]

        ldr        r1, [r0, #NFCONT_OFFSET]
        orr        r1, r1, #0x03     /*使能NAND控制器、关闭chip select   这一步以上同样配置过...
        str     r1, [r0, #NFCONT_OFFSET]

        mov        pc, lr


注:这里的NANDFLASH配置没有配置ecc
(


ldr r1, [r0, #NFCONT_OFFSET]
ldr r2, =0x707C7
bic r1, r1, r2
ldr r2, =NFCONT_VAL                     *ECC  LOCK   INTERRUPT 等设置
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET]








)
下篇预告《DDR2工作原理分析》




  • 1.png
  • 3.png
  • 12.jpg

回帖(3)

HelloWii

2015-9-17 12:57:54
不错,,感谢分享。。。。。
举报

mrbushy

2015-9-17 14:31:28
引用: HelloWii 发表于 2015-9-17 12:57
不错,,感谢分享。。。。。

真怀疑你有没有看。。。。。到处水经验..
举报

HelloWii

2015-9-17 14:59:20
引用: mrbushy 发表于 2015-9-17 14:31
真怀疑你有没有看。。。。。到处水经验..

   我有看的,,,,好贴不能沉,,我要顶起来。。。。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分