From 7995ba6433d1d87a487c9c3dcdc3ed5ed177e3b2 Mon Sep 17 00:00:00 2001 From: michael Date: Wed, 4 Jul 2018 20:37:30 +0800 Subject: [PATCH] fix(sdio_slave): improve sdio slave for high speed and 4 bit mode --- components/driver/include/driver/sdio_slave.h | 8 +- components/driver/sdio_slave.c | 82 ++++++++++--------- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/components/driver/include/driver/sdio_slave.h b/components/driver/include/driver/sdio_slave.h index a54b824c99..05f08102ae 100644 --- a/components/driver/include/driver/sdio_slave.h +++ b/components/driver/include/driver/sdio_slave.h @@ -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 diff --git a/components/driver/sdio_slave.c b/components/driver/sdio_slave.c index 5dd8709370..3e994b527d 100644 --- a/components/driver/sdio_slave.c +++ b/components/driver/sdio_slave.c @@ -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; }