/** * @brief Sends an SDIO command with a long response expected and CRC. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] cmd card command * @param[in] arg command argument * @param[out] resp pointer to the response buffer (four words) * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. * @retval HAL_FAILED operation failed. * * @notapi */ bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp) { uint32_t sta; (void)sdcp; sdcp->sdmmc->ARG = arg; sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_WAITRESP_1 | SDMMC_CMD_CPSMEN; while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) == 0) ; sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL); if ((sta & (SDMMC_STA_ERROR_MASK)) != 0) { sdc_lld_collect_errors(sdcp, sta); return HAL_FAILED; } /* Save bytes in reverse order because MSB in response comes first.*/ *resp++ = sdcp->sdmmc->RESP4; *resp++ = sdcp->sdmmc->RESP3; *resp++ = sdcp->sdmmc->RESP2; *resp = sdcp->sdmmc->RESP1; return HAL_SUCCESS; }
/** * @brief Performs clean transaction stopping in case of errors. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] n number of blocks in transaction * @param[in] resp pointer to the response buffer * * @notapi */ static void sdc_lld_error_cleanup(SDCDriver *sdcp, uint32_t n, uint32_t *resp) { dmaStreamClearInterrupt(sdcp->dma); dmaStreamDisable(sdcp->dma); SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; SDIO->MASK = 0; SDIO->DCTRL = 0; sdc_lld_collect_errors(sdcp); if (n > 1) sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); }
/** * @brief Performs clean transaction stopping in case of errors. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] n number of blocks in transaction * @param[in] resp pointer to the response buffer * * @notapi */ static void sdc_lld_error_cleanup(SDCDriver *sdcp, uint32_t n, uint32_t *resp) { uint32_t sta = sdcp->sdmmc->STA; dmaStreamDisable(sdcp->dma); sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; sdcp->sdmmc->MASK = 0; sdcp->sdmmc->DCTRL = 0; sdc_lld_collect_errors(sdcp, sta); if (n > 1) sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); }
/** * @brief Sends an SDIO command with a short response expected and CRC. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] cmd card command * @param[in] arg command argument * @param[out] resp pointer to the response buffer (one word) * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. * @retval HAL_FAILED operation failed. * * @notapi */ bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp) { uint32_t sta; sdcp->sdmmc->ARG = arg; sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN; while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) == 0) ; sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL); if ((sta & (SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) != 0) { sdc_lld_collect_errors(sdcp, sta); return HAL_FAILED; } *resp = sdcp->sdmmc->RESP1; return HAL_SUCCESS; }
*/ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp) { uint32_t sta; (void)sdcp; SDIO->ARG = arg; SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN; while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) == 0) ; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) { sdc_lld_collect_errors(sdcp); return CH_FAILED; } *resp = SDIO->RESP1; return CH_SUCCESS;
*/ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp) { uint32_t sta; (void)sdcp; SDIO->ARG = arg; SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 | SDIO_CMD_CPSMEN; while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) == 0) ; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; if ((sta & (STM32_SDIO_STA_ERROR_MASK)) != 0) { sdc_lld_collect_errors(sdcp); return CH_FAILED; } /* Save bytes in reverse order because MSB in response comes first.*/ *resp++ = SDIO->RESP4; *resp++ = SDIO->RESP3; *resp++ = SDIO->RESP2; *resp = SDIO->RESP1; return CH_SUCCESS;