SDMMC 主机驱动
概述
ESP32-S3 的 SDMMC 主机外设共有两个卡槽,用于插入 SD 卡、连接 SDIO 设备或连接 eMMC 芯片,每个卡槽均可单独使用。
卡槽 SDMMC_HOST_SLOT_0 和 SDMMC_HOST_SLOT_1 都支持 1、4、8 线的 SD 接口,这些卡槽通过 GPIO 交换矩阵连接到 ESP32-S3 的 GPIO,即每个 SD 卡信号都可以使用任意 GPIO 连接。
支持的速率模式
SDMMC 主机驱动支持以下速率模式:
- 默认速率 (20 MHz):对于 SD 卡,支持 1 线或 4 线传输;对于 3.3 V eMMC,支持 1 线、4 线或 8 线传输。 
- 高速模式 (40 MHz):对于 SD 卡,支持 1 线或 4 线传输;对于 3.3 V eMMC,支持 1 线、4 线或 8 线传输。 
- 高速 DDR 模式 (40 MHz):对于 3.3 V eMMC,支持 4 线传输。 
当前尚不支持的速率模式:
- 高速 DDR 模式:不支持 8 线 eMMC 传输 
使用 SDMMC 主机驱动
在大多数应用程序中,只有下列函数会被直接调用:
其他函数将通过 sdmmc_host_t 结构体中的函数指针由 SD/MMC 协议层调用,例如:
配置总线宽度和频率
使用 sdmmc_host_t 和 sdmmc_slot_config_t 的默认初始化配置,即 SDMMC_HOST_DEFAULT 和 SDMMC_SLOT_CONFIG_DEFAULT 时,SDMMC 主机驱动会尝试以当前卡所支持的最大总线宽度进行通信(SD 卡为 4 线,eMMC 为 8 线),并使用 20 MHz 的通信频率。
在支持 40 MHz 频率通信的设计中,可以调整 sdmmc_host_t 结构体中的 max_freq_khz 字段,提升总线频率:
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
如需选择标准速率以外的特定频率,请根据所使用的 SD 接口(SDMMC 或 SDSPI)确定适当频率范围,并选择其中的任意值。然而,实际的时钟频率会由底层驱动程序计算,可能与你所需的值不同。
使用 SDMMC 接口时,max_freq_khz 即频率上限,因此最终的频率值应始终低于或等于该上限。而使用 SDSPI 接口时,驱动程序会提供最接近的适配频率,因此该值可以大于、等于或小于 max_freq_khz。
请配置 sdmmc_slot_config_t 的 width 字段,配置总线宽度。例如,配置 1 线模式的代码如下:
sdmmc_slot_config_t slot = SDMMC_SLOT_CONFIG_DEFAULT();
slot.width = 1;
配置 GPIO
通过配置结构体 sdmmc_slot_config_t,ESP32-S3 的 SDMMC 主机可以根据需要,为每个信号配置任意的 GPIO 管脚。
例如,使用以下代码,可以将 GPIO 1-6 分别用于 CLK、CMD、D0-D3 信号:
sdmmc_slot_config_t slot = SDMMC_SLOT_CONFIG_DEFAULT();
slot.clk = GPIO_NUM_1;
slot.cmd = GPIO_NUM_2;
slot.d0 = GPIO_NUM_3;
slot.d1 = GPIO_NUM_4;
slot.d2 = GPIO_NUM_5;
slot.d3 = GPIO_NUM_6;
也可以配置 CD 和 WP 管脚。与配置其他信号的方法类似,你只需配置相同结构体的 cd 和 wp 参数:
slot.cd = GPIO_NUM_7;
slot.wp = GPIO_NUM_8;
SDMMC_SLOT_CONFIG_DEFAULT 将 CD 和 WP 管脚都配置为 GPIO_NUM_NC,表明默认情况下不会使用这两个管脚。
通过上述方式初始化 sdmmc_slot_config_t 结构体后,即可在调用 sdmmc_host_init_slot() 或其他任意高层函数(如 esp_vfs_fat_sdmmc_mount())时使用该结构体。
eMMC 芯片的 DDR 模式
默认情况下,如果满足以下条件,将使用 DDR 模式:
- 在 - sdmmc_host_t结构体中将 SDMMC 主机频率配置为- SDMMC_FREQ_HIGHSPEED,且
- eMMC 芯片在其 CSD 寄存器中报告支持 DDR 模式 
DDR 模式对信号完整性要求更高。如果要在保持 SDMMC_FREQ_HIGHSPEED 频率的同时禁用 DDR 模式,请在 sdmmc_host_t 结构体的 sdmmc_host_t::flags 字段中清除 SDMMC_HOST_FLAG_DDR 位:
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
host.flags &= ~SDMMC_HOST_FLAG_DDR;
相关文档
- SD/SDIO/MMC 驱动程序:介绍了实现协议层的高层驱动程序。 
- SD SPI 主机驱动程序:介绍了一种类似驱动,该驱动使用 SPI 控制器且受限于 SD 协议的 SPI 模式。 
- SD 上拉需求 介绍了模组和开发套件上的上拉支持和兼容信息。 
API 参考
Header File
- This header file can be included with: - #include "driver/sdmmc_host.h" 
- This header file is a part of the API provided by the - esp_driver_sdmmccomponent. To declare that your component depends on- esp_driver_sdmmc, add the following to your CMakeLists.txt:- REQUIRES esp_driver_sdmmc - or - PRIV_REQUIRES esp_driver_sdmmc 
Functions
- 
esp_err_t sdmmc_host_init(void)
- Initialize SDMMC host peripheral. - 备注 - This function is not thread safe - 返回:
- ESP_OK on success or if sdmmc_host_init was already initialized with this function 
- ESP_ERR_NO_MEM if memory can not be allocated 
 
 
- 
esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
- Initialize given slot of SDMMC peripheral. - On the ESP32, SDMMC peripheral has two slots: - Slot 0: 8-bit wide, maps to HS1_* signals in PIN MUX 
- Slot 1: 4-bit wide, maps to HS2_* signals in PIN MUX 
 - Card detect and write protect signals can be routed to arbitrary GPIOs using GPIO matrix. - 备注 - This function is not thread safe - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- slot_config -- additional configuration for the slot 
 
