]> granicus.if.org Git - esp-idf/commitdiff
fix(sdio_slave): improve sdio slave for high speed and 4 bit mode
authormichael <xiaoxufeng@espressif.com>
Wed, 4 Jul 2018 12:37:30 +0000 (20:37 +0800)
committermichael <xiaoxufeng@espressif.com>
Wed, 1 Aug 2018 07:23:24 +0000 (15:23 +0800)
components/driver/include/driver/sdio_slave.h
components/driver/sdio_slave.c

index a54b824c99ea3f24ec15ccd2a3d0a14adb8115de..05f08102ae886236ef8a47e414b5d56e2716cd39 100644 (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
index 5dd87093703eaa107ba2bf1c0dd3fe75f1b65aca..3e994b527d307495dbbea788dccc9b3e03a395f0 100644 (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;
     }