天天看點

糾正幾個NANDFLASH很容易犯的錯誤

今天在看别人如何根據實體位址計算NANDFLASH的列位址(column addres)和頁位址(page address),結果看到這篇文章時,感覺有點不對勁。http://blog.csdn.net/feihuxiaozi/article/details/6943124。我在u-boot下根據代碼計算,不管怎麼計算都和他的例子對不上:

0xBB8CCB8 = 00001011  1011 1000  1100 1100  1011 1000,分别配置設定到5個位址周期就是:

                B      B     8    C   C    B     8    

第一個周期:A[0:7]  也就是B8

第二個周期:A[8:11]  取四位 1100, 再添4位0,也就是0000 1100   即0C

第三個周期:A[12:19]  取八位 1000 1100  即8C

第四個周期:A[20:27]  取八位 1011 1011  即BB

第五個周期:A[28]     取一位 0,補齊八位 即 0000 0000 也就是00

看一下K9F2G08X0A的尋址圖:

糾正幾個NANDFLASH很容易犯的錯誤

Column address=addr%2048

ROW Address     =addr/2048

在此處,A0-A11代表Column address,A12-A28代表ROW Address,此處的A11還是column address,不需要我們确定,是以對于輸入的addr=0xBB8CCB8,其中每周期的資料輸入如下:

第一個周期:A[0:7]  也就是B8

第二個周期:A[8:11]  取addr[8:10]=100, 再添5位0,也就是0000 0100   即04

第三個周期:A[12:19]  取addr[11:18]=000 11001  即19

第四個周期:A[20:27]  取addr[11:18]=0111 0111  即77

第五個周期:A[28]     取一位addr[19] =1,補齊八位 即 0000 0001 也就是01

同時我研究了下page =(512+16)byte的NANDFLASH,發現它與(2K+64)位元組的NANDFLASH的又不同,這裡借用這位部落客的部落格說明下:http://www.cnblogs.com/hnrainll/archive/2011/06/01/2065508.html

關于NANDFLASH位址 A8尋址

在NAND Flash中有8個I/O引腳(IO0—IO7)、5個全能信号(nWE ALE CLE nCE nRE)、一個引腳,1個寫保護引腳。操作NAND Flash時,先傳輸指令,然後傳輸位址,最後讀寫資料。對于64MB的NAND Flash,需要一個26位的位址。隻能8個I/O引腳充當位址、資料、指令的複用端口,是以每次傳位址隻能傳8位。這樣就需要4個位址序列。是以讀寫一次nand flash需要傳送4次(A[7:0] A[16:9] A[24:17] A[25])。64M的NAND Flash的位址範圍為0x00000000—0x03FFFFFF。128M的NAND Flash的位址範圍為0x00000000---0x07FFFFFF。1KB = 0x000-0x3FF.128位元組=0x00H--7FH。

    一頁有528個位元組,而在前512B中存放着使用者的資料。在後面的16位元組中(OOB)中存放着執行指令後的狀态資訊。主要是ECC校驗的辨別。列位址A0-A7可以尋址的範圍是256個位元組,要尋址528位元組的話,将一頁分為了A.(1 half array)B(2 half array) C(spare array)。A區0—255位元組,B區 256-511 位元組C區512—527位元組。通路某頁時必須標明特定的區。這可以使位址指針指向特定的區實作。

在NAND Flash 中存在三類位址,分别為Block Address 、Column Address Page Address.。(實際就是塊位址和頁位址)

    Column Address 用來選擇是在上半頁尋址還是在下半頁尋址A[0]—A[7].也就相當于頁内的偏移位址。在進行擦除時不需要列位址,因為擦除是以塊為機關擦除。32個Page需要5bit來表示。也就是A[13:9];也就是頁在塊内的相對位址。A8這一位用來設定512位元組的上半頁,還是下半頁,1表示是在上半頁,而2表示是在下半頁。Block的位址有A[25:14]組成.

    一個容量為64M(512Mbit)的NAND Flash,分為131072頁,528列。(實際中由于存在spare area,故都大于這個值),有4096塊,需要12bit來表示即A[25:14].如果是128M(1Gbit)的話,blodk Address為A[26:14].由于位址隻能在IO0—IO7上傳送。程式設計時通常通過移位來實作位址的傳送。傳送過程如下:

第1個位址序列:傳遞column address,也就是NAND Flash[7:0],這一周期不需要移位即可傳遞到I/O[7:0]上,而half page pointer 即A8是由操作指令決定,00h,在A區,01h在B區,指令決定在哪個half page上進行讀寫,而真正A8的值是不需要程式員關心的;

第2個位址序列:就是将NAND_ADDR 右移9位,而不是8位,将NAND_ADDR[16:9]傳遞到I/O[7:0]上;

第3個位址序列:将NAND_ADDR[24:17] 傳遞到I/O[7:0]上;

第4個位址序列:将NAND_ADDR[25]傳送到I/O上。

    整個位址的傳送過程需要4步才能完成。如果NAND Flash 的大小是32MB的以下的話,那麼block address 最高位隻到bit24,是以尋址隻需要3步,就可以完成。

在進行擦除操作時由于是以塊進行擦除,是以隻需要3個位址序列,也就是隻傳遞塊的位址,即A[14:25]。

NAND Flash位址的計算:

Column Address 翻譯過來是列位址,也就是在一頁裡的偏移位址。其實是指定Page上的某個Byte,指定這個Byte,其實也就是指定此頁的讀寫起始位址。

      Page Address:頁位址。頁的位址總是以512Bytes對齊的,是以它的低9位問題0,确定讀寫操作在NAND Flash中的哪個頁進行。

    當我們得到一個Nand Flash位址addr時,我們可以這樣分解出Column Address和Page Address。

