2.6 SDIO 模組
2.6.1 SDIO 功能說明
STM32F 微控器的 SDIO 功能包含兩個部份,圖 2-36 為 SDIO 模組方塊 圖,內含SDIO 轉接器與 AHB 匯流排界兩個模組,其中 SDIO Adapter 轉接 器模組用來實現有關於 MMC/SD/SD-I/O 介面卡的所有功能,如 SCK 頻率 的產生、命令和資料的傳送等。AHB 匯流排介面用來操作 SDIO Adapter 轉 接器中的暫存器,並且可以產生中斷與DMA 請求。
圖 2-36 SDIO 模組方塊圖 [1]
圖2-37 為 SDIO Adapter 轉接器模組的方塊圖,其包含了轉接器暫存器 (Adapter registers)、控制單元(Control unit)、命令通道(Command path)、資料 通道(Data path)與數據 FIFO 等 5 個部分,我們將針對命令通道與資料通道 進行說明。
命令通道(Command Path)
命令通道是執行向多媒體卡發送命令並接收從卡發出回應的單元,命 令的運作是通過命令通道狀態機(CPSM)來完成的。圖 2-38 為 SDIO 命令通 道狀態機的方塊圖,系統重置後CPSM 處於空閒狀態(Idle),當命令參數寫 入命令暫存器(SDIO_CMD)並設置了 CPSMEN 位元,就會開始發送命令;
命令發送完成時,命令通道狀態機(CPSM)設置狀態暫存器(SDIO_STA)的狀 態標誌,並在不需要回應時進入空閒狀態;當收到回應後,接收到的 CRC 碼將會與內部產生的CRC 碼比較,然後設置相應的狀態標誌;當進入等候 狀態時,命令計數器開始運行;當 CPSM 進入接收狀態之前如果產生了超 時,則會設置超時標誌並進入空閒狀態。
圖 2-38 SDIO 命令通道狀態機方塊圖 [1]
圖 2-39 為用來發送命令的 SDIO_Send_Command( )副程式,將命令參
輸 入:*SDIO_CmdInitStruct 輸 出:無
void SDIO_SendCommand (SDIO_CmdInitTypeDef *SDIO_CmdInitStruct) {
u32 tmpreg = 0;
SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument; // 設定Argument 參數
tmpreg = SDIO->CMD; // 讀取 SDIO_CMD 值到 tmpreg tmpreg &= CMD_CLEAR_MASK; // 清除 SDIO_CMD 設定位元 tmpreg |= (u32)SDIO_CmdInitStruct->SDIO_CmdIndex // 設定CMD 命令參數 | SDIO_CmdInitStruct->SDIO_Response // 設定WAITRESP 位元
資料通道(Data Path)
資料通道控制主裝置與多媒體卡之間的傳輸資料,STM32 微控器的 SDIO 模組,是以 1 位元資料匯流排為初始設定,一個時鐘週期只在 SDIO_D0 上傳輸 1 位元資料,在 SDIO_CLKCR 暫存器中,可以設置 WIDBUS[1:0]
位元來更改資料匯流排的寬度。圖2-40 為 SDIO 模組的 DPSM 資料通道狀 態機的方塊圖,系統重置後DPSM 處於空閒狀態(Idle),將資料傳輸模式設 定寫入SDIO_DCTRL 暫存器,並且設置 SDIO_DCTRL 暫存器的致能 DTEN 位元後,資料通道狀態機將根據傳輸的方向(發送或接收)進入 Wait_S 或 Wait_R 狀態。
發送時DPSM 進入 Wait_S 狀態,如果發送 FIFO 中有資料,則 DPSM 進入發送狀態(Send),同時資料通道開始向多媒體卡發送資料。
接收時DPSM 進入 Wait_R 狀態並等待開始位元,當收到開始位元後,
DPSM 進入接收狀態(Reveive),同時資料通道開始從多媒體卡接收資料。
圖2-41 為資料通道狀態機(DPSM)的設定副程式,先將 Time Out 設定 值寫入 SDIO_DTIMER 暫存器,資料長度寫入 SDIO_DLEN 暫存器,再將 區塊大小、傳輸方向、傳輸模式寫入SDIO_DCTRL 暫存器,最後設定 DPSM
SDIO->DTIMER = SDIO_DataInitStruct->SDIO_DataTimeOut; // 設定 TimeOut value SDIO->DLEN = SDIO_DataInitStruct->SDIO_DataLength; // 設定DataLength value
tmpreg = SDIO->DCTRL; // 讀取 SDIO_DCTRL 值到 tmpreg tmpreg &= DCTRL_CLEAR_MASK; // 清除 SDIO_DCTRL 設定位元 tmpreg |= (u32)SDIO_DataInitStruct->SDIO_DataBlockSize // 設定DBCKSIZE 位元 | SDIO_DataInitStruct->SDIO_TransferDir // 設定DTDIR 位元
STM32 微控器的 SDIO 模組設定
在使用 SDIO 介面之前,需要對 SDIO 模組進行初始設定與啟動,
圖 2-42 為啟動 SDIO 模組的的 SDIO_Init( )設定流程,首先清除時鐘控制 暫存器,接著設定時鐘頻率(f = SDICLK/[CLKDIV+2]),再設定是否進入省 電模式,最後將設定好的參數填入SDIO_CLKCR 暫存器內就完成設定。
程式名稱:SDIO_Init ( )
功能敘述:STM32 微控器的 SDIO 模組設定
輸 入:SDIO_InitTypeDef* SDIO_InitStruct 輸 出:無
void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct) {
u32 tmpreg = 0;
/* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */
tmpreg &= CLKCR_CLEAR_MASK; // 清除設定資料 /* Set CLKDIV bits according to SDIO_ClockDiv value *
/* Set PWRSAV bit according to SDIO_ClockPowerSave value */
/* Set BYPASS bit according to SDIO_ClockBypass value */
/* Set WIDBUS bits according to SDIO_BusWide value */
/* Set NEGEDGE bits according to SDIO_ClockEdge value */
/* Set HWFC_EN bits according to SDIO_HardwareFlowControl value */
tmpreg |= (SDIO_InitStruct->SDIO_ClockDiv
| SDIO_InitStruct->SDIO_ClockPowerSave // 設定省電模式 | SDIO_InitStruct->SDIO_ClockBypass // 設定頻率來源 | SDIO_InitStruct->SDIO_BusWide // 設定資料匯流排
| SDIO_InitStruct->SDIO_ClockEdge // 設定頻率與資料對齊方式 | DIO_InitStruct->SDIO_HardwareFlowControl); // 設定硬體流程控制
/* Write to SDIO CLKCR */
SDIO->CLKCR = tmpreg; // 寫入控制暫存器 }
圖 2-42 SDIO 模式設定副程式
SDIO 暫存器介紹 數;SDIO_DCTRL 暫存器用來控制資料狀態機 DPSM;SDIO_STA 暫存器 用來顯示SDIO 模組的工作狀態
表 2-9 SDIO 時鐘控制暫存器 [1]
31:15 14 13 12 11 10 9 7:0
Res HWFC_EN NEGEDGE WIDBUS BYPAS PWRSAV CLKEN CLKDIV
Res R/W R/W R/W R/W R/W R/W R/W
HWFC_EN:硬體流控制致能 0:關閉硬體流控制
1:致能硬體流控制
NEGEDGE:SDIO_CK 相位選擇位元
0:在主時鐘 SDIOCLK 的上升沿產生 SDIO_CK 1:在主時鐘 SDIOCLK 的下降沿產生 SDIO_CK WIDBUS:寬匯流排模式致能位元
表 2-10 SDIO 資料控制暫存器 [1]
31:15 14 13 12 11 10 9 8 7:6 5:0
Res SDIOEN PWMOD RWSTOP RWSTART DBLOCKSIZE DMAEN DTMODE DTDIR DTEN
R R/W R/W R/W R/W R/W R/W R/W R/W R/W
Res ATACMD nIEN ENCMD SDIOSuspend CPSMEN WAITPEND WAITINT WAITRESP CMDINDEX
R R/W R/W R/W R/W R/W R/W R/W R/W R/W
表 2-12 SDIO 參數暫存器 [1]
31:0 CMDARG
R/W
CMDARG[31:0] CMDARG:命令參數是發送到卡中的命令的一部分,如果一個命令包含一個參數,必須在寫命令 到命令暫存器之前載入這個暫存器
表 2-13 SDIO 狀態暫存器 [1]
31:24 23 22 21 20 19 18 17 16 15 14 13
Res
CEATACEN SDIOIT RXDAVL TXDAVL RXFIFOE TXFIFOE RXFIFOF TXFIFOF RXFIFOHF TXFIFOHE RXACT
Res R R R R R R R R R R R
12 11 10 9 8 7 6 5 4 3 2 1 0
TXACT CMDACT DBCKEND STBITERR DATAEND CMDSENT CMDREND RXOVERR TXUNDERR DTMEOUT CTIMEOUT DCRCFAIL CCRCFAIL
R R R R R R R R R R R R R
CEATAEND:在 CMD61 接收到 CE-ATA 命令完成信號 CMDACT:正在傳輸命令
SDIOIT:收到 SDIO 中斷。 DBCKEND:已發送/接收資料塊(CRC 檢測成功) RXDVAL:在接收 FIFO 中的資料可用 STBITERR:在寬匯流排模式,沒有在所有資料信號上檢
測到起始位元
TXDVAL:在發送 FIFO 中的資料可用 DATAEND:資料結束(資料計數器,SDIO_DCOUNT = 0) RXFIFOE:接收 FIFO 空 CMDSENT:命令已發送(不需要回應)
TXFIFOE:發送 FIFO 空 CMDREND:已接收到回應(CRC 檢測成功) RXFIFOF:接收 FIFO 滿 RXOVERR:接收 FIFO 上溢錯誤
TXFIFOF:發送 FIFO 滿 TXUNDERR:發送 FIFO 下溢錯誤 RXFIFOHF:接收 FIFO 半滿:FIFO 中至少還有 8 個字 DTIMEOUT:數據超時
TXFIFOHE:發送 FIFO 半空:FIFO 中至少還可以寫入 8 個字
CTIMEOUT:命令回應超時 ,命令逾時時間是一個固定的 值,為64 個 SDIO_CK 時鐘週期
RXACT:正在接收資料 DCRCFAIL:已發送/接收資料塊(CRC 檢測失敗) TXACT:正在發送資料 CCRCFAIL:已收到命令響應(CRC 檢測失敗)