5.24 SDIO Guide
SDIO is the SD card host interface of the N32H49x standard peripheral library, supporting SD memory cards, SD I/O cards, and MMC 4.2 cards with a command channel, a data channel, and a data FIFO, and performing block read/write and erase together with DMA. This chapter covers the files of the driver, its 66 public functions, and the example SD_Card. For the SDIO bus protocol, the command and response formats, the command and data state machines, and the register bit definitions, read it together with the “SDIO interface (SDIO)” chapter of the user manual.
5.24.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32h49x_std_periph_driver/inc/n32h49x_sdio.h |
Defines the SDIO_InitType, SDIO_CmdInitType, and SDIO_DataInitType structures and the macros for power, clock division, bus width, command response, and data block length;declares the 66 public functions grouped as reset and initialization, interrupts and DMA, command and response, data path configuration, block read/write, erase, card identification, and response error checking |
firmware/n32h49x_std_periph_driver/src/n32h49x_sdio.c |
Implements the 66 functions: register reset and initialization, power and clock control, command transmission and response reading, data path configuration, FIFO access, block read/write and erase commands, and the error checks for each response type |
projects/n32h49x_EVAL/examples/SDIO/ |
SDIO example root, containing the single example SD_Card |
projects/n32h49x_EVAL/examples/SDIO/SD_Card/ |
Project layout of that example: inc/, src/, readme.txt, MDK-ARM/, EWARM/ |
projects/n32h49x_EVAL/bsp/ |
Board support files used by the example: the log print interface log.c and log.h, the delay interface delay.c, and the evaluation-board pin and clock definitions |
5.24.2 API reference
The 66 public functions below follow the declaration order of n32h49x_sdio.h and fall into 13 groups; each entry gives a summary and the original comment directly above the function in n32h49x_sdio.c.
Reset and initialization
SDIO_DeInit, SDIO_Init, SDIO_InitStruct, SDIO_EnableClock, SDIO_SetPower, SDIO_GetPower
Interrupts and DMA
SDIO_ConfigInt, SDIO_DMACmd
Command and response
SDIO_SendCmd, SDIO_InitCmdStruct, SDIO_GetCmdResp, SDIO_GetResp
Data path configuration
SDIO_ConfigData, SDIO_InitDataStruct, SDIO_GetDataCountValue, SDIO_ReadData, SDIO_WriteData, SDIO_GetFifoCounter
Read wait
SDIO_EnableReadWait, SDIO_EnableReadWaitMode, SDIO_StartReadWait, SDIO_StopReadWait
SD I/O mode and command completion
SDIO_EnableSdioOperation, SDIO_EnableSendSdioSuspend, SDIO_EnableCommandCompletion
Flags and interrupt status
SDIO_GetFlag, SDIO_ClrFlag, SDIO_GetIntStatus
Basic commands
SDIO_CmdShortResponse1, SDIO_CmdShortResponse3, SDIO_CmdLongResponse2, SDIO_CmdBlockLength, SDIO_CmdBlockCount
Block read/write commands
SDIO_CmdReadSingleBlock, SDIO_CmdReadMultiBlock, SDIO_CmdWriteSingleBlock, SDIO_CmdWriteMultiBlock
Erase commands
SDIO_CmdSDEraseStartAdd, SDIO_CmdSDEraseEndAdd, SDIO_CmdEraseStartAdd, SDIO_CmdEraseEndAdd, SDIO_CmdErase
Card identification commands
SDIO_CmdLockUnlock, SDIO_CmdStopTransfer, SDIO_CmdSelDesel, SDIO_CmdGoIdleState, SDIO_CmdOperCond, SDIO_CmdAppCommand, SDIO_CmdAppOperCommand, SDIO_CmdBusWidth, SDIO_CmdSendSCR, SDIO_CmdAllSendCID, SDIO_CmdSendCID, SDIO_CmdSendCSD
Address and status commands
SDIO_CmdSetRelAdd, SDIO_CmdSetRelAddMmc, SDIO_CmdSendStatus, SDIO_CmdStatusRegister, SDIO_CmdOpCondition, SDIO_CmdSwitch, SDIO_CmdSendEXTCSD
Response error checking
SDIO_GetCmdResp1, SDIO_GetCmdResp2, SDIO_GetCmdResp3, SDIO_GetCmdResp6, SDIO_GetCmdResp7
void SDIO_DeInit(void)Reset the SDIO peripheral registers to their default reset values.
name SDIO_DeInit.
fun Reset the SDIO peripheral registers to their default reset values.
param none
return none
void SDIO_Init(SDIO_InitType* InitStruct)Initializes the SDIO peripheral according to the specified parameters in the InitStruct.
name SDIO_Init.
fun Initializes the SDIO peripheral according to the specified
parameters in the InitStruct.
param InitStruct pointer to a SDIO_InitType structure.
The input parameters must be the following values:
- ClkEdge:
- SDIO_CLK_EDGE_RISING
- SDIO_CLK_EDGE_FALLING
- ClkBypass:
- SDIO_CLK_BYPASS_DISABLE
- SDIO_CLK_BYPASS_ENABLE
- ClkPwrSave:
- SDIO_CLK_POWER_SAVE_DISABLE
- SDIO_CLK_POWER_SAVE_ENABLE
- BusWidth:
- SDIO_BUS_WIDTH_1B
- SDIO_BUS_WIDTH_4B
- SDIO_BUS_WIDTH_8B
- HardwareClkCtrl:
- SDIO_HARDWARE_CLKCTRL_DISABLE
- SDIO_HARDWARE_CLKCTRL_ENABLE
- ClkDiv: Must be a value between 0x00 and 0x1FF.
return none
void SDIO_InitStruct(SDIO_InitType* InitStruct)Fills each InitStruct member with its default value.
name SDIO_InitStruct.
fun Fills each InitStruct member with its default value.
param InitStruct pointer to an SDIO_InitType structure which will be initialized.
return none
void SDIO_EnableClock(FunctionalState Cmd)Enables or disables the SDIO Clock.
name SDIO_EnableClock.
fun Enables or disables the SDIO Clock.
param Cmd new state of the SDIO Clock.
This parameter must be one of the following values:
- ENABLE
- DISABLE
return none
void SDIO_SetPower(uint32_t PowerState)Sets the power status of the controller.
name SDIO_SetPower.
fun Sets the power status of the controller.
param PowerState new state of the Power state.
This parameter must be one of the following values:
- SDIO_POWER_CTRL_OFF
- SDIO_POWER_CTRL_ON
return none
uint32_t SDIO_GetPower(void)Gets the power status of the controller.
name SDIO_GetPower.
fun Gets the power status of the controller.
param none
return Current Power status,the value can be:
- SDIO_POWER_CTRL_OFF
- SDIO_POWER_CTRL_UP
- SDIO_POWER_CTRL_ON
void SDIO_ConfigInt(uint32_t Int, FunctionalState Cmd)Enables or disables the SDIO interrupts.
name SDIO_ConfigInt.
fun Enables or disables the SDIO interrupts.
param Int specifies the SDIO interrupt sources to be enabled or disabled.
This parameter must be a value or combination of the following values:
- SDIO_INT_CCRCERR
- SDIO_INT_DCRCERR
- SDIO_INT_CMDTIMEOUT
- SDIO_INT_DATTIMEOUT
- SDIO_INT_TXURERR
- SDIO_INT_RXORERR
- SDIO_INT_CMDRESPRECV
- SDIO_INT_CMDSEND
- SDIO_INT_DATEND
- SDIO_INT_SBERR
- SDIO_INT_DATBLKEND
- SDIO_INT_CMDRUN
- SDIO_INT_TXRUN
- SDIO_INT_RXRUN
- SDIO_INT_TFIFOE
- SDIO_INT_TFIFOHE
- SDIO_INT_TFIFOF
- SDIO_INT_TDATVALID
- SDIO_INT_RFIFOE
- SDIO_INT_RFIFOHF
- SDIO_INT_RFIFOF
- SDIO_INT_RDATVALID
- SDIO_INT_SDIOINT
param Cmd new state of the specified SDIO interrupts.Must be one of one of the following values:
- ENABLE
- DISABLE
return none
void SDIO_DMACmd(FunctionalState Cmd)Enables or disables the SDIO DMA request.
name SDIO_DMACmd.
fun Enables or disables the SDIO DMA request.
param Cmd new state of the SDIO DMA request.
This parameter must be one of the following values:
- ENABLE
- DISABLE
return none
void SDIO_SendCmd(SDIO_CmdInitType* CmdInitStruct)Initializes the SDIO Command according to the specified parameters in the CmdInitStruct and send the command.
name SDIO_SendCmd.
fun Initializes the SDIO Command according to the specified
parameters in the CmdInitStruct and send the command.
param CmdInitStruct pointer to a SDIO_CmdInitType structure.
The input parameters must be the following values:
- CmdArgument: Optional SDIO command argument.
- CmdIndex: SDIO command index, must be lower than 0x40.
- ResponseType:
- SDIO_RESP_NO
- SDIO_RESP_SHORT
- SDIO_RESP_LONG
- WaitType:
- SDIO_WAIT_NO
- SDIO_WAIT_INT
- SDIO_WAIT_PEND
- CPSMConfig:
- SDIO_CPSM_DISABLE
- SDIO_CPSM_ENABLE
return none
void SDIO_InitCmdStruct(SDIO_CmdInitType* CmdInitStruct)Fills each CmdInitStruct member with its default value.
name SDIO_InitCmdStruct.
fun Fills each CmdInitStruct member with its default value.
param CmdInitStruct pointer to a SDIO_CmdInitType structure.
return none
uint8_t SDIO_GetCmdResp(void)Returns command index of last command for which response received.
name SDIO_GetCmdResp.
fun Returns command index of last command for which response received.
param none
return Command index of the last command response received
uint32_t SDIO_GetResp(uint32_t SDIO_RESP)Returns response received from the card for the last command.
name SDIO_GetResp.
fun Returns response received from the card for the last command.
param SDIO_RESP Specifies the SDIO response register.
This parameter must be one of the following values:
- SDIO_RESPONSE_1
- SDIO_RESPONSE_2
- SDIO_RESPONSE_3
- SDIO_RESPONSE_4
return The Corresponding response register value.
void SDIO_ConfigData(SDIO_DataInitType* DataInitStruct)Initializes the SDIO data path according to the specified parameters in the DataInitStruct.
name SDIO_ConfigData.
fun Initializes the SDIO data path according to the specified
parameters in the DataInitStruct.
param DataInitStruct pointer to a SDIO_DataInitType structure.
The input parameters must be the following values:
- DatTimeout: data timeout period.
- DatLen: Number of data bytes to be transferred,
must be a value between 0x0 and 0x01FFFFFF
- DatBlkSize:
- SDIO_DATBLK_SIZE_1B
- SDIO_DATBLK_SIZE_2B
- SDIO_DATBLK_SIZE_4B
- SDIO_DATBLK_SIZE_8B
- SDIO_DATBLK_SIZE_16B
- SDIO_DATBLK_SIZE_32B
- SDIO_DATBLK_SIZE_64B
- SDIO_DATBLK_SIZE_128B
- SDIO_DATBLK_SIZE_256B
- SDIO_DATBLK_SIZE_512B
- SDIO_DATBLK_SIZE_1024B
- SDIO_DATBLK_SIZE_2048B
- SDIO_DATBLK_SIZE_4096B
- SDIO_DATBLK_SIZE_8192B
- SDIO_DATBLK_SIZE_16384B
- TransferDirection:
- SDIO_TRANSDIR_TOCARD
- SDIO_TRANSDIR_TOSDIO
- TransferMode:
- SDIO_TRANSMODE_BLOCK
- SDIO_TRANSMODE_STREAM
- DPSMConfig:
- SDIO_DPSM_DISABLE
- SDIO_DPSM_ENABLE
return none
void SDIO_InitDataStruct(SDIO_DataInitType* DataInitStruct)Fills each DataInitStruct member with its default value.
name SDIO_InitDataStruct.
fun Fills each DataInitStruct member with its default value.
param DataInitStruct pointer to a SDIO_DataInitType structure.
return none
uint32_t SDIO_GetDataCountValue(void)Returns number of remaining data bytes to be transferred.
name SDIO_GetDataCountValue.
fun Returns number of remaining data bytes to be transferred.
param none
return Number of remaining data bytes to be transferred.
uint32_t SDIO_ReadData(void)Read one data word from Rx DATFIFO.
name SDIO_ReadData.
fun Read one data word from Rx DATFIFO.
param none
return Data received.
void SDIO_WriteData(uint32_t Data)Write one data word to Tx DATFIFO.
name SDIO_WriteData.
fun Write one data word to Tx DATFIFO.
param Data 32-bit data word to write.
return none
uint32_t SDIO_GetFifoCounter(void)Returns the number of words left to be written to or read from DATFIFO.
name SDIO_GetFifoCounter.
fun Returns the number of words left to be written to or read from DATFIFO.
param none
return Remaining number of words in the FIFO.
void SDIO_EnableReadWait(FunctionalState Cmd)Enable the SD I/O Read Wait operation.
name SDIO_EnableReadWait.
fun Enable the SD I/O Read Wait operation.
param Cmd new state of the read wait operation.
This parameter must be one of the following values:
- ENABLE
- DISABLE
return none
void SDIO_EnableReadWaitMode(uint32_t ReadWaitMode)Sets one of the two options of inserting read wait interval.
name SDIO_EnableSdioReadWaitMode.
fun Sets one of the two options of inserting read wait interval.
param ReadWaitMode SD I/O Read Wait operation mode.
This parameter must be one of the following values:
- SDIO_RDWAIT_MODE_CLK
- SDIO_RDWAIT_MODE_DAT2
return none
void SDIO_StartReadWait(void)Start the SD I/O Read Wait operation when RWAITEN bit is set.
name SDIO_StartReadWait.
fun Start the SD I/O Read Wait operation when RWAITEN bit is set.
param none
return none
void SDIO_StopReadWait(void)Stop the SD I/O Read Wait operation when RWAITEN bit is set.
name SDIO_StopReadWait.
fun Stop the SD I/O Read Wait operation when RWAITEN bit is set.
param none
return none
void SDIO_EnableSdioOperation(FunctionalState Cmd)Enables the SD I/O Mode Operation.
name SDIO_EnableSdioOperation.
fun Enables the SD I/O Mode Operation.
param Cmd new state of the SD I/O Mode Operation.
This parameter must be one of the following values:
- ENABLE
- DISABLE
return none
void SDIO_EnableSendSdioSuspend(FunctionalState Cmd)Enables the SD I/O Mode suspend command sending.
name SDIO_EnableSendSdioSuspend.
fun Enables the SD I/O Mode suspend command sending.
param Cmd new state of the SD I/O Mode suspend command sending.
This parameter must be one of the following values:
- ENABLE
- DISABLE
return none
void SDIO_EnableCommandCompletion(FunctionalState Cmd)Enables the command completion signal.
name SDIO_EnableCommandCompletion.
fun Enables the command completion signal.
param Cmd new state of the command completion signal.
This parameter must be one of the following values:
- ENABLE
- DISABLE
return none
FlagStatus SDIO_GetFlag(uint32_t Flag)Checks whether the specified SDIO flag is set or not.
name SDIO_GetFlag.
fun Checks whether the specified SDIO flag is set or not.
param Flag specifies the flag to check.
This parameter must be one of the following values:
- SDIO_FLAG_CCRCERR
- SDIO_FLAG_DCRCERR
- SDIO_FLAG_CMDTIMEOUT
- SDIO_FLAG_DATTIMEOUT
- SDIO_FLAG_TXURERR
- SDIO_FLAG_RXORERR
- SDIO_FLAG_CMDRESPRECV
- SDIO_FLAG_CMDSEND
- SDIO_FLAG_DATEND
- SDIO_FLAG_SBERR
- SDIO_FLAG_DATBLKEND
- SDIO_FLAG_CMDRUN
- SDIO_FLAG_TXRUN
- SDIO_FLAG_RXRUN
- SDIO_FLAG_TFIFOE
- SDIO_FLAG_TFIFOHE
- SDIO_FLAG_TFIFOF
- SDIO_FLAG_TDATVALID
- SDIO_FLAG_RFIFOE
- SDIO_FLAG_RFIFOHF
- SDIO_FLAG_RFIFOF
- SDIO_FLAG_RDATVALID
- SDIO_FLAG_SDIOINT
return FlagStatus:
- SET
- RESET
void SDIO_ClrFlag(uint32_t FlagClr)Clears the SDIO’s pending flags.
name SDIO_ClrFlag.
fun Clears the SDIO's pending flags.
param FlagClr specifies the flag to clear.
This parameter must be one of the following values:
- SDIO_FLAG_CCRCERR
- SDIO_FLAG_DCRCERR
- SDIO_FLAG_CMDTIMEOUT
- SDIO_FLAG_DATTIMEOUT
- SDIO_FLAG_TXURERR
- SDIO_FLAG_RXORERR
- SDIO_FLAG_CMDRESPRECV
- SDIO_FLAG_CMDSEND
- SDIO_FLAG_DATEND
- SDIO_FLAG_SBERR
- SDIO_FLAG_DATBLKEND
- SDIO_FLAG_SDIOINT
return none
INTStatus SDIO_GetIntStatus(uint32_t Int)Checks whether the specified SDIO interrupt has occurred or not.
name SDIO_GetIntStatus.
fun Checks whether the specified SDIO interrupt has occurred or not.
param Int specifies the SDIO interrupt source to check.
This parameter must be one of the following values:
- SDIO_INT_CCRCERR
- SDIO_INT_DCRCERR
- SDIO_INT_CMDTIMEOUT
- SDIO_INT_DATTIMEOUT
- SDIO_INT_TXURERR
- SDIO_INT_RXORERR
- SDIO_INT_CMDRESPRECV
- SDIO_INT_CMDSEND
- SDIO_INT_DATEND
- SDIO_INT_SBERR
- SDIO_INT_DATBLKEND
- SDIO_INT_CMDRUN
- SDIO_INT_TXRUN
- SDIO_INT_RXRUN
- SDIO_INT_TFIFOE
- SDIO_INT_TFIFOHE
- SDIO_INT_TFIFOF
- SDIO_INT_TDATVALID
- SDIO_INT_RFIFOE
- SDIO_INT_RFIFOHF
- SDIO_INT_RFIFOF
- SDIO_INT_RDATVALID
- SDIO_INT_SDIOINT
return INTStatus:
- SET
- RESET
uint32_t SDIO_CmdShortResponse1(uint8_t Cmd, uint32_t Arg, uint32_t timeout)Send command with argument and check R1 response with timeout.
name SDIO_CmdShortResponse1.
fun Send command with argument and check R1 response with timeout.
param Cmd specifies the command index to be sent.
param Arg specifies the command argument.
param timeout timeout value for response, can not be 0.
return SDIO error state
uint32_t SDIO_CmdShortResponse3(uint8_t Cmd, uint32_t Arg)Send command with argument and check R3 response.
name SDIO_CmdShortResponse3.
fun Send command with argument and check R3 response.
param Cmd specifies the command index to be sent.
param Arg specifies the command argument.
return SDIO error state
uint32_t SDIO_CmdLongResponse2(uint8_t Cmd, uint32_t Arg)Send command with argument and check the R2 response.
name SDIO_CmdLongResponse2.
fun Send command with argument and check the R2 response.
param Cmd specifies the command index to be sent.
param Arg specifies the command argument.
return SDIO error state
uint32_t SDIO_CmdBlockLength(uint32_t BlockSize)Send the Data Block Length command and check the response
name SDIO_CmdBlockLength.
fun Send the Data Block Length command and check the response
param BlockSize specifies the SDIO data block length.
return SDIO error state
uint32_t SDIO_CmdBlockCount(uint32_t BlockCnt)Send the Set Data Block Count command and check the response
name SDIO_CmdBlockCount.
fun Send the Set Data Block Count command and check the response
param BlockCnt specifies the SDIO block count.
return SDIO error state
uint32_t SDIO_CmdReadSingleBlock(uint32_t ReadAdd)Send the Read Single Block command and check the response
name SDIO_CmdReadSingleBlock.
fun Send the Read Single Block command and check the response
param ReadAdd specifies the start address for reading.
return SDIO error state
uint32_t SDIO_CmdReadMultiBlock(uint32_t ReadAdd)Send the Read Multi Block command and check the response
name SDIO_CmdReadMultiBlock.
fun Send the Read Multi Block command and check the response
param ReadAdd specifies the start address for reading.
return SDIO error state
uint32_t SDIO_CmdWriteSingleBlock(uint32_t WriteAdd)Send the Write Single Block command and check the response
name SDIO_CmdWriteSingleBlock.
fun Send the Write Single Block command and check the response
param WriteAdd specifies the start address for writing.
return SDIO error state
uint32_t SDIO_CmdWriteMultiBlock(uint32_t WriteAdd)Send the Write Multi Block command and check the response
name SDIO_CmdWriteMultiBlock.
fun Send the Write Multi Block command and check the response
param WriteAdd specifies the start address for writing.
return SDIO error state
uint32_t SDIO_CmdSDEraseStartAdd(uint32_t StartAdd)Send the Start Address Erase command for SD and check the response
name SDIO_CmdSDEraseStartAdd.
fun Send the Start Address Erase command for SD and check the response
param StartAdd specifies the start address for erasing.
return SDIO error state
uint32_t SDIO_CmdSDEraseEndAdd(uint32_t EndAdd)Send the End Address Erase command for SD and check the response
name SDIO_CmdSDEraseEndAdd.
fun Send the End Address Erase command for SD and check the response
param EndAdd specifies the end address for erasing.
return SDIO error state
uint32_t SDIO_CmdEraseStartAdd(uint32_t StartAdd)Send the Start Address Erase command and check the response
name SDIO_CmdEraseStartAdd.
fun Send the Start Address Erase command and check the response
param StartAdd specifies the start address for erasing.
return SDIO error state
uint32_t SDIO_CmdEraseEndAdd(uint32_t EndAdd)Send the End Address Erase command and check the response
name SDIO_CmdEraseEndAdd.
fun Send the End Address Erase command and check the response
param StartAdd specifies the start address for erasing.
return SDIO error state
uint32_t SDIO_CmdErase(void)Send the Erase command and check the response
name SDIO_CmdErase.
fun Send the Erase command and check the response
param none
return SDIO error state
uint32_t SDIO_CmdLockUnlock(uint32_t Arg)Send the lock/unlock command and check the response
name SDIO_CmdLockUnlock.
fun Send the lock/unlock command and check the response
param none
return SDIO error state
uint32_t SDIO_CmdStopTransfer(void)Send the Stop Transfer command and check the response.
name SDIO_CmdStopTransfer.
fun Send the Stop Transfer command and check the response.
param none
return SDIO error state
uint32_t SDIO_CmdSelDesel(uint16_t RCA)Send the Select Deselect command and check the response.
name SDIO_CmdSelDesel.
fun Send the Select Deselect command and check the response.
param RCA: Address of the card to be selected
return SDIO error state
uint32_t SDIO_CmdGoIdleState(void)Send the Go Idle State command and check the response.
name SDIO_CmdGoIdleState.
fun Send the Go Idle State command and check the response.
param none
return SDIO error state
uint32_t SDIO_CmdOperCond(void)Send the Operating Condition command and check the response.
name SDIO_CmdOperCond.
fun Send the Operating Condition command and check the response.
param none
return SDIO error state
uint32_t SDIO_CmdAppCommand(uint32_t Arg)Send the Application command to verify that that the next command is an application specific com-mand rather than a standard command and check the response.
name SDIO_CmdAppCommand.
fun Send the Application command to verify that that the next command
is an application specific com-mand rather than a standard command
and check the response.
param Arg: Command Argument
return SDIO error state
uint32_t SDIO_CmdAppOperCommand(uint32_t Arg)Send the command asking the accessed card to send its operating condition register (OCR)
name SDIO_CmdAppOperCommand.
fun Send the command asking the accessed card to send its operating
condition register (OCR)
param Arg: Command Argument
return SDIO error state
uint32_t SDIO_CmdBusWidth(uint32_t BusWidth)Send the Bus Width command and check the response.
name SDIO_CmdBusWidth.
fun Send the Bus Width command and check the response.
param BusWidth: Bus width
return SDIO error state
uint32_t SDIO_CmdSendSCR(void)Send the Send SCR command and check the response.
name SDIO_CmdSendSCR.
fun Send the Send SCR command and check the response.
param none
return SDIO error state
uint32_t SDIO_CmdAllSendCID(void)Send the Send all CID command and check the response.
name SDIO_CmdAllSendCID.
fun Send the Send all CID command and check the response.
param none
return SDIO error state
uint32_t SDIO_CmdSendCID(uint16_t RCA)Send the Send CID command and check the response.
name SDIO_CmdSendCID.
fun Send the Send CID command and check the response.
param RCA: Card RCA
return SDIO error state
uint32_t SDIO_CmdSendCSD(uint16_t RCA)Send the Send CSD command and check the response.
name SDIO_CmdSendCSD.
fun Send the Send CSD command and check the response.
param RCA: Card RCA
return SDIO error state
uint32_t SDIO_CmdSetRelAdd(uint16_t *pRCA)Send the Set Relative Address command.
name SDIO_CmdSetRelAdd.
fun Send the Set Relative Address command.
param pRCA: pointer to the Card RCA
return SDIO error state
uint32_t SDIO_CmdSetRelAddMmc(uint16_t RCA)Send the Set Relative Address command to MMC card (not SD card).
name SDIO_CmdSetRelAddMmc.
fun Send the Set Relative Address command to MMC card (not SD card).
param RCA: Card RCA
return SDIO error state
uint32_t SDIO_CmdSendStatus(uint32_t Arg)Send the Status command and check the response.
name SDIO_CmdSendStatus.
fun Send the Status command and check the response.
param Arg: command argument
return SDIO error state
uint32_t SDIO_CmdStatusRegister(void)Send the Status register command and check the response.
name SDIO_CmdStatusRegister.
fun Send the Status register command and check the response.
param none
return SDIO error state
uint32_t SDIO_CmdOpCondition(uint32_t Arg)Sends host capacity support information and activates the card’s initialization process by send SDMMC_CMD_SEND_OP_COND command.
name SDIO_CmdOpCondition.
fun Sends host capacity support information and activates the card's
initialization process by send SDMMC_CMD_SEND_OP_COND command.
param Arg: command argument
return SDIO error state
uint32_t SDIO_CmdSwitch(uint32_t Arg)Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH command
name SDIO_CmdSwitch.
fun Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH command
param Arg: command argument
return SDIO error state
uint32_t SDIO_CmdSendEXTCSD(uint32_t Arg)Send the Send EXT_CSD command and check the response.
name SDIO_CmdSendEXTCSD.
fun Send the Send EXT_CSD command and check the response.
param Arg: command argument
return SDIO error state
uint32_t SDIO_GetCmdResp1(uint8_t Cmd, uint32_t Timeout)Checks for error conditions for R1 response.
name SDIO_GetCmdResp1.
fun Checks for error conditions for R1 response.
param Cmd: The sent command index
param Timeout: timeout value, can not be 0.
return SDIO error state
uint32_t SDIO_GetCmdResp2(void)Checks for error conditions for R2 (CID or CSD) response.
name SDIO_GetCmdResp2.
fun Checks for error conditions for R2 (CID or CSD) response.
param none
return SDIO error state
uint32_t SDIO_GetCmdResp3(void)Checks for error conditions for R3 (OCR) response.
name SDIO_GetCmdResp3.
fun Checks for error conditions for R3 (OCR) response.
param none
return SDIO error state
uint32_t SDIO_GetCmdResp6(uint8_t Cmd, uint16_t *pRCA)Checks for error conditions for R6 (RCA) response.
name SDIO_GetCmdResp6
fun Checks for error conditions for R6 (RCA) response.
param Cmd: The sent command index
param pRCA: Pointer to the variable that will contain the SD card relative address RCA
return SDIO error state
uint32_t SDIO_GetCmdResp7(void)Checks for error conditions for R7 response.
name SDIO_GetCmdResp7
fun Checks for error conditions for R7 response.
param none
return SDIO error state
5.24.3 Demo descriptions
This section covers the only SDIO example, SD_Card, which performs one read, erase, and write test on the on-board TF card through the SDIO host interface and verifies the data.
5.24.3.1 SD_Card SD card read, erase, and write test
Example directory: projects/n32h49x_EVAL/examples/SDIO/SD_Card/
Initialize the SDIO pins and peripheral→Power on and identify the TF card→Switch to the transfer clock and the 4-bit bus→Read the target blocks and print the data→Erase and then write the same data back→Read the blocks again and compare byte by byte→Print the test result
| Item | Source analysis |
|---|---|
| Function | Performs one complete read, erase, and write test on the on-board TF card through the SDIO host interface; after a key press it reads the first 4 data blocks, erases that area, writes new test data, and finally reads the blocks back for a byte-by-byte comparison. |
| Source files | src/main.c: main loop, key and LED handling, card information printing, and buffer comparison;src/sdcard.c and inc/sdcard.h: SDIO port initialization, card power-on and identification, block read/write, erase, and DMA channel configuration;inc/main.h: test address, block count, DMA channel, and LED and key defines;readme.txt: function, environment, and usage;MDK-ARM/ and EWARM/: Keil and IAR projects. |
| Key configuration | SDIO host interface, SDIOCLK is 120 MHz (HCLK/2), the initialization divider is 298 and the transfer divider is 4; CLK is PC12, CMD is PD2, D0 is PB4, D1 is PB0, D2 is PC10, and D3 is PC11, all as alternate-function push-pull; rising clock edge, hardware flow control disabled, 4-bit bus; read and write use DMA1 channel 1, the test start address is 0, the block count is 4, and the block size is 512 bytes; the key is PA0 and the indicator LED is PA3. The system clock is 240 MHz and the print UART is PA9 at 115200 baud. |
| Program and data path | main initializes the log, the LED, and the key and then enters the loop;after the key is pressed and released it calls SD_Init to initialize the card and then SD_ShowCardInfo to print the card information;it calls SD_ReadBlocks, SD_Erase, and SD_WriteBlocks in turn to read, erase, and write, and then reads back for comparison;after every step it waits for SD_GetCardState to return to the transfer state. |
| Main APIs | SD_Init, SD_GetCardState, SD_ReadBlocks, SD_WriteBlocks, SD_Erase, SDIO_DMACmd |
| Verification | Insert a TF card into the slot, build, download, and reset the board; press PA0 once to trigger a round, and the UART prints the demo start message and the card information, then the result of each read, erase, and write step, and finally SD/MMC Card test OK!. |
| Use note | An external TF card slot with an inserted TF card is required before the test; the read, erase, and write operations destroy the first 4 data blocks, so make sure that area holds no useful data; Toolchains are KEIL MDK-ARM 5.34 and IAR EWARM 8.50.1. |
Core-code walkthrough and porting
After a key press the example performs one read, erase, and write round on the TF card through the SDIO host interface: it reads the blocks back, erases the area, writes new test data, and finally reads the blocks back for comparison.
Data path: main → SD_Init configures the SDIO peripheral and powers on and identifies the card → SD_ShowCardInfo prints the card information → SD_ReadBlocks reads the data back with DMA → SD_Erase erases the area → SD_WriteBlocks writes the test data → SD_ReadBlocks reads back again for comparison → SD_GetCardState waits for the card to return to the transfer state
1. Configure the pins and the peripheral. SD_PortInit enables the GPIO clocks of the SDIO pins and sets CLK, CMD, and D0 to D3 as alternate-function push-pull, then SD_Init enables the SDIO clock, resets the registers, and writes the initialization divider into the peripheral.
/* SDIO pin config */
GPIO_InitPara.GPIO_Mode = GPIO_MODE_AF_PP;
GPIO_InitPara.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
GPIO_InitPara.GPIO_Pull = GPIO_NO_PULL;
GPIO_InitPara.GPIO_Current = GPIO_DS_12mA;
/* CLK */
GPIO_InitPara.Pin = SD_CLK_PIN;
GPIO_InitPara.GPIO_Alternate = SD_CLK_AF;
GPIO_InitPeripheral(SD_CLK_PORT, &GPIO_InitPara);
/* CMD */
GPIO_InitPara.Pin = SD_CMD_PIN;
GPIO_InitPara.GPIO_Alternate = SD_CMD_AF;
GPIO_InitPeripheral(SD_CMD_PORT, &GPIO_InitPara);
/* D0 */
GPIO_InitPara.Pin = SD_D0_PIN;
GPIO_InitPara.GPIO_Alternate = SD_D0_AF;
GPIO_InitPeripheral(SD_D0_PORT, &GPIO_InitPara);
/* D1 */
GPIO_InitPara.Pin = SD_D1_PIN;
GPIO_InitPara.GPIO_Alternate = SD_D1_AF;
GPIO_InitPeripheral(SD_D1_PORT, &GPIO_InitPara);
/* D2 */
GPIO_InitPara.Pin = SD_D2_PIN;
GPIO_InitPara.GPIO_Alternate = SD_D2_AF;
GPIO_InitPeripheral(SD_D2_PORT, &GPIO_InitPara);
/* D3 */
GPIO_InitPara.Pin = SD_D3_PIN;
GPIO_InitPara.GPIO_Alternate = SD_D3_AF;
GPIO_InitPeripheral(SD_D3_PORT, &GPIO_InitPara);
/* SDIOCLK = HCLK, SDIO_CLK = HCLK/(2 + ClkDiv) */
/* SDIO_CLK for initialization should not exceed 400 KHz */
SDIO_InitPara.ClkDiv = SD_INIT_CLK_DIV;
SDIO_InitPara.ClkEdge = SDIO_CLK_EDGE_RISING;
SDIO_InitPara.ClkBypass = ClockBypass;
SDIO_InitPara.ClkPwrSave = SDIO_CLK_POWER_SAVE_DISABLE;
SDIO_InitPara.BusWidth = SDIO_BUS_WIDTH_1B;
SDIO_InitPara.HardwareClkCtrl = SDIO_HARDWARE_CLKCTRL_DISABLE;
SDIO_Init(&SDIO_InitPara);
/* Set Power State to ON */
SDIO_SetPower(SDIO_POWER_CTRL_ON);
/* Enable SDIO Clock */
SDIO_EnableClock(ENABLE);
The initialization phase uses a 1-bit bus and a clock of no more than 400 kHz; the transfer clock and the 4-bit bus are switched in only after the card is identified.
2. Power on and identify the card. SD_PowerON sends CMD0, CMD8, and CMD55 with ACMD41 in turn (CMD1 for an MMC card) to finish power-up and voltage matching, then SD_InitCard uses CMD2, CMD3, CMD9, and CMD10 to obtain the card address and the CID and CSD information.
/*Next, send a series of commands to start the card identification process*/
/* CMD0: GO_IDLE_STATE. No CMDCTRL response required */
error = SDIO_CmdGoIdleState();
if (error != SDMMC_ERROR_NONE)
{
/* CMDCTRL Response TimeOut (wait for CMDSEND flag) */
return (error);
}
/* Required power up waiting time before starting the SD initialization sequence */
Delay(SystemCoreClock/1000); /* about 4ms */
/* CMD8: SEND_IF_COND */
/* Send CMD8 to verify SD card interface operating condition */
/* Argument: - [31:12]: Reserved (shall be set to '0')
- [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
- [7:0]: Check Pattern (recommended 0xAA) */
/* CMDCTRL Response: R7 */
error = SDIO_CmdOperCond();
if (error == SDMMC_ERROR_NONE) // If there is a response, card follows SD protocol version 2.0
{
SDCardInfo.CardVersion = CARD_V2_X;
}
else // No response, indicates 1.X or MMC card
{
SDCardInfo.CardVersion = CARD_V1_X;
}
/* Send cmd55 to detect SD card, MMC card, or unsupported card */
/* If errorstatus is Command TimeOut, it is a MMC card */
/* If errorstatus is SDMMC_ERROR_NONE it is a SD card: SD card 2.0 (voltage range mismatch)
or SD card 1.x */
error = SDIO_CmdAppCommand(0U);
if (error == SDMMC_ERROR_NONE) // Responded to cmd55, SD card, may be 1.X, may be 2.0
{
/*Start to send the voltage range supported by SDIO circularly for a certain number of times*/
/* Send ACMD41 SD_APP_OP_COND with Argument */
while ((!validvoltage) && (count < SDMMC_MAX_VOLT_TRIAL))
{
/* Because acmd41 is ACMD command. So cmd55 must send to card first */
/* SEND CMD55 APP_CMD with RCA as 0 */
error = SDIO_CmdAppCommand(0U);
if (error != SDMMC_ERROR_NONE)
{
return (error); // No response to cmd55, return
}
// acmd41,The command parameters consist of the supported voltage range and HCs bits. The HCS position is
// used to distinguish whether the card is SDSC or SDHC
error = SDIO_CmdAppOperCommand(SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY);
if (error != SDMMC_ERROR_NONE)
{
return (error); // Acmd41 not received correctly, error, return
}
/*If the card demand voltage is within the supply voltage range of SDIO, it will automatically power on and
* mark PWR UP bit*/
resp = SDIO_GetResp(SDIO_RESPONSE_1);
validvoltage = (resp & SDMMC_CARD_POWER_UP); // Read the PWR up bit of the card's OCR register to see if it is working at normal voltage
count++; // Calculate number of cycles
}
/* CMD2 */
error = SDIO_CmdAllSendCID();
if (SDMMC_ERROR_NONE != error)
{
return (error);
}
CID_Tab[0] = SDIO_GetResp(SDIO_RESPONSE_1);
CID_Tab[1] = SDIO_GetResp(SDIO_RESPONSE_2);
CID_Tab[2] = SDIO_GetResp(SDIO_RESPONSE_3);
CID_Tab[3] = SDIO_GetResp(SDIO_RESPONSE_4);
CMD8 verifies whether the card supports the 2.0 protocol, and an SD card must receive CMD8 before ACMD41.
3. Switch to the transfer clock and the 4-bit bus. After identification, SD_Init reconfigures the peripheral with the transfer divider, and SD_CofigBusWidth switches both the card and the host to the 4-bit bus through ACMD6.
error = SD_CofigBusWidth(BusWidth);
if (error != SDMMC_ERROR_NONE)
{
/* CMDCTRL Response TimeOut (wait for CMDSEND flag) */
return (error);
}
return (SDMMC_ERROR_NONE);
else if(CARD_SDIO != SDCardInfo.CardType)
{
if (SDIO_BUS_WIDTH_8B == WideMode) // 2.0 SD does not support 8bits
{
return (SDMMC_ERROR_UNSUPPORTED_FEATURE);
}
else if (SDIO_BUS_WIDTH_4B == WideMode) // 4 data line mode
{
error = SD_EnableWideBus(ENABLE); // Use acmd6 to set the bus width and the transmission mode of the card
if (SDMMC_ERROR_NONE != error)
{
return error;
}
SDIO_InitPara.BusWidth = SDIO_BUS_WIDTH_4B;
SDIO_Init(&SDIO_InitPara);
}
else // Single data line mode
{
error = SD_EnableWideBus(DISABLE); // Use acmd6 to set the bus width and the transmission mode of the card
if (SDMMC_ERROR_NONE != error)
{
return error;
}
SDIO_InitPara.BusWidth = SDIO_BUS_WIDTH_1B;
SDIO_Init(&SDIO_InitPara);
}
}
The bus width can only be changed in the transfer state after the card is selected with CMD7; this example switches both ends to 4 bits.
4. Read and write data blocks with DMA. SD_ReadBlocks and SD_WriteBlocks first configure the data path from the block count and send the single-block or multi-block command, then start the DMA channel to move the data, and finally wait for the DMA completion flag and the data-end flag.
/* Config data register */
InitData.DatTimeout = SDMMC_DATATIMEOUT;
InitData.DatLen = NumberOfBlocks * SD_BLOCKSIZE;
InitData.DatBlkSize = SDIO_DATBLK_SIZE_512B;
InitData.TransferDirection = SDIO_TRANSDIR_TOSDIO;
InitData.TransferMode = SDIO_TRANSMODE_BLOCK;
InitData.DPSMConfig = SDIO_DPSM_ENABLE;
SDIO_ConfigData(&InitData);
/* Send command for reading */
if(NumberOfBlocks > 1U)
{
error = SDIO_CmdReadMultiBlock(ReadAddr);
}
else
{
error = SDIO_CmdReadSingleBlock(ReadAddr);
}
if(error != SDMMC_ERROR_NONE)
{
/* Clear all the static flags */
SDIO_ClrFlag(SDIO_STATIC_FLAGS);
return (error);
}
#if defined(SD_DMA_MODE)
SD_DMA_RxConfig((uint32_t*)ReadBuf, ((NumberOfBlocks * SD_BLOCKSIZE)/4));
SDIO_DMACmd(ENABLE);
timeout = Timeout;
while(1)
{
if( (DMA_GetFlagStatus(SDIO_DMA_ENDFLAG,SDIO_DMA) == SET)
&&(SDIO_GetFlag(SDIO_FLAG_DATEND) == SET) )
{
break;
}
if(0U == timeout )
{
break;
}
else
{
timeout--;
}
}
SDIO_DMACmd(DISABLE);
if(0U == timeout )
{
/* Clear all the static flags */
SDIO_ClrFlag(SDIO_STATIC_FLAGS);
return (SDMMC_ERROR_TIMEOUT);
}
#if defined(SD_DMA_MODE)
SD_DMA_TxConfig((uint32_t*)SrcBuf, ((NumberOfBlocks * SD_BLOCKSIZE)/4));
SDIO_DMACmd(ENABLE);
timeout = Timeout;
while(1)
{
if( (DMA_GetFlagStatus(SDIO_DMA_ENDFLAG,SDIO_DMA) == SET)
&&(SDIO_GetFlag(SDIO_FLAG_DATEND) == SET) )
{
break;
}
if(0U == timeout )
{
break;
}
else
{
timeout--;
}
}
SDIO_DMACmd(DISABLE);
if(0U == timeout )
{
/* Clear all the static flags */
SDIO_ClrFlag(SDIO_STATIC_FLAGS);
return (SDMMC_ERROR_TIMEOUT);
}
The data length is written into the data control register as the block count times 512 bytes, and the DMA transfer exits the wait loop on the completion flag.
5. Erase and verify in the main loop. SD_Erase converts the address according to the card type and sends CMD32, CMD33, and CMD38; the main loop queries the card state after every step and then reads the written data back for a byte-by-byte comparison.
if( (SDCardInfo.CardType == CARD_SDHC_SDXC) \
||(SDCardInfo.CardType == CARD_MMC_HC) ) // The address of the high capacity card is block(512bytes) number, not byte address
{
StrAddr /= 512;
EndAddr /= 512;
}
if( (SDCardInfo.CardType == CARD_MMC_HC) \
||(SDCardInfo.CardType == CARD_MMC_LC) )
{
/* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
error = SDIO_CmdEraseStartAdd(StrAddr);
}
else if(SDCardInfo.CardType != CARD_SDIO)
{
/* Send CMD32 SD_ERASE_GRP_START with argument as addr */
error = SDIO_CmdSDEraseStartAdd(StrAddr);
}
else
{
error = SDMMC_ERROR_NONE;
}
if(error != SDMMC_ERROR_NONE)
{
/* Clear all the static flags */
SDIO_ClrFlag(SDIO_STATIC_FLAGS);
return (error);
}
if( (SDCardInfo.CardType == CARD_MMC_HC) \
||(SDCardInfo.CardType == CARD_MMC_LC) )
{
/* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
error = SDIO_CmdEraseEndAdd(EndAddr);
}
else if(SDCardInfo.CardType != CARD_SDIO)
{
/* Send CMD33 SD_ERASE_GRP_END with argument as addr */
error = SDIO_CmdSDEraseEndAdd(EndAddr);
}
else
{
error = SDMMC_ERROR_NONE;
}
if(error != SDMMC_ERROR_NONE)
{
/* Clear all the static flags */
SDIO_ClrFlag(SDIO_STATIC_FLAGS);
return (error);
}
/* Send CMD38 ERASE */
error = SDIO_CmdErase();
if(error != SDMMC_ERROR_NONE)
{
/* Clear all the static flags */
SDIO_ClrFlag(SDIO_STATIC_FLAGS);
return (error);
}
/* Initialize the SDIO interface and SD card */
error = SD_Init(SDIO_CLK_BYPASS_DISABLE, SD_TRANSFER_CLK_DIV, SDIO_BUS_WIDTH_4B);
if(error != SDMMC_ERROR_NONE)
{
log_debug("SD/MMC Card initialization failed,error=%d!\r\n",error);
while(1);
}
else
{
log_debug("SD/MMC Card initialization success!\r\n");
}
/* Forth step: Check write result by read and compare */
Memset(RxBuf,0x55U,TEST_BUF_LEN);
error = SD_ReadBlocks(RxBuf,TEST_CARD_ADDR,TEST_BLOCK_NUM,SDMMC_DATATIMEOUT);
if(error != SDMMC_ERROR_NONE)
{
log_debug("SD/MMC Card read after write failed,error=%d!\r\n",error);
while(1);
}
/* Check card state */
while(SD_GetCardState() != SDMMC_CARD_TRANSFER);
/* Check write result */
for(i=0;i<TEST_BUF_LEN;i++)
{
if(RxBuf[i] != TxBuf[i])
break;
}
if(i<TEST_BUF_LEN)
{
log_debug("SD/MMC Card write check fail,i=%d,data=0x%02x!\r\n",i,RxBuf[i]);
while(1);
}
else
{
log_debug("SD/MMC Card write success!\r\n");
}
Every step waits until the card returns to the transfer state, and a pass is printed only when the data read back matches the write buffer exactly.
Corresponding source files: src/main.c, src/sdcard.c
5.24.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| Number of cards | SDIO supports only one SD/SDIO/MMC 4.2 card at a time; multiple MMC 4.1 and earlier cards may be connected. |
User manual |
| Data bus width | Only SDIO_DAT0 carries data after power-up or reset by default; MMC V3.31 and earlier support a 1-bit data line only, so the 4-bit or 8-bit bus must be configured by the host after initialization. |
User manual |
| Command state machine idle timing | The command state machine stays in the idle state for at least 8 SDIO_CLK cycles to satisfy the NCC and NRC timing limits. | User manual |
| Command timeout | The command timeout is fixed at 64 SDIO_CLK cycles and cannot be configured. | User manual |
| Data path wait-for-send timing | The data path stays in the wait-for-send state for at least 2 clock cycles to meet the NWR timing, the interval between the card response and the start of the host data transfer. | User manual |
| SD card initialization order | When an SD card is initialized, CMD8 must be sent before ACMD41; during card identification the card must work at the FOD clock frequency of 400 kHz. |
User manual |
| Bus width switching time | The ACMD6 command that sets the bus width is valid only in the transfer state, so the card must be selected with CMD7 before the bus width is changed. | User manual |