-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
ESP32-C5 SDIO slave not receiving data from STM32 SPI master (MOSI/CMD issue)
Environment
ESP32 Side:
- Chip: ESP32-C5 (eco2)
- Firmware: ESP-AT v5.1.0.0-dev (factory_ESP32C5-SDIO.bin)
- Compile: Feb 5 2026 13:16:02
- ESP-IDF: v5.5.1-833-gcc569cbd80-dirty
- Mode: SDIO Slave (1-bit mode)
Host Side:
- MCU: STM32H750VBT6
- Interface: SPI6 as SDSPI master (software SDIO emulation)
- Clock: 468 kHz (Prescaler 256)
- Library: esp-at/examples/at_sdspi_host (ported to STM32H7)
Hardware Connection
| STM32H750 Pin | Function | ESP32-C5 GPIO | SDIO Signal | Pull-up |
|---|---|---|---|---|
| PG13 | SPI6_SCK | GPIO9 | CLK | No |
| PG14 | SPI6_MOSI | GPIO10 | CMD | 10kΩ ✅ |
| PG12 | SPI6_MISO | GPIO8 | DAT0 | 10kΩ ✅ |
| PA8 | GPIO_EXTI8 | GPIO7 | DAT1 (HS) | 10kΩ ✅ |
| PA15 | GPIO_Output | GPIO13 | DAT3 (CS) | 10kΩ ✅ |
Verified: All connections confirmed with multimeter, pull-up resistors present.
Problem Description
Symptom 1: MISO works, but MOSI doesn't
MISO (ESP32 → STM32): ✅ Working
STM32 receives data from ESP32:
- Pattern 1: 0xA5 0xA5 0xA5 0xA5 0xA5 0xA5 0xA5 0xA5
- Pattern 2: 0x3C 0xD1 0x05 0x90 0x61 0x74 0x05 0x90
This proves the hardware connection is good!
MOSI (STM32 → ESP32): ❌ Not working
STM32 sends:
- Idle clocks: 0xFF 0xFF 0xFF 0xFF ... (20 bytes)
- CMD0: 0x40 0x00 0x00 0x00 0x00 0x95 0xFF 0xFF ... (15 bytes)
ESP32 response: Nothing (timeout)
Error from STM32 sdspi library:
E sdspi_transaction: Not found response
E sdspi_transaction: CMD0 response error, expect 0x1, response 0
Symptom 2: ESP32 always logs error during initialization
ESP32 UART log:
I (933) main_task: Calling app_main()
I (933) at-workaround: no external 32k oscillator, disable it now.
Waiting 3 seconds for STM32 host to boot...
Starting AT interface...
I (4001) at-init: at param mode: 1
...
I (6941) at-init: module_name: ESP32C5-SDIO
I (6944) at-init: max tx power=78, ret=0
...
I (6960) at-init: v5.1.0.0-dev (unknown)
E (6964) at-sdio: invalid data:0 or len:-1 ← Always occurs!
I (6968) wifi:mode : sta (3c:dc:75:84:51:58) + softAP (3c:dc:75:84:51:59)
Error location: main/interface/sdio/at_sdio_task.c
- Line 50 in
at_sdio_write_data():if (len < 0 || data == NULL) - Line 86 in
at_sdio_read_data():if (data == NULL || len < 0)
Timing: This error occurs 23ms after SDIO initialization, regardless of when STM32 sends CMD0.
Symptom 3: ESP32 stops reading MOSI after error
After the "invalid data" error appears:
- ✅ ESP32 continues to send data on MISO (STM32 receives it)
- ❌ ESP32 stops receiving data on MOSI (ignores STM32's CMD0)
Theory: After the error, ESP32 enters an error state and disables MOSI/CMD reception.
What We Tried
1. Timing adjustments ⏱️
Attempt 1: Added 3-second delay in app_main() before esp_at_init()
// C:\ESP\esp-at\main\app_main.c
void app_main(void)
{
esp_at_main_preprocess();
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_at_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
printf("Waiting 3 seconds for STM32 host to boot...\n");
vTaskDelay(pdMS_TO_TICKS(3000)); // ← Added delay
printf("Starting AT interface...\n");
esp_at_init();
}Result: "invalid data" error still occurs at the same timing (E (6964))
Attempt 2: STM32 waits 4.8s ~ 8s after ESP32 reset
Result: No difference, CMD0 still fails
2. SPI clock speed 🔄
- Tested: 15 MHz, 468 kHz
- Result: No difference
3. Hardware verification ✅
- Multimeter: All connections verified, continuity OK
- Oscilloscope: MISO shows data, MOSI shows clock but ESP32 doesn't respond
- Pull-ups: Confirmed 10kΩ on CMD, DAT0, DAT1, DAT3
4. DAT1 (HS) interrupt implementation
- Configured PA8 as GPIO_EXTI with falling edge trigger
- Implemented semaphore handler in
sdspi_port.c - Result: No change
5. DMA settings
- Tried: DMA_CIRCULAR, DMA_NORMAL modes
- Tried: Polling mode instead of DMA
- Result: No difference (hardware signals confirmed with oscilloscope)
Code References
STM32 SDSPI Port (working part)
Based on esp-at/examples/at_sdspi_host/STM32 example, ported to STM32H7:
User/Src/sdspi_port.c: Hardware abstraction layerUser/Src/sdspi_host.c: SDSPI protocol implementation (unchanged from example)User/Src/esp_sdspi.c: High-level API
Key function: at_spi_transmit()
esp_err_t at_spi_transmit(void* tx_buff, void* rx_buff, uint32_t len)
{
// Cache operations for STM32H7
SCB_CleanDCache_by_Addr((uint32_t*)tx_buff, len);
// SPI transfer (tried both DMA and Polling modes)
HAL_SPI_TransmitReceive(&hspi6, tx_buff, rx_buff, len, 1000);
SCB_InvalidateDCache_by_Addr((uint32_t*)rx_buff, len);
return ESP_OK;
}Debug Logs
STM32 Debug Output:
[SDSPI] Resetting ESP32-C5...
[SDSPI] Wait 4.8s (ESP32 boot 2s + app delay 3s)...
TX[20]: FF FF FF FF FF FF FF FF (CS=1) ← Idle clocks
RX[20]: A5 A5 A5 A5 A5 A5 A5 A5 ← ESP32 responds!
TX[15]: 40 00 00 00 00 95 FF FF (CS=0) ← CMD0
RX[15]: 40 00 00 00 00 95 FF FF ← Echo back (no ESP32 response)
E sdspi_transaction: Not found response
E sdspi_transaction: CMD0 response error, expect 0x1, response 0
ESP32 Debug Output:
I (933) main_task: Calling app_main()
Waiting 3 seconds for STM32 host to boot...
Starting AT interface...
I (4001) at-init: at param mode: 1
I (6941) at-init: module_name: ESP32C5-SDIO
E (6964) at-sdio: invalid data:0 or len:-1 ← Always occurs
I (6968) wifi:mode : sta (3c:dc:75:84:51:58) + softAP (3c:dc:75:84:51:59)
Questions
1. What causes "invalid data:0 or len:-1" error?
Looking at at_sdio_task.c:
static int32_t at_sdio_write_data(uint8_t *data, int32_t len)
{
if (len < 0 || data == NULL) {
ESP_LOGE(TAG, "invalid data:%p or len:%d", data, len); // ← Line 50
return -1;
}
// ...
}Who calls this function with NULL/invalid args during initialization?
- Is this expected during AT core initialization?
- Should we ignore this error?
2. Why does ESP32 stop receiving MOSI after the error?
static void at_sdio_task(void *params)
{
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
for (;;) {
esp_err_t ret = sdio_slave_recv(&handle, &addr, &size, portMAX_DELAY); // ← Should wait forever
// ...
}
}The task uses portMAX_DELAY, so it should wait forever for data from STM32. But after the "invalid data" error, ESP32 doesn't receive CMD0 from STM32.
Does the error state disable MOSI/CMD pin reception?
3. Is ESP32-C5 SDIO slave tested with SPI-based hosts?
The example at_sdspi_host is based on STM32F1 with hardware SDIO controller. We're using STM32H7 with SPI6 emulating SDIO.
Is software SDIO emulation (SPI) tested/supported with ESP32-C5?
Workaround Attempts
We tried modifying at_sdio_task.c to ignore the error:
// Commented out error log
if (len < 0 || data == NULL) {
// ESP_LOGE(TAG, "invalid data:%p or len:%d", data, len); // Commented
return -1;
}Result: Error log disappears, but ESP32 still doesn't receive CMD0.
Request
- Root cause analysis: Why does "invalid data" error occur during initialization?
- Workaround: How to make ESP32 receive MOSI/CMD data after initialization?
- Confirmation: Is ESP32-C5 SDIO slave + STM32 SPI master a supported configuration?
We've spent over a month on this issue. Any help would be greatly appreciated!
Additional Information
- STM32 MISO reception works (proves hardware is OK)
- STM32 can read data from ESP32 (0xA5, 0x3C patterns)
- Only MOSI direction fails (ESP32 can't read from STM32)
- Problem is not timing-related (tried many variations)
- Problem is not clock speed-related (tested 468kHz ~ 15MHz)
Thank you!