S3C2416裸機開發(fā)系列十六_sd卡驅(qū)動實現(xiàn)
標簽:S3C2416裸機開發(fā)sd卡驅(qū)動sd2.0gcc
2014-05-26 12:562429人閱讀評論(3)收藏舉報
分類:
s3c2416裸機開發(fā)(24)
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。
目錄(?)[+]
S3C2416裸機開發(fā)系列十六sd卡驅(qū)動實現(xiàn)象棋小子 1048272975
SD卡(Secure Digital Memory Card)具有體積小、容量大、數(shù)據(jù)傳輸快、可插拔、安全性好等優(yōu)點,被廣泛應用于便攜式設備上。例如作為數(shù)碼相機的存儲卡,作為手機、平板多媒體擴展卡用的TF卡(micro sd)。筆者此處就s3c2416 sd卡驅(qū)動的實現(xiàn)作一個簡單的介紹。
1. sd卡概述sd卡技術(shù)是在MMC卡的基礎上發(fā)展起來的,其尺寸與MMC卡一樣,只是比MMC卡厚了0.7mm,因此sd設備可以識別并存取MMC卡。sd卡接口除了保留MMC卡的7針外,還在兩邊加了2針,作為數(shù)據(jù)線,目的是通過把傳輸方式由串行變成并行,以提高傳輸速率。此時的規(guī)范為sd1.0版本,最高容量只能到4GB。為了跟進產(chǎn)品的更新?lián)Q代,sd聯(lián)合協(xié)會在06年發(fā)布了容量更大、存儲更快的下一代sd卡規(guī)范sd2.0。該規(guī)范重新定義了sd卡的速度等級,分為三檔:Class 2、4、6,分別對應寫入速度2MB/s、4MB/s、6MB/s。根據(jù)卡容量又分為標準卡(小于2GB)和高容量卡(2GB~32GB),目前市面上應用的sd卡絕大部分都是sd2.0版本的卡。為了讓儲存卡更加迷你,通過sd卡規(guī)范標準,又衍生了MiniSD卡和Micro SD卡,這些卡均比標準sd卡尺寸小,通過sd轉(zhuǎn)接卡可以當作一般的sd卡使用。尤其是Micro SD卡,可以算是最小的存儲卡了,超小的體積可以極大的節(jié)省消費電子產(chǎn)品內(nèi)部設計的空間,基本目前的Android手機均是選用Micro SD卡作為多媒體擴展儲存卡。隨著科技的進步,sd2.0規(guī)范sd卡也漸漸無法滿足應用的需求,在10年sd聯(lián)合協(xié)會又發(fā)布了新的sd3.0規(guī)范,該規(guī)范定義了sdxc和uhs,并增加了Class10,容量范圍為32GB~2TB。在sdxc卡仍需進一步坐等其價格下降的情況下,sd4.0規(guī)范已經(jīng)開始在緊張的制訂中,這已超出本文的討論范圍內(nèi)了。
2. sd卡驅(qū)動編寫sd卡共支持三種傳輸模式:spi模式、1位sd模式、4位sd模式。所有的sd卡都必須支持較老的spi/mmc模式,這個模式支持慢速的四線spi接口,使很多微控制器都可以通過spi或模擬spi接口來讀寫sd卡。由于s3c2416具有sd總線控制器,并且兼容sd2.0的sd卡,因此此處只分析4位sd模式、sd2.0及sd1.0版本的sd卡驅(qū)動實現(xiàn),sd2.0以上版本sd卡、MMC卡、spi方式讀寫sd卡在本文不適用。
sd卡驅(qū)動的編寫必須參考sd2.0規(guī)范,此處只根據(jù)sd2.0規(guī)范講解幾個重要的過程或概念,這些過程具體的實現(xiàn)請參考sd驅(qū)動模塊中相應的函數(shù)實現(xiàn)。
2.1. sd卡初始化及識別過程sd卡上電后,將進入idle狀態(tài),此時的sd卡為1位sd模式。通過拉低CS線將可使sd進入spi模式(不再討論范圍內(nèi)),在sd模式下卡的初始化及識別過程見圖2.1.1,其步驟如下:
1) 發(fā)送CMD0軟件復位所有的卡到idle狀態(tài)。
2) 發(fā)送CMD8來檢查卡是否支持主機電壓(2.7v~3.3v),這個命令在sd2.0以上才被定義,若沒有收到回復信號,則可能為sd1.0或MMC卡,若接收到卡回復信號,說明為sd2.0版本卡,跳轉(zhuǎn)到步驟5
3) CMD8沒有收到回復信號,可進一步發(fā)送ACMD41(CMD55+CMD41),參數(shù)HCS位為0(非高容量卡),如果沒有回復信號,說明是MMC卡或其它不能識別的卡,可進一步發(fā)送CMD1確定是否MMC卡(此處不再分析)
4) ACMD41能收到回復,并且從回復中確定sd卡己準備好,即可確定這是sd1.x版本的卡,若回復中表明sd卡未準備好,則需重復發(fā)送ACMD41等待卡準備好,可通過超時(卡一直busy)判斷卡不支持主機電壓,此時表明卡不可用。判斷出sd1.x的卡后,跳轉(zhuǎn)到步驟9
5) CMD8有回復說明為sd2.0以上的卡,從回復中確定卡是否能在該電壓下工作,不能則認為卡不可用。
6) 回復中確定卡能在2.7v~3.3v電壓工作后,進一步發(fā)送ACMD41(CMD55+CMD41),參數(shù)HCS位為1表明主機支持高容量的卡
7) 檢查ACMD41卡回復中忙標志,若卡處于忙狀態(tài),則重復發(fā)送ACDM41,直到卡準備好,可通過超時(卡一直忙狀態(tài))可認為該卡不可用。
8) ACMD41回復準備好后,再檢查回復中的CCS位,該位為1說明是sd2.0高容量sdhc卡,若為0,則說明為sd2.0標準容量卡。
9) 在識別出sd1.x、sd2.0標準卡或sd2.0高容量卡后,此時卡進入ready態(tài)。進一步通過CMD2請求卡發(fā)送其CID(Card Identification),此時卡進入Identification態(tài)。
10) 卡在Identification態(tài)后,發(fā)送CMD3請求卡發(fā)布一個16位新的相對地址(RCA),以后主機與卡之間的點對點通信均會以這個RCA地址來進行,此時卡進入Stand-by態(tài)。
11) 至此,卡的初始化及識別過程結(jié)束,此時卡進入數(shù)據(jù)傳輸模式(data transfer mode)
圖2.1.1. sd卡初始化及識別流程
2.2. 數(shù)據(jù)傳輸模式sd卡主控制器是一個非常典型的狀態(tài)機,每個狀態(tài)只會響應該個狀態(tài)下的特定命令,不要嘗試在某個狀態(tài)下發(fā)送這個狀態(tài)不支持的命令,sd卡不會對該命令進行響應,命令只會超時。應該通過特定的觸發(fā)條件轉(zhuǎn)變狀態(tài)或等待狀態(tài)遷移完成后,再發(fā)送對應狀態(tài)的命令。如圖2.2.1,要想寫一個塊的數(shù)據(jù)到sd卡,在stand-by態(tài)的情況下,必須通過CMD7選擇卡,讓卡進入transfer態(tài),然后再發(fā)送CMD24單塊寫命令,再發(fā)送一塊的數(shù)據(jù),此時卡進入Programming態(tài),這時如果又緊接發(fā)送CMD24進行單塊寫將不會成功,必須等待sd卡編程完,從Programming態(tài)返回到transfer態(tài)才能再次接收下一個塊寫命令。同樣,在transfer態(tài)想通過CMD9來獲得Card-Specific Data(CSD),必須通過CMD7取消選擇卡,此時卡進入stand-by態(tài)后,即可通過CMD9來獲得卡信息。
圖2.2.1. sd卡數(shù)據(jù)傳輸模式
2.3. 主機控制器具體對卡的初始化任何cpu的sd卡主機控制器都可以根據(jù)sd2.0規(guī)范給出的卡初始化及識別流程進行卡的初始化,對于具體的cpu,需要進行一些與控制器相關的設置,主要有以下幾點,具體的實現(xiàn)可參考Hsmmc_Init()這個初始化函數(shù)。
1) 設置功能引腳,把相應引腳配置成sd接口用引腳
2) 設置sd卡時鐘在100k~400k,sd卡在識別階段必須用慢速時鐘進行訪問
3) 按照規(guī)范給出的卡初始化流程對卡進行發(fā)送相應的命令并處理回復,成功后卡進入stand-by態(tài)
4) 通過發(fā)送CMD7選擇卡,使卡進入transfer態(tài),因為卡的大部分操作如讀、寫、擦除等均是在這個狀態(tài)下來進行的,此時卡已完全準備好接收讀寫命令了。
5) 設置sd卡的時鐘到一個較高值,sd卡默認支持最高25M時鐘,可以設置成高速模式,最高支持50M,頻率越高,數(shù)據(jù)傳輸速率越快
6) 通過ACMD6(CMD55+CMD6)來設置sd模式的位寬為4,sd卡初始化后默認是1線寬,更多的數(shù)據(jù)線將有更大的帶寬,數(shù)據(jù)傳輸速率最高12.5MB/s(25M、4線)或25MB/s(50M、4線)。
7) 發(fā)送CMD16設置塊長度,對于標準卡,可通過CMD16來設置塊命令(如塊讀、塊寫)所操作塊的長度(以字節(jié)數(shù)計),可實現(xiàn)字節(jié)的讀寫,但對于高容量卡這個命令將被忽略,高容量卡一個塊的長度均是固定512字節(jié)的。通常通過CMD16設置塊長度為512字節(jié)。至此卡初始化完成。
2.4. 主機命令的發(fā)送sd規(guī)范對命令包格式、回復包、數(shù)據(jù)的傳輸方式等均作了詳細的要求。雖然sd卡主機控制器可以幫我們對命令進行打包,對回復進行解包,產(chǎn)生CRC,并在sd總線上輸出相應的時序。我們?nèi)孕枰嬖Vsd卡主機控制器需發(fā)送的命令、這個命令的參數(shù)、這個命令發(fā)送后是否需要使用data線, sd卡的回復類型。具體到s3c2416的sd卡主機控制器,這些設置通過CMDREG寄存器來實現(xiàn)。主要有以下幾點,具體的實現(xiàn)可參考Hsmmc_IssueCommand()這個命令發(fā)送函數(shù)。
1) 命令發(fā)送時,需檢查命令線是否已被使用,若是,則等待正在發(fā)送的命令發(fā)送完才能發(fā)送這個命令
2) 如果命令回復會帶忙信號(如R1b回復),則需檢查數(shù)據(jù)線是否已被使用,若是,則等待數(shù)據(jù)線空閑,帶忙回復命令發(fā)送后,sd卡會拉低DAT[0]線表明sd卡正忙,數(shù)據(jù)線不可用。
3) 把命令參數(shù)寫入ARGUMENT這個寄存器中
4) 在CMDREG中設置命令值[13:8]
5) 設置是否需使用data線,如塊讀、塊寫等命令發(fā)送后,會緊接著在data線上傳輸數(shù)據(jù),其它不需傳輸數(shù)據(jù)的命令不要設置使用data線CMDREG[5]
6) 設置sd卡的回復類型,絕大部分命令在sd卡正確響應后,都會對主機進行回復(R1-R7,R1b),每個命令對應的回復類型請參考sd卡規(guī)范?;貜皖愋烷L度可能為136或48,回復中是否包含CRC或命令值的反饋,如果包含,則告訴主控制器檢查回復中相應的CRC或命令值反饋是否正確,以確定傳輸正確。CMDREG設置好后,主控制器就會發(fā)送命令并接收設定長度的回復并根據(jù)設定檢查CRC、命令值反饋是否正確(若回復中包含CRC或命令值反饋的話)
7) 等待命令完成,檢查中斷狀態(tài)位NORINTSTS[15]以確定命令是否有錯誤,若沒有錯誤并且檢測到NORINTSTS[0]命令完成位為1,則說明命令發(fā)送成功。其它情況說明命令未能成功發(fā)送。
2.5. 主機對sd卡的讀寫通常對于一個sd卡驅(qū)動模塊,至少實現(xiàn)卡初始化、塊讀、塊寫這三個接口函數(shù)。塊讀、塊寫必須在卡初始化完成后,在transfer態(tài)下才有效。通常有以下幾點需要注意,具體可參考Hsmmc_ReadBlock()和Hsmm