From: michael <xiaoxufeng@espressif.com>
Date: Fri, 25 May 2018 11:44:53 +0000 (+0800)
Subject: feature(sdio): allow to enable internal pullups of the SDIO host and slave as a debug... 
X-Git-Tag: v3.2-dev^2~2
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b37a96ddcc080f72df056cdf3567026f57c7246;p=esp-idf

feature(sdio): allow to enable internal pullups of the SDIO host and slave as a debug feature

NOTE: the internal pullups are not totally reliable, please do add external pullups on your bus.
---

diff --git a/components/driver/include/driver/sdio_slave.h b/components/driver/include/driver/sdio_slave.h
index 66b3bc5e21..ed0767b492 100644
--- a/components/driver/include/driver/sdio_slave.h
+++ b/components/driver/include/driver/sdio_slave.h
@@ -20,7 +20,7 @@
 #include "esp_err.h"
 #include "rom/queue.h"
 
-#include "soc/host_reg.h"
+#include "soc/sdio_slave_periph.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -71,6 +71,23 @@ typedef struct {
                             ///< All data that do not fully fill a buffer is still counted as one buffer. E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer.
                             ///< Buffer size of the slave pre-defined between host and slave before communication. All receive buffer given to the driver should be larger than this.
     sdio_event_cb_t     event_cb;           ///< when the host interrupts slave, this callback will be called with interrupt number (0-7).
+    uint32_t            flags; ///< Features to be enabled for the slave, combinations of ``SDIO_SLAVE_FLAG_*``.
+#define SDIO_SLAVE_FLAG_DAT2_DISABLED       BIT(0)      /**< It is required by the SD specification that all 4 data 
+        lines should be used and pulled up even in 1-bit mode or SPI mode. However, as a feature, the user can speicfy 
+        this flag to make use of DAT2 pin in 1-bit mode. Note that the host cannot read CCCR registers to know we don't 
+        support 4-bit mode anymore, please do this at your own risk.
+        */
+#define SDIO_SLAVE_FLAG_HOST_INTR_DISABLED  BIT(1)      /**< The DAT1 line is used as the interrupt line in SDIO        
+        protocol. However, as a feature, the user can speicfy this flag to make use of DAT1 pin of the slave in 1-bit 
+        mode. Note that the host has to do polling to the interrupt registers to know whether there are interrupts from
+        the slave. And it cannot read CCCR registers to know we don't support 4-bit mode anymore, please do this at 
+        your own risk.
+        */
+#define SDIO_SLAVE_FLAG_INTERNAL_PULLUP     BIT(2)      /**< Enable internal pullups for enabled pins. It is required 
+        by the SD specification that all the 4 data lines should be pulled up even in 1-bit mode or SPI mode. Note that 
+        the internal pull-ups are not sufficient for stable communication, please do connect external pull-ups on the 
+        bus. This is only for example and debug use.
+        */
 } sdio_slave_config_t;
 
 /** Handle of a receive buffer, register a handle by calling ``sdio_slave_recv_register_buf``. Use the handle to load the buffer to the
diff --git a/components/driver/include/driver/sdmmc_host.h b/components/driver/include/driver/sdmmc_host.h
index 2c610ad365..f57b959cc7 100644
--- a/components/driver/include/driver/sdmmc_host.h
+++ b/components/driver/include/driver/sdmmc_host.h
@@ -55,6 +55,12 @@ typedef struct {
     gpio_num_t gpio_cd;     ///< GPIO number of card detect signal
     gpio_num_t gpio_wp;     ///< GPIO number of write protect signal
     uint8_t width;          ///< Bus width used by the slot (might be less than the max width supported)
+    uint32_t flags;         ///< Features used by this slot
+#define SDMMC_SLOT_FLAG_INTERNAL_PULLUP  BIT(0) 
+        /**< Enable internal pullups on enabled pins. The internal pullups
+         are insufficient however, please make sure external pullups are
+         connected on the bus. This is for debug / example purpose only.
+         */
 } sdmmc_slot_config_t;
 
 #define SDMMC_SLOT_NO_CD      ((gpio_num_t) -1)     ///< indicates that card detect line is not used
