1.u-boot參考源碼
Nand Flash的初始化代碼在board/samsung/tiny210/lowlevel_init.S
2.初始化Nand Flash
在u-boot中,Nand的低級初始化在lowlevel_init.S中的nand_asm_init函數中。打開原理圖,配置各個功能引腳----狀态引腳R/nB, 讀使能引用腳nRE, 片選信号nCE, 指令使能引腳CLE ,位址使能引腳ALE, 寫使能引腳nWE。

搜尋各個引腳的值,比如R/nB接在Xm0FRnB0上,搜尋Xm0FRnB0,發現Xm0FRnB0和ONDXL_INT0/MP03_4共用一個引腳,上圖中将各個信号線的複用引腳全部在左邊用紅色标注出來。
2.1配置片選信号引腳
查找到nCE接在複用引腳Xm0CSn2/NFCSn0/MP01_2上,打開S5PV210晶片手冊,P185頁查找到MP0_1 Control Registe,MP0_1CON[2]的配置如下:
是以,隻需将這一位,配置成011,才能識别成Nand Flash。
/*ELFIN_GPIO_BASE 0xE0200000*/
ldr r0, =ELFIN_GPIO_BASE
/*Nand Flash nCE pin*/
ldr r1, [r0, #MP01CON_OFFSET] @0x2E0
bic r1, r1, #(0xf<<8)
orr r1, r1, #(0x3<<8)
str r1, [r0, #MP01CON_OFFSET] @0x2E0
将Port Group MP0_1 Control Register 的4-5位全部清為0
/*MP01PUD_OFFSET 0x2E8*/
ldr r1, [r0, #MP01PUD_OFFSET]
bic r1, r1, #(0x3<<4)
str r1, [r0, #MP01PUD_OFFSET]
我們的nCE片選信号是低電平有效,在電路圖中,像我們的三星的原理圖中,nXX表示低電平有效,而在TI的晶片手冊中,XXn表示低電平有效,比如,上面的晶片手冊中nCE表示低電平有效,而在TI的晶片手冊中,則是CEn,表示的也是低電平片選信号有效,反正看到帶n的引腳,即表示低電平有效。
2.2配置CLE/ALE/nWE/nRE/R/nB引腳
除開nCE引腳,其餘的幾個引腳都是複用的MP03,OK,一起配置,查找MP03,P189,Port Group MP0_3 Control Register,配置如下:
Port Group MP0_3 Control Register (MP0_3CON, R/W, Address = 0xE020_0320 )
先将0-23位全部清零,然後全部置為0010,也就是全部置為2
/*MP03CON_OFFSET 0x320*/
ldr r1, [r0, #MP03CON_OFFSET]
bic r1, r1, #0xFFFFFF
ldr r2, =0x22222222
orr r1, r1, r2
str r1, [r0, #MP03CON_OFFSET]
将Port Group MP0_3 Control Register的0-23位全部清為0
Port Group MP0_3 Control Register (MP0_3PUD, R/W, Address = 0xE020_0328)
/*MP03PUD_OFFSET 0x328*/
ldr r1, [r0, #MP03PUD_OFFSET]
ldr r2, =0x3fff
bic r1, r1, r2
str r1, [r0, #MP03PUD_OFFSET]
2.3 配置Nandf Flash控制器的寄存器NFCONF
Nand Flash Configuration Register (NFCONF, R/W, Address = 0xB0E0_0000)
先看前四位[3:0]
[0]位保留,置為0。
[1]用來配置頁的一個位址周期,這款K9F2G08UOB的page是2K,那麼位址周期是多少,再去看K9F2G08UOB的晶片手冊,看到第P6頁
顯示位址周期為5th,是以 [1]配為1 。
先看[3],這裡是配置是SLC還是MCL,根據晶片名稱,這款K9F2G08UOB是SLC存儲,是以 [3]配為0 ;
再來看[2],K9F2G08UOB是SLC,PageSize是2K,是以 [2]配為0
整理,前四位配置為-- 0010 。OK,繼續配置。
這裡多出了兩個不認識的東西TWRPH1和TWRPH0。檢視一下晶片手冊上的NAND FLASH MEMORY TIMING, P693-P694
TACLS:當将CLE和ALE拉高以後,再過多少時間才能發出寫使能信号(nWE)
TWRPH0:nWE使能持續時間,信号被拉低的時間
TWRPH1:當将CLE和ALE拉高以後,WE使能,這時,後面開始發資料,這就是資料起作用的時間(Data hold time)
TACLS是發給NAND FLASH的,是以去檢視K9F2G08UOB的晶片手冊,打開P17頁,并沒有顯示出來CLE拉高後,經過多少時間nWE,将WE的信号拉低,根據下面的時序圖,顯示:
打開K9F2G08UOB的晶片手冊,在P10頁查找到各個pin腳在各個狀态下的最小時間
OK,至此,三個最小時間查出來了,序列槽通訊中最麻煩的就是時序,OK,整理資料
TACLS = tCLS-tWP = 12 -12 =0
TWRPH0 = tWP = 12
TWRPH1 = tDH = 5
OK,現在再傳回去看NFCONF寄存器裡這幾個bit的一個計算公式:
這裡S5PV210的NandFlash的HCLK頻率為133MHz(P363頁),NFCON屬于HCLKD0 = 133MHz,T = 1/133 = 7.5ns
TACLS:配置0,算出時間為7.5*( 0 +1)= 7.5ns >0ns
TWRPH0:配置1,算出時間為7.5*( 1 +1)= 15ns >12ns
TWRPH1:配置0,算出時間為7.5*( 0 +1)= 7.5ns >5ns
通過實際的測試,如果配置成最小值,Nand Flash會出現無法讀寫的情況,這裡我們還是參考提供的Nand Flash的裸機的參考代碼,将這三位配成1--4--1
TACLS:配置0,算出時間為7.5*( 1 +1)= 15ns >0ns
TWRPH0:配置1,算出時間為7.5*( 4 +1)= 15ns >37.5ns
TWRPH1:配置0,算出時間為7.5*( 1 +1)= 15ns >5ns
OK,符合我們的最小時序的要求,是以[7:4] 1,[11:8] 4,[12:15] 1。
/*ELFIN_NAND_BASE 0xB0E00000*/
ldr r0, =ELFIN_NAND_BASE
ldr r1, [r0, #NFCONF_OFFSET]
ldr r2, =0x777F
bic r1, r1, r2
/* NFCONF_VAL (1<<12)|(4<<8)|(1<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0) */
ldr r2, =NFCONF_VAL
orr r1, r1, r2
str r1, [r0, #NFCONF_OFFSET]
ECC我們先不開,其餘的全部配置為0,OK,到此,全部位配置完成。
2.4配置CONTROL REGISTER
(NFCONT, R/W, ADDRESS = 0XE720_0004)
第[0]位,讓NAND Flash控制器Enable,這裡設定為1。使能意思就是生效的意思。 剩下的幾位,我沒有設定,Nand Flash也沒有出現問題,不過,為了謹慎期間,還是用三星的參考代碼,全部設定上。OK,代碼整理一下
ldr r1, [r0, #NFCONT_OFFSET]
ldr r2, =0x707C7
bic r1, r1, r2
/*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)*/
ldr r2, =NFCONT_VAL
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET]
OK,至此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)
orr r1, r1, #(0x3<<8)
str r1, [r0, #MP01CON_OFFSET]
/*MP01PUD_OFFSET 0x2E8*/
ldr r1, [r0, #MP01PUD_OFFSET]
bic r1, r1, #(0x3<<4)
str r1, [r0, #MP01PUD_OFFSET]
/*MP03CON_OFFSET 0x320*/
ldr r1, [r0, #MP03CON_OFFSET]
bic r1, r1, #0xFFFFFF
ldr r2, =0x22222222
orr r1, r1, r2
str r1, [r0, #MP03CON_OFFSET]
/*MP03PUD_OFFSET 0x328*/
ldr r1, [r0, #MP03PUD_OFFSET]
ldr r2, =0x3fff
bic r1, r1, r2
str r1, [r0, #MP03PUD_OFFSET]
/*ELFIN_NAND_BASE 0xB0E00000*/
ldr r0, =ELFIN_NAND_BASE
ldr r1, [r0, #NFCONF_OFFSET]
ldr r2, =0x777F
bic r1, r1, r2
/* NFCONF_VAL (0<<12)|(1<<8)|(0<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0) */
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
/*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)*/
ldr r2, =NFCONT_VAL
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET]
mov pc, lr
OK,下一步,開始去分析Nand Flash的代碼搬移那一塊的代碼,看Nand Flash是如何工作的。