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

Search API66 functions

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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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)
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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).
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.
Source comment
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.

src/sdcard.csrc/sdcard.c · SD_PortInit
    /* 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);
src/sdcard.csrc/sdcard.c · SD_Init
    /* 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.

src/sdcard.csrc/sdcard.c · SD_PowerON
    /*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;
    }
src/sdcard.csrc/sdcard.c · SD_PowerON
    /* 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
        }
src/sdcard.csrc/sdcard.c · SD_InitCard
        /* 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.

src/sdcard.csrc/sdcard.c · SD_Init
    error = SD_CofigBusWidth(BusWidth);
    if (error != SDMMC_ERROR_NONE)
    {
        /* CMDCTRL Response TimeOut (wait for CMDSEND flag) */
        return (error);
    }

    return (SDMMC_ERROR_NONE);
src/sdcard.csrc/sdcard.c · SD_CofigBusWidth
    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.

src/sdcard.csrc/sdcard.c · SD_ReadBlocks
    /* 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);
    }
src/sdcard.csrc/sdcard.c · SD_ReadBlocks
#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);
    }
src/sdcard.csrc/sdcard.c · SD_WriteBlocks
#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.

src/sdcard.csrc/sdcard.c · SD_Erase
    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);
    }
src/main.csrc/main.c · main
        /* 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");
        }
src/main.csrc/main.c · main
        /* 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
Nations Technologies DevKit Docs

Datasheets, SDK, driver APIs and demo guides for Nations Technologies MCU development kits, organized by chip series.

© 2026 Nations Technologies Inc. All rights reserved.粤ICP备11069485号This site uses cookie-free anonymous analytics.