@@ -68,6 +74,7 @@ typedef struct {
     .gpio_cd = SDMMC_SLOT_NO_CD, \
     .gpio_wp = SDMMC_SLOT_NO_WP, \
     .width   = SDMMC_SLOT_WIDTH_DEFAULT, \
+    .flags = 0, \
 }
 
 /**
@@ -199,6 +206,23 @@ esp_err_t sdmmc_host_io_int_wait(int slot, TickType_t timeout_ticks);
  */
 esp_err_t sdmmc_host_deinit();
 
+/**
+ * @brief Enable the pull-ups of sd pins.
+ * 
+ * @note You should always place actual pullups on the lines instead of using
+ * this function. Internal pullup resistance are high and not sufficient, may
+ * cause instability in products. This is for debug or examples only.
+ * 
+ * @param slot Slot to use, normally set it to 1.
+ * @param width Bit width of your configuration, 1 or 4.
+ * 
+ * @return
+ *      - ESP_OK: if success
+ *      - ESP_ERR_INVALID_ARG: if configured width larger than maximum the slot can
+ *              support
+ */
+esp_err_t sdmmc_host_pullup_en(int slot, int width);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/driver/sdio_slave.c b/components/driver/sdio_slave.c
index 1727e4349c..8402878dea 100644
--- a/components/driver/sdio_slave.c
+++ b/components/driver/sdio_slave.c
@@ -86,10 +86,7 @@ The driver of FIFOs works as below:
 
 #include <string.h>
 #include "driver/sdio_slave.h"
-#include "soc/slc_struct.h"
-#include "soc/slc_reg.h"
-#include "soc/host_struct.h"
-#include "soc/hinf_struct.h"
+#include "soc/sdio_slave_periph.h"
 #include "rom/lldesc.h"
 #include "esp_log.h"
 #include "esp_intr_alloc.h"
@@ -119,41 +116,6 @@ typedef enum {
     STATE_SENDING = 3,
 } send_state_t;
 
-typedef struct {
-    uint32_t clk;
-    uint32_t cmd;
-    uint32_t d0;
-    uint32_t d1;
-    uint32_t d2;
-    uint32_t d3;
-    int      func;
-} sdio_slave_slot_info_t ;
-
-// I/O slot of sdio slave:
-// 0: GPIO 6, 11, 7, 8, 9, 10,
-// 1: GPIO 14, 15, 2, 4, 12, 13 for CLK, CMD, D0, D1, D2, D3 respectively.
-// only one peripheral for SDIO and only one slot can work at the same time.
-// 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,
-        .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,
-        .func = 4,
-    },
-};
-
 // first 3 WORDs of this struct is defined by and compatible to the DMA link list format.
 // sdio_slave_buf_handle_t is of type buf_desc_t*;
 typedef struct  buf_desc_s{
@@ -499,13 +461,21 @@ 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!=UINT32_MAX);
+
+    PIN_INPUT_ENABLE(reg);
+    PIN_FUNC_SELECT(reg, sdmmc_func);
+    PIN_SET_DRV(reg, drive_strength);
+    if (pullup) {
+        gpio_pullup_en(pin);
+        gpio_pulldown_dis(pin);
+    }
 }
 
 static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
@@ -514,13 +484,20 @@ static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
     SLC.slc0_int_ena.val = 0;
 
     //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);