- 返回:
- ESP_OK on success 
- ESP_ERR_INVALID_STATE if host has not been initialized using sdmmc_host_init 
- ESP_ERR_INVALID_ARG if GPIO pins from slot_config are not valid 
 
 
- 
esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
- Select bus width to be used for data transfer. - SD/MMC card must be initialized prior to this command, and a command to set bus width has to be sent to the card (e.g. SD_APP_SET_BUS_WIDTH) - 备注 - This function is not thread safe - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- width -- bus width (1, 4, or 8 for slot 0; 1 or 4 for slot 1) 
 
- 返回:
- ESP_OK on success 
- ESP_ERR_INVALID_ARG if slot number or width is not valid 
 
 
- 
size_t sdmmc_host_get_slot_width(int slot)
- Get bus width configured in - sdmmc_host_init_slotto be used for data transfer.- 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- 返回:
- configured bus width of the specified slot. 
 
- 
esp_err_t sdmmc_host_set_card_clk(int slot, uint32_t freq_khz)
- Set card clock frequency. - Currently only integer fractions of 40MHz clock can be used. For High Speed cards, 40MHz can be used. For Default Speed cards, 20MHz can be used. - 备注 - This function is not thread safe - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- freq_khz -- card clock frequency, in kHz 
 
- 返回:
- ESP_OK on success 
- other error codes may be returned in the future 
 
 
- 
esp_err_t sdmmc_host_set_bus_ddr_mode(int slot, bool ddr_enabled)
- Enable or disable DDR mode of SD interface. - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- ddr_enabled -- enable or disable DDR mode 
 