Columnaddr = addr % 512   // column address

Pageaddr = addr>>9           // page address

實際上A0~A7是頁内位址,比如從第2個開始讀起。不過一般都從0開始讀起,呵呵。

也就是一個Nand Flash位址的A0-A7是它的column address ,A9—A25是它的Page Address,位址A8被忽略。

現在假設我要從Nand Flash中的第5000位元組處開始讀取1024個位元組到記憶體的0x30000000處,我們這樣調用read函數

NF_Read(5000, 0x30000000,1024);

我們來分析5000這個src_addr.

根據:

column_addr=src_addr%512;

page_address=(src_addr>>9);

我們可得出column_addr=5000%512=392

page_address=(5000>>9)=9

于是我們可以知道5000這個位址是在第9頁的第392個位元組處,于是我們的NF_read函數将這樣發送指令和參數

column_addr=5000%512;

page_address=(5000>>9);

NF_CMD=0x01; //要從2nd half開始讀取 是以要發送指令0x01

NF_ADDR= column_addr &0xff; //1st Cycle A[7:0]

NF_ADDR=page_address& 0xff

NF_ADDR=(page_address>>8)&0xff; //3rd.Cycle A[24:17]

NF_ADDR=(page_address>>16)&0xff; //4th.Cycle A[25]

    向NandFlash的指令寄存器和位址寄存器發送完以上指令和參數之後,我們就可以從rNFDATA寄存器(NandFlash資料寄存器)讀取資料了.

我用下面的代碼進行資料的讀取.

for(i=column_addr;i<512;i++)

*buf++=NF_RDDATA();

每當讀取完一個Page之後,資料指針會落在下一個Page的0号Column(0号Byte).

//========================下面是另外一篇,差不多=====================

http://blog.csdn.net/intint/archive/2009/10/13/4664659.aspx

一、NAND flash的實體組成

NAND Flash 的資料是以bit的方式儲存在memory cell,一般來說,一個cell 中隻能存儲一個bit。這些cell 以8個或者16個為機關,連成bit line,形成所謂的byte(x8)/word(x16),這就是NAND Device的位寬。這些Line會再組成Page,(NAND Flash 有多種結構,我使用的NAND Flash 是K9F1208,下面内容針對三星的K9F1208U0M),每頁528Bytes(512byte(Main Area)+16byte(Spare Area)),每32個page形成一個Block(32*528B)。具體一片flash上有多少個Block視需要所定。我所使用的三星k9f1208U0M具有4096個block,故總容量為4096*(32*528B)=66MB,但是其中的2MB是用來儲存ECC校驗碼等額外資料的,故實際中可使用的為64MB。

NAND flash以頁為機關讀寫資料,而以塊為機關擦除資料。按照這樣的組織方式可以形成所謂的三類位址:

Column Address:Starting Address of the Register. 翻成中文為列位址,位址的低8位

Page Address :頁位址

Block Address :塊位址

對于NAND Flash來講,位址和指令隻能在I/O[7:0]上傳遞,資料寬度是8位。

二、NAND Flash位址的表示

512byte需要9bit來表示,對于528byte系列的NAND,這512byte被分成1st half Page Register和2nd half Page Register,各自的通路由位址指針指令來選擇,A[7:0]就是所謂的column address(列位址),在進行擦除操作時不需要它,why?因為以塊為機關擦除。32個page需要5bit來表示,占用A[13:9],即該page在塊内的相對位址。A8這一位位址被用來設定512byte的1st half page還是2nd half page,0表示1st,1表示2nd。Block的位址是由A14以上的bit來表示。

例如64MB(512Mb)的NAND flash(實際中由于存在spare area,故都大于這個值),共4096block,是以,需要12個bit來表示,即A[25:14],如果是128MB(1Gbit) 的528byte/page的NAND Flash,則block address用A[26:14]表示。而page address就是blcok address|page address in block NAND Flash 的位址表示為: Block Address|Page Address in block|halfpage pointer|Column Address 位址傳送順序是Column Address,Page Address,Block Address。

由于位址隻能在I/O[7:0]上傳遞,是以,必須采用移位的方式進行。 例如,對于512Mbit x8的NAND flash,位址範圍是0~0x3FF_FFFF,隻要是這個範圍内的數值表示的位址都是有效的。 以NAND_ADDR 為例:

第1 步是傳遞column address,就是NAND_ADDR[7:0],不需移位即可傳遞到I/O[7:0]上,而halfpage pointer即A8 是由操作指令決定的,即指令決定在哪個halfpage 上進行讀

寫,而真正的A8 的值是不需程式員關心的。

第2 步就是将NAND_ADDR 右移9位,将NAND_ADDR[16:9]傳到I/O[7:0]上;

第3 步将NAND_ADDR[24:17]放到I/O上;

第4步需要将NAND_ADDR[25]放到I/O上;

是以,整個位址傳遞過程需要4 步才能完成,即4-step addressing。 如果NAND Flash 的容量是32MB(256Mbit)以下,那麼,block adress最高位隻到bit24,是以尋址隻需要3步。

下面,就x16 的NAND flash 器件稍微進行一下說明。 由于一個page 的main area 的容量為256word,仍相當于512byte。但是,這個時候沒有所謂的1st halfpage 和2nd halfpage 之分了,是以,bit8就變得沒有意義了,也就是這個時候 A8 完全不用管,位址傳遞仍然和x8 器件相同。除了,這一點之外,x16 的NAND使用方法和 x8 的使用方法完全相同。

繼續閱讀