+    const sdio_slave_slot_info_t *slot = &sdio_slave_slot_info[1];
+
+    bool pullup = config->flags & SDIO_SLAVE_FLAG_INTERNAL_PULLUP;
+    configure_pin(slot->clk_gpio, slot->func, false);   //clk doesn't need a pullup
+    configure_pin(slot->cmd_gpio, slot->func, pullup);
+    configure_pin(slot->d0_gpio, slot->func, pullup);
+    if ((config->flags & SDIO_SLAVE_FLAG_HOST_INTR_DISABLED)==0) {
+        configure_pin(slot->d1_gpio, slot->func, pullup);
+    } 
+    if ((config->flags & SDIO_SLAVE_FLAG_DAT2_DISABLED)==0) {
+       configure_pin(slot->d2_gpio, slot->func, pullup); 
+    }
+    configure_pin(slot->d3_gpio, slot->func, pullup);
+
     //enable module and config
     periph_module_reset(PERIPH_SDIO_SLAVE_MODULE);
     periph_module_enable(PERIPH_SDIO_SLAVE_MODULE);
diff --git a/components/driver/sdmmc_host.c b/components/driver/sdmmc_host.c
index 95cb81fdcf..0887e04293 100644
--- a/components/driver/sdmmc_host.c
+++ b/components/driver/sdmmc_host.c
@@ -17,76 +17,21 @@
 #include <sys/param.h>
 #include "esp_log.h"
 #include "esp_intr_alloc.h"
-#include "soc/sdmmc_struct.h"
-#include "soc/sdmmc_reg.h"
 #include "soc/io_mux_reg.h"
-#include "soc/gpio_sig_map.h"
 #include "rom/gpio.h"
 #include "driver/gpio.h"
 #include "driver/sdmmc_host.h"
 #include "driver/periph_ctrl.h"
 #include "sdmmc_private.h"
 #include "freertos/semphr.h"
+#include "soc/sdmmc_periph.h"
 
 #define SDMMC_EVENT_QUEUE_LENGTH 32
 
-typedef struct {
-    uint32_t clk;
-    uint32_t cmd;
-    uint32_t d0;
-    uint32_t d1;
-    uint32_t d2;
-    uint32_t d3;
-    uint32_t d4;
-    uint32_t d5;
-    uint32_t d6;
-    uint32_t d7;
-    uint8_t d1_gpio;
-    uint8_t d3_gpio;
-    uint8_t card_detect;
-    uint8_t write_protect;
-    uint8_t card_int;
-    uint8_t width;
-} sdmmc_slot_info_t;
-
 
 static void sdmmc_isr(void* arg);
 static void sdmmc_host_dma_init();
 
-static const sdmmc_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,
-        .d1_gpio = 8,
-        .d3_gpio = 10,
-        .d4 = PERIPHS_IO_MUX_GPIO16_U,
-        .d5 = PERIPHS_IO_MUX_GPIO17_U,
-        .d6 = PERIPHS_IO_MUX_GPIO5_U,
-        .d7 = PERIPHS_IO_MUX_GPIO18_U,
-        .card_detect = HOST_CARD_DETECT_N_1_IDX,
-        .write_protect = HOST_CARD_WRITE_PRT_1_IDX,
-        .card_int = HOST_CARD_INT_N_1_IDX,
-        .width = 8
-    },
-    {
-        .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,
-        .d1_gpio = 4,
-        .d3_gpio = 13,
-        .card_detect = HOST_CARD_DETECT_N_2_IDX,
-        .write_protect = HOST_CARD_WRITE_PRT_2_IDX,
-        .card_int = HOST_CARD_INT_N_2_IDX,
-        .width = 4
-    }
-};
 
 static const char* TAG = "sdmmc_periph";
 static intr_handle_t s_intr_handle;
@@ -340,18 +285,24 @@ esp_err_t sdmmc_host_init()
     return ESP_OK;
 }
 
-
-static inline void configure_pin(uint32_t io_mux_reg)
+static void configure_pin(int pin)
 {
     const int sdmmc_func = 3;
     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 != UINT32_MAX);