- 返回:
- ESP_OK on success 
- ESP_ERR_NOT_SUPPORTED if DDR mode is not supported on this slot 
 
 
- 
esp_err_t sdmmc_host_set_cclk_always_on(int slot, bool cclk_always_on)
- Enable or disable always-on card clock When cclk_always_on is false, the host controller is allowed to shut down the card clock between the commands. When cclk_always_on is true, the clock is generated even if no command is in progress. - 参数:
- slot -- slot number 
- cclk_always_on -- enable or disable always-on clock 
 
- 返回:
- ESP_OK on success 
- ESP_ERR_INVALID_ARG if the slot number is invalid 
 
 
- 
esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t *cmdinfo)
- Send command to the card and get response. - This function returns when command is sent and response is received, or data is transferred, or timeout occurs. - Attention
- Data buffer passed in cmdinfo->data must be in DMA capable memory and aligned to 4 byte boundary. If it's behind the cache, both cmdinfo->data and cmdinfo->buflen need to be aligned to cache line boundary. 
 - 备注 - This function is not thread safe w.r.t. init/deinit functions, and bus width/clock speed configuration functions. Multiple tasks can call sdmmc_host_do_transaction as long as other sdmmc_host_* functions are not called. - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- cmdinfo -- pointer to structure describing command and data to transfer 
 
- 返回:
- ESP_OK on success 
- ESP_ERR_TIMEOUT if response or data transfer has timed out 
- ESP_ERR_INVALID_CRC if response or data transfer CRC check has failed 
- ESP_ERR_INVALID_RESPONSE if the card has sent an invalid response 
- ESP_ERR_INVALID_SIZE if the size of data transfer is not valid in SD protocol 
- ESP_ERR_INVALID_ARG if the data buffer is not in DMA capable memory 
 
 
- 
esp_err_t sdmmc_host_io_int_enable(int slot)
- Enable IO interrupts. - This function configures the host to accept SDIO interrupts. - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- 返回:
- returns ESP_OK, other errors possible in the future 
 
- 
esp_err_t sdmmc_host_io_int_wait(int slot, TickType_t timeout_ticks)
- Block until an SDIO interrupt is received, or timeout occurs. - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- timeout_ticks -- number of RTOS ticks to wait for the interrupt 
 
- 返回:
- ESP_OK on success (interrupt received) 
- ESP_ERR_TIMEOUT if the interrupt did not occur within timeout_ticks 
 
 
- 
esp_err_t sdmmc_host_deinit_slot(int slot)
- Disable SDMMC host and release allocated resources gracefully. - 备注 - If there are more than 1 active slots, this function will just decrease the reference count and won't actually disable the host until the last slot is disabled - 备注 - This function is not thread safe - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- 返回:
- ESP_OK on success 
- ESP_ERR_INVALID_STATE if SDMMC host has not been initialized 
- ESP_ERR_INVALID_ARG if invalid slot number is used 
 
 
- 
esp_err_t sdmmc_host_deinit(void)
- Disable SDMMC host and release allocated resources forcefully. - 备注 - This function will deinitialize the host immediately, regardless of the number of active slots - 备注 - This function is not thread safe - 返回:
- ESP_OK on success 
- ESP_ERR_INVALID_STATE if SDMMC host has not been initialized 
 
 
- 
esp_err_t sdmmc_host_get_real_freq(int slot, int *real_freq_khz)
- Provides a real frequency used for an SD card installed on specific slot of SD/MMC host controller. - This function calculates real working frequency given by current SD/MMC host controller setup for required slot: it reads associated host and card dividers from corresponding SDMMC registers, calculates respective frequency and stores the value into the 'real_freq_khz' parameter - 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- real_freq_khz -- [out] output parameter for the result frequency (in kHz) 
 
- 返回:
- ESP_OK on success 
- ESP_ERR_INVALID_ARG on real_freq_khz == NULL or invalid slot number used 
 
 
- 
esp_err_t sdmmc_host_set_input_delay(int slot, sdmmc_delay_phase_t delay_phase)
- set input delay - This API sets delay when the SDMMC Host samples the signal from the SD Slave. 
- This API will check if the given - delay_phaseis valid or not.
- This API will print out the delay time, in picosecond (ps) 
 - 备注 - ESP32 doesn't support this feature, you will get an - ESP_ERR_NOT_SUPPORTED- 参数:
