Merge branch 'feat/support_sdio_on_c61' into 'master'

feat(sdio): supported slave sdio on esp32c61

Closes IDF-12883, IDF-12594, and IDF-10151

See merge request espressif/esp-idf!40485
This commit is contained in:
Gao Xu
2025-07-18 16:37:48 +08:00
12 changed files with 631 additions and 10 deletions

View File

@@ -3,12 +3,10 @@ menu "SDIO Slave Test Host Configuration"
prompt "SDIO Slave Chip" prompt "SDIO Slave Chip"
default TEST_SDIO_SLAVE_TARGET_ESP32 default TEST_SDIO_SLAVE_TARGET_ESP32
help help
SDIO Slave chip target default test board conditions targets: ESP32, ESP32C6, ESP32C61
config TEST_SDIO_SLAVE_TARGET_ESP32 config TEST_SDIO_SLAVE_TARGET_ESP32
bool "SDIO Slave ESP32" bool "SDIO Slave ESP32"
config TEST_SDIO_SLAVE_TARGET_ESP32C6
bool "SDIO Slave ESP32C6"
config TEST_SDIO_SLAVE_TARGET_ESP32C5 config TEST_SDIO_SLAVE_TARGET_ESP32C5
bool "SDIO Slave ESP32C5" bool "SDIO Slave ESP32C5"
endchoice endchoice

View File

@@ -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'])] 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'])] 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'])] 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'])] 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) 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 # From host speed tests
def test_sdio_speed_frhost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: 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') 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) 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 # To host speed tests
def test_sdio_speed_tohost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: 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') 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) 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 # Retention tests
def test_sdio_retention(dut: Tuple[IdfDut, IdfDut]) -> None: def test_sdio_retention(dut: Tuple[IdfDut, IdfDut]) -> None:
dut[1].expect('Press ENTER to see the list of tests') dut[1].expect('Press ENTER to see the list of tests')

View File

@@ -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 # SDIO Cross Chips Test Apps: SDIO Slave App

View File

@@ -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 <sys/queue.h>
#include <stdbool.h>
#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

View File

@@ -155,6 +155,10 @@ config SOC_ETM_SUPPORTED
bool bool
default y default y
config SOC_SDIO_SLAVE_SUPPORTED
bool
default y
config SOC_PAU_SUPPORTED config SOC_PAU_SUPPORTED
bool bool
default y default y

View File

@@ -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

View File

@@ -64,7 +64,7 @@
#define SOC_MODEM_CLOCK_SUPPORTED 1 #define SOC_MODEM_CLOCK_SUPPORTED 1
#define SOC_REG_I2C_SUPPORTED 1 #define SOC_REG_I2C_SUPPORTED 1
#define SOC_ETM_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_PAU_SUPPORTED 1
#define SOC_LIGHT_SLEEP_SUPPORTED 1 #define SOC_LIGHT_SLEEP_SUPPORTED 1
#define SOC_DEEP_SLEEP_SUPPORTED 1 #define SOC_DEEP_SLEEP_SUPPORTED 1

View File

@@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#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,
},
};

View File

@@ -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'] 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 = [ ESP32C6_DOCS = [
'api-guides/RF_calibration.rst', 'api-guides/RF_calibration.rst',

View File

@@ -39,7 +39,6 @@ api-reference/peripherals/dac.rst
api-reference/peripherals/ppa.rst api-reference/peripherals/ppa.rst
api-reference/peripherals/camera_driver.rst api-reference/peripherals/camera_driver.rst
api-reference/peripherals/spi_features.rst api-reference/peripherals/spi_features.rst
api-reference/peripherals/sdio_slave.rst
api-reference/peripherals/touch_pad.rst api-reference/peripherals/touch_pad.rst
api-reference/peripherals/lcd/i80_lcd.rst api-reference/peripherals/lcd/i80_lcd.rst
api-reference/peripherals/lcd/spi_lcd.rst api-reference/peripherals/lcd/spi_lcd.rst

View File

@@ -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 See README.md in the parent folder

View File

@@ -119,6 +119,7 @@ env_markers =
twai_network: multiple runners form a TWAI network. twai_network: multiple runners form a TWAI network.
sdio_master_slave: Test sdio multi board, esp32+esp32 sdio_master_slave: Test sdio multi board, esp32+esp32
sdio_multidev_32_c6: Test sdio multi board, esp32+esp32c6 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 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) 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 twai_std: twai runner with all twai supported targets connect to usb-can adapter