]> granicus.if.org Git - esp-idf/commitdiff
Merge branch 'bugfix/spi_native_pins' into 'master'
authorAngus Gratton <angus@espressif.com>
Tue, 15 May 2018 06:19:20 +0000 (14:19 +0800)
committerAngus Gratton <angus@espressif.com>
Tue, 15 May 2018 06:19:20 +0000 (14:19 +0800)
fix several spi issues about pin configurations

See merge request idf/esp-idf!2309

components/driver/gpio.c
components/driver/include/driver/gpio.h
components/driver/spi_common.c

index 9563b1506676258a019ab8a361fbe769e464ec85..e017cd87dff6628d78ba042cec370dee9bb90068 100644 (file)
@@ -546,4 +546,17 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
         r = ESP_ERR_NOT_SUPPORTED;
     }
     return r == ESP_OK ? ESP_OK : ESP_ERR_NOT_SUPPORTED;
-}
\ No newline at end of file
+}
+
+void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx)
+{
+    GPIO.func_in_sel_cfg[signal_idx].sig_in_sel = 0;
+    PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio]);
+}
+
+void gpio_iomux_out(uint8_t gpio_num, int func, bool oen_inv)
+{
+    GPIO.func_out_sel_cfg[gpio_num].oen_sel = 0;
+    GPIO.func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv;
+    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], func);
+}
index 30225bdc90edabfcd85af4b3a7b0a29750de1066..f8aa33abf9d4c04e033392b56fdd5e2851e06fb3 100644 (file)
@@ -31,11 +31,11 @@ extern "C" {
 
 #define GPIO_SEL_0              (BIT(0))                         /*!< Pin 0 selected */
 #define GPIO_SEL_1              (BIT(1))                         /*!< Pin 1 selected */
-#define GPIO_SEL_2              (BIT(2))                         /*!< Pin 2 selected 
+#define GPIO_SEL_2              (BIT(2))                         /*!< Pin 2 selected
                                                                       @note There are more macros
                                                                       like that up to pin 39,
                                                                       excluding pins 20, 24 and 28..31.
-                                                                      They are not shown here 
+                                                                      They are not shown here
                                                                       to reduce redundant information. */
 /** @cond */
 #define GPIO_SEL_3              (BIT(3))                         /*!< Pin 3 selected */
@@ -172,7 +172,7 @@ typedef enum {
     GPIO_NUM_38 = 38,   /*!< GPIO38, input mode only */
     GPIO_NUM_39 = 39,   /*!< GPIO39, input mode only */
     GPIO_NUM_MAX = 40,
-/** @endcond */    
+/** @endcond */
 } gpio_num_t;
 
 typedef enum {
@@ -554,6 +554,22 @@ esp_err_t gpio_hold_en(gpio_num_t gpio_num);
   */
  esp_err_t gpio_hold_dis(gpio_num_t gpio_num);
 
+/**
+  * @brief Set pad input to a peripheral signal through the IOMUX.
+  * @param gpio_num GPIO number of the pad.
+  * @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
+  */
+void gpio_iomux_in(uint32_t gpio_num, uint32_t signal_idx);
+
+/**
+  * @brief Set peripheral output to an GPIO pad through the IOMUX.
+  * @param gpio_num gpio_num GPIO number of the pad.
+  * @param func The function number of the peripheral pin to output pin.
+  *        One of the ``FUNC_X_*`` of specified pin (X) in ``soc/io_mux_reg.h``.
+  * @param oen_inv True if the output enable needs to be inversed, otherwise False.
+  */
+void gpio_iomux_out(uint8_t gpio_num, int func, bool oen_inv);
+
 #ifdef __cplusplus
 }
 #endif
index 0aab4ee026f400bcaccb3bc335f1588516993500..52f239af3bb1c097d03866c2ff7770c685f5e980 100644 (file)
@@ -46,6 +46,9 @@ static const char *SPI_TAG = "spi";
 
 typedef struct spi_device_t spi_device_t;
 
+#define FUNC_SPI    1   //all pins of HSPI and VSPI shares this function number
+#define FUNC_GPIO   PIN_FUNC_GPIO
+
 /*
  Stores a bunch of per-spi-peripheral data.
 */
@@ -220,7 +223,7 @@ bool spicommon_dma_chan_free(int dma_chan)
 
 /*
 Do the common stuff to hook up a SPI host to a bus defined by a bunch of GPIO pins. Feed it a host number and a
-bus config struct and it'll set up the GPIO matrix and enable the device. If a pin is set to non-negative value, 
+bus config struct and it'll set up the GPIO matrix and enable the device. If a pin is set to non-negative value,
 it should be able to be initialized.
 */
 esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan, uint32_t flags, uint32_t* flags_o)
@@ -250,7 +253,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
     }
     if (bus_config->quadhd_io_num>=0) {
         SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(bus_config->quadhd_io_num), "spihd not valid", ESP_ERR_INVALID_ARG);
-        if (bus_config->quadhd_io_num != io_signal[host].spihd_native) native = false;        
+        if (bus_config->quadhd_io_num != io_signal[host].spihd_native) native = false;
     } else {
         quad_pins_exist = false;
         SPI_CHECK((flags&SPICOMMON_BUSFLAG_WPHD)==0, "spihd pin required.", ESP_ERR_INVALID_ARG);
@@ -277,11 +280,11 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
     } else {
         SPI_CHECK((flags&SPICOMMON_BUSFLAG_MISO)==0, "miso pin required.", ESP_ERR_INVALID_ARG);
     }
