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