esp-hosted
esp-hosted copied to clipboard
Switching SDIO speeds in feature branch
First off. Long time no see. I would like to propose a pull request of my stm32h7 host code. It is pretty complete except for the SDIOIT part and the topic of this issue. I don't think I have things set up properly to transfer to high speed sdio after the initial negotiation with the esp32 slave. the stm32 host codebase is now updated to the currnet esp_as_mcu_host but the command look a bit stale on my front, in telling the slave to switch to a faster clock speed:
/**
**
* @brief Initialize GPSIO in SDMMC AF
* Please check SDMMC_reg.h for pin definitions
*
* @param None
* @retval None
*/
void sdio_gpio_init(void)
{
HAL_SD_MspInit(hsd1);
}
int sdio_card_init(void *ctx)
{
log_sdio_clock_settings();
INIT_SDIO_DEBUG();
uint8_t bus_width;
SDMMC_CmdInitTypeDef cmd;
HAL_StatusTypeDef errorstate;
g_h.funcs->_h_evt_grp_setbits(wait_trans_evt_grp, SDIO_DATA_FREE_BIT);
uint32_t sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
__HAL_RCC_SDMMC1_CLK_ENABLE();
SD_InitTypeDef sdmmc_init = {
.ClockEdge = SDMMC_CLOCK_EDGE_RISING,
.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE,
.BusWide = SDMMC_BUS_WIDE_1B,
.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE,
.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ)};
sdio_trans_ready_mutex = g_h.funcs->_h_create_semaphore(10);
SDMMC_Init(hsd1->Instance, sdmmc_init);
hsd1->Instance->DCTRL |= SDMMC_DCTRL_SDIOEN;
hsd1->Instance->POWER |= SDMMC_POWER_PWRCTRL;
/* wait 74 Cycles: required power up waiting time before starting
the SD initialization sequence */
HAL_Delay(1U + (74U * 1000U / (sdmmc_clk / (2U * sdmmc_init.ClockDiv))));
/* Enable SDMMC */
/* EXTI interrupt init*/
// HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
// HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
// __SDMMC_ENABLE_IT(hsd1->Instance, SDMMC_IT_SDIOIT);
__SDMMC_OPERATION_ENABLE(hsd1->Instance);
HAL_Delay(1U + (74U * 1000U / (sdmmc_clk / (2U * sdmmc_init.ClockDiv))));
/* Command 0 - SD reset */
cmd.Argument = 0U;
cmd.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
cmd.Response = SDMMC_RESPONSE_NO;
cmd.WaitForInterrupt = SDMMC_WAIT_NO;
cmd.CPSM = SDMMC_CPSM_ENABLE;
SDMMC_SendCommandWait(&cmd);
/* Command 5 - IO_SEND_OP_COND */
cmd.Argument = 0U;
cmd.CmdIndex = SDMMC_CMD_SDMMC_SEN_OP_COND;
SDMMC_SendCommandWait(&cmd);
/* Command 5 - Set VDD Voltage Window: 3.2~3.4V */
cmd.Argument = 0x00FF8000;
SDMMC_SendCommandWait(&cmd);
/* Command 3 - Get WiFi address (CMD3: SEND_RELATIVE_ADDR,
* Ask the card to publish a new relative address (RCA)) */
cmd.Argument = 0;
cmd.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
cmd.Response = SDMMC_RESPONSE_SHORT;
SDMMC_SendCommandWait(&cmd);
hsd1->SdCard.RelCardAdd = SDMMC_GetResponse(hsd1->Instance, SDMMC_RESP1);
/* Command 7 - Select WiFi (SELECT/DESELECT_CARD) */
cmd.Argument = 0;
cmd.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
SDMMC_SendCommandWait(&cmd);
hsd1->SdCard.BlockSize = SDMMC_GetResponse(hsd1->Instance, SDMMC_RESP1);
/* Above sequence is needed while communicating to IO only device.
* In case of failure/timeouts despite of maximum retry, IO would be unusable
*/
ESP_LOGI(TAG, "RCA: %lu", hsd1->SdCard.RelCardAdd);
cmd.Argument = hsd1->SdCard.RelCardAdd;
cmd.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
SDMMC_SendCommandWait(&cmd);
uint8_t card_cap = 0;
sdio_io_read_byte(hsd1, SDIO_FUNC_0, SD_IO_CCCR_CARD_CAP, &card_cap);
if (!(card_cap & CCCR_CARD_CAP_LSC) || (card_cap & CCCR_CARD_CAP_4BLS))
{
bus_width = CCCR_BUS_WIDTH_4;
}
sdio_io_read_byte(hsd1, SDIO_FUNC_0, SD_IO_CCCR_BUS_WIDTH, &bus_width);
ESP_LOGI(TAG, "Bus Width 0x%02x. sdmmc_clk: %d ClockDiv %d", bus_width, sdmmc_clk, sdmmc_init.ClockDiv);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, SD_IO_CCCR_BUS_WIDTH, CCCR_BUS_WIDTH_4, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x02, 0x02, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x10, 0x00, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x11, 0x02, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x110, 0x00, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x111, 0x02, NULL);
sdmmc_init.BusWide = SDMMC_BUS_WIDE_4B;
sdmmc_init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
sdmmc_init.ClockDiv = 0;
errorstate = SDMMC_Init(hsd1->Instance, sdmmc_init);
hsd1->Instance->DCTRL |= SDMMC_DCTRL_SDIOEN;
if (errorstate)
return ESP_FAIL;
sdio_io_read_byte(hsd1, SDIO_FUNC_0, SD_IO_CCCR_BUS_WIDTH, &bus_width);
ESP_LOGI(TAG, "Bus Width 0x%02x. sdmmc_clk: %d ClockDiv %d", bus_width, sdmmc_clk, sdmmc_init.ClockDiv);
hsd1->State = HAL_SD_STATE_READY;
// output CIS info from the slave
if (hosted_sdio_print_cis_information(hsd1) != ESP_OK)
{
ESP_LOGW(TAG, "failed to print card info");
}
// initialise the card functions
if (hosted_sdio_card_fn_init(hsd1) != ESP_OK)
{
ESP_LOGE(TAG, "hosted_sdio_init failed");
return ESP_FAIL;
}
return ESP_OK;
}
the part in question is either
sdio_io_write_byte(hsd1, SDIO_FUNC_0, SD_IO_CCCR_BUS_WIDTH, CCCR_BUS_WIDTH_4, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x02, 0x02, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x10, 0x00, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x11, 0x02, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x110, 0x00, NULL);
sdio_io_write_byte(hsd1, SDIO_FUNC_0, 0x111, 0x02, NULL);
sdmmc_init.BusWide = SDMMC_BUS_WIDE_4B;
sdmmc_init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
sdmmc_init.ClockDiv = 0; << strange behaviour as I can't seem to get communication at any other clockspeed
or (and my memory is hazy on this)
if (hosted_sdio_card_fn_init(hsd1) != ESP_OK)
where do we tell the slave to change speed?
I hope everything is good with you and I hope to commence my project successfully as from when we last chatted.