From 01080bb062a9d6f84def562dee700304e5101062 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Thu, 10 Jul 2025 11:17:07 +0800 Subject: [PATCH 1/3] fix(sdio): supported slave sdio on esp32c61 --- .../sdio/sdio_common_tests/sdio/README.md | 4 +- .../hal/esp32c61/include/hal/sdio_slave_ll.h | 538 ++++++++++++++++++ .../esp32c61/include/soc/Kconfig.soc_caps.in | 4 + .../esp32c61/include/soc/sdio_slave_pins.h | 14 + .../soc/esp32c61/include/soc/soc_caps.h | 2 +- components/soc/esp32c61/sdio_slave_periph.c | 20 + examples/peripherals/sdio/slave/README.md | 4 +- 7 files changed, 581 insertions(+), 5 deletions(-) create mode 100644 components/hal/esp32c61/include/hal/sdio_slave_ll.h create mode 100644 components/soc/esp32c61/include/soc/sdio_slave_pins.h create mode 100644 components/soc/esp32c61/sdio_slave_periph.c diff --git a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/README.md b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/README.md index 6cd75100aa..f8cbceb22b 100644 --- a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/README.md +++ b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | -| ----------------- | ----- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-C61 | +| ----------------- | ----- | -------- | -------- | --------- | # SDIO Cross Chips Test Apps: SDIO Slave App diff --git a/components/hal/esp32c61/include/hal/sdio_slave_ll.h b/components/hal/esp32c61/include/hal/sdio_slave_ll.h new file mode 100644 index 0000000000..fb746c8b4f --- /dev/null +++ b/components/hal/esp32c61/include/hal/sdio_slave_ll.h @@ -0,0 +1,538 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The LL layer for SDIO slave register operations +// It's strange but `tx_*` regs for host->slave transfers while `rx_*` regs for slave->host transfers +// To reduce ambiguity, we call (host->slave, tx) transfers receiving and (slave->host, rx) transfers receiving + +#pragma once + +#include +#include +#include "hal/sdio_slave_types.h" +#include "hal/misc.h" +#include "soc/sdio_slc_struct.h" +#include "soc/sdio_slc_reg.h" +#include "soc/sdio_slc_host_struct.h" +#include "soc/sdio_slc_host_reg.h" +#include "soc/sdio_hinf_struct.h" +#include "soc/pcr_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// Get address of the only SLC registers +#define sdio_slave_ll_get_slc(ID) (&SLC) +/// Get address of the only HOST registers +#define sdio_slave_ll_get_host(ID) (&HOST) +/// Get address of the only HINF registers +#define sdio_slave_ll_get_hinf(ID) (&HINF) + +/* + * SLC2 DMA Desc struct, aka sdio_slave_ll_desc_t + * + * -------------------------------------------------------------- + * | own | EoF | sub_sof | 1'b0 | length [13:0] | size [13:0] | + * -------------------------------------------------------------- + * | buf_ptr [31:0] | + * -------------------------------------------------------------- + * | next_desc_ptr [31:0] | + * -------------------------------------------------------------- + */ + +/* this bitfield is start from the LSB!!! */ +typedef struct sdio_slave_ll_desc_s { + volatile uint32_t size : 14, + length: 14, + offset: 1, /* starting from bit28, h/w reserved 1bit, s/w use it as offset in buffer */ + sosf : 1, /* start of sub-frame */ + eof : 1, /* end of frame */ + owner : 1; /* hw or sw */ + volatile const uint8_t *buf; /* point to buffer data */ + union { + volatile uint32_t empty; + STAILQ_ENTRY(sdio_slave_ll_desc_s) qe; /* pointing to the next desc */ + }; +} sdio_slave_ll_desc_t; + +/// Mask of general purpose interrupts sending from the host. +typedef enum { + SDIO_SLAVE_LL_SLVINT_0 = BIT(0), ///< General purpose interrupt bit 0. + SDIO_SLAVE_LL_SLVINT_1 = BIT(1), + SDIO_SLAVE_LL_SLVINT_2 = BIT(2), + SDIO_SLAVE_LL_SLVINT_3 = BIT(3), + SDIO_SLAVE_LL_SLVINT_4 = BIT(4), + SDIO_SLAVE_LL_SLVINT_5 = BIT(5), + SDIO_SLAVE_LL_SLVINT_6 = BIT(6), + SDIO_SLAVE_LL_SLVINT_7 = BIT(7), +} sdio_slave_ll_slvint_t; + +/** + * @brief Enable the bus clock for the SDIO slave module + * + * @param enable true to enable, false to disable + */ +static inline void sdio_slave_ll_enable_bus_clock(bool enable) +{ + PCR.sdio_slave_conf.sdio_slave_clk_en = enable; +} + +/** + * @brief Reset the SDIO slave module + */ +static inline void sdio_slave_ll_reset_register(void) +{ + PCR.sdio_slave_conf.sdio_slave_rst_en = 1; + PCR.sdio_slave_conf.sdio_slave_rst_en = 0; +} + +/** + * Initialize the hardware. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_init(slc_dev_t *slc) +{ + slc->slc_slc0int_ena.val = 0; + + slc->slc_conf0.slc0_rx_auto_wrback = 1; + slc->slc_conf0.slc0_token_auto_clr = 0; + slc->slc_conf0.slc0_rx_loop_test = 0; + slc->slc_conf0.slc0_tx_loop_test = 0; + + slc->slc_conf1.slc0_rx_stitch_en = 0; + slc->slc_conf1.slc0_tx_stitch_en = 0; + slc->slc_conf1.slc0_len_auto_clr = 0; + + slc->slc_rx_dscr_conf.slc0_token_no_replace = 1; +} + +/** + * Set the timing for the communication + * + * @param host Address of the host registers + * @param timing Timing configuration to set + */ +static inline void sdio_slave_ll_set_timing(host_dev_t *host, sdio_slave_timing_t timing) +{ + switch (timing) { + case SDIO_SLAVE_TIMING_PSEND_PSAMPLE: + host->slc_host_conf.slchost_frc_sdio20 = 0x1f; + host->slc_host_conf.slchost_frc_sdio11 = 0; + host->slc_host_conf.slchost_frc_pos_samp = 0x1f; + host->slc_host_conf.slchost_frc_neg_samp = 0; + break; + case SDIO_SLAVE_TIMING_PSEND_NSAMPLE: + host->slc_host_conf.slchost_frc_sdio20 = 0x1f; + host->slc_host_conf.slchost_frc_sdio11 = 0; + host->slc_host_conf.slchost_frc_pos_samp = 0; + host->slc_host_conf.slchost_frc_neg_samp = 0x1f; + break; + case SDIO_SLAVE_TIMING_NSEND_PSAMPLE: + host->slc_host_conf.slchost_frc_sdio20 = 0; + host->slc_host_conf.slchost_frc_sdio11 = 0x1f; + host->slc_host_conf.slchost_frc_pos_samp = 0x1f; + host->slc_host_conf.slchost_frc_neg_samp = 0; + break; + case SDIO_SLAVE_TIMING_NSEND_NSAMPLE: + host->slc_host_conf.slchost_frc_sdio20 = 0; + host->slc_host_conf.slchost_frc_sdio11 = 0x1f; + host->slc_host_conf.slchost_frc_pos_samp = 0; + host->slc_host_conf.slchost_frc_neg_samp = 0x1f; + break; + } +} + +/** + * Set the CCCR, SDIO and Physical Layer version + */ +static inline void sdio_slave_ll_init_version(hinf_dev_t *hinf) +{ + hinf->cfg_data1.sdio_ver = 0x232; +} + +/** + * Set the HS supported bit to be read by the host. + * + * @param hinf Address of the hinf registers + * @param hs true if supported, otherwise false. + */ +static inline void sdio_slave_ll_enable_hs(hinf_dev_t *hinf, bool hs) +{ + if (hs) { + hinf->cfg_data1.highspeed_enable = 1; + } else { + hinf->cfg_data1.highspeed_enable = 0; + } +} + +/** + * Set the IO Ready bit to be read by the host. + * + * @param hinf Address of the hinf registers + * @param ready true if ready, otherwise false. + */ +static inline void sdio_slave_ll_set_ioready(hinf_dev_t *hinf, bool ready) +{ + hinf->cfg_data1.sdio_ioready1 = (ready ? 1 : 0); //set IO ready to 1 to stop host from using +} + +/*--------------------------------------------------------------------------- + * Send + *--------------------------------------------------------------------------*/ +/** + * Reset the sending DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_reset(slc_dev_t *slc) +{ + //reset to flush previous packets + slc->slc_conf0.slc0_rx_rst = 1; + slc->slc_conf0.slc0_rx_rst = 0; +} + +/** + * Start the sending DMA with the given descriptor. + * + * @param slc Address of the SLC registers + * @param desc Descriptor to send + */ +static inline void sdio_slave_ll_send_start(slc_dev_t *slc, const sdio_slave_ll_desc_t *desc) +{ + slc->slc_slc0rx_link_addr.slc0_rxlink_addr = (uint32_t)desc; + slc->slc_slc0rx_link.slc0_rxlink_start = 1; +} + +/** + * Write the PKT_LEN register to be written by the host to a certain value. + * + * @param slc Address of the SLC registers + * @param len Length to write + */ +static inline void sdio_slave_ll_send_write_len(slc_dev_t *slc, uint32_t len) +{ + slc->slc_slc0_len_conf.val = FIELD_TO_VALUE2(SDIO_SLC0_LEN_WDATA, len) | FIELD_TO_VALUE2(SDIO_SLC0_LEN_WR, 1); +} + +/** + * Read the value of PKT_LEN register. The register may keep the same until read + * by the host. + * + * @param host Address of the host registers + * @return The value of PKT_LEN register. + */ +static inline uint32_t sdio_slave_ll_send_read_len(host_dev_t *host) +{ + return host->slc_host_pkt_len.slchost_hostslchost_slc0_len; +} + +/** + * Enable the rx_done interrupt. (sending) + * + * @param slc Address of the SLC registers + * @param ena true if enable, otherwise false. + */ +static inline void sdio_slave_ll_send_part_done_intr_ena(slc_dev_t *slc, bool ena) +{ + slc->slc_slc0int_ena.slc0_rx_done_int_ena = (ena ? 1 : 0); +} + +/** + * Clear the rx_done interrupt. (sending) + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_part_done_clear(slc_dev_t *slc) +{ + slc->slc_slc0int_clr.slc0_rx_done_int_clr = 1; +} + +/** + * Check whether the hardware is ready for the SW to use rx_done to invoke + * the ISR. + * + * @param slc Address of the SLC registers + * @return true if ready, otherwise false. + */ +static inline bool sdio_slave_ll_send_invoker_ready(slc_dev_t *slc) +{ + return slc->slc_slc0int_raw.slc0_rx_done_int_raw; +} + +/** + * Stop the sending DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_stop(slc_dev_t *slc) +{ + slc->slc_slc0rx_link.slc0_rxlink_stop = 1; +} + +/** + * Enable the sending interrupt (rx_eof). + * + * @param slc Address of the SLC registers + * @param ena true to enable, false to disable + */ +static inline void sdio_slave_ll_send_intr_ena(slc_dev_t *slc, bool ena) +{ + slc->slc_slc0int_ena.slc0_rx_eof_int_ena = (ena ? 1 : 0); +} + +/** + * Clear the sending interrupt (rx_eof). + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_send_intr_clr(slc_dev_t *slc) +{ + slc->slc_slc0int_clr.slc0_rx_eof_int_clr = 1; +} + +/** + * Check whether the sending is done. + * + * @param slc Address of the SLC registers + * @return true if done, otherwise false + */ +static inline bool sdio_slave_ll_send_done(slc_dev_t *slc) +{ + return slc->slc_slc0int_st.slc0_rx_eof_int_st != 0; +} + +/** + * Clear the host interrupt indicating the slave having packet to be read. + * + * @param host Address of the host registers + */ +static inline void sdio_slave_ll_send_hostint_clr(host_dev_t *host) +{ + host->slc_host_slc0host_int_clr.slchost_slc0_rx_new_packet_int_clr = 1; +} + +/*--------------------------------------------------------------------------- + * Receive + *--------------------------------------------------------------------------*/ +/** + * Enable the receiving interrupt. + * + * @param slc Address of the SLC registers + * @param ena + */ +static inline void sdio_slave_ll_recv_intr_ena(slc_dev_t *slc, bool ena) +{ + slc->slc_slc0int_ena.slc0_tx_done_int_ena = (ena ? 1 : 0); +} + +/** + * Start receiving DMA with the given descriptor. + * + * @param slc Address of the SLC registers + * @param desc Descriptor of the receiving buffer. + */ +static inline void sdio_slave_ll_recv_start(slc_dev_t *slc, sdio_slave_ll_desc_t *desc) +{ + slc->slc_slc0tx_link_addr.slc0_txlink_addr = (uint32_t)desc; + slc->slc_slc0tx_link.slc0_txlink_start = 1; +} + +/** + * Increase the receiving buffer counter by 1. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_size_inc(slc_dev_t *slc) +{ + // fields wdata and inc_more should be written by the same instruction. + slc->slc_slc0token1.val = FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WDATA, 1) | FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_INC_MORE, 1); +} + +/** + * Reset the receiving buffer. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_size_reset(slc_dev_t *slc) +{ + slc->slc_slc0token1.val = FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WDATA, 0) | FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WR, 1); +} + +/** + * Check whether there is a receiving finished event. + * + * @param slc Address of the SLC registers + * @return + */ +static inline bool sdio_slave_ll_recv_done(slc_dev_t *slc) +{ + return slc->slc_slc0int_raw.slc0_tx_done_int_raw != 0; +} + +/** + * Clear the receiving finished interrupt. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_done_clear(slc_dev_t *slc) +{ + slc->slc_slc0int_clr.slc0_tx_done_int_clr = 1; +} + +/** + * Restart the DMA. Call after you modified the next pointer of the tail descriptor to the appended + * descriptor. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_restart(slc_dev_t *slc) +{ + slc->slc_slc0tx_link.slc0_txlink_restart = 1; +} + +/** + * Reset the receiving DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_reset(slc_dev_t *slc) +{ + slc->slc_conf0.slc0_tx_rst = 1; + slc->slc_conf0.slc0_tx_rst = 0; +} + +/** + * Stop the receiving DMA. + * + * @param slc Address of the SLC registers + */ +static inline void sdio_slave_ll_recv_stop(slc_dev_t *slc) +{ + slc->slc_slc0tx_link.slc0_txlink_stop = 1; +} + +/*--------------------------------------------------------------------------- + * Host + *--------------------------------------------------------------------------*/ +/** + * Get the address of the shared general purpose register. Internal. + * + * @param host Address of the host registers + * @param pos Position of the register, 0-63 except 24-27. + * @return address of the register. + */ +static inline intptr_t sdio_slave_ll_host_get_w_reg(host_dev_t *host, int pos) +{ + return (intptr_t) & (host->slc_host_conf_w0) + pos + (pos > 23 ? 4 : 0) + (pos > 31 ? 12 : 0); +} + +/** + * Get the value of the shared general purpose register. + * + * @param host Address of the host registers + * @param pos Position of the register, 0-63, except 24-27. + * @return value of the register. + */ +static inline uint8_t sdio_slave_ll_host_get_reg(host_dev_t *host, int pos) +{ + return *(uint8_t *)sdio_slave_ll_host_get_w_reg(host, pos); +} + +/** + * Set the value of the shared general purpose register. + * + * @param host Address of the host registers + * @param pos Position of the register, 0-63, except 24-27. + * @param reg Value to set. + */ +static inline void sdio_slave_ll_host_set_reg(host_dev_t *host, int pos, uint8_t reg) +{ + uint32_t *addr = (uint32_t *)(sdio_slave_ll_host_get_w_reg(host, pos) & (~3)); + uint32_t shift = (pos % 4) * 8; + *addr &= ~(0xff << shift); + *addr |= ((uint32_t)reg << shift); +} + +/** + * Get the interrupt enable bits for the host. + * + * @param host Address of the host registers + * @return Enabled interrupts + */ +static inline sdio_slave_hostint_t sdio_slave_ll_host_get_intena(host_dev_t *host) +{ + return (sdio_slave_hostint_t)host->slc_host_slc0host_func1_int_ena.val; +} + +/** + * Set the interrupt enable bits for the host. + * + * @param host Address of the host registers + * @param mask Mask of interrupts to enable + */ +static inline void sdio_slave_ll_host_set_intena(host_dev_t *host, const sdio_slave_hostint_t *mask) +{ + host->slc_host_slc0host_func1_int_ena.val = (*mask); +} + +/** + * Clear the interrupt bits for the host. + * @param host Address of the host registers + * @param mask Mask of interrupts to clear. + */ +static inline void sdio_slave_ll_host_intr_clear(host_dev_t *host, const sdio_slave_hostint_t *mask) +{ + host->slc_host_slc0host_int_clr.val = (*mask); +} + +/** + * Send general purpose interrupts to the host. + * @param slc Address of the SLC registers + * @param mask Mask of interrupts to seend to host + */ +static inline void sdio_slave_ll_host_send_int(slc_dev_t *slc, const sdio_slave_hostint_t *mask) +{ + //use registers in SLC to trigger, rather than write HOST registers directly + //other interrupts than tohost interrupts are not supported yet + HAL_FORCE_MODIFY_U32_REG_FIELD(slc->slc_slcintvec_tohost, slc0_tohost_intvec, *mask); +} + +/** + * Enable some of the slave interrupts (send from host) + * + * @param slc Address of the SLC registers + * @param mask Mask of interrupts to enable, all those set to 0 will be disabled. + */ +static inline void sdio_slave_ll_slvint_set_ena(slc_dev_t *slc, const sdio_slave_ll_slvint_t *mask) +{ + //other interrupts are not enabled + slc->slc_slc0int_ena.val = (slc->slc_slc0int_ena.val & (~0xff)) | ((*mask) & 0xff); +} + +/** + * Fetch the slave interrupts (send from host) and clear them. + * + * @param slc Address of the SLC registers + * @param out_slv_int Output of the slave interrupts fetched and cleared. + */ +static inline void sdio_slave_ll_slvint_fetch_clear(slc_dev_t *slc, sdio_slave_ll_slvint_t *out_slv_int) +{ + sdio_slave_ll_slvint_t slv_int = (sdio_slave_ll_slvint_t)(slc->slc_slc0int_st.val & 0xff); + *out_slv_int = slv_int; + slc->slc_slc0int_clr.val = slv_int; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index c00c0a0e08..2377889f4a 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -155,6 +155,10 @@ config SOC_ETM_SUPPORTED bool default y +config SOC_SDIO_SLAVE_SUPPORTED + bool + default y + config SOC_PAU_SUPPORTED bool default y diff --git a/components/soc/esp32c61/include/soc/sdio_slave_pins.h b/components/soc/esp32c61/include/soc/sdio_slave_pins.h new file mode 100644 index 0000000000..d177e91355 --- /dev/null +++ b/components/soc/esp32c61/include/soc/sdio_slave_pins.h @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 25 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 26 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 27 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 28 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2 22 +#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3 23 +#define SDIO_SLAVE_SLOT0_FUNC 0 diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index b080b1b16b..0eb445721b 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -64,7 +64,7 @@ #define SOC_MODEM_CLOCK_SUPPORTED 1 #define SOC_REG_I2C_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 -// \#define SOC_SDIO_SLAVE_SUPPORTED 0 +#define SOC_SDIO_SLAVE_SUPPORTED 1 #define SOC_PAU_SUPPORTED 1 #define SOC_LIGHT_SLEEP_SUPPORTED 1 #define SOC_DEEP_SLEEP_SUPPORTED 1 diff --git a/components/soc/esp32c61/sdio_slave_periph.c b/components/soc/esp32c61/sdio_slave_periph.c new file mode 100644 index 0000000000..251ff82cb7 --- /dev/null +++ b/components/soc/esp32c61/sdio_slave_periph.c @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "soc/sdio_slave_periph.h" +#include "soc/sdio_slave_pins.h" + +const sdio_slave_slot_info_t sdio_slave_slot_info[1] = { + { + .clk_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK, + .cmd_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD, + .d0_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0, + .d1_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1, + .d2_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2, + .d3_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3, + .func = SDIO_SLAVE_SLOT0_FUNC, + }, +}; diff --git a/examples/peripherals/sdio/slave/README.md b/examples/peripherals/sdio/slave/README.md index 163e5cc415..593707c9d6 100644 --- a/examples/peripherals/sdio/slave/README.md +++ b/examples/peripherals/sdio/slave/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | -| ----------------- | ----- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-C61 | +| ----------------- | ----- | -------- | -------- | --------- | See README.md in the parent folder From d3e2177342fabfe35c0b3bcc58069f901f45b477 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Tue, 15 Jul 2025 10:12:08 +0800 Subject: [PATCH 2/3] ci(sdio): enable 32_c61 sdio test and runner --- .../host_sdmmc/main/Kconfig.projbuild | 4 +- .../sdio/sdio_common_tests/pytest_sdio.py | 47 +++++++++++++++++++ pytest.ini | 1 + 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/Kconfig.projbuild b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/Kconfig.projbuild index fcfd842856..b744e7ce35 100644 --- a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/Kconfig.projbuild +++ b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/Kconfig.projbuild @@ -3,12 +3,10 @@ menu "SDIO Slave Test Host Configuration" prompt "SDIO Slave Chip" default TEST_SDIO_SLAVE_TARGET_ESP32 help - SDIO Slave chip target + default test board conditions targets: ESP32, ESP32C6, ESP32C61 config TEST_SDIO_SLAVE_TARGET_ESP32 bool "SDIO Slave ESP32" - config TEST_SDIO_SLAVE_TARGET_ESP32C6 - bool "SDIO Slave ESP32C6" config TEST_SDIO_SLAVE_TARGET_ESP32C5 bool "SDIO Slave ESP32C5" endchoice diff --git a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py index aae7644179..6728893cc9 100644 --- a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py +++ b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py @@ -36,9 +36,17 @@ esp32p4_c5_param = [ ] ] +esp32_c61_param = [ + [ + f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}', + 'esp32|esp32c61', + ] +] + esp32_param_default = [pytest.param(*param) for param in parameter_expand(esp32_32_param, ['default|default'])] c6_param_default = [pytest.param(*param) for param in parameter_expand(esp32_c6_param, ['default|default'])] c5_param_default = [pytest.param(*param) for param in parameter_expand(esp32p4_c5_param, ['esp32p4_esp32c5|default'])] +c61_param_default = [pytest.param(*param) for param in parameter_expand(esp32_c61_param, ['default|default'])] c6_param_retention = [pytest.param(*param) for param in parameter_expand(esp32_c6_param, ['default|sleep_retention'])] @@ -95,6 +103,19 @@ def test_sdio_esp32p4_esp32c5(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_flow(dut) +@pytest.mark.sdio_multidev_32_c61 +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) +@pytest.mark.parametrize('app_path, target, config', c61_param_default, indirect=True) +def test_sdio_esp32_esp32c61(dut: Tuple[IdfDut, IdfDut]) -> None: + test_sdio_flow(dut) + + # From host speed tests def test_sdio_speed_frhost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: dut[1].expect('Press ENTER to see the list of tests') @@ -154,6 +175,19 @@ def test_sdio_speed_frhost_esp32p4_esp32c5(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_speed_frhost_flow(dut, 10000, 4000) +@pytest.mark.sdio_multidev_32_c61 +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) +@pytest.mark.parametrize('app_path, target, config', c61_param_default, indirect=True) +def test_sdio_speed_frhost_esp32_esp32c61(dut: Tuple[IdfDut, IdfDut]) -> None: + test_sdio_speed_frhost_flow(dut, 10000, 4000) + + # To host speed tests def test_sdio_speed_tohost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: dut[1].expect('Press ENTER to see the list of tests') @@ -213,6 +247,19 @@ def test_sdio_speed_tohost_esp32p4_esp32c5(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_speed_tohost_flow(dut, 8500, 4000) +@pytest.mark.sdio_multidev_32_c61 +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) +@pytest.mark.parametrize('app_path, target, config', c61_param_default, indirect=True) +def test_sdio_speed_tohost_esp32_esp32c61(dut: Tuple[IdfDut, IdfDut]) -> None: + test_sdio_speed_tohost_flow(dut, 8500, 4000) + + # Retention tests def test_sdio_retention(dut: Tuple[IdfDut, IdfDut]) -> None: dut[1].expect('Press ENTER to see the list of tests') diff --git a/pytest.ini b/pytest.ini index 5d570974f9..e12d1747bd 100644 --- a/pytest.ini +++ b/pytest.ini @@ -119,6 +119,7 @@ env_markers = twai_network: multiple runners form a TWAI network. sdio_master_slave: Test sdio multi board, esp32+esp32 sdio_multidev_32_c6: Test sdio multi board, esp32+esp32c6 + sdio_multidev_32_c61: Test sdio multi board, esp32+esp32c61 sdio_multidev_p4_c5: Test sdio multi board, esp32p4+esp32c5 usj_device: Test usb_serial_jtag and usb_serial_jtag is used as serial only (not console) twai_std: twai runner with all twai supported targets connect to usb-can adapter From a4bbc07ad851adf2fecab67f8a9b25cebbbf45b1 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Tue, 15 Jul 2025 10:12:41 +0800 Subject: [PATCH 3/3] docs(sdio): update c61 sdio support docs --- docs/conf_common.py | 2 +- docs/docs_not_updated/esp32c61.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/conf_common.py b/docs/conf_common.py index 972805f610..4e57b76ea2 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -292,7 +292,7 @@ ESP32C2_DOCS = ['api-guides/RF_calibration.rst', 'api-guides/phy.rst'] ESP32C5_DOCS = ['api-guides/phy.rst', 'api-reference/peripherals/sd_pullup_requirements.rst'] -ESP32C61_DOCS = ['api-guides/phy.rst'] +ESP32C61_DOCS = ['api-guides/phy.rst', 'api-reference/peripherals/sd_pullup_requirements.rst'] ESP32C6_DOCS = [ 'api-guides/RF_calibration.rst', diff --git a/docs/docs_not_updated/esp32c61.txt b/docs/docs_not_updated/esp32c61.txt index 662bee8a5e..3315f17f73 100644 --- a/docs/docs_not_updated/esp32c61.txt +++ b/docs/docs_not_updated/esp32c61.txt @@ -39,7 +39,6 @@ api-reference/peripherals/dac.rst api-reference/peripherals/ppa.rst api-reference/peripherals/camera_driver.rst api-reference/peripherals/spi_features.rst -api-reference/peripherals/sdio_slave.rst api-reference/peripherals/touch_pad.rst api-reference/peripherals/lcd/i80_lcd.rst api-reference/peripherals/lcd/spi_lcd.rst