Merge branch 'feat/add_sdio_slave_reset_hardware_support' into 'master'

add sdio_slave_reset_hw

See merge request espressif/esp-idf!39686
This commit is contained in:
Li Peng
2025-06-24 16:10:17 +08:00
6 changed files with 68 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -92,10 +92,20 @@ void sdio_slave_stop(void);
/** Clear the data still in the driver, as well as reset the PKT_LEN and TOKEN1 counting. /** Clear the data still in the driver, as well as reset the PKT_LEN and TOKEN1 counting.
* *
* @return always return ESP_OK. * @return
* - ESP_ERR_INVALID_STATE if already started.
* - ESP_OK otherwise.
*/ */
esp_err_t sdio_slave_reset(void); esp_err_t sdio_slave_reset(void);
/** Reset sdio hardware, and clear the data still in the driver, as well as reset the PKT_LEN and TOKEN1 counting.
*
* @return
* - ESP_ERR_INVALID_STATE if already started.
* - ESP_OK otherwise.
*/
esp_err_t sdio_slave_reset_hw(void);
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Receive * Receive
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
@@ -220,7 +230,7 @@ esp_err_t sdio_slave_transmit(uint8_t* addr, size_t len);
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Host * Host
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
/** Read the spi slave register shared with host. /** Read the sdio slave register shared with host.
* *
* @param pos register address, 0-27 or 32-63. * @param pos register address, 0-27 or 32-63.
* *
@@ -230,7 +240,7 @@ esp_err_t sdio_slave_transmit(uint8_t* addr, size_t len);
*/ */
uint8_t sdio_slave_read_reg(int pos); uint8_t sdio_slave_read_reg(int pos);
/** Write the spi slave register shared with host. /** Write the sdio slave register shared with host.
* *
* @param pos register address, 0-11, 14-15, 18-19, 24-27 and 32-63, other address are reserved. * @param pos register address, 0-11, 14-15, 18-19, 24-27 and 32-63, other address are reserved.
* @param reg the value to write. * @param reg the value to write.

View File

@@ -456,6 +456,13 @@ esp_err_t sdio_slave_reset(void)
return err; return err;
} }
esp_err_t sdio_slave_reset_hw(void)
{
sdio_slave_hw_deinit();
sdio_slave_hw_init(&context.config);
return sdio_slave_reset();
}
void sdio_slave_stop(void) void sdio_slave_stop(void)
{ {
sdio_slave_hal_set_ioready(context.hal, false); sdio_slave_hal_set_ioready(context.hal, false);

View File

@@ -203,7 +203,7 @@ TEST_CASE("SDIO_SDMMC: test register", "[sdio]")
/*--------------------------------------------------------------- /*---------------------------------------------------------------
SDMMC_SDIO: test reset SDMMC_SDIO: test reset
---------------------------------------------------------------*/ ---------------------------------------------------------------*/
TEST_CASE("SDIO_SDMMC: test reset", "[sdio]") static void test_reset(void)
{ {
essl_handle_t handle = NULL; essl_handle_t handle = NULL;
test_sdio_param_t test_param = { test_sdio_param_t test_param = {
@@ -243,6 +243,16 @@ TEST_CASE("SDIO_SDMMC: test reset", "[sdio]")
s_master_deinit(); s_master_deinit();
} }
TEST_CASE("SDIO_SDMMC: test reset", "[sdio]")
{
test_reset();
}
TEST_CASE("SDIO_SDMMC: test reset hw", "[sdio]")
{
test_reset();
}
/*--------------------------------------------------------------- /*---------------------------------------------------------------
SDMMC_SDIO: test fixed addr SDMMC_SDIO: test fixed addr
---------------------------------------------------------------*/ ---------------------------------------------------------------*/

View File

@@ -105,14 +105,18 @@ TEST_CASE("SDIO_Slave: test register", "[sdio]")
/*--------------------------------------------------------------- /*---------------------------------------------------------------
SDMMC_SDIO: test reset SDMMC_SDIO: test reset
---------------------------------------------------------------*/ ---------------------------------------------------------------*/
TEST_CASE("SDIO_Slave: test reset", "[sdio]") static void test_reset(bool reset_hw)
{ {
s_slave_init(SDIO_SLAVE_SEND_PACKET); s_slave_init(SDIO_SLAVE_SEND_PACKET);
TEST_ESP_OK(sdio_slave_start()); TEST_ESP_OK(sdio_slave_start());
ESP_LOGI(TAG, "slave ready"); ESP_LOGI(TAG, "slave ready");
sdio_slave_stop(); sdio_slave_stop();
if (!reset_hw) {
TEST_ESP_OK(sdio_slave_reset()); TEST_ESP_OK(sdio_slave_reset());
} else {
TEST_ESP_OK(sdio_slave_reset_hw());
}
TEST_ESP_OK(sdio_slave_start()); TEST_ESP_OK(sdio_slave_start());
//tx //tx
@@ -155,6 +159,16 @@ TEST_CASE("SDIO_Slave: test reset", "[sdio]")
sdio_slave_deinit(); sdio_slave_deinit();
} }
TEST_CASE("SDIO_Slave: test reset", "[sdio]")
{
test_reset(false);
}
TEST_CASE("SDIO_Slave: test reset hw", "[sdio]")
{
test_reset(true);
}
/*--------------------------------------------------------------- /*---------------------------------------------------------------
SDMMC_SDIO: test fixed addr SDMMC_SDIO: test fixed addr
---------------------------------------------------------------*/ ---------------------------------------------------------------*/

View File

@@ -276,6 +276,16 @@ There are several ways to use the ``arg`` in the queue parameter:
For more about this, see :example:`peripherals/sdio`. For more about this, see :example:`peripherals/sdio`.
Reset SDIO
^^^^^^^^^^^^
Calling ``sdio_slave_reset`` can reset PKT_LEN (Packet length accumulator value) and TOKEN1 (Receiving buffers accumulated number) at the SDIO slave driver software level to resynchronize the transmit and receive counts with the host.
If there is a usage scenario where the ESP chip remains powered on but the HOST is powered off. During the power-off period of the HOST, some unknown signals may be generated on the SDIO signal line, causing the SDIO hardware state machine to be abnormal. The HOST restarts and executes the card identification process, and the ESP will not respond normally. In this case, consider calling ``sdio_slave_reset_hw`` to reset the SDIO hardware.
.. note::
Reset the SDIO hardware. The interrupt enable status and shared register values will be lost. You may need to call ``sdio_slave_set_host_intena`` and ``sdio_slave_write_reg`` to set them.
Application Example Application Example
------------------- -------------------

View File

@@ -276,6 +276,16 @@ SDIO 从机驱动程序的相关术语如下:
更多详情,请参阅 :example:`peripherals/sdio` 更多详情,请参阅 :example:`peripherals/sdio`
重置 SDIO
^^^^^^^^^^^^
调用 ``sdio_slave_reset`` 可以重置 SDIO 从机驱动程序软件层面的 PKT_LEN (从机发送包长度累加值) 和 TOKEN1 (接收 buffer 累计数量), 便于与主机重新同步收发计数。
如果存在 ESP 芯片保持上电状态,但 HOST 端会下电的使用场景。HOST 端下电期间, SDIO 信号线上可能会产生一些未知的信号导致 SDIO 硬件状态机异常。HOST 重新启动, 执行卡识别流程, ESP 将不会正常响应。这种情况下,考虑调用 ``sdio_slave_reset_hw``, 重置 SDIO 硬件。
.. note::
重置 SDIO 硬件,中断使能状态和共享寄存器的值会丢失,可能需要调用 ``sdio_slave_set_host_intena````sdio_slave_write_reg`` 设置。
应用示例 应用示例
-------- --------