上篇博文我們按照210的啟動流程,分析到了初始化串口,由於接下來的取消存儲保護不是很重要,所以我們今天按照u-boot的啟動流程對nand flash初始化進行分析。
今天我們會用到的文檔:
1. 2440芯片手冊:http://download.csdn.net/detail/wrjvszq/8358949
2. 6410芯片手冊:http://download.csdn.net/detail/wrjvszq/8358965
3. 210芯片手冊:S5PV210_UM_REV1.1(我的不知道為什么傳不上去大家去百度搜吧)
4. Nand flash芯片手冊:大家根據自己的nand flash芯片型號,找到對應的手冊
我們今天會通過以下幾點,對nand flash的初始化進行介紹:
1. Nand flash簡介
2. Nand flash初始化
3. Nand flash讀寫操作
1. 分類
Nand flash閃存芯片又分為
1) SLC(單層單元,每個存儲格上存一個)
2) MLC(多層單元,每個存儲格上存兩個)
3) TLC(三層單元,每個存儲格上存三個)
2. 訪問方式
類似與我們單片機里面的外設,其有自己的控制器,可以對數據解析,我們要按照固定的格式和協議進行訪問。
3. 地址構成
在Nand flash芯片手冊中我們很容易找到其構成圖,我們結合下圖對其進行簡單分析
1) device:一個Nand flash可以分為多個block
2) block:一個block可以分為多個pages
3) page:一個page可以分為兩個區,分別為數據區和信息區(包括校驗碼等內容)
其地址構成分為:
行地址:表示要訪問的頁在塊中的頁編號
列地址:表示要訪問的地址在該頁中的偏移
l Nand flash初始化
通過上面的分析我們對nand的基本信息有了了解,下面我們來分析其初始化,同樣我們可以參考u-boot給出的代碼得出其初始化流程:
1) 設置管腳
2) 初始化NFCONF寄存器
3) 初始化NFCONT寄存器
1. 初始化NFCONF寄存器
在初始化NFCONF寄存器的時候我們要特別注意下面幾個值(這三個值是將nand flash和我們芯片自有的nand flash控制器的時序相匹配的重要值):TACLS、TWRPH0、TWRPH1。
我們可以在我們的芯片手冊中找到nand flash控制器所提供的時序圖,其中TACLS、TWRPH0、TWRPH1是我們自己可以配置的。
同時可以在nand flash芯片手冊中找到其所需要的時序圖,如下
簡單通過時序比較我們就可以清楚的知道,TACLS、TWRPH0、TWRPH1分別對應tCLS、twp、tCLH
那么其所需要的這些值的大小到底是多少呢?我們通過nand的芯片手冊就可以找到下表,其中的值是該時序所需的最小值。
通過以上分析,我們再結合在http://www.cnblogs.com/wrjvszq/p/4227435.html一文中設置的系統時鍾,就可以輕松的設置我們的NFCONF寄存器了,NFCONT寄存器設置比較簡單,按照寄存器說明即可,在此也就不過多分析了。
1 /* 2 * Nand Interface Init for SMDKC110 3 */ 4 nand_asm_init: 5 6 /* Setting GPIO for NAND */ 7 /* This setting is NAND initialze code at booting time in iROM. */ 8 9 ldr r0, =ELFIN_GPIO_BASE 10 11 ldr r1, [r0, #MP01CON_OFFSET] 12 bic r1, r1, #(0xf<<8) 13 orr r1, r1, #(0x3<<8) 14 str r1, [r0, #MP01CON_OFFSET] 15 16 ldr r1, [r0, #MP01PUD_OFFSET] 17 bic r1, r1, #(0x3<<4) 18 str r1, [r0, #MP01PUD_OFFSET] 19 20 ldr r1, [r0, #MP03CON_OFFSET] 21 bic r1, r1, #0xFFFFFF 22 ldr r2, =0x22222222 23 orr r1, r1, r2 24 str r1, [r0, #MP03CON_OFFSET] 25 26 ldr r1, [r0, #MP03PUD_OFFSET] 27 ldr r2, =0x3fff 28 bic r1, r1, r2 29 str r1, [r0, #MP03PUD_OFFSET] 30 31 ldr r0, =ELFIN_NAND_BASE 32 33 ldr r1, [r0, #NFCONF_OFFSET] 34 ldr r2, =0x777F 35 bic r1, r1, r2 36 ldr r2, =NFCONF_VAL 37 orr r1, r1, r2 38 str r1, [r0, #NFCONF_OFFSET] 39 40 ldr r1, [r0, #NFCONT_OFFSET] 41 ldr r2, =0x707C7 42 bic r1, r1, r2 43 ldr r2, =NFCONT_VAL 44 orr r1, r1, r2 45 str r1, [r0, #NFCONT_OFFSET] 46 47 ldr r1, [r0, #NFCONF_OFFSET] 48 orr r1, r1, #0x70 49 orr r1, r1, #0x7700 50 str r1, [r0, #NFCONF_OFFSET] 51 52 ldr r1, [r0, #NFCONT_OFFSET] 53 orr r1, r1, #0x03 54 str r1, [r0, #NFCONT_OFFSET] 55 56 mov pc, lr
經過上述內容我們對nand的初始化有了一定的了解,u-boot在此階段做的內容也就完成了,但是為了不在以后返回來分析nand,我們今天趁熱打鐵,將其的讀寫操作一同分析。
l Nand flash讀寫操作
我們的nand flash支持兩種讀操作,一種是頁讀(整頁讀取,只需用行地址),一種是隨機讀(隨機讀取,需要行列地址),今天我們重點分析頁讀,隨機讀取跟其類似。
按照以前自己在做單片機時候的經驗,我們既然要和外設通信,那么就必須按照外設自身所規定的時序發送內容,所以自己在nand芯片手冊中找到了讀操作的時序圖(如下),根據此時序圖我們可以很容易總結出讀操作的流程,有了流程我們的代碼實現起來就比較簡單了。
1. 選中nand芯片
2. 清除rb
3. 發送0x00
4. 發送列地址
5. 發送行地址
6. 發送0x30
7. 等待R/B
8. 讀數據
9. 取消選中
2. 寫操作
我們的nand flash同樣支持兩種寫操作,一種是頁寫(整頁寫入,只需用行地址),一種是隨機寫(隨機寫入,需要行列地址),今天我們重點分析頁寫,隨機寫入跟其類似。
同樣我們可以在nand芯片手冊中找到寫操作的時序圖(如下),根據此時序圖我們可以很容易總結出寫操作的流程,有了流程我們的代碼實現起來就比較簡單了。
1. 選中nand芯片
2. 清除rb
3. 發送0x80命令
4. 發送列地址
5. 發送行地址
6. 寫入數據
7. 發送0x10命令
8. 等待R/B
9. 發送0x70命令
10. 讀取寫入結果
11. 取消選中
經過上述內容我們對nand的讀寫操作進行了簡單的流程分析,對於nand還有其他操作,比如復位,擦除等操作,其實其實現都可以仿照我們實現讀寫的思路,進行實現。