fix(sdio_slave): improve sdio slave for high speed and 4 bit mode

This commit is contained in:
michael
2018-07-04 20:37:30 +08:00
parent 5019ff3345
commit 7995ba6433
2 changed files with 49 additions and 41 deletions

View File

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

View File

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