feat(sdmmc): supported UHS-I SDR50 (100Mhz) and DDR50 mode

This commit is contained in:
Armando
2024-11-06 12:09:25 +08:00
parent 31dc34a909
commit 04cd469e4a
26 changed files with 650 additions and 131 deletions

View File

@@ -42,7 +42,11 @@ esp_err_t sdmmc_init_ocr(sdmmc_card_t* card)
acmd41_arg |= SD_OCR_SDHC_CAP;
}
if ((card->host.flags & SDMMC_HOST_FLAG_UHS1) != 0) {
bool to_set_to_uhs1 = false;
if (card->host.is_slot_set_to_uhs1) {
ESP_RETURN_ON_ERROR(card->host.is_slot_set_to_uhs1(card->host.slot, &to_set_to_uhs1), TAG, "failed to get slot info");
}
if (to_set_to_uhs1) {
acmd41_arg |= SD_OCR_S18_RA;
acmd41_arg |= SD_OCR_XPC;
}
@@ -188,6 +192,21 @@ esp_err_t sdmmc_init_card_hs_mode(sdmmc_card_t* card)
return ESP_OK;
}
esp_err_t sdmmc_init_sd_driver_strength(sdmmc_card_t *card)
{
return sdmmc_select_driver_strength(card, card->host.driver_strength);
}
esp_err_t sdmmc_init_sd_current_limit(sdmmc_card_t *card)
{
return sdmmc_select_current_limit(card, card->host.current_limit);
}
esp_err_t sdmmc_init_sd_timing_tuning(sdmmc_card_t *card)
{
return sdmmc_do_timing_tuning(card);
}
esp_err_t sdmmc_init_host_bus_width(sdmmc_card_t* card)
{
int bus_width = 1;
@@ -215,6 +234,14 @@ esp_err_t sdmmc_init_host_frequency(sdmmc_card_t* card)
esp_err_t err;
assert(card->max_freq_khz <= card->host.max_freq_khz);
#if !SOC_SDMMC_UHS_I_SUPPORTED
ESP_RETURN_ON_FALSE(card->host.input_delay_phase != SDMMC_DELAY_PHASE_AUTO, ESP_ERR_INVALID_ARG, TAG, "auto tuning not supported");
#endif
if (card->host.input_delay_phase == SDMMC_DELAY_PHASE_AUTO) {
ESP_RETURN_ON_FALSE((card->host.max_freq_khz == SDMMC_FREQ_SDR50 || card->host.max_freq_khz == SDMMC_FREQ_SDR104), ESP_ERR_INVALID_ARG, TAG, "auto tuning only supported for SDR50 / SDR104");
}
if (card->max_freq_khz > SDMMC_FREQ_PROBING) {
err = (*card->host.set_card_clk)(card->host.slot, card->max_freq_khz);
if (err != ESP_OK) {
@@ -346,6 +373,19 @@ esp_err_t sdmmc_fix_host_flags(sdmmc_card_t* card)
card->host.flags |= width_4bit;
}
}
#if !SOC_SDMMC_UHS_I_SUPPORTED
if ((card->host.max_freq_khz == SDMMC_FREQ_SDR50) ||
(card->host.max_freq_khz == SDMMC_FREQ_DDR50) ||
(card->host.max_freq_khz == SDMMC_FREQ_SDR104)) {
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "UHS-I is not supported");
}
#else
if (card->host.max_freq_khz == SDMMC_FREQ_DDR50) {
ESP_RETURN_ON_FALSE(((card->host.flags & SDMMC_HOST_FLAG_DDR) != 0), ESP_ERR_INVALID_ARG, TAG, "DDR is not selected");
}
#endif
return ESP_OK;
}