--- title: Secure digital input/output interface (SDIO) categories: SDIO, STM32F4 ... Introduction ============ What is the SD/MMC? -------------------------- - Secure Digital縮寫SD,全名Secure Digital Memory Card,中文翻譯為安全數位卡,為一種記憶卡,被廣泛地於攜帶型裝置上使用,例如數位相機、個人數位助理和多媒體播放器等。SD卡的技術是建基於MMC(MultiMedia)卡格式上。SD卡有比較高的資料傳送速度,而且不斷更新標準。 - SD 是一種 flash memory card 的標準,也就是一般常見的 SD 記憶卡,而 MMC 則是較早的一種記憶卡標準,目前已經被 SD 標準所取代. .. image:: /sdio2.png 後來還出了SDHC(Secure Digital High Capacity),是由SD卡協會(SD Card Association)在2006年3月發表的Secure Digital高容量版本。SD卡協會有强制規定,所有符合SDHC規範的設備都必須標明“SDHC”的標誌. SDHC與SD的主要差異在於,舊版本使用FAT16檔案系統,意思是管理檔案所在位置的表格用16位元表示,所以最多只能管理65536個範圍,再考慮每個範圍能儲存32KB的資料量,所以65536 × 32KB = 2GB,SD卡容量上限只能到達2GB。為解決FAT16格式可支援容量有限的問題,SDHC改用了FAT32格式;依規格定義,容量最大可達到32GB。 發佈SDHC的時候,制定了三種不同的級數(Class),分別是Class 2、Class 4及Class 6,表示該記憶卡穩定的最小存取速度。 後來,增加了Class 10及全新制定的UHS(Ultra High Speed) .. image:: /class_speed.png What is the SDIO? ----------------- - SDIO 是目前我們比較關心的技術,SDIO 故名思義,就是 SD 的 I/O 介面(interface)的意思,不過這樣解釋可能還有點抽像。更具體的說明,SD 本來是記憶卡的標準,但是現在也可以把 SD 拿來插上一些週邊介面使用,這樣的技術便是 SDIO。 - 所以 SDIO 本身是一種相當單純的技術,透過 SD 的 I/O 接腳來連接外部週邊,並且透過 SD 上的 I/O 資料接位與這些週邊傳輸資料,而且 SD 協會會員也推出很完整的 SDIO stack 驅動程式,使得 SDIO 週邊(我們稱為 SDIO 卡)的開發與應用變得相當熱門。 - A SDIO (Secure Digital Input Output) card is an extension of the SD specification to cover I/O functions. - Host devices that support SDIO can use the SD slot to support: 1. GPS receivers. 2. digital cameras. 3. RFID readers. 4. FM radio tuners. 5. TV tuners. 6. Wi-Fi. 7. Bluetooth. Many other SDIO devices have been proposed, but it is now more common for I/O devices to connect using the USB interface. - SDIO cards support most of the memory commands of SD cards. SDIO cards can be structured as 8 logical cards, although currently, the typical way that an SDIO card uses this capability is to structure itself as one I/O card and one memory card. .. image:: /sdio1.png SDIO bus topology ================= .. image:: /Selection_015.png .. image:: /Selection_016.png Note: The SDIO will not send any data as long as the Busy signal is asserted (SDIO_D0 pulled low). .. image:: /Selection_017.png .. image:: /Selection_018.png .. image:: /Selection_019.png SDIO functional description ============================ .. image:: /sdio_functional_description.png 圖說明: - SDIO_D0預設是用來當作資料傳輸 , 而在初始化時 , host端可以設定其資料寬度。 - 當MMC連至bus時 , MMC可以支援只有1bit模式。 - 當SD/SD I/O連至bus時,data transfer可以由host端來設定是SDIO_D0(1bit mode) 或者是 SDIO_D[3:0](4bit mode) 而所有的data lines都是操作於push-pull mode. SDIO_CMD has two operational modes: - Open-drain for initialization (only for MMCV3.31 or previous) - Push-pull for command transfer (SD/SD I/O card MMC4.2 use push-pull drivers also for initialization) SDIO_CK is the clock to the card: - 在clock cycle 中 , 1 bit是用來切換command 或是 data lines. - clock的頻率依照規格不同有所不同: * between 0 and 20 MHz (for a MultiMediaCard V3.31). * between 0 and 48 MHz for a MultiMediaCard V4.0/4.2). * between 0 and 25 MHz (for an SD/SD I/O card). - The SDIO uses two clock signals: * SDIO adapter clock(SDIOCLK = 48MHz is coming from a specific output of PLL (PLL48CLK) ). * APB2 bus clock(PCLK2). NOTE: PCLK2 與 SDIO_CLK 之clock頻率必須遵循以下條件: Frequency PCLK2 ≥ (3/8) * Frequency SDIO_CK ????????????????? The signals shown in Table 149 are used on the MultiMediaCard/SD/SD I/O card bus .. image:: /SDIO_IO_definitions.png SDIO adapter ============== block diagram of an SDIO adapter. .. image:: /sdio_adapter.png 上圖中包含了五個子單元: - Adapter register block - Control unit - Command path - Data path - Data FIFO 由圖中可以看出 , adapter registers 和 FIFO都是採用APB2 bus clock domain (PCLK2), 而control unit , command path , data path 則是採用SDIO adapter clock domain(SDIOCLK). Q&A : WHY?????????????????????????????????????????????????????? 上圖中之左側部份(Adapter registers and FIFO): Adapter registers 主要包含了所有SDIO的暫存器 , 而這些暫存器是用來配置一些參數,以用來實現SD協定中的時序,最終目的是用來實現SD卡的命令傳輸。 而FIFO則是為了實現與data path的傳輸 , 而這兩個分別代表著對SD卡的兩種操作模式 , 一個是命令的傳輸 , 一個是資料的傳輸。 上圖中之右側 主要分為三個子單元 , Control Unit , Command Path and Data Path , Control Unit主要用來控制電源以及時鐘的控制 , 而這些控制是根據Adapter registers當中的暫存器來做配置 , 而Command Path連結SDIO_CMD , 他用來控制命令的傳輸 , 最後Data Path則是連結SDIO_D[7:0],控制資料的傳輸。 底下分單元描述 - Adapter register block: The adapter register block contains all system registers. This block also generates the signals that clear the static flags in the multimedia card. The clear signals are generated when 1 is written into the corresponding bit location in the SDIO Clear register. - Control Unit: 這部份又在其內部分為兩個子單元 , 一個是Power management , 另一個是Clock management , 其兩個子單元都受控制於Adapter registers. 詳見下圖(Figure 328) .. image:: /control_unit.png Power management: There are three power phases: * power-off * power-up * power-on NOTE!! The power management subunit disables the card bus output signals during the power-off and power-up phases. Clock management: 用來產生和控制SDIO_CK , 而其SDIO_CK又可選擇兩種模式: * clock Divide (SDIO_CK = SDIO_CLK/div .) * clock Bypass (SDIO_CK = SDIO_CLK). 而在底下的情況下 , Clock是不輸出訊號的 * after reset * during the power-off or power-up phases * if the power saving mode is enabled and the card bus is in the Idle state (eight clock periods after both the command and data path subunits enter the Idle phase). /*********************/ SDIO APB2 interface ------------------- ARM 的 APB2 介面由 data path,register decoder 與 interrupt/DMA logic 組成,除了會產生 interrupt 與 DMA 的 request,也會存取 SDIO adapter registers 與 data FIFO。 SDIO interrupt: - 當任何一個透過 mask register 預先選擇的特定 flags 之 status flag 為 high 時,interrupt logic 將會產生一個 interrupt request。又若某個 mask flag 被 set 的話,其對應的 status flag 也會產生 interrupt request。 /*********************/ Sample Code ============ - https://github.com/JackABK/STM32F4-FreeRTOS/tree/master (Switch master branch) .. code-block:: prettyprint SD_Error SD_Init(void) { __IO SD_Error errorstatus = SD_OK; /* SDIO Peripheral Low Level Init */ SD_LowLevel_Init(); //SDIO_DeInit(); errorstatus = SD_PowerON(); if (errorstatus != SD_OK) { /*!< CMD Response TimeOut (wait for CMDSENT flag) */ return(errorstatus); } errorstatus = SD_InitializeCards(); if (errorstatus != SD_OK) { /*!< CMD Response TimeOut (wait for CMDSENT flag) */ return(errorstatus); } /*!< Configure the SDIO peripheral */ /*!< SDIO_CK = SDIOCLK / (SDIO_TRANSFER_CLK_DIV + 2) */ /*!< on STM32F4xx devices, SDIOCLK is fixed to 48MHz */ SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; SDIO_Init(&SDIO_InitStructure); /*----------------- Read CSD/CID MSD registers ------------------*/ errorstatus = SD_GetCardInfo(&SDCardInfo); if (errorstatus == SD_OK) { /* Select Card*/ errorstatus = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16)); } if (errorstatus == SD_OK) { errorstatus = SD_EnableWideBusOperation(SDIO_BusWide_4b); } return(errorstatus); } Demo ============ Reference ========== - `Secure Digital wiki`_ - `SDIO接口介绍`_ - `Linux(open source)的 SD/MMC/SDIO 支援現況概要`_ - `SD/MMC/SDIO概念區分`_ - `STM32 控制 SD 卡`_ - `STM32 + SDIO + FATFS 文件系统 直讀 SD 卡`_ - `零死角玩轉 stm32 - 高級篇之 SDIO(4bit + DMA、支持SDHC、帶協議分析)`_