硬件原理
1.1.NorFlash簡介
NORFlash是Intel在1988年推出的一款商業(yè)性閃存芯片,它需要很長的時間進行抹寫,大半生它能夠提供完整的尋址與數(shù)據(jù)總線,并允許隨機存取存儲器上的任何區(qū)域,而且它可以忍受一萬次到一百萬次擦寫,是早期的閃存媒體的基礎。
1.2.處理器連接
從處理器的角度來看,每個地址對應的是一個BYTE的數(shù)據(jù)單元。而NorFlash的每個地址有可能對應的是一個BYTE的數(shù)據(jù)單元,也有可能對應的是一個HALF-WORD的數(shù)據(jù)單元。所以在硬件設計中,連接ARM處理器和NorFlash時,必須根據(jù)實際情況對地址信號做特別的處理。如果ARM處理器外部擴展的是8-BIT的NORFlash,數(shù)據(jù)線和地址線的連接應該如圖1所示。從圖中我們可以看到,處理器的數(shù)據(jù)信號D0-D7和Flash的數(shù)據(jù)信號D0-D7是一一對應連接的,處理器的地址信號A0-An和NORFlash的地址信號A0-An也是一一對應連接的。
如果ARM處理器外部擴展的是16-BIT的NorFlash,數(shù)據(jù)線必須要錯位連接。圖2給了一個ARM處理器和16-BITNORFlash的連接示意圖。如圖2所示,ARM處理器的數(shù)據(jù)信號D0-D15和Flash的數(shù)據(jù)信號D0-D15是一一對應的。而ARM處理器的地址信號和NorFlash的地址信號是錯位連接的,ARM的A0懸空,ARM的A1連接Flash的A0,ARM的A2連接Flash的A1,依次類推。需要錯位連接的原因是:ARM處理器的每個地址對應的是一個BYTE的數(shù)據(jù)單元,而16-BIT的Flash的每個地址對應的是一個HALF-WORD(16-BIT)的數(shù)據(jù)單元。為了保持匹配,所以必須錯位連接。這樣,從ARM處理器發(fā)送出來的地址信號的最低位A0對16-BITFlash來說就被屏蔽掉了。
補充說明:
1、一般來說,ARM處理器內部要設置相應的寄存器,告訴處理器外部擴展的Flash的位寬(8-BIT/16-BIT/32-BIT)。這樣,處理器才知道在訪問的時候如何從Flash正確的讀取數(shù)據(jù)。
2、有些ARM處理器內部可以設置地址的錯位。對于支持軟件選擇地址錯位的處理器,在連接16-BITFlash的時候,硬件上可以不需要把地址線錯位。
3、如果處理器支持內部設置地址錯位,在實際訪問的時候,送出的地址實際上是在MCU內部做了錯位處理,其作用是等效于硬件連接上的錯位的。
2.芯片手冊
2.1.特性
容量2MB
扇區(qū)分布
一個16K,兩個8K,一個32K,31個64K(BoottomBootDevice
2.2.引腳描述
2.3.邏輯圖
2.4.設備總線操作
字節(jié)還是半字選擇,BYET#引腳高,半字;低,字節(jié)。
開機或復位自動進入讀狀態(tài)。
寫命令序列,繞過解鎖模式UnlockBypass只需要2個周期,而不是4個周期
編程和擦除需要輪詢狀態(tài)位。
自動選擇模式:讀ID,扇區(qū)組保護,硅扇區(qū)。兩種方法進入自動選擇模式,編程器電壓方式,寫命令方式。
2.5.CFI
2.6.指令集
見數(shù)據(jù)手冊
2.7.讀
NorFlash上電后處于數(shù)據(jù)讀取狀態(tài)(ReadingArrayData)。此狀態(tài)可以進行正常的讀,這和讀取SDRAM/SRAM/ROM一樣。(要是不一樣的話,芯片上電后如何從NorFlash中讀取啟動代碼)。
2.8.讀ID
一般再對Flash進行操作前都要讀取芯片信息比如設備ID號。這樣做的主要目的是為了判斷自己寫的程序是否支持該設備。NorFlash支持2種方式獲取ID號:一種是編程器所用的方法需要高電壓(8.5V-12.5V);另一種方法就是所謂的in-system方法,就是在系統(tǒng)中通過NorFlash的命令寄存器來完成。本文中只對in-system方法進行說明,此時需要切換到自動選擇(AutoselectCommand),這要通過發(fā)送命令來完成。注意:進入自動選擇(AutoselectCommand)模式后需要發(fā)送復位命令才能回到數(shù)據(jù)讀取狀態(tài)(ReadingArrayData)。
2.9.擦除
在完成信息獲取后一般就要擦除數(shù)據(jù)。NorFlash支持扇區(qū)擦除(SectorErase)和整片擦除(ChipErase),這2種模式都有對應的命令序列,在完成擦除命令后會自動返回到數(shù)據(jù)讀取(ReadingArrayData)狀態(tài),在返回前可查詢編程的狀態(tài)。
2.10.編程
完成擦除后就需要對芯片進行寫入操作也就是編程,這就需要進入編程(Program)狀態(tài)。在完成編程命令后會自動返回到數(shù)據(jù)讀取(ReadingArrayData)狀態(tài),在返回前可查詢編程的狀態(tài),注意:編程前一定要先擦除.因為編程只能將'1'改寫為'0',通過擦寫可以將數(shù)據(jù)全部擦寫為'1'。
2.11.等待操作
NorFlash提供幾個數(shù)據(jù)位來確定一個寫操作的狀態(tài),它們分別是:DQ2、DQ3、DQ5、DQ6、DQ7、andRY/BY#。如上圖所示。其中DQ7,RY/BY#引腳,和DQ6中的每一個都提供了一種方法來判斷一個編程或者擦除操作是否已經完成或正在進行中。實際編程中只需要使用其中的一種。
DQ7:Data#Pollingbit,DQ7在編程時的狀態(tài)變化。在編程過程中從正在編程的地址中讀出的數(shù)據(jù)的DQ7為要寫入數(shù)據(jù)的補碼。比如寫入的數(shù)據(jù)為0x0000,及輸入的DQ7為'0',則在編程中讀出的數(shù)據(jù)為'1';當編程完成時讀出的數(shù)據(jù)又變回輸入的數(shù)據(jù)即'0'。在擦除過程中DQ7輸出為'0';擦除完成后輸出為'1';注意讀取的地址必須是擦除范圍內的地址。
RY/BY#:高電平表示'就緒',低電平表示'忙'。
DQ6:輪轉位1(ToggleBit1)。
在編程和擦除期間,讀任意地址都會導致DQ6的輪轉(0,1間相互變換)當操作完成后,DQ6停止轉換。
DQ2:輪轉位2(ToggleBit2)。當某個扇區(qū)被選中擦除時,讀有效地址(地址都在擦除的扇區(qū)范圍內)會導致DQ2的輪轉。
注意:DQ2只能判斷一個特定的扇區(qū)是否被選中擦除。但不能區(qū)分這個快是否正在擦除中或者正處于擦除暫停狀態(tài)。相比之下,DQ6可以區(qū)分NorFlash是否處于擦除中或者擦除狀態(tài),但不能區(qū)分哪個快被選中擦除。因此需要這2個位來確定扇區(qū)和模式狀態(tài)信息。
DQ5:超時位(ExceededTimingLimits),當編程或擦除操作超過了一個特定內部脈沖計數(shù)是DQ5=1,這表明操作失敗。當編程時把'0'改為'1'就會導致DQ5=1,因為只有擦除擦做才能把'0'改為'1'。當錯誤發(fā)生后需要執(zhí)行復位命令(見圖1-1)才能返回到讀數(shù)據(jù)狀態(tài)。
DQ3:(扇區(qū)擦除計時位)SectorEraseTimer,只在扇區(qū)擦除指令時起作用。當擦除指令真正開始工作是DQ3=1,此時輸入的命令(除擦除暫停命令外)都被忽略。DQ3=0,是可以添加附加的扇區(qū)用于多扇區(qū)擦除。
以上講了這些狀態(tài)為,實際只需要使用幾個就行,比較簡單的就是選擇DQ5,DQ6/DQ2。
3.mini2440電路圖
4.S3C2440寄存器
/*******************************************************************
*Copyright(C),2011-2012,XXX.
*FileName:nand.h
*Author:HuangYinqing
*Version:1.0
*Date::2012-04-22
*Description:norflash驅動.
*FunctionList:
*History:
******************************************************************/
#ifndef__NOR_H__
#define__NOR_H__
/*norflash調試等級*/
#defineDBG_NOR_LEVEL1
#defineNOR_TYPE_S29AL016J0x00012249
/*norflash信息*/
#defineNOR_MAIN_SECT_SIZE(64*1024)//==1頁2k
#defineNOR_SIZE(2*1024*1024)//==容量256M
#defineNOR_FLASH_BASE0x00000000//==nor基地址0
/*命令地址*/
#defineNOR_CMD_ADDR1(*(volatileunsignedshort*)(NOR_FLASH_BASE+(0x00000555<<1)))
#defineNOR_CMD_ADDR2(*(volatileunsignedshort*)(NOR_FLASH_BASE+(0x000002AA<<1)))
/*操作命令*/
#defineNOR_CMD_UNLOCK10x000000AA
#defineNOR_CMD_UNLOCK20x00000055
#defineNOR_CMD_RESET0xF0
#defineNOR_CMD_AUTOSELECT0x90
#defineNOR_CMD_PROGRAM0xA0
#defineNOR_CMD_ERASE_SETUP0x80
#defineNOR_CMD_CHIP_ERASE0x30
#defineNOR_CMD_SECTOR_ERASE0x10
/*函數(shù)*/
void NorTe