FSDev_SD_Card_BSP_CmdWaitEnd()
void FSDev_SD_Card_BSP_CmdWaitEnd (FS_QTY unit_nbr,
FS_DEV_SD_CARD_CMD *p_cmd,
CPU_INT32U *p_resp,
FS_DEV_SD_CARD_ERR *p_err);
File |
Called from |
Code enabled by |
fs_dev_sd_card_bsp.c |
SD/MMC cardmode driver |
N/A |
Wait for command to end and get command response.
Arguments
unit_nbr
Unit number of SD/MMC card.
p_cmd
Pointer to command that is ending.
p_resp
Pointer to buffer that will receive command response, if any.
p_err
Pointer to variable that will receive the return error code from this function:
Returned Value
None.
Notes/Warnings
- This function will be called even if no response is expected from the command.
- This function will not be called if FSDev_SD_Card_BSP_CmdStart() returned an error.
- The data stored in the response buffer should include only the response data, i.e., should not include the start bit, transmission bit, command index, CRC and end bit.
For a command with a normal (48-bit) response, a 4-byte response should be stored in p_resp.
For a command with a long (136-bit) response, a 16-byte response should be returned in p_resp:
The first 4-byte word should hold bits 127..96 of the response.
The second 4-byte word should hold bits 95..64 of the response.
The third 4-byte word should hold bits 63..32 of the response.
The four 4-byte word should hold bits 31.. 0 of the response.
Example
The implementation of FSDev_SD_Card_BSP_CmdWaitEnd() in is targeted for the same host controller as the other listings in this chapter; for more information, see FSDev_SD_Card_BSP_CmdStart().
void FSDev_SD_Card_BSP_CmdWaitEnd (FS_QTY unit_nbr, FS_DEV_SD_CARD_CMD *p_cmd, CPU_INT32U *p_resp, FS_DEV_SD_CARD_ERR *p_err) { CPU_INT16U interrupt_status; CPU_INT16U error_status; CPU_INT16U timeout; timeout = 0u; /* Wait until cmd exec complete.*/ (1) interrupt_status = REG_INTERRUPT_STATUS; while (DEF_BIT_IS_CLR(interrupt_status, BIT_INTERRUPT_STATUS_ERROR | BIT_INTERRUPT_STATUS_COMMAND_COMPLETE) == DEF_YES)) { timeout++; interrupt_status = REG_INTERRUPT_STATUS; if (timeout == TIMEOUT_RESP_MAX) { *p_err = FS_DEV_SD_CARD_ERR_WAIT_TIMEOUT; return; } } /* Handle error. */ (2) if (DEF_BIT_IS_SET(interrupt_status, BIT_INTERRUPT_STATUS_ERROR) == DEF_YES) { error_status = REG_ERROR_STATUS; if (DEF_BIT_IS_SET(error_status, REG_ERROR_STATUS_COMMAND_INDEX) == DEF_YES) { *p_err = FS_DEV_SD_CARD_ERR_RESP_CMD_IX; } else if (DEF_BIT_IS_SET(error_status, REG_ERROR_STATUS_COMMAND_END_BIT) == DEF_YES) { *p_err = FS_DEV_SD_CARD_ERR_RESP_END_BIT; } else if (DEF_BIT_IS_SET(error_status, REG_ERROR_STATUS_COMMAND_CRC) == DEF_YES) { *p_err = FS_DEV_SD_CARD_ERR_RESP_CRC; } else if (DEF_BIT_IS_SET(error_status, REG_ERROR_STATUS_COMMAND_TIMEOUT) == DEF_YES) { *p_err = FS_DEV_SD_CARD_ERR_RESP_TIMEOUT; } else { *p_err = FS_DEV_SD_CARD_ERR_RESP; } REG_ERROR_STATUS = error_status; REG_INTERRUPT_STATUS = interrupt_status; return; } |
/* Read response. */ (3) REG_INTERRUPT_STATUS = BIT_INTERRUPT_STATUS_COMMAND_COMPLETE; if (DEF_BIT_IS_SET(p_cmd->Flags, FS_DEV_SD_CARD_CMD_FLAG_RESP) == DEF_YES) { if (DEF_BIT_IS_SET(p_cmd->Flags, FS_DEV_SD_CARD_CMD_FLAG_RESP_LONG) == DEF_YES) { *(p_resp + 3) = REG_RESPONSE_00 *(p_resp + 2) = REG_RESPONSE_01 *(p_resp + 1) = REG_RESPONSE_02 *(p_resp + 0) = REG_RESPONSE_03 } else { *(p_resp + 0) = REG_RESPONSE_00 } }
*p_err = FS_DEV_SD_CARD_ERR_NONE; } |
-
- FSDev_SD_Card_BSP_CmdWaitEnd()
- Wait until command execution completes or an error occurs. The wait loop (or wait on semaphore) should always have a timeout to avoid blocking the task in the case of an unforeseen hardware malfunction or a software flaw.
- Check if an error occurred. The error status register is decoded to produce the actual error condition. That is not necessary, strictly, but error counters that accumulate within the generic driver based upon returned error values may be useful while debugging a port.
- Read the response, if any. Note that the order in which a long response is stored in the buffer may oppose its storage in the controller’s register or FIFO.
- FSDev_SD_Card_BSP_CmdWaitEnd()