mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(sdmmc): add high speed mode switch validation check for SDIO
This commit is contained in:
parent
9ac85e1d7b
commit
1af74c8a4a
@ -124,6 +124,8 @@ esp_err_t sdmmc_init_mmc_decode_cid(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_ocr(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_spi_crc(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_io(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_io_init_read_card_cap(sdmmc_card_t* card, uint8_t* card_cap);
|
||||
esp_err_t sdmmc_io_init_check_card_cap(sdmmc_card_t* card, uint8_t* card_cap);
|
||||
esp_err_t sdmmc_init_sd_blocklen(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_sd_scr(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_sd_ssr(sdmmc_card_t* card);
|
||||
|
@ -32,6 +32,16 @@ static const char* TAG = "sdmmc_init";
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
#define SDMMC_INIT_STEP_PARAM(condition, function, param) \
|
||||
do { \
|
||||
if ((condition)) { \
|
||||
esp_err_t err = (function)(card, param); \
|
||||
if (err != ESP_OK) { \
|
||||
ESP_LOGD(TAG, "%s: %s returned 0x%x", __func__, #function, err); \
|
||||
return err; \
|
||||
} \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
{
|
||||
@ -115,6 +125,10 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
/* MMC cards: read CXD */
|
||||
SDMMC_INIT_STEP(is_mmc, sdmmc_init_mmc_read_ext_csd);
|
||||
|
||||
/* SDIO cards: read CCCR card capabilities */
|
||||
uint8_t card_cap = 0;
|
||||
SDMMC_INIT_STEP_PARAM(is_sdio, sdmmc_io_init_read_card_cap, &card_cap);
|
||||
|
||||
/* Try to switch card to HS mode if the card supports it.
|
||||
* Set card->max_freq_khz value accordingly.
|
||||
*/
|
||||
@ -138,7 +152,8 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
SDMMC_INIT_STEP(is_sdmem, sdmmc_check_scr);
|
||||
/* Sanity check after eMMC switch to HS mode */
|
||||
SDMMC_INIT_STEP(is_mmc, sdmmc_init_mmc_check_ext_csd);
|
||||
/* TODO: add similar checks for SDIO */
|
||||
/* Sanity check for SDIO after switching the frequency */
|
||||
SDMMC_INIT_STEP_PARAM(is_sdio, sdmmc_io_init_check_card_cap, &card_cap);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -120,6 +120,48 @@ esp_err_t sdmmc_init_io(sdmmc_card_t* card)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t sdmmc_io_init_read_card_cap(sdmmc_card_t* card, uint8_t *card_cap)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
err = sdmmc_io_rw_direct(card, 0, SD_IO_CCCR_CARD_CAP,
|
||||
SD_ARG_CMD52_READ, card_cap);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (read SD_IO_CCCR_CARD_CAP) returned 0x%0x", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t sdmmc_io_init_check_card_cap(sdmmc_card_t* card, uint8_t *card_cap)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
/*
|
||||
* Integrity check required if card is switched to HS mode
|
||||
* For frequency less than SDMMC_FREQ_HIGHSPEED, see sdmmc_io_enable_hs_mode()
|
||||
*/
|
||||
if (card->max_freq_khz < SDMMC_FREQ_HIGHSPEED) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* If frequency switch has been performed, read card capabilities from CCCR to confirm
|
||||
* that data can be read correctly at the new frequency.
|
||||
*/
|
||||
uint8_t temp_card_cap = 0;
|
||||
err = sdmmc_io_rw_direct(card, 0, SD_IO_CCCR_CARD_CAP,
|
||||
SD_ARG_CMD52_READ, &temp_card_cap);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (read SD_IO_CCCR_CARD_CAP) returned 0x%0x", __func__, err);
|
||||
return err;
|
||||
}
|
||||
if (*card_cap != temp_card_cap) {
|
||||
ESP_LOGE(TAG, "%s: got corrupted data after increasing clock frequency", __func__);
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t sdmmc_init_io_bus_width(sdmmc_card_t* card)
|
||||
{
|
||||
esp_err_t err;
|
||||
|
Loading…
Reference in New Issue
Block a user