/** * @brief Prepares card to handle read transaction. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] startblk first block to read * @param[in] n number of blocks to read * @param[in] resp pointer to the response buffer * * @return The operation status. * @retval CH_SUCCESS operation succeeded. * @retval CH_FAILED operation failed. * * @notapi */ static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk, uint32_t n, uint32_t *resp) { /* Driver handles data in 512 bytes blocks (just like HC cards). But if we have not HC card than we must convert address from blocks to bytes.*/ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) startblk *= MMCSD_BLOCK_SIZE; if (n > 1) { /* Send read multiple blocks command to card.*/ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, startblk, resp) || MMCSD_R1_ERROR(resp[0])) return CH_FAILED; } else{ /* Send read single block command.*/ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK, startblk, resp) || MMCSD_R1_ERROR(resp[0])) return CH_FAILED; } return CH_SUCCESS; }
/** * @brief Reads special registers using data bus. * @details Needs only during card detection procedure. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[out] buf pointer to the read buffer * @param[in] bytes number of bytes to read * @param[in] cmd card command * @param[in] arg argument for command * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. * @retval HAL_FAILED operation failed. * * @notapi */ bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes, uint8_t cmd, uint32_t arg) { uint32_t resp[1]; if(sdc_lld_prepare_read_bytes(sdcp, buf, bytes)) goto error; if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp) || MMCSD_R1_ERROR(resp[0])) goto error; if (sdc_lld_wait_transaction_end(sdcp, 1, resp)) goto error; return HAL_SUCCESS; error: sdc_lld_error_cleanup(sdcp, 1, resp); return HAL_FAILED; }