I am attempting to use the SDIO device on an ESP32 WROVER module in connection with an STM32 and have had some issues seeing any action on the ESP32s side. I believe the hardware has been checked out, and pull-up resistors are present, so an issue must be in my software.
At the current moment, I am doing nothing but using the terminal to send CMD 52 6 == 8, part of the initialization specified by Esprecssif . Instead of getting a response, it times out. Looking at the oscilloscope the signal matches what I would expect on the CMD line with no seen response from the ESP32.
I have tried every timing mode, and there are no issues printed in the console about any failure to initialize SDIO. Here is my code so far, mostly built from the SDIO example for testing.
Initialization:
Code: Select all
esp_err_t ret;
/*
* Initialize SDIO
*/
sdio_slave_config_t sdioConfig = {
.timing = SDIO_SLAVE_TIMING_NSEND_NSAMPLE,
.sending_mode = SDIO_SLAVE_SEND_PACKET,
.send_queue_size = TEABUSCLIENT_QUE_SIZE,
.recv_buffer_size = TEABUSCLIENT_BUFFER_SIZE,
.event_cb = TeaBusClient_SDIOCallback,
.flags = 0,
};
ret = sdio_slave_initialize(&sdioConfig);
if(ret != ESP_OK){
printf("Error initializing SDIO. Error %d!\n", ret);
return;
}
/*
* Initialize SDIO registers
*/
for(uint8_t i = 0; i < TEABUSCLIENT_BUFFER_NUMBER; i++){
sdio_slave_buf_handle_t handle = sdio_slave_recv_register_buf(TeaBusClient_Buffer[i]);
ret = sdio_slave_recv_load_buf(handle);
if(ret != ESP_OK){
printf("Error adding SDIO buffer %d. Error %d!\n", i, ret);
return;
}
}
sdio_slave_set_host_intena(SDIO_SLAVE_HOSTINT_SEND_NEW_PACKET |
SDIO_SLAVE_HOSTINT_BIT0 | SDIO_SLAVE_HOSTINT_BIT1 |
SDIO_SLAVE_HOSTINT_BIT2 | SDIO_SLAVE_HOSTINT_BIT3 |
SDIO_SLAVE_HOSTINT_BIT4 | SDIO_SLAVE_HOSTINT_BIT5 |
SDIO_SLAVE_HOSTINT_BIT6 | SDIO_SLAVE_HOSTINT_BIT7);
sdio_slave_start();
printf("SDIO interface started!\n");
Code: Select all
esp_err_t ret;
uint16_t packetSize = 0;
sdio_slave_buf_handle_t handle;
ret = sdio_slave_recv_packet(&handle, 0);
if(ret != ESP_ERR_TIMEOUT){
printf("SDIO receive begin. code %d!\n", ret);
// Receive all possible data
TeaBusClient_Static.recvQueue[packetSize++] = handle;
while (ret == ESP_ERR_NOT_FINISHED) {
ret = sdio_slave_recv_packet(&handle, portMAX_DELAY);
TeaBusClient_Static.recvQueue[packetSize++] = handle;
printf("SDIO extended packed %d!\n", packetSize);
}
if(ret != ESP_OK){
printf("SDIO Error %d!\n", ret);
return;
}
// Calculate full packet size
uint16_t packetLen = 0;
for (uint16_t i = 0; i < packetSize; i++) {
size_t buf_len;
sdio_slave_recv_get_buf(TeaBusClient_Static.recvQueue[i], &buf_len);
packetLen += buf_len;
}
printf("Packet Received. Length: %d!\n", packetLen);
}
For any curiosity about what initialization looks like on the STM32 side, here is its current state. Note most its taken from HAL:
Code: Select all
if(TeaBus_Ready){
Terminal_PrintF(&RootTerminal_Static, "Warning, TeaBus already initialized.\n");
return;
}
__HAL_RCC_SDIO_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
//Initalzie SDIO Hardware
HAL_StatusTypeDef status;
SD_InitTypeDef Init;
/* Default SDIO peripheral configuration for SD card initialization */
Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
Init.ClockBypass = SDIO_CLOCK_EDGE_FALLING;
Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
Init.BusWide = SDIO_BUS_WIDE_1B;
Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
Init.ClockDiv = SDIO_INIT_CLK_DIV;
/* Initialize SDIO peripheral interface with default configuration */
status = SDIO_Init(SDIO, Init);
if(status != HAL_OK)
{
Terminal_PrintF(&RootTerminal_Static, "Failed to initialize SDIO. Error: %d\n", status);
return;
}
__SDIO_DISABLE(SDIO);
SDIO_PowerState_ON(SDIO);
__SDIO_ENABLE(SDIO);
TeaBus_Ready = 1;
Terminal_PrintF(&RootTerminal_Static, "SDIO OK\n", status);
Oscilloscope decoded goes as follows:
Code: Select all
S D CMDINX R FFF A S ADDRESS S DATA CRC7 E
0 1 110100 1 000 1 0 00000000000000110 0 00001000 1010111 1