diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 43119962eb..7ace5eb7b5 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -487,6 +487,7 @@ pytest_examples_esp32h2_adc: needs: - build_pytest_examples_esp32h2 tags: [ esp32h2, adc ] + example_test_pytest_esp32s3_emmc: extends: - .pytest_examples_dir_template diff --git a/components/driver/sdmmc/sdmmc_host.c b/components/driver/sdmmc/sdmmc_host.c index e9c1e2065f..97b015c7cc 100644 --- a/components/driver/sdmmc/sdmmc_host.c +++ b/components/driver/sdmmc/sdmmc_host.c @@ -107,9 +107,31 @@ void sdmmc_host_reset(void) static void sdmmc_host_set_clk_div(int div) { - // Set frequency to 160MHz / div - // div = l + 1 - // duty cycle = (h + 1)/(l + 1) (should be = 1/2) + /** + * Set frequency to 160MHz / div + * + * n: counter resets at div_factor_n. + * l: negedge when counter equals div_factor_l. + * h: posedge when counter equals div_factor_h. + * + * We set the duty cycle to 1/2 + */ +#if CONFIG_IDF_TARGET_ESP32 + assert (div > 1 && div <= 16); + int h = div - 1; + int l = div / 2 - 1; + + SDMMC.clock.div_factor_h = h; + SDMMC.clock.div_factor_l = l; + SDMMC.clock.div_factor_n = h; + + // Set phases for in/out clocks + // 180 degree phase on input and output clocks + SDMMC.clock.phase_dout = 4; + SDMMC.clock.phase_din = 4; + SDMMC.clock.phase_core = 0; + +#elif CONFIG_IDF_TARGET_ESP32S3 assert (div > 1 && div <= 16); int l = div - 1; int h = div / 2 - 1; @@ -130,7 +152,19 @@ static void sdmmc_host_set_clk_div(int div) */ SDMMC.clock.phase_dout = 1; SDMMC.clock.phase_din = 0; - esp_rom_delay_us(1); +#endif //CONFIG_IDF_TARGET_ESP32S3 + + // Wait for the clock to propagate + esp_rom_delay_us(10); +} + +static inline int s_get_host_clk_div(void) +{ +#if CONFIG_IDF_TARGET_ESP32 + return SDMMC.clock.div_factor_h + 1; +#elif CONFIG_IDF_TARGET_ESP32S3 + return SDMMC.clock.div_factor_l + 1; +#endif } static void sdmmc_host_input_clk_disable(void) @@ -261,7 +295,7 @@ esp_err_t sdmmc_host_get_real_freq(int slot, int* real_freq_khz) return ESP_ERR_INVALID_ARG; } - int host_div = SDMMC.clock.div_factor_l + 1; + int host_div = s_get_host_clk_div(); int card_div = slot == 0 ? SDMMC.clkdiv.div0 : SDMMC.clkdiv.div1; *real_freq_khz = sdmmc_host_calc_freq(host_div, card_div); diff --git a/examples/storage/emmc/main/emmc_example_main.c b/examples/storage/emmc/main/emmc_example_main.c index da112787e0..75285167b6 100644 --- a/examples/storage/emmc/main/emmc_example_main.c +++ b/examples/storage/emmc/main/emmc_example_main.c @@ -56,6 +56,7 @@ void app_main(void) // For setting a specific frequency, use host.max_freq_khz (range 400kHz - 52MHz for SDMMC) // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000; sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + host.max_freq_khz = SDMMC_FREQ_52M; // This initializes the slot without card detect (CD) and write protect (WP) signals. // Other fields will be initialized to zero diff --git a/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py b/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py index 7da27f2b91..5eb2e3da3d 100644 --- a/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py +++ b/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py @@ -40,4 +40,4 @@ def test_examples_sd_card_sdmmc(dut: Dut) -> None: 'Card unmounted') for msg in message_list: - dut.expect(msg, timeout=20) + dut.expect(msg, timeout=60)