mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 03:34:32 +02:00
fix(sdio_slave): improve sdio slave for high speed and 4 bit mode
This commit is contained in:
@@ -47,10 +47,12 @@ typedef enum {
|
||||
|
||||
/// Timing of SDIO slave
|
||||
typedef enum {
|
||||
SDIO_SLAVE_TIMING_NSEND_PSAMPLE = 0,///< Send at negedge, and sample at posedge. Default value for SD protocol.
|
||||
SDIO_SLAVE_TIMING_NSEND_NSAMPLE, ///< Send at negedge, and sample at negedge
|
||||
SDIO_SLAVE_TIMING_PSEND_PSAMPLE, ///< Send at posedge, and sample at posedge
|
||||
SDIO_SLAVE_TIMING_PSEND_PSAMPLE = 0,/**< Send at posedge, and sample at posedge. Default value for HS mode.
|
||||
* Normally there's no problem using this to work in DS mode.
|
||||
*/
|
||||
SDIO_SLAVE_TIMING_NSEND_PSAMPLE ,///< Send at negedge, and sample at posedge. Default value for DS mode and below.
|
||||
SDIO_SLAVE_TIMING_PSEND_NSAMPLE, ///< Send at posedge, and sample at negedge
|
||||
SDIO_SLAVE_TIMING_NSEND_NSAMPLE, ///< Send at negedge, and sample at negedge
|
||||
} sdio_slave_timing_t;
|
||||
|
||||
/// Configuration of SDIO slave mode
|
||||
|
@@ -120,12 +120,12 @@ typedef enum {
|
||||
} send_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t clk;
|
||||
uint32_t cmd;
|
||||
uint32_t d0;
|
||||
uint32_t d1;
|
||||
uint32_t d2;
|
||||
uint32_t d3;
|
||||
uint32_t clk_gpio;
|
||||
uint32_t cmd_gpio;
|
||||
uint32_t d0_gpio;
|
||||
uint32_t d1_gpio;
|
||||
uint32_t d2_gpio;
|
||||
uint32_t d3_gpio;
|
||||
int func;
|
||||
} sdio_slave_slot_info_t ;
|
||||
|
||||
@@ -136,20 +136,20 @@ typedef struct {
|
||||
// currently slot 0 is occupied by SPI for flash
|
||||
static const sdio_slave_slot_info_t s_slot_info[2] = {
|
||||
{
|
||||
.clk = PERIPHS_IO_MUX_SD_CLK_U,
|
||||
.cmd = PERIPHS_IO_MUX_SD_CMD_U,
|
||||
.d0 = PERIPHS_IO_MUX_SD_DATA0_U,
|
||||
.d1 = PERIPHS_IO_MUX_SD_DATA1_U,
|
||||
.d2 = PERIPHS_IO_MUX_SD_DATA2_U,
|
||||
.d3 = PERIPHS_IO_MUX_SD_DATA3_U,
|
||||
.clk_gpio = 6,
|
||||
.cmd_gpio = 11,
|
||||
.d0_gpio = 7,
|
||||
.d1_gpio = 8,
|
||||
.d2_gpio = 9,
|
||||
.d3_gpio = 10,
|
||||
.func = 0,
|
||||
}, {
|
||||
.clk = PERIPHS_IO_MUX_MTMS_U,
|
||||
.cmd = PERIPHS_IO_MUX_MTDO_U,
|
||||
.d0 = PERIPHS_IO_MUX_GPIO2_U,
|
||||
.d1 = PERIPHS_IO_MUX_GPIO4_U,
|
||||
.d2 = PERIPHS_IO_MUX_MTDI_U,
|
||||
.d3 = PERIPHS_IO_MUX_MTCK_U,
|
||||
.clk_gpio = 14,
|
||||
.cmd_gpio = 15,
|
||||
.d0_gpio = 2,
|
||||
.d1_gpio = 4,
|
||||
.d2_gpio = 12,
|
||||
.d3_gpio = 13,
|
||||
.func = 4,
|
||||
},
|
||||
};
|
||||
@@ -193,7 +193,7 @@ typedef struct {
|
||||
SemaphoreHandle_t remain_cnt;
|
||||
} sdio_ringbuf_t;
|
||||
|
||||
#define offset_of(type, field) ( (unsigned int)&(((type *)(0))->field) )
|
||||
#define offset_of(type, field) ( (unsigned int)&(((type *)(0))->field) )
|
||||
typedef enum {
|
||||
ringbuf_write_ptr = offset_of(sdio_ringbuf_t, write_ptr),
|
||||
ringbuf_read_ptr = offset_of(sdio_ringbuf_t, read_ptr),
|
||||
@@ -304,7 +304,7 @@ no_mem:
|
||||
}
|
||||
|
||||
//calculate a pointer with offset to a original pointer of the specific ringbuffer
|
||||
static inline uint8_t* sdio_ringbuf_offset_ptr( sdio_ringbuf_t *buf, sdio_ringbuf_pointer_t ptr, uint32_t offset )
|
||||
static inline uint8_t* sdio_ringbuf_offset_ptr( sdio_ringbuf_t *buf, sdio_ringbuf_pointer_t ptr, uint32_t offset )
|
||||
{
|
||||
uint8_t *buf_ptr = (uint8_t*)*(uint32_t*)(((uint8_t*)buf)+ptr); //get the specific pointer of the buffer
|
||||
uint8_t *offset_ptr=buf_ptr+offset;
|
||||
@@ -499,13 +499,18 @@ no_mem:
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
static inline void configure_pin(uint32_t io_mux_reg, uint32_t func)
|
||||
static void configure_pin(int pin, uint32_t func, bool pullup)
|
||||
{
|
||||
const int sdmmc_func = func;
|
||||
const int drive_strength = 3;
|
||||
PIN_INPUT_ENABLE(io_mux_reg);
|
||||
PIN_FUNC_SELECT(io_mux_reg, sdmmc_func);
|
||||
PIN_SET_DRV(io_mux_reg, drive_strength);
|
||||
assert(pin!=-1);
|
||||
uint32_t reg = GPIO_PIN_MUX_REG[pin];
|
||||
assert(reg!=0);
|
||||
|
||||
PIN_INPUT_ENABLE(reg);
|
||||
PIN_FUNC_SELECT(reg, sdmmc_func);
|
||||
PIN_SET_DRV(reg, drive_strength);
|
||||
gpio_pulldown_dis(pin);
|
||||
}
|
||||
|
||||
static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
|
||||
@@ -515,12 +520,13 @@ static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
|
||||
|
||||
//initialize pin
|
||||
const sdio_slave_slot_info_t *slot = &s_slot_info[1];
|
||||
configure_pin(slot->clk, slot->func);
|
||||
configure_pin(slot->cmd, slot->func);
|
||||
configure_pin(slot->d0, slot->func);
|
||||
configure_pin(slot->d1, slot->func);
|
||||
configure_pin(slot->d2, slot->func);
|
||||
configure_pin(slot->d3, slot->func);
|
||||
configure_pin(slot->clk_gpio, slot->func, false); //clk doesn't need a pullup
|
||||
configure_pin(slot->cmd_gpio, slot->func, false);
|
||||
configure_pin(slot->d0_gpio, slot->func, false);
|
||||
configure_pin(slot->d1_gpio, slot->func, false);
|
||||
configure_pin(slot->d2_gpio, slot->func, false);
|
||||
configure_pin(slot->d3_gpio, slot->func, false);
|
||||
|
||||
//enable module and config
|
||||
periph_module_reset(PERIPH_SDIO_SLAVE_MODULE);
|
||||
periph_module_enable(PERIPH_SDIO_SLAVE_MODULE);
|
||||
@@ -539,28 +545,28 @@ static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
|
||||
|
||||
switch( config->timing ) {
|
||||
case SDIO_SLAVE_TIMING_PSEND_PSAMPLE:
|
||||
HOST.conf.frc_sdio20 = 0xf;
|
||||
HOST.conf.frc_sdio20 = 0x1f;
|
||||
HOST.conf.frc_sdio11 = 0;
|
||||
HOST.conf.frc_pos_samp = 0xf;
|
||||
HOST.conf.frc_pos_samp = 0x1f;
|
||||
HOST.conf.frc_neg_samp = 0;
|
||||
break;
|
||||
case SDIO_SLAVE_TIMING_PSEND_NSAMPLE:
|
||||
HOST.conf.frc_sdio20 = 0xf;
|
||||
HOST.conf.frc_sdio20 = 0x1f;
|
||||
HOST.conf.frc_sdio11 = 0;
|
||||
HOST.conf.frc_pos_samp = 0;
|
||||
HOST.conf.frc_neg_samp = 0xf;
|
||||
HOST.conf.frc_neg_samp = 0x1f;
|
||||
break;
|
||||
case SDIO_SLAVE_TIMING_NSEND_PSAMPLE:
|
||||
HOST.conf.frc_sdio20 = 0;
|
||||
HOST.conf.frc_sdio11 = 0xf;
|
||||
HOST.conf.frc_pos_samp = 0xf;
|
||||
HOST.conf.frc_sdio11 = 0x1f;
|
||||
HOST.conf.frc_pos_samp = 0x1f;
|
||||
HOST.conf.frc_neg_samp = 0;
|
||||
break;
|
||||
case SDIO_SLAVE_TIMING_NSEND_NSAMPLE:
|
||||
HOST.conf.frc_sdio20 = 0;
|
||||
HOST.conf.frc_sdio11 = 0xf;
|
||||
HOST.conf.frc_sdio11 = 0x1f;
|
||||
HOST.conf.frc_pos_samp = 0;
|
||||
HOST.conf.frc_neg_samp = 0xf;
|
||||
HOST.conf.frc_neg_samp = 0x1f;
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user