esp32/sdcard: Unable to use SD card on some ESP32-P4 boards.
Port, board and/or hardware
esp32 port, ESP32-P4-Function-EV-Board (probably other boards with the ESP32-P4 too)
MicroPython version
MicroPython v1.27.0 on 2025-12-09; Generic ESP32P4 module with ESP32P4
Reproduction
Following the docs:
>>> import machine
>>> vfs.mount(machine.SDCard(), "/sd")
Expected behaviour
SD card should mount and be readable/writable.
Observed behaviour
E (11418) sdmmc_common: sdmmc_init_ocr: send_op_cond (1) returned 0x107
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: 16
SD card does not mount, and is not readable/writable.
Additional Information
I've debugged this, and there are 2 problems.
For context, the ESP32-P4 supports 2 SDMMC slots. Espressif confusingly uses both 1 indexing and 0 indexing in different contexts, so I'll adhere to strict 0 indexing here.
- Slot 0 supports SDIO 3.0, and is capable of the fast UHS-I mode, but is on fixed GPIO pins (39-48). SDIO 3.0 also requires IO signals to switch between 3.3V and 1.8V, so those GPIO pins are powered by the
VDD_IO_5power pin, which can be powered by one of the internal LDOs on the ESP32-P4. - Slot 1 is only SDIO 2.0, but can be routed to any GPIO pin via the GPIO matrix. It always runs at 3.3V.
Again, I'm using the ESP32-P4-Function-EV-Board. Here is the schematic, look at the use of ESP_LDO_VO4 to power VDD_IO_5 the SDIO pull up resistors.
~Problem 1 - Default slot~
~The DEFAULT_SLOT is hard coded to 1 when using SDMMC:~
https://github.com/micropython/micropython/blob/5c00edcee28491b6961a5db6aa0e5aa856664de4/ports/esp32/machine_sdcard.c#L216-L218
~This board uses slot 0. It's likely that other boards will also use slot 0, since it supports SDIO 3.0.
I propose 2 possible solutions:~
- ~Make
DEFAULT_SLOT=0on the ESP32-P4.~ - ~Make the default
slotconfigurable inmpconfigboard.h. This is probably the better solution.~
~FWIW just setting slot=0 is not enough to get the SD card to work on this board.~
Problem 2 - IO voltage
SDIO 3.0 requires the IO voltage level to change between 3.3V and 1.8V. To achieve this, the board must connect an internal LDO on the ESP32-P4 to the VDD_IO_5 power pin, and the self->host.pwr_ctrl_handle must be configured in machine_sdcard_make_new(). I have a working solution based on the ESP-IDF SDMMC example, with the following changes to machine_sdcard.c:
+#include "sd_pwr_ctrl_by_on_chip_ldo.h"
...
static mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
...
#if SOC_SDMMC_HOST_SUPPORTED
else {
sdmmc_host_t _temp_host = SDMMC_HOST_DEFAULT();
_temp_host.max_freq_khz = freq / 1000;
self->host = _temp_host;
}
#endif
+ sd_pwr_ctrl_ldo_config_t ldo_config = {
+ .ldo_chan_id = 4,
+ };
+ sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
+
+ int ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle);
+ if (ret != ESP_OK) {
+ DEBUG_printf(" Failed to create a new on-chip LDO power control driver");
+ }
+ self->host.pwr_ctrl_handle = pwr_ctrl_handle;
DEBUG_printf(" Calling host.init()");
check_esp_err(self->host.init());
self->flags |= SDCARD_CARD_FLAGS_HOST_INIT_DONE;
...
}
This is sufficient for the SD card to work:
>>> import machine, os
>>> vfs.mount(machine.SDCard(slot=0), "/sd")
>>> os.listdir()
['sd', 'boot.py']
I'm currently hard coding ldo_chan_id = 4 since that's what the ESP32-P4-Function-EV-Board uses, but other dev boards may use a different LDO. I think the best solution would be for the default LDO to be defined in mpconfigboard.h.
It's worth noting that a board could power VDD_IO_5 from somewhere other than an internal LDO, in which case this gets more tricky. Espressif's docs say to "implement a custom sd_pwr_ctrl driver"; IMO it's probably not worth the extra effort to support this.
Code of Conduct
Yes, I agree
ESP32 Cannot mount SD Card on Wemos LOLIN D32 Pro V2.0.0
Firmware:
esp32spiram-20210623-v1.16.bin
Board:
Wemos LOLIN D32 Pro V2.0.0, ESP32-WROVER, ESP32-D0WDQ6 (revision 1)
According the Wemos D32 Pro Schematic and verified using a continuity meter, the SD card pins are as follows:
- SCK: GPIO18
- MOSI: GPIO23
- MISO: GPIO19
- CS: GPIO4
Trying to mount the SD card but encountering the following error:
>>> import uos, machine
>>> uos.mount(machine.SDCard(slot=2, width=1, sck=18, mosi=23, miso=19, cs=4), '/sd')
E (61965) sdmmc_sd: sdmmc_init_spi_crc: sdmmc_send_cmd_crc_on_off returned 0x106
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: 16