SDIO(Secure Digital Input and Output)中文名稱:安全數(shù)字輸入輸出,SDIO在SD標(biāo)準(zhǔn)上定義了一種外設(shè)接口。SDIO主要有兩類應(yīng)用——可移動和不可移動??梢苿釉O(shè)備作為Palm和Windows Mobile的擴(kuò)展設(shè)備,用來增加藍(lán)牙、照相機(jī)、GPS和802.11b功能。不可移動設(shè)備遵循相同的電氣標(biāo)準(zhǔn),但不要求符合物理標(biāo)準(zhǔn)。某些手機(jī)內(nèi)包含通過SDIO連接CPU的802.11芯片。此舉將“珍貴”的I/ O管腳資源用于更重要的功能。
藍(lán)牙、照相機(jī)、GPS和802.11b設(shè)備有專為它們定義的應(yīng)用規(guī)范。這些應(yīng)用規(guī)范與為PCI和USB設(shè)備定義的類規(guī)范很相像。它們允許任何宿主設(shè)備與任意外設(shè)“通話”,只要它們都支持應(yīng)用規(guī)范。
SDIO和SD卡規(guī)范間的一個重要區(qū)別是增加了低速標(biāo)準(zhǔn)。SDIO卡只需要SPI和1位SD傳輸模式。低速卡的目標(biāo)應(yīng)用是以最小的硬件開支支持低速I/ O能力。低速卡支持類似調(diào)制解調(diào)器、條碼掃描儀和GPS接受器等應(yīng)用。對“組合”卡(存儲器+ SDIO)而言,全速和4位操作對卡內(nèi)存儲器和SDIO部分都是強(qiáng)制要求的。
MM32F3270系列控制器支持SDIO接口,本文在接下來會對MM32F3270的SDIO進(jìn)行介紹,并通過實(shí)驗(yàn)演示SDIO驅(qū)動SD卡。
01 、SDIO 簡介
SD/MMC/SDIO 控制器是 AMBA AHB 從外設(shè),用于控制外部 SD/MMC/SDIO 卡,并支持 DSP/MCU的讀/寫訪問。它作為主機(jī)與連接的 SD/MMC/SDIO 卡進(jìn)行通信。所述控制器是基于 AMBA HCLK 域的完全同步設(shè)計。
1.1、SDIO 功能框圖
圖1 SDIO功能框圖
1) AHB 從模式接口:為 32 位 AHB 總線提供接口。
2) FIFO 控制:產(chǎn)生握手信號到 DMA 硬件接口,并控制對外部數(shù)據(jù) FIFO(128x32)的讀/寫訪問。
3) 總線接口單元:包括控制寄存器和命令緩沖單元。
4) 多重塊控制:控制多塊數(shù)據(jù)的讀寫。
6) 命令通路:從總線接口單元或 irq 響應(yīng)中加載新的命令,然后發(fā)送命令,并接收響應(yīng) crc7 檢查和 8 個空時鐘。
7) 數(shù)據(jù)通路:發(fā)送和接收數(shù)據(jù),用 crc16 檢查。
8) 緩沖接口:控制對數(shù)據(jù) FIFO 的讀寫控制信號。
1.2、SDIO 功能描述
1) 完全兼容 SD 記憶卡規(guī)格 1.0
2) 完全兼容 SD 存儲卡規(guī)格 1.1(高速)
3) 完全兼容 SD 記憶卡規(guī)格 2.0(SDHC)
4) 完全兼容 MMC 系統(tǒng)規(guī)格 2.0~4.2
5) 完全兼容 SDIO 存儲卡規(guī)格 1.1.0
6) 標(biāo)準(zhǔn)的 MMC 模式接口支持
7) 可編程時鐘速率
8) 自動命令/響應(yīng) CRC 生成/檢查
9) 自動數(shù)據(jù) CRC 生成/檢查
10) 可編程超時檢測
11) AMBA 2.0 32 位 AHB 接口
12) 用于 AHB 數(shù)據(jù)訪問的總共外部 128*32 數(shù)據(jù) FIFO
13) 32 位 DMA 硬件接口,用于更快的 DMA 訪問
14) DMA 接口可以配置為啟用/禁用
15) DMA 請求是可配置的
16) 組合中斷輸出
02 、SD 存儲卡
根據(jù) Read-Write 屬性不同可分為兩種類型的 SD 存儲卡:
1) 可讀可寫(RW)卡(FLASH, OTP, MTP)。這些卡通常作為空白媒介來售賣,用于海量終端用戶的視頻、音頻或數(shù)字圖像記錄的存儲。
2) 只讀存儲卡(ROM)。這些卡是用固定的數(shù)據(jù)內(nèi)容生產(chǎn)出來的,它們通常用作軟件、音頻、視頻等的傳播媒介。
2.2、電源電壓
根據(jù)工作電源電壓不同可分為兩種類型的 SD 存儲卡:
1) 高電壓 SD 存儲卡,可以在 2.7-3.6V 的電壓范圍內(nèi)工作;
2) 雙電壓 SD 存儲卡,可以在 1.6-3.6V 的電壓范圍內(nèi)工作。
2.3、卡容量
根據(jù)卡容量不同可分為兩種類型的 SD 存儲卡:
1) 標(biāo)準(zhǔn)容量的 SD 存儲卡支持最大 2G 字節(jié)的容量。所有版本的物理規(guī)格都定義了標(biāo)準(zhǔn)容量 SD 存儲卡;
2) 高容量 SD 存儲卡支持超過 2G 字節(jié)的容量,此版本規(guī)范限制容量高達(dá) 32GB。高容量 SD 存儲卡是物理層規(guī)范版本 2.00 中新定義的。
2.4、傳輸速度
定義了四種速度等級,表示 SD 卡的最低性能:
1) Class0:這類卡不指定性能;
2) Class2:速度不低于 2MB/s;
3) Class4:速度不低于 4MB/s;
4) Class6:速度不低于 6MB/s;
大容量 SD 存儲卡應(yīng)支持速度等級規(guī)范,性能大于或等于 2 級。
2.5、總線拓?fù)?/strong>
SD 卡系統(tǒng)定義了兩種通信協(xié)議:SD 和 SPI。主機(jī)系統(tǒng)可以選擇任意一種。當(dāng)收到 reset 命令的時候, SD 卡通過主機(jī)的信息來決定使用何種模式,并且之后的通訊都會使用相同模式。不推薦多卡槽用共同的總線信號。一個單獨(dú)的 SD 總線應(yīng)該連接一個單獨(dú)的 SD 卡。SD 總線包含下面的信號:
1) CLK:時鐘信號;
2) CMD:雙向命令/響應(yīng)信號;
3) DAT0-DAT3:雙向數(shù)據(jù)信號;
4) Vdd, Vss1, Vss2:電源和地信號。
2.6、總線協(xié)議
SD 總線通信:
1) Command:命令是一次操作開始的令牌,從主機(jī)發(fā)送到一個卡片(編址命令)或者連接到主機(jī)的所有卡片(廣播命令)。命令在 CMD 線上連續(xù)傳輸。
2) Response:響應(yīng)是從已尋址的卡或從所有連接上的卡發(fā)送到主機(jī)的令牌,作為對先前接收到指令的應(yīng)答。響應(yīng)在 CMD 線上連續(xù)傳輸。
3) Data:數(shù)據(jù)可以通過 DATA 線雙向傳輸。
卡片尋址通過使用會話地址來實(shí)現(xiàn),會話地址會在初始化階段分配給卡。SD 總線上的基本交互是命令/響應(yīng)交互。這種總線交互直接在命令或者響應(yīng)的結(jié)構(gòu)里面?zhèn)鬏斔麄兊男畔?。此外,某些操作還有數(shù)據(jù)令牌。SD 卡發(fā)送或接收的數(shù)據(jù)在塊(block)中完成。數(shù)據(jù)塊以 CRC 位來保證傳輸成功。目前有單塊和多塊操作。
注:多塊操作模式在快速寫操作時更好一點(diǎn)。多塊傳輸在 CMD 線上產(chǎn)生 stop 命令時結(jié)束。主機(jī)端可以配置數(shù)據(jù)傳輸是單線還是多線。
SDIO“無響應(yīng)”和“無數(shù)據(jù)”操作
SDIO(多)數(shù)據(jù)塊讀操作
SDIO連續(xù)讀操作
SDIO連續(xù)寫操作
03、卡的初始化以及識別過程
初始化進(jìn)程以命令 ACMD41 作為開始,通過設(shè)置工作條件和 OCR 來進(jìn)行。HCS(HighCapacitySupport)位為 1 表示主機(jī)支持高容量 SD 卡??ㄍㄟ^ OCR 的 busy 位來通知主機(jī) ACMD41 的初始化完成了。busy 位為 0表示卡仍然在初始化;為 1 表示已經(jīng)完成初始化。主機(jī)會重復(fù)發(fā)送 ACMD41,直到 busy 位被置 1??ㄆ荚诘谝粋€ ACMD41 的命令時,檢查工作條件和 OCR 里面的 HCS 位。當(dāng)重復(fù) ACMD41 的時候,除了 CMD0,主機(jī)不再發(fā)其他命令。接著主機(jī)會發(fā)送命令 ALL_SEND_CID(CMD2),來獲得卡的 CID 號。未識別的卡(處于Ready 狀態(tài)的)發(fā)送自己的 CID 作為響應(yīng)。當(dāng)卡發(fā)送 CID 后,進(jìn)入卡識別(Identification)狀態(tài)。之后主機(jī)發(fā)送 SEND_RELATIVE_ADDR(CMD3)命令要求卡發(fā)布新的相對地址(RCA),一旦收到 RCA,卡就會變?yōu)榈却⊿tand-by)狀態(tài)。主機(jī)會重復(fù)識別進(jìn)程,為系統(tǒng)中每個卡循環(huán)發(fā)送 CMD2 和 CMD3。對于 SDI/O 卡而言,總線被激活后 SDIO 卡主機(jī)先發(fā)送 IO_SEND_OP_COND(CMD5)命令,得到的響應(yīng)是卡的工作條件寄存器的內(nèi)容,之后再同上發(fā)送 CMD3 命令,執(zhí)行后續(xù)操作。
04、MM32F3270 SDIO驅(qū)動SD卡
MM32的SDIO支持SD/MMC/SDIO卡,其中SDIO卡與SD存儲卡是有區(qū)別的。SDIO卡實(shí)際上就是利用SDIO接口的一些模塊,插入SD的插槽中,擴(kuò)展設(shè)備的功能,如:SDIO wifi, SDIO CMOS相機(jī)等。SD存儲卡就是平時常見的用于存儲數(shù)據(jù)的卡。
本實(shí)驗(yàn)中使用的Micro SD卡屬于SDSC(標(biāo)準(zhǔn)容量,最大2G)卡。介紹卡的種類是因?yàn)镾D協(xié)議中的命令也支持這三種類型的卡,因此對MM32中的SDIO接口進(jìn)行初始化后,上電后就要對接入的卡進(jìn)行檢測、分類,這個過程是通過向卡發(fā)送一系列不同的命令,根據(jù)卡不同的響應(yīng)來進(jìn)行分類。
本實(shí)驗(yàn)使用MM32F3270的SDIO對SD卡進(jìn)行讀寫測試,首先填充一個塊大小的存儲器,通過寫入操作把數(shù)據(jù)寫入到 SD卡內(nèi),然后通過讀取操作讀取數(shù)據(jù)到另外的存儲器,然后再對比存儲器內(nèi)容,判斷讀寫操作是否正確。
實(shí)現(xiàn)的大概流程包括:初始化SDIO 外設(shè)以及GPIO,配置 SDIO 基本通信環(huán)境進(jìn)入卡識別模式,通過命令處理后獲取卡信息及狀態(tài)。如果是SD卡正常則進(jìn)行數(shù)據(jù)傳輸,接下來就可以進(jìn)行讀、寫以及擦除操作,否則打印SD卡錯誤信息,不再進(jìn)行后續(xù)操作。
硬件設(shè)計
實(shí)驗(yàn)使用MB-039開發(fā)板,主控芯片為MM32F3277G9P,如圖是MB-039開發(fā)板的SDIO/TF卡接口部分,完整原理圖可以通過官網(wǎng)下載。
各個信號引腳對應(yīng)如下:
程序設(shè)計
根據(jù) SD 卡識別過程和數(shù)據(jù)傳輸過程理解 SD 卡驅(qū)動函數(shù)代碼。這部分代碼內(nèi)容也較多,在本文中只對部分核心函數(shù)介紹其功能,詳細(xì)代碼可到靈動官網(wǎng)下載參考。
SPIO配置初始化
void SDIO_ConfigInit(void) { SDIO_InitTypeDef SDIO_InitStruct; SDIO_PIN_GPIO_Config(); SDIO_Detect_Pin_Config(); RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, ENABLE); SDIO_DeInit(); RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, DISABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, ENABLE); SDIO_ClockSet(0x2F); SDIO_StructInit( SDIO_InitStruct); SDIO_InitStruct.SDIO_OPMSel = SDIO_MMC_CTRL_OPMSel; SDIO_InitStruct.SDIO_SelPTSM = SDIO_MMC_CTRL_SelSM; SDIO_InitStruct.SDIO_DATWT = SDIO_MMC_CTRL_DATWT; SDIO_Init( SDIO_InitStruct); SDIO_CRCConfig(SDIO_MMC_CRCCTL_CMD_CRCEN | SDIO_MMC_CRCCTL_DAT_CRCEN, ENABLE); } void show_sdcard_info(void) { switch(SDCardInfo.CardType) { case SDIO_STD_CAPACITY_SD_CARD_V1_1: printf("Card Type:SDSC V1.1rn"); break; case SDIO_STD_CAPACITY_SD_CARD_V2_0: printf("Card Type:SDSC V2.0rn"); break; case SDIO_HIGH_CAPACITY_SD_CARD: printf("Card Type:SDHC V2.0rn"); break; case SDIO_MULTIMEDIA_CARD: printf("Card Type:MMC Cardrn"); break; } printf("Card ManufacturerID:%drn", SDCardInfo.SD_cid.ManufacturerID); //The manufacturer ID printf("Card RCA:%drn", SDCardInfo.RCA); //Card relative address printf("Card Capacity:%d MBrn", (u32)(SDCardInfo.CardCapacity >> 20)); printf("Card BlockSize:%drnrn", SDCardInfo.CardBlockSize); }
SD卡的初始化主要進(jìn)行卡識別和卡狀態(tài)獲取,定義SD_Init()如下:
SD_Error SD_Init(void) { u32 clk; RCC_ClocksTypeDef bclk; u32 targetFreq; __IO SD_Error errorstatus = SD_OK; u8 clkdiv = 0; INTX_DISABLE(); errorstatus = SD_PowerON(); //SD Power On if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_InitializeCards(); //Initialize SD Card if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_GetCardInfo( SDCardInfo); //Get card information if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_SelectDeselect((u32)(SDCardInfo.RCA << 16)); //Select the SD card if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_EnableWideBusOperation(1); //4 bit width, if it is an MMC card, you cannot use 4 bit mode if ((errorstatus != SD_OK)) { if( (SDIO_MULTIMEDIA_CARD == CardType)) { if (SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V1_1 || SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V2_0) { clkdiv = 0; //V1.1/V2.0 card with the maximum setting of 48/4=12Mhz } else { clkdiv = 1; //For other cards such as SDHC, the maximum setting is 48/2=24Mhz } if(clkdiv != 0) { targetFreq = 24000000; } else { targetFreq = 12000000; } RCC_GetClocksFreq( bclk); clk = (bclk.HCLK_Frequency / 2 / 2 / targetFreq - 1); SDIO_ClockSet(clk); } else { __NOP(); } } else { if (SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V1_1 || SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V2_0) { clkdiv = 0; } else { clkdiv = 1; } if(clkdiv != 0) { targetFreq = 24000000; } else { targetFreq = 12000000; } RCC_GetClocksFreq( bclk); clk = (bclk.HCLK_Frequency / 2 / 2 / targetFreq - 1); SDIO_ClockSet(clk); } INTX_ENABLE(); return errorstatus; }
1) SD_PowerON()函數(shù)用于查詢卡的工作電壓和時鐘控制配置,并返回 SD_Error 類型錯誤,該函數(shù)是整個 SD 識別的關(guān)鍵函數(shù)。
2) SD_InitializeCards()函數(shù)初始化SD卡,并將其置入就緒狀態(tài);
3) SD_GetCardInfo()函數(shù)獲取SD卡的信息;
4) SD_SelectDeselect()選擇SD卡,發(fā)送CMD7命令,選擇具有相對地址(RCA)的卡作為ADDR;
5) SD_EnableWideBusOperation()配置SDIO數(shù)據(jù)寬度;
6) SDIO_ClockSet()配置SDIO的時鐘頻率。
獲取SD卡信息及數(shù)據(jù)的函數(shù)定義如下:
void read_sd_card_info(void) { u16 i = 5; SD_Error result; u32 sd_size; SDIO_ConfigInit(); printf("SDCARD TESTrn"); while(1) { result = SD_Init(); if(result == SD_OK) { break; } printf("SD Card Error!rn"); DELAY_Ms(1); } show_sdcard_info(); i = 5; while(i--) { if(SD_ReadDisk( vbuf[0], 0, 1) == 0) { printf("UART Sending Data...rn"); printf("SECTOR 0 DATA:rn"); for(sd_size = 0; sd_size < 512; sd_size++) { printf("%02x ", vbuf[sd_size]); } printf("rnDATA ENDEDrn"); printf("UART Send Data Over!rn"); } DELAY_Ms(50); } }
實(shí)驗(yàn)演示
在MB-039開發(fā)板的SDIO/TF卡槽插入SD卡,運(yùn)行程序,串口調(diào)試助手顯示如下:
如果SD卡可用,串口調(diào)試助手會打印SD卡的信息,包括卡類型、生產(chǎn)ID、RCA、容量和塊大小,接著打印扇區(qū)0的數(shù)據(jù),會連續(xù)打印5次該部分內(nèi)容。
本次實(shí)驗(yàn)的例程可以通過MindMotion的官網(wǎng)下載MM32F3270 lib_Samples:
工程路徑如下:
~MM32F327x_Samples LibSamplesSDIOSDIO_ReadSDCardInfo
可以看到詳細(xì)的樣例與功能操作。
來源:靈動MM32MCU
審核編輯:湯梓紅
-
控制器
+關(guān)注
關(guān)注
112文章
16367瀏覽量
178114 -
接口
+關(guān)注
關(guān)注
33文章
8605瀏覽量
151191 -
SD卡
+關(guān)注
關(guān)注
2文章
565瀏覽量
63906 -
SDIO
+關(guān)注
關(guān)注
2文章
73瀏覽量
19325
發(fā)布評論請先 登錄
相關(guān)推薦
評論