+    PIN_INPUT_ENABLE(reg);
+    PIN_FUNC_SELECT(reg, sdmmc_func);
+    PIN_SET_DRV(reg, drive_strength);
 }
 
 esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
 {
+    bool pullup = slot_config->flags & SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
+    if (pullup) {
+        sdmmc_host_pullup_en(slot, slot_config->width);
+    }
     if (!s_intr_handle) {
         return ESP_ERR_INVALID_STATE;
     }
@@ -366,7 +317,7 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
     uint8_t slot_width = slot_config->width;
 
     // Configure pins
-    const sdmmc_slot_info_t* pslot = &s_slot_info[slot];
+    const sdmmc_slot_info_t* pslot = &sdmmc_slot_info[slot];
 
     if (slot_width == SDMMC_SLOT_WIDTH_DEFAULT) {
         slot_width = pslot->width;
@@ -376,13 +327,13 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
     }
     s_slot_width[slot] = slot_width;
 
-    configure_pin(pslot->clk);
-    configure_pin(pslot->cmd);
-    configure_pin(pslot->d0);
+    configure_pin(pslot->clk_gpio);
+    configure_pin(pslot->cmd_gpio);
+    configure_pin(pslot->d0_gpio);
 
     if (slot_width >= 4) {
-        configure_pin(pslot->d1);
-        configure_pin(pslot->d2);
+        configure_pin(pslot->d1_gpio);
+        configure_pin(pslot->d2_gpio);
         //force pull-up D3 to make slave detect SD mode. connect to peripheral after width configuration.
         gpio_config_t gpio_conf = {
             .pin_bit_mask = BIT(pslot->d3_gpio),
@@ -394,10 +345,10 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
         gpio_config( &gpio_conf );
         gpio_set_level( pslot->d3_gpio, 1 );
         if (slot_width == 8) {
-            configure_pin(pslot->d4);
-            configure_pin(pslot->d5);
-            configure_pin(pslot->d6);
-            configure_pin(pslot->d7);
+            configure_pin(pslot->d4_gpio);
+            configure_pin(pslot->d5_gpio);
+            configure_pin(pslot->d6_gpio);
+            configure_pin(pslot->d7_gpio);
         }
     }
 
@@ -482,7 +433,7 @@ esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
     if (!(slot == 0 || slot == 1)) {
         return ESP_ERR_INVALID_ARG;
     }
-    if (s_slot_info[slot].width < width) {
+    if (sdmmc_slot_info[slot].width < width) {
         return ESP_ERR_INVALID_ARG;
     }
     const uint16_t mask = BIT(slot);
@@ -492,10 +443,10 @@ esp_err_t sdmmc_host_set_bus_width(int slot, size_t width)
     } else if (width == 4) {
         SDMMC.ctype.card_width_8 &= ~mask;
         SDMMC.ctype.card_width |= mask;
-        configure_pin(s_slot_info[slot].d3);   // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
+        configure_pin(sdmmc_slot_info[slot].d3_gpio);   // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
     } else if (width == 8){
         SDMMC.ctype.card_width_8 |= mask;
-        configure_pin(s_slot_info[slot].d3);   // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
+        configure_pin(sdmmc_slot_info[slot].d3_gpio);   // D3 was set to GPIO high to force slave into SD 1-bit mode, until 4-bit mode is set
     } else {
         return ESP_ERR_INVALID_ARG;
     }
@@ -550,7 +501,7 @@ void sdmmc_host_dma_resume()
 
 esp_err_t sdmmc_host_io_int_enable(int slot)
 {
-    configure_pin(s_slot_info[slot].d1);
+    configure_pin(sdmmc_slot_info[slot].d1_gpio);
     return ESP_OK;
 }
 
@@ -566,7 +517,7 @@ esp_err_t sdmmc_host_io_int_wait(int slot, TickType_t timeout_ticks)
 
     SDMMC.intmask.sdio &= ~BIT(slot);   /* Disable SDIO interrupt */
     SDMMC.rintsts.sdio = BIT(slot);
-    if (gpio_get_level(s_slot_info[slot].d1_gpio) == 0) {
+    if (gpio_get_level(sdmmc_slot_info[slot].d1_gpio) == 0) {
         return ESP_OK;
     }
     /* Otherwise, need to wait for an interrupt. Since D1 was high,
@@ -627,3 +578,34 @@ static void sdmmc_isr(void* arg) {
     }
 }
 
+esp_err_t sdmmc_host_pullup_en(int slot, int width)
+{
+    if (width > sdmmc_slot_info[slot].width) {
+        //in esp32 we only support 8 bit in slot 0, note this is occupied by the flash by default
+        return ESP_ERR_INVALID_ARG;
+    }
+    //according to the spec, the host control the clk, we don't to pull it up here
+    gpio_pullup_en(sdmmc_slot_info[slot].cmd_gpio);
+    gpio_pulldown_dis(sdmmc_slot_info[slot].cmd_gpio);
+    gpio_pullup_en(sdmmc_slot_info[slot].d0_gpio);
+    gpio_pulldown_dis(sdmmc_slot_info[slot].d0_gpio);
+    if (width >= 4) {
+        gpio_pullup_en(sdmmc_slot_info[slot].d1_gpio);
+        gpio_pulldown_dis(sdmmc_slot_info[slot].d1_gpio);
+        gpio_pullup_en(sdmmc_slot_info[slot].d2_gpio);
+        gpio_pulldown_dis(sdmmc_slot_info[slot].d2_gpio);
+        gpio_pullup_en(sdmmc_slot_info[slot].d3_gpio);
+        gpio_pulldown_dis(sdmmc_slot_info[slot].d3_gpio);
+    }
+    if (width == 8) {
+        gpio_pullup_en(sdmmc_slot_info[slot].d4_gpio);
+        gpio_pulldown_dis(sdmmc_slot_info[slot].d4_gpio);
+        gpio_pullup_en(sdmmc_slot_info[slot].d5_gpio);
+        gpio_pulldown_dis(sdmmc_slot_info[slot].d5_gpio);
+        gpio_pullup_en(sdmmc_slot_info[slot].d6_gpio);
+        gpio_pulldown_dis(sdmmc_slot_info[slot].d6_gpio);
+        gpio_pullup_en(sdmmc_slot_info[slot].d7_gpio);
+        gpio_pulldown_dis(sdmmc_slot_info[slot].d7_gpio);
+    }
+    return ESP_OK;
+}
\ No newline at end of file
diff --git a/components/driver/sdmmc_private.h b/components/driver/sdmmc_private.h
index 5a10a3b672..8f0aab78b2 100644
--- a/components/driver/sdmmc_private.h
+++ b/components/driver/sdmmc_private.h
@@ -19,7 +19,7 @@
 #include "esp_err.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/queue.h"
-#include "soc/sdmmc_struct.h"
+#include "soc/sdmmc_periph.h"
 
 typedef struct {
     uint32_t sdmmc_status;      ///< masked SDMMC interrupt status
diff --git a/components/driver/sdmmc_transaction.c b/components/driver/sdmmc_transaction.c
index 8abf9bb923..495d3d4a15 100644
--- a/components/driver/sdmmc_transaction.c
+++ b/components/driver/sdmmc_transaction.c
@@ -19,8 +19,7 @@
 #include "freertos/FreeRTOS.h"
 #include "freertos/queue.h"
 #include "freertos/semphr.h"
-#include "soc/sdmmc_reg.h"
-#include "soc/sdmmc_struct.h"
+#include "soc/sdmmc_periph.h"
 #include "soc/soc_memory_layout.h"
 #include "driver/sdmmc_types.h"
 #include "driver/sdmmc_defs.h"
diff --git a/components/driver/sdspi_transaction.c b/components/driver/sdspi_transaction.c
index 4b9c695846..d25521deaa 100644
--- a/components/driver/sdspi_transaction.c
+++ b/components/driver/sdspi_transaction.c
@@ -17,7 +17,7 @@
 #include "esp_log.h"
 #include "sys/lock.h"
 #include "soc/sdmmc_reg.h"
-#include "soc/sdmmc_struct.h"
+#include "soc/sdmmc_periph.h"
 #include "driver/sdmmc_types.h"
 #include "driver/sdmmc_defs.h"
 #include "driver/sdmmc_host.h"
diff --git a/components/soc/esp32/include/soc/sdio_slave_pins.h b/components/soc/esp32/include/soc/sdio_slave_pins.h
new file mode 100644
index 0000000000..968f194aba
--- /dev/null
+++ b/components/soc/esp32/include/soc/sdio_slave_pins.h
@@ -0,0 +1,34 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _SOC_SDIO_SLAVE_PINS_H_
+#define _SOC_SDIO_SLAVE_PINS_H_
+
+#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK  6
+#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD  11
+#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0   7
+#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1   8
+#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2   9
+#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3   10
+#define SDIO_SLAVE_SLOT0_FUNC               0
+
+#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK  14
+#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD  15
+#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0   2
+#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1   4
+#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2   12
+#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3   13
+#define SDIO_SLAVE_SLOT1_FUNC               4
+
+#endif /* _SOC_SDIO_SLAVE_PINS_H_ */
\ No newline at end of file
diff --git a/components/soc/esp32/include/soc/sdmmc_pins.h b/components/soc/esp32/include/soc/sdmmc_pins.h
new file mode 100644
index 0000000000..9a37ad0c1a
--- /dev/null
+++ b/components/soc/esp32/include/soc/sdmmc_pins.h
@@ -0,0 +1,38 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _SOC_SDMMC_PINS_H_
+#define _SOC_SDMMC_PINS_H_
+
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_CLK  6
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_CMD  11
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D0   7
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D1   8
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D2   9
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D3   10
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D4   16
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D5   17
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D6   5
+#define SDMMC_SLOT0_IOMUX_PIN_NUM_D7   18
+#define SDMMC_SLOT0_FUNC               0
+
+#define SDMMC_SLOT1_IOMUX_PIN_NUM_CLK  14
+#define SDMMC_SLOT1_IOMUX_PIN_NUM_CMD  15
+#define SDMMC_SLOT1_IOMUX_PIN_NUM_D0   2
+#define SDMMC_SLOT1_IOMUX_PIN_NUM_D1   4
+#define SDMMC_SLOT1_IOMUX_PIN_NUM_D2   12
+#define SDMMC_SLOT1_IOMUX_PIN_NUM_D3   13
+#define SDMMC_SLOT1_FUNC               4
+
+#endif /* _SOC_SDMMC_PINS_H_ */
\ No newline at end of file
diff --git a/components/soc/esp32/sdio_slave_periph.c b/components/soc/esp32/sdio_slave_periph.c
new file mode 100644
index 0000000000..d3b8cfc3dc
--- /dev/null
+++ b/components/soc/esp32/sdio_slave_periph.c
@@ -0,0 +1,43 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdint.h>
+#include "soc/sdio_slave_periph.h"
+#include "soc/io_mux_reg.h"
+#include "soc/sdio_slave_pins.h"
+
+// I/O slot of sdio slave:
+// 0: GPIO 6, 11, 7, 8, 9, 10,
+// 1: GPIO 14, 15, 2, 4, 12, 13 for CLK, CMD, D0, D1, D2, D3 respectively.
+// only one peripheral for SDIO and only one slot can work at the same time.
+// currently slot 0 is occupied by SPI for flash
+const sdio_slave_slot_info_t sdio_slave_slot_info[2]  = {
+    {
+        .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,
+    }, {
+        .clk_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK,
+        .cmd_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD,
+        .d0_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0,
+        .d1_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1,
+        .d2_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2,
+        .d3_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3,
+        .func = SDIO_SLAVE_SLOT1_FUNC,
+    },
+};
diff --git a/components/soc/esp32/sdmmc_periph.c b/components/soc/esp32/sdmmc_periph.c
new file mode 100644
index 0000000000..319e5e4022
--- /dev/null
+++ b/components/soc/esp32/sdmmc_periph.c
@@ -0,0 +1,50 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "soc/sdmmc_periph.h"
+
+const sdmmc_slot_info_t sdmmc_slot_info[2]  = {
+    {
+        .clk_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK,
+        .cmd_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD,
+        .d0_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D0,
+        .d1_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D1,
+        .d2_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D2,
+        .d3_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D3,
+        .d4_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D4,
+        .d5_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D5,
+        .d6_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D6,
+        .d7_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D7,
+        .card_detect = HOST_CARD_DETECT_N_1_IDX,
+        .write_protect = HOST_CARD_WRITE_PRT_1_IDX,
+        .card_int = HOST_CARD_INT_N_1_IDX,
+        .width = 8
+    },
+    {
+        .clk_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK,
+        .cmd_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD,
+        .d0_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D0,
+        .d1_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D1,
+        .d2_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D2,
+        .d3_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D3,
+        .d4_gpio = -1,  //slot1 has no D4-7
+        .d5_gpio = -1,
+        .d6_gpio = -1,
+        .d7_gpio = -1,
+        .card_detect = HOST_CARD_DETECT_N_2_IDX,
+        .write_protect = HOST_CARD_WRITE_PRT_2_IDX,
+        .card_int = HOST_CARD_INT_N_2_IDX,
+        .width = 4
+    }
+};
\ No newline at end of file
diff --git a/components/soc/include/soc/sdio_slave_periph.h b/components/soc/include/soc/sdio_slave_periph.h
new file mode 100644
index 0000000000..cc1c8cbca3
--- /dev/null
+++ b/components/soc/include/soc/sdio_slave_periph.h
@@ -0,0 +1,49 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _SOC_SDIO_SLAVE_PERIPH_H_
+#define _SOC_SDIO_SLAVE_PERIPH_H_
+
+#include <stdint.h>
+//include soc related (generated) definitions
+#include "soc/sdio_slave_pins.h"
+#include "soc/slc_reg.h"
+#include "soc/slc_struct.h"
+#include "soc/host_reg.h"
+#include "soc/host_struct.h"
+#include "soc/hinf_reg.h"
+#include "soc/hinf_struct.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** pin and signal information of each slot */
+typedef struct {
+    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;
+
+extern const sdio_slave_slot_info_t sdio_slave_slot_info[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SOC_SDIO_SLAVE_PERIPH_H_ */
\ No newline at end of file
diff --git a/components/soc/include/soc/sdmmc_periph.h b/components/soc/include/soc/sdmmc_periph.h
new file mode 100644
index 0000000000..183a658123
--- /dev/null
+++ b/components/soc/include/soc/sdmmc_periph.h
@@ -0,0 +1,53 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _SOC_SDMMC_PERIPH_H_
+#define _SOC_SDMMC_PERIPH_H_
+
+#include <stdint.h>
+//include soc related (generated) definitions
+#include "soc/sdmmc_pins.h"
+#include "soc/sdmmc_reg.h"
+#include "soc/sdmmc_struct.h"
+#include "soc/gpio_sig_map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    uint8_t clk_gpio;
+    uint8_t cmd_gpio;
+    uint8_t d0_gpio;
+    uint8_t d1_gpio;
+    uint8_t d2_gpio;
+    uint8_t d3_gpio;
+    uint8_t d4_gpio;
+    uint8_t d5_gpio;
+    uint8_t d6_gpio;
+    uint8_t d7_gpio;
+    uint8_t card_detect;
+    uint8_t write_protect;
+    uint8_t card_int;
+    uint8_t width;
+} sdmmc_slot_info_t;
+
+/** pin and signal information of each slot */
+extern const sdmmc_slot_info_t sdmmc_slot_info[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SOC_SDMMC_PERIPH_H_ */
\ No newline at end of file