Skip to content

Commit

Permalink
sdmmc: in/out phase adapted to esp32 and esp32s3
Browse files Browse the repository at this point in the history
  • Loading branch information
Icarus113 committed Apr 24, 2023
1 parent 5b18007 commit 6102cfd
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitlab/ci/target-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 39 additions & 5 deletions components/driver/sdmmc/sdmmc_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions examples/storage/emmc/main/emmc_example_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 6102cfd

Please sign in to comment.