- slot -- slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- delay_phase -- delay phase, this API will convert the phase into picoseconds and print it out 
 
- 返回:
- ESP_OK: ON success. 
- ESP_ERR_INVALID_ARG: Invalid argument. 
- ESP_ERR_NOT_SUPPORTED: ESP32 doesn't support this feature. 
 
 
- 
esp_err_t sdmmc_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info)
- Get the DMA memory information for the host driver. - Deprecated:
- This API is deprecated 
 - 参数:
- slot -- [in] slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- dma_mem_info -- [out] DMA memory information structure 
 
- 返回:
- ESP_OK: ON success. 
- ESP_ERR_INVALID_ARG: Invalid argument. 
 
 
- 
bool sdmmc_host_check_buffer_alignment(int slot, const void *buf, size_t size)
- Check if the buffer meets the alignment requirements. - 参数:
- slot -- [in] slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) 
- buf -- [in] buffer pointer 
- size -- [in] buffer size 
 
- 返回:
- True for aligned buffer, false for not aligned buffer 
 
- 
esp_err_t sdmmc_host_is_slot_set_to_uhs1(int slot, bool *is_uhs1)
- Check if the slot is set to uhs1 or not. - 参数:
- slot -- [in] Slot id 
- is_uhs1 -- [out] Is uhs1 or not 
 
- 返回:
- ESP_OK: on success 
- ESP_ERR_INVALID_STATE: driver not in correct state 
 
 
- 
esp_err_t sdmmc_host_get_state(sdmmc_host_state_t *state)
- Get the state of SDMMC host. - 参数:
- state -- [out] output parameter for SDMMC host state structure 
- 返回:
- ESP_OK on success 
- ESP_ERR_INVALID_ARG on invalid argument 
 
 
Structures
- 
struct sdmmc_slot_config_t
- Extra configuration for SDMMC peripheral slot - Public Members - 
gpio_num_t clk
- GPIO number of CLK signal. 
 - 
gpio_num_t cmd
- GPIO number of CMD signal. 
 - 
gpio_num_t d0
- GPIO number of D0 signal. 
 - 
gpio_num_t d1
- GPIO number of D1 signal. 
 - 
gpio_num_t d2
- GPIO number of D2 signal. 
 - 
gpio_num_t d3
- GPIO number of D3 signal. 
 - 
gpio_num_t d4
- GPIO number of D4 signal. Ignored in 1- or 4- line mode. 
 - 
gpio_num_t d5
- GPIO number of D5 signal. Ignored in 1- or 4- line mode. 
 - 
gpio_num_t d6
- GPIO number of D6 signal. Ignored in 1- or 4- line mode. 
 - 
gpio_num_t d7
- GPIO number of D7 signal. Ignored in 1- or 4- line mode. 
 - 
gpio_num_t gpio_cd
- GPIO number of card detect signal. 
 - 
gpio_num_t cd
- GPIO number of card detect signal; shorter name. 
 - 
gpio_num_t gpio_wp
- GPIO number of write protect signal. 
 - 
gpio_num_t wp
- GPIO number of write protect signal; shorter name. 
 - 
uint8_t width
- Bus width used by the slot (might be less than the max width supported) 
 - 
uint32_t flags
- Features used by this slot. 
 
- 
gpio_num_t clk
- 
struct sdmmc_host_state_t
- SD/MMC host state structure 
Macros
- 
SDMMC_SLOT_FLAG_INTERNAL_PULLUP
- Enable internal pullups on enabled pins. The internal pullups are insufficient however, please make sure external pullups are connected on the bus. This is for debug / example purpose only. 
- 
SDMMC_SLOT_FLAG_WP_ACTIVE_HIGH
- GPIO write protect polarity. 0 means "active low", i.e. card is protected when the GPIO is low; 1 means "active high", i.e. card is protected when GPIO is high. 
- 
SDMMC_SLOT_FLAG_UHS1
- Enable UHS-I mode for this slot