mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 18:57:19 +02:00
change(sdmmc): make sdmmc_host_clock_update_command compatible with CMD11
This commit is contained in:
@ -176,7 +176,7 @@ static void sdmmc_host_set_clk_div(int div)
|
|||||||
esp_rom_delay_us(10);
|
esp_rom_delay_us(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t sdmmc_host_clock_update_command(int slot)
|
static esp_err_t sdmmc_host_clock_update_command(int slot, bool is_cmd11)
|
||||||
{
|
{
|
||||||
// Clock update command (not a real command; just updates CIU registers)
|
// Clock update command (not a real command; just updates CIU registers)
|
||||||
sdmmc_hw_cmd_t cmd_val = {
|
sdmmc_hw_cmd_t cmd_val = {
|
||||||
@ -184,38 +184,10 @@ static esp_err_t sdmmc_host_clock_update_command(int slot)
|
|||||||
.update_clk_reg = 1,
|
.update_clk_reg = 1,
|
||||||
.wait_complete = 1
|
.wait_complete = 1
|
||||||
};
|
};
|
||||||
bool repeat = true;
|
if (is_cmd11) {
|
||||||
while (repeat) {
|
cmd_val.volt_switch = 1;
|
||||||
|
|
||||||
ESP_RETURN_ON_ERROR(sdmmc_host_start_command(slot, cmd_val, 0), TAG, "sdmmc_host_start_command returned 0x%x", err_rc_);
|
|
||||||
|
|
||||||
int64_t yield_delay_us = 100 * 1000; // initially 100ms
|
|
||||||
int64_t t0 = esp_timer_get_time();
|
|
||||||
int64_t t1 = 0;
|
|
||||||
while (true) {
|
|
||||||
t1 = esp_timer_get_time();
|
|
||||||
if (t1 - t0 > SDMMC_HOST_CLOCK_UPDATE_CMD_TIMEOUT_US) {
|
|
||||||
return ESP_ERR_TIMEOUT;
|
|
||||||
}
|
|
||||||
// Sending clock update command to the CIU can generate HLE error.
|
|
||||||
// According to the manual, this is okay and we must retry the command.
|
|
||||||
if (sdmmc_ll_get_interrupt_raw(s_host_ctx.hal.dev) & SDMMC_LL_EVENT_HLE) {
|
|
||||||
sdmmc_ll_clear_interrupt(s_host_ctx.hal.dev, SDMMC_LL_EVENT_HLE);
|
|
||||||
repeat = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// When the command is accepted by CIU, start_command bit will be
|
|
||||||
// cleared in SDMMC.cmd register.
|
|
||||||
if (sdmmc_ll_is_command_taken(s_host_ctx.hal.dev)) {
|
|
||||||
repeat = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (t1 - t0 > yield_delay_us) {
|
|
||||||
yield_delay_us *= 2;
|
|
||||||
vTaskDelay(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ESP_RETURN_ON_ERROR(sdmmc_host_start_command(slot, cmd_val, 0), TAG, "sdmmc_host_start_command returned 0x%x", err_rc_);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -282,7 +254,7 @@ esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz)
|
|||||||
|
|
||||||
// Disable clock first
|
// Disable clock first
|
||||||
sdmmc_ll_enable_card_clock(s_host_ctx.hal.dev, slot, false);
|
sdmmc_ll_enable_card_clock(s_host_ctx.hal.dev, slot, false);
|
||||||
esp_err_t err = sdmmc_host_clock_update_command(slot);
|
esp_err_t err = sdmmc_host_clock_update_command(slot, false);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "disabling clk failed");
|
ESP_LOGE(TAG, "disabling clk failed");
|
||||||
ESP_LOGE(TAG, "%s: sdmmc_host_clock_update_command returned 0x%x", __func__, err);
|
ESP_LOGE(TAG, "%s: sdmmc_host_clock_update_command returned 0x%x", __func__, err);
|
||||||
@ -299,7 +271,7 @@ esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz)
|
|||||||
// Program card clock settings, send them to the CIU
|
// Program card clock settings, send them to the CIU
|
||||||
sdmmc_ll_set_card_clock_div(s_host_ctx.hal.dev, slot, card_div);
|
sdmmc_ll_set_card_clock_div(s_host_ctx.hal.dev, slot, card_div);
|
||||||
sdmmc_host_set_clk_div(host_div);
|
sdmmc_host_set_clk_div(host_div);
|
||||||
err = sdmmc_host_clock_update_command(slot);
|
err = sdmmc_host_clock_update_command(slot, false);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "setting clk div failed");
|
ESP_LOGE(TAG, "setting clk div failed");
|
||||||
ESP_LOGE(TAG, "%s: sdmmc_host_clock_update_command returned 0x%x", __func__, err);
|
ESP_LOGE(TAG, "%s: sdmmc_host_clock_update_command returned 0x%x", __func__, err);
|
||||||
@ -309,7 +281,7 @@ esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz)
|
|||||||
// Re-enable clocks
|
// Re-enable clocks
|
||||||
sdmmc_ll_enable_card_clock(s_host_ctx.hal.dev, slot, true);
|
sdmmc_ll_enable_card_clock(s_host_ctx.hal.dev, slot, true);
|
||||||
sdmmc_ll_enable_card_clock_low_power(s_host_ctx.hal.dev, slot, true);
|
sdmmc_ll_enable_card_clock_low_power(s_host_ctx.hal.dev, slot, true);
|
||||||
err = sdmmc_host_clock_update_command(slot);
|
err = sdmmc_host_clock_update_command(slot, false);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "re-enabling clk failed");
|
ESP_LOGE(TAG, "re-enabling clk failed");
|
||||||
ESP_LOGE(TAG, "%s: sdmmc_host_clock_update_command returned 0x%x", __func__, err);
|
ESP_LOGE(TAG, "%s: sdmmc_host_clock_update_command returned 0x%x", __func__, err);
|
||||||
@ -425,7 +397,25 @@ esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg)
|
|||||||
int64_t yield_delay_us = 100 * 1000; // initially 100ms
|
int64_t yield_delay_us = 100 * 1000; // initially 100ms
|
||||||
int64_t t0 = esp_timer_get_time();
|
int64_t t0 = esp_timer_get_time();
|
||||||
int64_t t1 = 0;
|
int64_t t1 = 0;
|
||||||
while (!sdmmc_ll_is_command_taken(s_host_ctx.hal.dev)) {
|
bool skip_wait = (cmd.volt_switch && cmd.update_clk_reg);
|
||||||
|
if (!skip_wait) {
|
||||||
|
while (!(sdmmc_ll_is_command_taken(s_host_ctx.hal.dev))) {
|
||||||
|
t1 = esp_timer_get_time();
|
||||||
|
if (t1 - t0 > SDMMC_HOST_START_CMD_TIMEOUT_US) {
|
||||||
|
return ESP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
if (t1 - t0 > yield_delay_us) {
|
||||||
|
yield_delay_us *= 2;
|
||||||
|
vTaskDelay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sdmmc_ll_set_command_arg(s_host_ctx.hal.dev, arg);
|
||||||
|
cmd.card_num = slot;
|
||||||
|
cmd.start_command = 1;
|
||||||
|
sdmmc_ll_set_command(s_host_ctx.hal.dev, cmd);
|
||||||
|
|
||||||
|
while (!(sdmmc_ll_is_command_taken(s_host_ctx.hal.dev))) {
|
||||||
t1 = esp_timer_get_time();
|
t1 = esp_timer_get_time();
|
||||||
if (t1 - t0 > SDMMC_HOST_START_CMD_TIMEOUT_US) {
|
if (t1 - t0 > SDMMC_HOST_START_CMD_TIMEOUT_US) {
|
||||||
return ESP_ERR_TIMEOUT;
|
return ESP_ERR_TIMEOUT;
|
||||||
@ -435,10 +425,6 @@ esp_err_t sdmmc_host_start_command(int slot, sdmmc_hw_cmd_t cmd, uint32_t arg)
|
|||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdmmc_ll_set_command_arg(s_host_ctx.hal.dev, arg);
|
|
||||||
cmd.card_num = slot;
|
|
||||||
cmd.start_command = 1;
|
|
||||||
sdmmc_ll_set_command(s_host_ctx.hal.dev, cmd);
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,10 +926,19 @@ esp_err_t sdmmc_host_set_cclk_always_on(int slot, bool cclk_always_on)
|
|||||||
} else {
|
} else {
|
||||||
sdmmc_ll_enable_card_clock_low_power(s_host_ctx.hal.dev, slot, true);
|
sdmmc_ll_enable_card_clock_low_power(s_host_ctx.hal.dev, slot, true);
|
||||||
}
|
}
|
||||||
sdmmc_host_clock_update_command(slot);
|
sdmmc_host_clock_update_command(slot, false);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sdmmc_host_enable_clk_cmd11(int slot, bool enable)
|
||||||
|
{
|
||||||
|
sdmmc_ll_enable_card_clock(s_host_ctx.hal.dev, slot, enable);
|
||||||
|
sdmmc_host_clock_update_command(slot, true);
|
||||||
|
if (enable) {
|
||||||
|
sdmmc_ll_enable_18v_mode(s_host_ctx.hal.dev, slot, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sdmmc_host_dma_stop(void)
|
void sdmmc_host_dma_stop(void)
|
||||||
{
|
{
|
||||||
sdmmc_ll_stop_dma(s_host_ctx.hal.dev);
|
sdmmc_ll_stop_dma(s_host_ctx.hal.dev);
|
||||||
|
@ -36,6 +36,8 @@ void sdmmc_host_dma_resume(void);
|
|||||||
|
|
||||||
bool sdmmc_host_card_busy(void);
|
bool sdmmc_host_card_busy(void);
|
||||||
|
|
||||||
|
void sdmmc_host_enable_clk_cmd11(int slot, bool enable);
|
||||||
|
|
||||||
esp_err_t sdmmc_host_transaction_handler_init(void);
|
esp_err_t sdmmc_host_transaction_handler_init(void);
|
||||||
|
|
||||||
void sdmmc_host_transaction_handler_deinit(void);
|
void sdmmc_host_transaction_handler_deinit(void);
|
||||||
|
Reference in New Issue
Block a user