-    //set flags for DUAL mode according to output-capability of MOSI and MISO pins.   
-    if ( (bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num)) && 
+    //set flags for DUAL mode according to output-capability of MOSI and MISO pins.
+    if ( (bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num)) &&
         (bus_config->miso_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->miso_io_num)) ) {
         temp_flag |= SPICOMMON_BUSFLAG_DUAL;
-    }    
+    }
     //set flags for QUAD mode according to the existence of wp and hd
     if (quad_pins_exist) temp_flag |= SPICOMMON_BUSFLAG_WPHD;
     //check native pins if required.
@@ -291,18 +294,33 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
         //All SPI native pin selections resolve to 1, so we put that here instead of trying to figure
         //out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
         ESP_LOGD(SPI_TAG, "SPI%d use native pins.", host );
-        if (bus_config->mosi_io_num >= 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], 1);
-        if (bus_config->miso_io_num >= 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], 1);
-        if (bus_config->quadwp_io_num >= 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], 1);
-        if (bus_config->quadhd_io_num >= 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], 1);
-        if (bus_config->sclk_io_num >= 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], 1);
+        if (bus_config->mosi_io_num >= 0) {
+            gpio_iomux_in(bus_config->mosi_io_num, io_signal[host].spid_in);
+            gpio_iomux_out(bus_config->mosi_io_num, FUNC_SPI, false);
+        }
+        if (bus_config->miso_io_num >= 0) {
+            gpio_iomux_in(bus_config->miso_io_num, io_signal[host].spiq_in);
+            gpio_iomux_out(bus_config->miso_io_num, FUNC_SPI, false);
+        }
+        if (bus_config->quadwp_io_num >= 0) {
+            gpio_iomux_in(bus_config->quadwp_io_num, io_signal[host].spiwp_in);
+            gpio_iomux_out(bus_config->quadwp_io_num, FUNC_SPI, false);
+        }
+        if (bus_config->quadhd_io_num >= 0) {
+            gpio_iomux_in(bus_config->quadhd_io_num, io_signal[host].spihd_in);
+            gpio_iomux_out(bus_config->quadhd_io_num, FUNC_SPI, false);
+        }
+        if (bus_config->sclk_io_num >= 0) {
+            gpio_iomux_in(bus_config->sclk_io_num, io_signal[host].spiclk_in);
+            gpio_iomux_out(bus_config->sclk_io_num, FUNC_SPI, false);
+        }
         temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
     } else {
         //Use GPIO matrix
-        ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host );        
+        ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host );
         if (bus_config->mosi_io_num >= 0) {
-            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], PIN_FUNC_GPIO);
-            if (mosi_output) {
+            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], FUNC_GPIO);
+            if (mosi_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
                 gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT);
                 gpio_matrix_out(bus_config->mosi_io_num, io_signal[host].spid_out, false, false);
             } else {
@@ -311,29 +329,29 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
             gpio_matrix_in(bus_config->mosi_io_num, io_signal[host].spid_in, false);
         }
         if (bus_config->miso_io_num >= 0) {
-            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], PIN_FUNC_GPIO);
-            if (miso_output) {
+            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], FUNC_GPIO);
+            if (miso_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
                 gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT_OUTPUT);
                 gpio_matrix_out(bus_config->miso_io_num, io_signal[host].spiq_out, false, false);
             } else {
                 gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT);
             }
-            gpio_matrix_in(bus_config->miso_io_num, io_signal[host].spiq_in, false);                
+            gpio_matrix_in(bus_config->miso_io_num, io_signal[host].spiq_in, false);
         }
         if (bus_config->quadwp_io_num >= 0) {
-            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], PIN_FUNC_GPIO);
+            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], FUNC_GPIO);
             gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_INPUT_OUTPUT);
             gpio_matrix_out(bus_config->quadwp_io_num, io_signal[host].spiwp_out, false, false);
             gpio_matrix_in(bus_config->quadwp_io_num, io_signal[host].spiwp_in, false);
         }
         if (bus_config->quadhd_io_num >= 0) {
-            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], PIN_FUNC_GPIO);
+            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], FUNC_GPIO);
             gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_INPUT_OUTPUT);
             gpio_matrix_out(bus_config->quadhd_io_num, io_signal[host].spihd_out, false, false);
             gpio_matrix_in(bus_config->quadhd_io_num, io_signal[host].spihd_in, false);
         }
         if (bus_config->sclk_io_num >= 0) {
-            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], PIN_FUNC_GPIO);
+            PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], FUNC_GPIO);
             gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT_OUTPUT);
             gpio_matrix_out(bus_config->sclk_io_num, io_signal[host].spiclk_out, false, false);
             gpio_matrix_in(bus_config->sclk_io_num, io_signal[host].spiclk_in, false);
@@ -377,10 +395,11 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
 {
     if (!force_gpio_matrix && cs_io_num == io_signal[host].spics0_native && cs_num == 0) {
         //The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
-        PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], 1);
+        gpio_iomux_in(cs_io_num, io_signal[host].spics_in);
+        gpio_iomux_out(cs_io_num, FUNC_SPI, false);
     } else {
         //Use GPIO matrix
-        PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], PIN_FUNC_GPIO);
+        PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO);
         gpio_matrix_out(cs_io_num, io_signal[host].spics_out[cs_num], false, false);
         if (cs_num == 0) gpio_matrix_in(cs_io_num, io_signal[host].spics_in, false);
     }