驅動文件使用的13年的ST的官方SD卡驅動,且經過安富萊硬漢的實驗,最初實現熱插拔,基本沒有問題(沒有做特別大量的測試)。但是同時加上他的代碼后,我的內存卡熱插拔基本無法使用,經排查,發現SD卡在SD_PowerON()階段中的,發送CMD8: SEND_IF_COND后的響應異常,會卡在電壓檢測那里,直到超時,電壓一直為0,然后換了個別的卡,就沒有那種現象。可以基本斷定是卡之間的差異。
后來,又經過屏蔽同事的代碼,查找的只要屏蔽他在100us的定時中斷中,can的發送,現象就沒了。至今沒有查找到為什么。
為了解決這個問題,在SD_PowerON中做了些改動,當CMD8響應不正常的時候,讓他重新嘗試從CMD0到CMD8的命令的發送,嘗試3遍。發現當響應不正常的時候,重新嘗試1遍,就可解決這種現象。
這個圖是那個Banq的出問題體的SD卡
這個是閃迪的SD卡。
出問題的那個卡,retyn=1,說明重試了一次,閃迪的不用重試。
下面簡單復制下SD的上電識別過程的一些基本知識。
STM32 控制器目前最高支持《Physical Layer SimplifiedSpecification V2.0》定義的 SD卡,STM32控制器對 SD卡進行數據讀寫之前需要識別卡的種類:V1.0標准卡、V2.0標准卡、V2.0 高容量卡或者不被識別卡。
SD 卡系統(包括主機和 SD卡)定義了兩種操作模式:卡識別模式和數據傳輸模式。在系統復位后,主機處於卡識別模式,尋找總線上可用的 SDIO 設備;同時,SD卡也處於卡識別模式,直到被主機識別到,即當 SD卡接收到 SEND_RCA(CMD3)命令后,SD卡就會進入數據傳輸模式,而主機在總線上所有卡被識別后也進入數據傳輸模式。在每個操作模式下,SD卡都有幾種狀態,參考表 37-4,通過命令控制實現卡狀態的切換。
1 卡識別模式
在卡識別模式下,主機會復位所有處於“卡識別模式”的 SD卡,確認其工作電壓范圍,識別 SD卡類型,並且獲取 SD卡的相對地址(卡相對地址較短,便於尋址)。在卡識別過程中,要求 SD卡工作在識別時鍾頻率 FOD 的狀態下。卡識別模式下 SD卡狀態轉換如
主機上電后,所有卡處於空閑狀態,包括當前處於無效狀態的卡。主機也可以發送GO_IDLE_STATE(CMD0)讓所有卡軟復位從而進入空閑狀態,但當前處於無效狀態的卡並不會復位。
主機在開始與卡通信前,需要先確定雙方在互相支持的電壓范圍內。SD卡有一個電壓支持范圍,主機當前電壓必須在該范圍可能才能與卡正常通信。SEND_IF_COND(CMD8)命令就是用於驗證卡接口操作條件的(主要是電壓支持)。卡會根據命令的參數來檢測操作條件匹配性,如果卡支持主機電壓就產生響應,否則不響應。而主機則根據響應內容確定卡的電壓匹配性。CMD8是 SD卡標准 V2.0 版本才有的新命令,所以如果主機有接收到響應,可以判斷卡為 V2.0 或更高版本 SD卡(上邊提的到問題,就出在此處,沒有響應)。
SD_SEND_OP_COND(ACMD41)命令可以識別或拒絕不匹配它的電壓范圍的卡。ACMD41命令的 VDD 電壓參數用於設置主機支持電壓范圍,卡響應會返回卡支持的電壓范圍。對於對 CMD8有響應的卡,把 ACMD41 命令的 HCS 位設置為 1,可以測試卡的容量類型,如果卡響應的 CCS 位為 1 說明為高容量 SD 卡,否則為標准卡。卡在響應ACMD41之后進入准備狀態,不響應 ACMD41 的卡為不可用卡,進入無效狀態。ACMD41是應用特定命令,發送該命令之前必須先發 CMD55。
ALL_SEND_CID(CMD2)用來控制所有卡返回它們的卡識別號(CID),處於准備狀態的卡在發送 CID 之后就進入識別狀態。之后主機就發送 SEND_RELATIVE_ADDR(CMD3)命令,讓卡自己推薦一個相對地址(RCA)並響應命令。這個 RCA是 16bit地址,而 CID 是128bit地址,使用 RCA 簡化通信。卡在接收到 CMD3 並發出響應后就進入數據傳輸模式,並處於待機狀態,主機在獲取所有卡 RCA之后也進入數據傳輸模式。