頁編程(寫操作) Nand flash的寫操作叫做編程Program,編程,一般情況下,是以頁為單位的。 有的Nand Flash,比如AFND1G08U3,支持部分頁編程,但是有一些限制:在同一個頁內的,連續的部分頁的編程,不能超過4次。一般情況下,很少使用到部分頁編程,都是以頁為單位進行編程操作的。 一個操作,用兩個命令去實現,看起來是多余,效率不高,但是實際上,有其特殊考慮, 至少對于塊擦除來說,開始的命令0x60是擦除設置命令(erase setup comman),然后傳入要擦除的塊地址,然后再傳入擦除確認命令(erase confirm command)0xD0,以開始擦除的操作。 這種,分兩步:開始設置,最后確認的命令方式,是為了避免由于外部由于無意的/未預料而產生的噪音,即使被nand flash誤認為是擦除操作,但是沒有之后的確認操作0xD0,nand flash就不會去擦除數據,這樣使得數據更安全,不會由于噪音而誤操作。 讀(read)操作過程詳解 以最簡單的read操作為例,解釋如何理解時序圖,以及將時序圖中的要求,轉化為代碼。 解釋時序圖之前,讓我們先要搞清楚,我們要做的事情:那就是,要從nand flash的某個頁里面,讀取我們要的數據。 要實現此功能,會涉及到幾部分的知識,至少很容易想到的就是:需要用到哪些命令,怎么發這些命令,怎么計算所需要的地址,怎么讀取我們要的數據等等。 下面,就一步步的解釋,需要做什么,以及如何去做: 1.需要使用何種命令 首先,是要了解,對于讀取數據,要用什么命令。 下面是datasheet中的命令集合:
頁面編程1.png (150.85 KB, 下載次數: 82)
下載附件
2018-7-17 15:49 上傳
圖5.Nand Flash AFND1G08U3的命令集合 很容易看出,我們要讀取數據,要用到Read命令,該命令需要2個周期,第一個周期發0x00,第二個周期發0x30。 2.發送命令前的準備工作以及時序圖各個信號的具體含義 知道了用何命令后,再去了解如何發送這些命令。
頁面編程2.png (145.45 KB, 下載次數: 86)
下載附件
2018-7-17 15:49 上傳
圖6.Nand Flash數據讀取操作的時序圖 注:此圖來自ATO的型號AFND1G08U3的nand flash的數據手冊(datasheet)。 我們來一起看看,我在圖6中的特意標注的①邊上的黃色豎線。 黃色豎線所處的時刻,是在發送讀操作的第一個周期的命令0x00之前的那一刻。 讓我們看看,在那一刻,其所穿過好幾行都對應什么值,以及進一步理解,為何要那個值。 (1)黃色豎線穿過的第一行,是CLE。還記得前面介紹命令所存使能(CLE)那個引腳吧?CLE,將CLE置1,就說明你將要通過I/O復用端口發送進入Nand Flash的,是命令,而不是地址或者其他類型的數據。只有這樣將CLE置1,使其有效,才能去通知了內部硬件邏輯,你接下來將收到的是命令,內部硬件邏輯,才會將受到的命令,放到命令寄存器中,才能實現后面正確的操作,否則,不去將CLE置1使其有效,硬件會無所適從,不知道你傳入的到底是數據還是命令了。 (2)而第二行,是CE#,那一刻的值是0。這個道理很簡單,你既然要向Nand Flash發命令,那么先要選中它,所以,要保證CE#為低電平,使其有效,也就是片選有效。 (3)第三行是WE#,意思是寫使能。因為接下來是往nand Flash里面寫命令,所以,要使得WE#有效,所以設為低電平。 (4)第四行,是ALE是低電平,而ALE是高電平有效,此時意思就是使其無效。而對應地,前面介紹的,使CLE有效,因為將要數據的是命令,而不是地址。如果在其他某些場合,比如接下來的要輸入地址的時候,就要使其有效,而使CLE無效了。 (5)第五行,RE#,此時是高電平,無效。可以看到,知道后面低6階段,才變成低電平,才有效,因為那時候,要發生讀取命令,去讀取數據。 (6)第六行,就是我們重點要介紹的,復用的輸入輸出I/O端口了,此刻,還沒有輸入數據,接下來,在不同的階段,會輸入或輸出不同的數據/地址。 (7)第七行,R/B#,高電平,表示R(Ready)/就緒,因為到了后面的第5階段,硬件內部,在第四階段,接受了外界的讀取命令后,把該頁的數據一點點送到頁寄存器中,這段時間,屬于系統在忙著干活,屬于忙的階段,所以,R/B#才變成低,表示Busy忙的狀態的。 介紹了時刻①的各個信號的值,以及為何是這個值之后,相信,后面的各個時刻,對應的不同信號的各個值,大家就會自己慢慢分析了,也就容易理解具體的操作順序和原理了。 3.如何計算出,我們要傳入的地址 在介紹具體讀取數據的詳細流程之前,還要做一件事,那就是,先要搞懂我們要訪問的地址,以及這些地址,如何分解后,一點點傳入進去,使得硬件能識別才行。 此處還是以AFND1G08U3為例,此nand flash,一共有1024個塊,每個塊內有64頁,每個頁是2K+64 Bytes,假設,我們要訪問其中的第1000個塊中的第25頁中的1208字節處的地址,此時,我們就要先把具體的地址算出來: 物理地址=塊大小×塊號+頁大小×頁號+頁內地址=1000×(64×(2K+64))+25×(2K+64)+1208=0x80F52F8,接下來,我們就看看,怎么才能把這個實際的物理地址,轉化為nand Flash所要求的格式。 在解釋地址組成之前,先要來看看其datasheet中關于地址周期的介紹:
頁面編程3.png (43.09 KB, 下載次數: 93)
下載附件
2018-7-17 15:49 上傳
圖7 Nand Flash的地址周期組成 結合圖7和圖5中的2,3階段,我們可以看出,此nand flash地址周期共有5個,2個列(Column)周期,2個行(Row)周期。 而對于對應地,我們可以看出,實際上, 列地址A0~A10,就是頁內地址,地址范圍是從0到2047,而多出的A11,理論上可以表示2048~4095,但是實際上,我們最多也只用到了2048~2112,用于表示頁內的oob區域,其大小是64字節。 A12~A27,稱作頁號,頁的號碼,可以定位到具體是哪一個頁。 而其中,A18~A27,表示對應的塊號,即屬于哪個塊。 // 可見:地址的傳輸順序是是 頁內地址,頁號,塊號。 從小到大。 簡單解釋完了地址組成,那么就很容易分析上面例子中的地址了: 0x80F52F8 = 1000 0000 1111 0101 0010 1111 1000,分別分配到4個地址周期就是: 1st 周期,A7~A0 :1111 1000 = 0xF8 2nd周期,A11~A8 :0000 0010 = 0x02 3rd周期,A19~A12 :1111 0101 = 0xF5 4th周期,A27~A20 :1000 0000 = 0x80 注意,與圖7中對應的,*L,意思是低電平,由于未用到那些位,datasheet中強制要求設為0,所以,才有上面的2nd周期中的高4位是0000。 因此,接下來要介紹的,我們要訪問第1000個塊中的第25頁中的1208字節處的話,所要傳入的地址就是分4個周期,分別傳入兩個列地址的:0xF8,0x02,然后再傳2個行地址的:0xF5,0x80,這樣硬件才能識別。 4.讀操作過程的解釋 準備工作終于完了,下面就可以開始解釋說明,對于讀操作的,上面圖中標出來的,1-6個階段,具體是什么含義。 (1) 操作準備階段:此處是讀(Read)操作,所以,先發一個圖5中讀命令的第一個階段的0x00,表示,讓硬件先準備一下,接下來的操作是讀。 (2) 發送兩個周期的列地址。也就是頁內地址,表示,我要從一個頁的什么位置開始讀取數據。 (3) 接下來再傳入兩個行地址。對應的也就是頁號。 (4) 然后再發一個讀操作的第二個周期的命令0x30。接下來,就是硬件內部自己的事情了。 (5) Nand Flash內部硬件邏輯,負責去按照你的要求,根據傳入的地址,找到哪個塊中的哪個頁,然后把整個這一頁的數據,都一點點搬運到頁緩存中去。而在此期間,你所能做的事,也就只需要去讀取狀態寄存器,看看對應的位的值,也就是R/B#那一位,是1還是0,0的話就表示,系統是busy,仍在”忙“(著讀取數據),如果是1,就說系統活干完了,忙清了,已經把整個頁的數據都搬運到頁緩存里去了,你可以接下來讀取你要的數據了。 對于這里。估計有人會問了,這一個頁一共2048+64字節,如果我傳入的頁內地址,就像上面給的1028一類的值,只是想讀取1028到2011這部分數據,而不是頁開始的0地址整個頁的數據,那么內部硬件卻讀取整個頁的數據出來,豈不是很浪費嗎?答案是,的確很浪費,效率看起來不高,但是實際就是這么做的,而且本身讀取整個頁的數據,相對時間并不長,而且讀出來之后,內部數據指針會定位到你剛才所制定的1208的那個位置。 (6) 接下來,就是你“竊取“系統忙了半天之后的勞動成果的時候了,呵呵。通過先去Nand Flash的控制器中的數據寄存器中寫入你要讀取多少個字節(byte)/字(word),然后就可以去Nand Flash的控制器的FIFO中,一點點讀取你要的數據了。 至此,整個Nand Flash的讀操作就完成了。 對于其他操作,可以根據我上面的分析,一點點自己去看datasheet,根據里面的時序圖去分析具體的操作過程,然后對照代碼,會更加清楚具體是如何實現的。 |