mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
Merge branch 'fix/sdio_init_for_io_card_only' into 'master'
fix(sdmmc): Allow disabling SDIO specific steps in sdmmc card init See merge request espressif/esp-idf!40735
This commit is contained in:
@@ -10,7 +10,8 @@ if(CONFIG_SOC_SDMMC_HOST_SUPPORTED)
|
||||
"sdmmc_test_trim_sd.c"
|
||||
"sdmmc_test_discard_sd.c"
|
||||
"sdmmc_test_sanitize_sd.c"
|
||||
"sdmmc_test_various_cmds.c")
|
||||
"sdmmc_test_various_cmds.c"
|
||||
"sdmmc_test_card_init.c")
|
||||
endif()
|
||||
|
||||
set(priv_requires "sdmmc"
|
||||
|
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "unity.h"
|
||||
#include "sdmmc_test_begin_end_sd.h"
|
||||
#if SOC_SDMMC_IO_POWER_EXTERNAL
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
#endif
|
||||
|
||||
#if SOC_SDMMC_HOST_SUPPORTED
|
||||
TEST_CASE("sdmmc_card_init with SDIO configuration test", "[sdmmc]")
|
||||
{
|
||||
sdmmc_card_t card;
|
||||
|
||||
// Test with slot 1, 1-bit width, default frequency
|
||||
sdmmc_test_sd_skip_if_board_incompatible(SLOT_1, 1, SDMMC_FREQ_DEFAULT, NO_DDR, NO_EMMC);
|
||||
|
||||
// Print current SDIO configuration for verification
|
||||
#ifdef CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
printf("\n[CONFIG] SDIO support is ENABLED\n");
|
||||
#else
|
||||
printf("\n[CONFIG] SDIO support is DISABLED\n");
|
||||
#endif
|
||||
|
||||
// Initialize using the test framework
|
||||
sdmmc_test_sd_begin(SLOT_1, 1, SDMMC_FREQ_DEFAULT, NO_DDR, &card);
|
||||
|
||||
// Print card information to verify card was initialized correctly
|
||||
sdmmc_card_print_info(stdout, &card);
|
||||
|
||||
// Verify basic card properties are initialized
|
||||
TEST_ASSERT_NOT_EQUAL(0, card.csd.capacity);
|
||||
TEST_ASSERT_NOT_EQUAL(0, card.csd.sector_size);
|
||||
|
||||
// Clean up
|
||||
sdmmc_test_sd_end(&card);
|
||||
}
|
||||
#endif
|
@@ -6,6 +6,14 @@ from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.sdcard
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'default',
|
||||
'nosdio',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_sdmmc(dut: IdfDut) -> None:
|
||||
# SDMMC driver can't be reinitialized if the test fails,
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# SDMMC Configuration
|
||||
CONFIG_SD_ENABLE_SDIO_SUPPORT=n
|
@@ -6,7 +6,8 @@ if(CONFIG_SOC_GPSPI_SUPPORTED)
|
||||
"sdmmc_test_probe_spi.c"
|
||||
"sdmmc_test_rw_spi.c"
|
||||
"sdmmc_test_erase_spi.c"
|
||||
"sdmmc_test_erase_common_spi.c")
|
||||
"sdmmc_test_erase_common_spi.c"
|
||||
"sdmmc_test_card_init_spi.c")
|
||||
endif()
|
||||
|
||||
set(priv_requires "sdmmc"
|
||||
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "driver/sdspi_host.h"
|
||||
#include "unity.h"
|
||||
#include "sdmmc_test_begin_end_spi.h"
|
||||
|
||||
#if CONFIG_SOC_GPSPI_SUPPORTED
|
||||
TEST_CASE("sdspi_card_init with SDIO configuration test", "[sdspi]")
|
||||
{
|
||||
sdmmc_card_t card;
|
||||
|
||||
// Test with slot 1, default frequency for SPI mode
|
||||
sdmmc_test_spi_skip_if_board_incompatible(SLOT_1, SDMMC_FREQ_DEFAULT);
|
||||
|
||||
// Print current SDIO configuration for verification
|
||||
#ifdef CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
printf("\n[CONFIG] SDIO support is ENABLED\n");
|
||||
#else
|
||||
printf("\n[CONFIG] SDIO support is DISABLED\n");
|
||||
#endif
|
||||
|
||||
// Initialize using the SPI test framework
|
||||
sdmmc_test_spi_begin(SLOT_1, SDMMC_FREQ_DEFAULT, &card, NULL, NULL, NULL);
|
||||
|
||||
// Print card information to verify card was initialized correctly
|
||||
sdmmc_card_print_info(stdout, &card);
|
||||
|
||||
// Verify basic card properties are initialized
|
||||
TEST_ASSERT_NOT_EQUAL(0, card.csd.capacity);
|
||||
TEST_ASSERT_NOT_EQUAL(0, card.csd.sector_size);
|
||||
|
||||
// Clean up
|
||||
sdmmc_test_spi_end(SLOT_1, &card);
|
||||
}
|
||||
#endif
|
@@ -7,6 +7,14 @@ from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='C5 C61 GPSPI same, so testing on C5 is enough')
|
||||
@pytest.mark.sdcard_spimode
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'default',
|
||||
'nosdio',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c3', 'esp32p4', 'esp32c5'], indirect=['target'])
|
||||
def test_sdspi(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(reset=True)
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# SDMMC Configuration
|
||||
CONFIG_SD_ENABLE_SDIO_SUPPORT=n
|
@@ -7,11 +7,14 @@ endif()
|
||||
set(srcs "sdmmc_cmd.c"
|
||||
"sdmmc_common.c"
|
||||
"sdmmc_init.c"
|
||||
"sdmmc_io.c"
|
||||
"sdmmc_mmc.c"
|
||||
"sdmmc_sd.c"
|
||||
"sd_pwr_ctrl/sd_pwr_ctrl.c")
|
||||
|
||||
if(CONFIG_SD_ENABLE_SDIO_SUPPORT)
|
||||
list(APPEND srcs "sdmmc_io.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_GP_LDO_SUPPORTED)
|
||||
list(APPEND srcs "sd_pwr_ctrl/sd_pwr_ctrl_by_on_chip_ldo.c")
|
||||
endif()
|
||||
|
8
components/sdmmc/Kconfig
Normal file
8
components/sdmmc/Kconfig
Normal file
@@ -0,0 +1,8 @@
|
||||
menu "SD Protocol Layer Configuration"
|
||||
config SD_ENABLE_SDIO_SUPPORT
|
||||
bool "Enable SDIO support"
|
||||
default y
|
||||
help
|
||||
Enable SDIO support.
|
||||
Disabling this will skip SDIO-specific initialization steps
|
||||
endmenu
|
@@ -1,3 +1,6 @@
|
||||
| Supported Targets | ESP32 | ESP32-P4 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- |
|
||||
|
||||
# SDMMC Protocol Layer Driver
|
||||
|
||||
## SD Host Side Related Component Architecture
|
||||
@@ -33,3 +36,10 @@
|
||||
- `esp_driver_sdmmc` is in driver layer (G2), it relies on `sdmmc`
|
||||
- `esp_driver_sdspi` is in driver layer (G2), it relies on `sdmmc`
|
||||
- `sdmmc` does not and should not rely on `esp_driver_sdmmc` or `esp_driver_sdspi`. Though `sdmmc` is independent, it still stays in G2.
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
|
||||
This configuration option allows you to enable/disable SDIO support. By default this option is enabled.
|
||||
Consider disabling SDIO support (`CONFIG_SD_ENABLE_SDIO_SUPPORT=n`) when card is **Memory-only card** and not when **Combo cards** which provide both I/O functionality and memory storage.
|
||||
|
@@ -113,6 +113,7 @@ esp_err_t sdmmc_decode_scr(uint32_t *raw_scr, sdmmc_scr_t* out_scr);
|
||||
esp_err_t sdmmc_decode_ssr(uint32_t *raw_ssr, sdmmc_ssr_t* out_ssr);
|
||||
uint32_t sdmmc_sd_get_erase_timeout_ms(const sdmmc_card_t* card, int arg, size_t erase_size_kb);
|
||||
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
/* SDIO specific */
|
||||
esp_err_t sdmmc_io_reset(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_io_enable_hs_mode(sdmmc_card_t* card);
|
||||
@@ -123,6 +124,7 @@ esp_err_t sdmmc_io_rw_direct(sdmmc_card_t* card, int function, uint32_t reg, uin
|
||||
// cache, unless `SDMMC_HOST_FLAG_ALLOC_ALIGNED_BUF` flag is set when calling `sdmmc_card_init`. This flag is mandory
|
||||
// when the buffer is behind the cache in byte mode.
|
||||
esp_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int function, uint32_t reg, int arg, void *data, size_t size);
|
||||
#endif
|
||||
|
||||
/* MMC specific */
|
||||
esp_err_t sdmmc_mmc_send_ext_csd_data(sdmmc_card_t* card, void *out_data, size_t datalen, size_t buffer_len);
|
||||
@@ -141,9 +143,6 @@ esp_err_t sdmmc_init_rca(sdmmc_card_t* card);
|
||||
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);
|
||||
@@ -152,7 +151,12 @@ esp_err_t sdmmc_init_mmc_read_ext_csd(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_mmc_read_cid(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_host_bus_width(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_sd_bus_width(sdmmc_card_t* card);
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
esp_err_t sdmmc_init_io(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_io_bus_width(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);
|
||||
#endif
|
||||
esp_err_t sdmmc_init_mmc_bus_width(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_card_hs_mode(sdmmc_card_t* card);
|
||||
esp_err_t sdmmc_init_host_frequency(sdmmc_card_t* card);
|
||||
|
@@ -180,8 +180,10 @@ esp_err_t sdmmc_init_card_hs_mode(sdmmc_card_t* card)
|
||||
esp_err_t err = ESP_ERR_NOT_SUPPORTED;
|
||||
if (card->is_mem && !card->is_mmc) {
|
||||
err = sdmmc_enable_hs_mode_and_check(card);
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
} else if (card->is_sdio) {
|
||||
err = sdmmc_io_enable_hs_mode(card);
|
||||
#endif
|
||||
} else if (card->is_mmc){
|
||||
err = sdmmc_mmc_enable_hs_mode(card);
|
||||
}
|
||||
|
@@ -51,7 +51,11 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
|
||||
const bool is_spi = host_is_spi(card);
|
||||
const bool always = true;
|
||||
#if !CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
card->is_mem = 1;
|
||||
#else
|
||||
const bool io_supported = true;
|
||||
#endif
|
||||
|
||||
if (config->pwr_ctrl_handle) {
|
||||
int voltage_mv = config->io_voltage * 1000;
|
||||
@@ -71,8 +75,10 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
/* Check if host function pointers are correctly initialised */
|
||||
SDMMC_INIT_STEP(always, sdmmc_check_host_function_ptr_integrity);
|
||||
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
/* Reset SDIO (CMD52, RES) before re-initializing IO (CMD5). */
|
||||
SDMMC_INIT_STEP(io_supported, sdmmc_io_reset);
|
||||
#endif
|
||||
|
||||
/* GO_IDLE_STATE (CMD0) command resets the card */
|
||||
SDMMC_INIT_STEP(always, sdmmc_send_cmd_go_idle_state);
|
||||
@@ -80,8 +86,10 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
/* SEND_IF_COND (CMD8) command is used to identify SDHC/SDXC cards. */
|
||||
SDMMC_INIT_STEP(always, sdmmc_init_sd_if_cond);
|
||||
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
/* IO_SEND_OP_COND(CMD5), Determine if the card is an IO card. */
|
||||
SDMMC_INIT_STEP(io_supported, sdmmc_init_io);
|
||||
#endif
|
||||
|
||||
const bool is_mem = card->is_mem;
|
||||
const bool is_sdio = !is_mem;
|
||||
@@ -133,9 +141,11 @@ 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);
|
||||
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
/* Try to switch card to HS mode if the card supports it.
|
||||
* Set card->max_freq_khz value accordingly.
|
||||
@@ -145,7 +155,9 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
|
||||
/* Set bus width. One call for every kind of card, then one for the host */
|
||||
if (!is_spi) {
|
||||
SDMMC_INIT_STEP(is_sdmem, sdmmc_init_sd_bus_width);
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
SDMMC_INIT_STEP(is_sdio, sdmmc_init_io_bus_width);
|
||||
#endif
|
||||
SDMMC_INIT_STEP(is_mmc, sdmmc_init_mmc_bus_width);
|
||||
SDMMC_INIT_STEP(always, sdmmc_init_host_bus_width);
|
||||
}
|
||||
@@ -169,8 +181,10 @@ 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);
|
||||
#if CONFIG_SD_ENABLE_SDIO_SUPPORT
|
||||
/* Sanity check for SDIO after switching the frequency */
|
||||
SDMMC_INIT_STEP_PARAM(is_sdio, sdmmc_io_init_check_card_cap, &card_cap);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
Reference in New Issue
Block a user