From ebfda40b7c5cd6811828b6e2aac0f3e9e10d4812 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Fri, 8 Jun 2018 15:32:43 +0800 Subject: [PATCH 1/3] refactor(spi): move pin information into soc folder --- .../driver/include/driver/periph_ctrl.h | 39 +--- components/driver/include/driver/spi_common.h | 5 +- components/driver/include/driver/spi_slave.h | 2 +- components/driver/spi_common.c | 192 ++++-------------- components/driver/spi_master.c | 6 +- components/driver/spi_slave.c | 6 +- components/driver/test/test_spi_master.c | 4 +- components/esp32/test/test_intr_alloc.c | 2 +- .../soc/esp32/include/soc/periph_defs.h | 61 ++++++ .../esp32/include/{driver => soc}/spi_pins.h | 13 +- components/soc/esp32/spi_periph.c | 91 +++++++++ components/soc/include/soc/spi_periph.h | 66 ++++++ 12 files changed, 283 insertions(+), 204 deletions(-) create mode 100644 components/soc/esp32/include/soc/periph_defs.h rename components/soc/esp32/include/{driver => soc}/spi_pins.h (76%) create mode 100644 components/soc/esp32/spi_periph.c create mode 100644 components/soc/include/soc/spi_periph.h diff --git a/components/driver/include/driver/periph_ctrl.h b/components/driver/include/driver/periph_ctrl.h index 82a328d67..9689a8cb2 100644 --- a/components/driver/include/driver/periph_ctrl.h +++ b/components/driver/include/driver/periph_ctrl.h @@ -1,4 +1,4 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// 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. @@ -14,49 +14,16 @@ #ifndef _DRIVER_PERIPH_CTRL_H_ #define _DRIVER_PERIPH_CTRL_H_ + #include "esp_err.h" #include "soc/soc.h" #include "soc/dport_reg.h" +#include "soc/periph_defs.h" #ifdef __cplusplus extern "C" { #endif -typedef enum { - PERIPH_LEDC_MODULE = 0, - PERIPH_UART0_MODULE, - PERIPH_UART1_MODULE, - PERIPH_UART2_MODULE, - PERIPH_I2C0_MODULE, - PERIPH_I2C1_MODULE, - PERIPH_I2S0_MODULE, - PERIPH_I2S1_MODULE, - PERIPH_TIMG0_MODULE, - PERIPH_TIMG1_MODULE, - PERIPH_PWM0_MODULE, - PERIPH_PWM1_MODULE, - PERIPH_PWM2_MODULE, - PERIPH_PWM3_MODULE, - PERIPH_UHCI0_MODULE, - PERIPH_UHCI1_MODULE, - PERIPH_RMT_MODULE, - PERIPH_PCNT_MODULE, - PERIPH_SPI_MODULE, - PERIPH_HSPI_MODULE, - PERIPH_VSPI_MODULE, - PERIPH_SPI_DMA_MODULE, - PERIPH_SDMMC_MODULE, - PERIPH_SDIO_SLAVE_MODULE, - PERIPH_CAN_MODULE, - PERIPH_EMAC_MODULE, - PERIPH_RNG_MODULE, - PERIPH_WIFI_MODULE, - PERIPH_BT_MODULE, - PERIPH_WIFI_BT_COMMON_MODULE, - PERIPH_BT_BASEBAND_MODULE, - PERIPH_BT_LC_MODULE, -} periph_module_t; - /** * @brief enable peripheral module * diff --git a/components/driver/include/driver/spi_common.h b/components/driver/include/driver/spi_common.h index d81a9430b..33c701ec5 100644 --- a/components/driver/include/driver/spi_common.h +++ b/components/driver/include/driver/spi_common.h @@ -1,4 +1,4 @@ -// Copyright 2010-2017 Espressif Systems (Shanghai) PTE LTD +// Copyright 2010-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. @@ -19,9 +19,8 @@ #include #include #include "esp_err.h" -#include "soc/spi_struct.h" #include "rom/lldesc.h" - +#include "soc/spi_periph.h" #ifdef __cplusplus extern "C" diff --git a/components/driver/include/driver/spi_slave.h b/components/driver/include/driver/spi_slave.h index 1d5ea3402..9ad4b9126 100644 --- a/components/driver/include/driver/spi_slave.h +++ b/components/driver/include/driver/spi_slave.h @@ -1,4 +1,4 @@ -// Copyright 2010-2017 Espressif Systems (Shanghai) PTE LTD +// Copyright 2010-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. diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index a605f144c..1eb1ebef8 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -1,4 +1,4 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// 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. @@ -15,10 +15,8 @@ #include #include "driver/spi_master.h" -#include "soc/gpio_sig_map.h" -#include "soc/spi_reg.h" #include "soc/dport_reg.h" -#include "soc/spi_struct.h" +#include "soc/spi_periph.h" #include "rom/ets_sys.h" #include "esp_types.h" #include "esp_attr.h" @@ -32,7 +30,6 @@ #include "driver/gpio.h" #include "driver/periph_ctrl.h" #include "esp_heap_caps.h" - #include "driver/spi_common.h" static const char *SPI_TAG = "spi"; @@ -49,109 +46,6 @@ 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. -*/ -typedef struct { - const uint8_t spiclk_out; //GPIO mux output signals - const uint8_t spiclk_in; - const uint8_t spid_out; - const uint8_t spiq_out; - const uint8_t spiwp_out; - const uint8_t spihd_out; - const uint8_t spid_in; //GPIO mux input signals - const uint8_t spiq_in; - const uint8_t spiwp_in; - const uint8_t spihd_in; - const uint8_t spics_out[3]; // /CS GPIO output mux signals - const uint8_t spics_in; - const uint8_t spiclk_iomux_pin; //IO pins of IO_MUX muxed signals - const uint8_t spid_iomux_pin; - const uint8_t spiq_iomux_pin; - const uint8_t spiwp_iomux_pin; - const uint8_t spihd_iomux_pin; - const uint8_t spics0_iomux_pin; - const uint8_t irq; //irq source for interrupt mux - const uint8_t irq_dma; //dma irq source for interrupt mux - const periph_module_t module; //peripheral module, for enabling clock etc - spi_dev_t *hw; //Pointer to the hardware registers -} spi_signal_conn_t; - -/* - Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc -*/ -static const spi_signal_conn_t io_signal[3] = { - { - .spiclk_out = SPICLK_OUT_IDX, - .spiclk_in = SPICLK_IN_IDX, - .spid_out = SPID_OUT_IDX, - .spiq_out = SPIQ_OUT_IDX, - .spiwp_out = SPIWP_OUT_IDX, - .spihd_out = SPIHD_OUT_IDX, - .spid_in = SPID_IN_IDX, - .spiq_in = SPIQ_IN_IDX, - .spiwp_in = SPIWP_IN_IDX, - .spihd_in = SPIHD_IN_IDX, - .spics_out = {SPICS0_OUT_IDX, SPICS1_OUT_IDX, SPICS2_OUT_IDX}, - .spics_in = SPICS0_IN_IDX, - .spiclk_iomux_pin = 6, - .spid_iomux_pin = 8, - .spiq_iomux_pin = 7, - .spiwp_iomux_pin = 10, - .spihd_iomux_pin = 9, - .spics0_iomux_pin = 11, - .irq = ETS_SPI1_INTR_SOURCE, - .irq_dma = ETS_SPI1_DMA_INTR_SOURCE, - .module = PERIPH_SPI_MODULE, - .hw = &SPI1 - }, { - .spiclk_out = HSPICLK_OUT_IDX, - .spiclk_in = HSPICLK_IN_IDX, - .spid_out = HSPID_OUT_IDX, - .spiq_out = HSPIQ_OUT_IDX, - .spiwp_out = HSPIWP_OUT_IDX, - .spihd_out = HSPIHD_OUT_IDX, - .spid_in = HSPID_IN_IDX, - .spiq_in = HSPIQ_IN_IDX, - .spiwp_in = HSPIWP_IN_IDX, - .spihd_in = HSPIHD_IN_IDX, - .spics_out = {HSPICS0_OUT_IDX, HSPICS1_OUT_IDX, HSPICS2_OUT_IDX}, - .spics_in = HSPICS0_IN_IDX, - .spiclk_iomux_pin = 14, - .spid_iomux_pin = 13, - .spiq_iomux_pin = 12, - .spiwp_iomux_pin = 2, - .spihd_iomux_pin = 4, - .spics0_iomux_pin = 15, - .irq = ETS_SPI2_INTR_SOURCE, - .irq_dma = ETS_SPI2_DMA_INTR_SOURCE, - .module = PERIPH_HSPI_MODULE, - .hw = &SPI2 - }, { - .spiclk_out = VSPICLK_OUT_IDX, - .spiclk_in = VSPICLK_IN_IDX, - .spid_out = VSPID_OUT_IDX, - .spiq_out = VSPIQ_OUT_IDX, - .spiwp_out = VSPIWP_OUT_IDX, - .spihd_out = VSPIHD_OUT_IDX, - .spid_in = VSPID_IN_IDX, - .spiq_in = VSPIQ_IN_IDX, - .spiwp_in = VSPIWP_IN_IDX, - .spihd_in = VSPIHD_IN_IDX, - .spics_out = {VSPICS0_OUT_IDX, VSPICS1_OUT_IDX, VSPICS2_OUT_IDX}, - .spics_in = VSPICS0_IN_IDX, - .spiclk_iomux_pin = 18, - .spid_iomux_pin = 23, - .spiq_iomux_pin = 19, - .spiwp_iomux_pin = 22, - .spihd_iomux_pin = 21, - .spics0_iomux_pin = 5, - .irq = ETS_SPI3_INTR_SOURCE, - .irq_dma = ETS_SPI3_DMA_INTR_SOURCE, - .module = PERIPH_VSPI_MODULE, - .hw = &SPI3 - } -}; #define DMA_CHANNEL_ENABLED(dma_chan) (BIT(dma_chan-1)) @@ -165,7 +59,7 @@ static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED; bool spicommon_periph_claim(spi_host_device_t host) { bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], false, true); - if (ret) periph_module_enable(io_signal[host].module); + if (ret) periph_module_enable(spi_periph_signal[host].module); return ret; } @@ -173,19 +67,19 @@ bool spicommon_periph_claim(spi_host_device_t host) bool spicommon_periph_free(spi_host_device_t host) { bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], true, false); - if (ret) periph_module_disable(io_signal[host].module); + if (ret) periph_module_disable(spi_periph_signal[host].module); return ret; } int spicommon_irqsource_for_host(spi_host_device_t host) { - return io_signal[host].irq; + return spi_periph_signal[host].irq; } spi_dev_t *spicommon_hw_for_host(spi_host_device_t host) { - return io_signal[host].hw; + return spi_periph_signal[host].hw; } bool spicommon_dma_chan_claim (int dma_chan) @@ -240,20 +134,20 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf if (bus_config->sclk_io_num>=0) { temp_flag |= SPICOMMON_BUSFLAG_SCLK; SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(bus_config->sclk_io_num), "sclk not valid", ESP_ERR_INVALID_ARG); - if (bus_config->sclk_io_num != io_signal[host].spiclk_iomux_pin) use_iomux = false; + if (bus_config->sclk_io_num != spi_periph_signal[host].spiclk_iomux_pin) use_iomux = false; } else { SPI_CHECK((flags&SPICOMMON_BUSFLAG_SCLK)==0, "sclk pin required.", ESP_ERR_INVALID_ARG); } if (bus_config->quadwp_io_num>=0) { SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(bus_config->quadwp_io_num), "spiwp not valid", ESP_ERR_INVALID_ARG); - if (bus_config->quadwp_io_num != io_signal[host].spiwp_iomux_pin) use_iomux = false; + if (bus_config->quadwp_io_num != spi_periph_signal[host].spiwp_iomux_pin) use_iomux = false; } else { quad_pins_exist = false; SPI_CHECK((flags&SPICOMMON_BUSFLAG_WPHD)==0, "spiwp pin required.", ESP_ERR_INVALID_ARG); } 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_iomux_pin) use_iomux = false; + if (bus_config->quadhd_io_num != spi_periph_signal[host].spihd_iomux_pin) use_iomux = false; } else { quad_pins_exist = false; SPI_CHECK((flags&SPICOMMON_BUSFLAG_WPHD)==0, "spihd pin required.", ESP_ERR_INVALID_ARG); @@ -265,7 +159,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf } else { SPI_CHECK(GPIO_IS_VALID_GPIO(bus_config->mosi_io_num), "mosi not valid", ESP_ERR_INVALID_ARG); } - if (bus_config->mosi_io_num != io_signal[host].spid_iomux_pin) use_iomux = false; + if (bus_config->mosi_io_num != spi_periph_signal[host].spid_iomux_pin) use_iomux = false; } else { SPI_CHECK((flags&SPICOMMON_BUSFLAG_MOSI)==0, "mosi pin required.", ESP_ERR_INVALID_ARG); } @@ -276,7 +170,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf } else { SPI_CHECK(GPIO_IS_VALID_GPIO(bus_config->miso_io_num), "miso not valid", ESP_ERR_INVALID_ARG); } - if (bus_config->miso_io_num != io_signal[host].spiq_iomux_pin) use_iomux = false; + if (bus_config->miso_io_num != spi_periph_signal[host].spiq_iomux_pin) use_iomux = false; } else { SPI_CHECK((flags&SPICOMMON_BUSFLAG_MISO)==0, "miso pin required.", ESP_ERR_INVALID_ARG); } @@ -295,23 +189,23 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf //out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway. ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host ); if (bus_config->mosi_io_num >= 0) { - gpio_iomux_in(bus_config->mosi_io_num, io_signal[host].spid_in); + gpio_iomux_in(bus_config->mosi_io_num, spi_periph_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_in(bus_config->miso_io_num, spi_periph_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_in(bus_config->quadwp_io_num, spi_periph_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_in(bus_config->quadhd_io_num, spi_periph_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_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in); gpio_iomux_out(bus_config->sclk_io_num, FUNC_SPI, false); } temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS; @@ -322,39 +216,39 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf 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); + gpio_matrix_out(bus_config->mosi_io_num, spi_periph_signal[host].spid_out, false, false); } else { gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT); } - gpio_matrix_in(bus_config->mosi_io_num, io_signal[host].spid_in, false); + gpio_matrix_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false); } if (bus_config->miso_io_num >= 0) { 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); + gpio_matrix_out(bus_config->miso_io_num, spi_periph_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, spi_periph_signal[host].spiq_in, false); } if (bus_config->quadwp_io_num >= 0) { 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); + gpio_matrix_out(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_out, false, false); + gpio_matrix_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, false); } if (bus_config->quadhd_io_num >= 0) { 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); + gpio_matrix_out(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_out, false, false); + gpio_matrix_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, false); } if (bus_config->sclk_io_num >= 0) { 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); + gpio_matrix_out(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_out, false, false); + gpio_matrix_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in, false); } } @@ -378,39 +272,39 @@ static void reset_func_to_gpio(int func) esp_err_t spicommon_bus_free_io(spi_host_device_t host) { - if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spid_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spid_iomux_pin], PIN_FUNC_GPIO); - if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spiq_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spiq_iomux_pin], PIN_FUNC_GPIO); - if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spiclk_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spiclk_iomux_pin], PIN_FUNC_GPIO); - if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spiwp_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spiwp_iomux_pin], PIN_FUNC_GPIO); - if (REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spihd_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spihd_iomux_pin], PIN_FUNC_GPIO); - reset_func_to_gpio(io_signal[host].spid_out); - reset_func_to_gpio(io_signal[host].spiq_out); - reset_func_to_gpio(io_signal[host].spiclk_out); - reset_func_to_gpio(io_signal[host].spiwp_out); - reset_func_to_gpio(io_signal[host].spihd_out); + if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spid_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spid_iomux_pin], PIN_FUNC_GPIO); + if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiq_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiq_iomux_pin], PIN_FUNC_GPIO); + if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiclk_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiclk_iomux_pin], PIN_FUNC_GPIO); + if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiwp_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spiwp_iomux_pin], PIN_FUNC_GPIO); + if (REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spihd_iomux_pin], MCU_SEL) == 1) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spihd_iomux_pin], PIN_FUNC_GPIO); + reset_func_to_gpio(spi_periph_signal[host].spid_out); + reset_func_to_gpio(spi_periph_signal[host].spiq_out); + reset_func_to_gpio(spi_periph_signal[host].spiclk_out); + reset_func_to_gpio(spi_periph_signal[host].spiwp_out); + reset_func_to_gpio(spi_periph_signal[host].spihd_out); return ESP_OK; } void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix) { - if (!force_gpio_matrix && cs_io_num == io_signal[host].spics0_iomux_pin && cs_num == 0) { + if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) { //The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define. - gpio_iomux_in(cs_io_num, io_signal[host].spics_in); + gpio_iomux_in(cs_io_num, spi_periph_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], 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); + gpio_matrix_out(cs_io_num, spi_periph_signal[host].spics_out[cs_num], false, false); + if (cs_num == 0) gpio_matrix_in(cs_io_num, spi_periph_signal[host].spics_in, false); } } void spicommon_cs_free(spi_host_device_t host, int cs_io_num) { - if (cs_io_num == 0 && REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spics0_iomux_pin], MCU_SEL) == 1) { - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spics0_iomux_pin], PIN_FUNC_GPIO); + if (cs_io_num == 0 && REG_GET_FIELD(GPIO_PIN_MUX_REG[spi_periph_signal[host].spics0_iomux_pin], MCU_SEL) == 1) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[spi_periph_signal[host].spics0_iomux_pin], PIN_FUNC_GPIO); } - reset_func_to_gpio(io_signal[host].spics_out[cs_io_num]); + reset_func_to_gpio(spi_periph_signal[host].spics_out[cs_io_num]); } //Set up a list of dma descriptors. dmadesc is an array of descriptors. Data is the buffer to point to. diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 02cb88455..ec54a3bad 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -1,4 +1,4 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// 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. @@ -36,10 +36,8 @@ queue and re-enabling the interrupt will trigger the interrupt again, which can #include #include "driver/spi_common.h" #include "driver/spi_master.h" -#include "soc/gpio_sig_map.h" -#include "soc/spi_reg.h" #include "soc/dport_reg.h" -#include "soc/spi_struct.h" +#include "soc/spi_periph.h" #include "rom/ets_sys.h" #include "esp_types.h" #include "esp_attr.h" diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index 7ee2222e2..7ff89e6c8 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -1,4 +1,4 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// 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. @@ -15,10 +15,8 @@ #include #include "driver/spi_common.h" #include "driver/spi_slave.h" -#include "soc/gpio_sig_map.h" -#include "soc/spi_reg.h" #include "soc/dport_reg.h" -#include "soc/spi_struct.h" +#include "soc/spi_periph.h" #include "rom/ets_sys.h" #include "esp_types.h" #include "esp_attr.h" diff --git a/components/driver/test/test_spi_master.c b/components/driver/test/test_spi_master.c index 329f3fe6a..a86b9ccd0 100644 --- a/components/driver/test/test_spi_master.c +++ b/components/driver/test/test_spi_master.c @@ -17,11 +17,9 @@ #include "driver/spi_master.h" #include "driver/spi_slave.h" #include "soc/dport_reg.h" -#include "soc/spi_reg.h" -#include "soc/spi_struct.h" #include "esp_heap_caps.h" #include "esp_log.h" -#include "driver/spi_pins.h" +#include "soc/spi_periph.h" #include "freertos/ringbuf.h" const static char TAG[] = "test_spi"; diff --git a/components/esp32/test/test_intr_alloc.c b/components/esp32/test/test_intr_alloc.c index 00a325b1e..0112814fa 100644 --- a/components/esp32/test/test_intr_alloc.c +++ b/components/esp32/test/test_intr_alloc.c @@ -231,7 +231,7 @@ TEST_CASE("Can allocate IRAM int only with an IRAM handler", "[esp32]") } -#include "soc/spi_struct.h" +#include "soc/spi_periph.h" typedef struct { bool flag1; bool flag2; diff --git a/components/soc/esp32/include/soc/periph_defs.h b/components/soc/esp32/include/soc/periph_defs.h new file mode 100644 index 000000000..7aa21fc96 --- /dev/null +++ b/components/soc/esp32/include/soc/periph_defs.h @@ -0,0 +1,61 @@ +// 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_PERIPH_DEFS_H_ +#define _SOC_PERIPH_DEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PERIPH_LEDC_MODULE = 0, + PERIPH_UART0_MODULE, + PERIPH_UART1_MODULE, + PERIPH_UART2_MODULE, + PERIPH_I2C0_MODULE, + PERIPH_I2C1_MODULE, + PERIPH_I2S0_MODULE, + PERIPH_I2S1_MODULE, + PERIPH_TIMG0_MODULE, + PERIPH_TIMG1_MODULE, + PERIPH_PWM0_MODULE, + PERIPH_PWM1_MODULE, + PERIPH_PWM2_MODULE, + PERIPH_PWM3_MODULE, + PERIPH_UHCI0_MODULE, + PERIPH_UHCI1_MODULE, + PERIPH_RMT_MODULE, + PERIPH_PCNT_MODULE, + PERIPH_SPI_MODULE, + PERIPH_HSPI_MODULE, + PERIPH_VSPI_MODULE, + PERIPH_SPI_DMA_MODULE, + PERIPH_SDMMC_MODULE, + PERIPH_SDIO_SLAVE_MODULE, + PERIPH_CAN_MODULE, + PERIPH_EMAC_MODULE, + PERIPH_RNG_MODULE, + PERIPH_WIFI_MODULE, + PERIPH_BT_MODULE, + PERIPH_WIFI_BT_COMMON_MODULE, + PERIPH_BT_BASEBAND_MODULE, + PERIPH_BT_LC_MODULE, +} periph_module_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _SOC_PERIPH_DEFS_H_ */ diff --git a/components/soc/esp32/include/driver/spi_pins.h b/components/soc/esp32/include/soc/spi_pins.h similarity index 76% rename from components/soc/esp32/include/driver/spi_pins.h rename to components/soc/esp32/include/soc/spi_pins.h index b94c48d7f..49be9b7c1 100644 --- a/components/soc/esp32/include/driver/spi_pins.h +++ b/components/soc/esp32/include/soc/spi_pins.h @@ -12,8 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _DRIVER_SPI_PINS_H_ -#define _DRIVER_SPI_PINS_H_ +#ifndef _SOC_SPI_PINS_H_ +#define _SOC_SPI_PINS_H_ + +#define SPI_IOMUX_PIN_NUM_MISO 7 +#define SPI_IOMUX_PIN_NUM_MOSI 8 +#define SPI_IOMUX_PIN_NUM_CLK 6 +#define SPI_IOMUX_PIN_NUM_CS 11 +#define SPI_IOMUX_PIN_NUM_WP 10 +#define SPI_IOMUX_PIN_NUM_HD 9 #define HSPI_IOMUX_PIN_NUM_MISO 12 #define HSPI_IOMUX_PIN_NUM_MOSI 13 @@ -29,4 +36,4 @@ #define VSPI_IOMUX_PIN_NUM_WP 22 #define VSPI_IOMUX_PIN_NUM_HD 21 -#endif \ No newline at end of file +#endif /* _SOC_SPI_PINS_H_ */ \ No newline at end of file diff --git a/components/soc/esp32/spi_periph.c b/components/soc/esp32/spi_periph.c new file mode 100644 index 000000000..92e748e93 --- /dev/null +++ b/components/soc/esp32/spi_periph.c @@ -0,0 +1,91 @@ +// 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/spi_periph.h" + +/* + Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc +*/ +const spi_signal_conn_t spi_periph_signal[3] = { + { + .spiclk_out = SPICLK_OUT_IDX, + .spiclk_in = SPICLK_IN_IDX, + .spid_out = SPID_OUT_IDX, + .spiq_out = SPIQ_OUT_IDX, + .spiwp_out = SPIWP_OUT_IDX, + .spihd_out = SPIHD_OUT_IDX, + .spid_in = SPID_IN_IDX, + .spiq_in = SPIQ_IN_IDX, + .spiwp_in = SPIWP_IN_IDX, + .spihd_in = SPIHD_IN_IDX, + .spics_out = {SPICS0_OUT_IDX, SPICS1_OUT_IDX, SPICS2_OUT_IDX}, + .spics_in = SPICS0_IN_IDX, + .spiclk_iomux_pin = SPI_IOMUX_PIN_NUM_CLK, + .spid_iomux_pin = SPI_IOMUX_PIN_NUM_MOSI, + .spiq_iomux_pin = SPI_IOMUX_PIN_NUM_MISO, + .spiwp_iomux_pin = SPI_IOMUX_PIN_NUM_WP, + .spihd_iomux_pin = SPI_IOMUX_PIN_NUM_HD, + .spics0_iomux_pin = SPI_IOMUX_PIN_NUM_CS, + .irq = ETS_SPI1_INTR_SOURCE, + .irq_dma = ETS_SPI1_DMA_INTR_SOURCE, + .module = PERIPH_SPI_MODULE, + .hw = &SPI1 + }, { + .spiclk_out = HSPICLK_OUT_IDX, + .spiclk_in = HSPICLK_IN_IDX, + .spid_out = HSPID_OUT_IDX, + .spiq_out = HSPIQ_OUT_IDX, + .spiwp_out = HSPIWP_OUT_IDX, + .spihd_out = HSPIHD_OUT_IDX, + .spid_in = HSPID_IN_IDX, + .spiq_in = HSPIQ_IN_IDX, + .spiwp_in = HSPIWP_IN_IDX, + .spihd_in = HSPIHD_IN_IDX, + .spics_out = {HSPICS0_OUT_IDX, HSPICS1_OUT_IDX, HSPICS2_OUT_IDX}, + .spics_in = HSPICS0_IN_IDX, + .spiclk_iomux_pin = HSPI_IOMUX_PIN_NUM_CLK, + .spid_iomux_pin = HSPI_IOMUX_PIN_NUM_MOSI, + .spiq_iomux_pin = HSPI_IOMUX_PIN_NUM_MISO, + .spiwp_iomux_pin = HSPI_IOMUX_PIN_NUM_WP, + .spihd_iomux_pin = HSPI_IOMUX_PIN_NUM_HD, + .spics0_iomux_pin = HSPI_IOMUX_PIN_NUM_CS, + .irq = ETS_SPI2_INTR_SOURCE, + .irq_dma = ETS_SPI2_DMA_INTR_SOURCE, + .module = PERIPH_HSPI_MODULE, + .hw = &SPI2 + }, { + .spiclk_out = VSPICLK_OUT_IDX, + .spiclk_in = VSPICLK_IN_IDX, + .spid_out = VSPID_OUT_IDX, + .spiq_out = VSPIQ_OUT_IDX, + .spiwp_out = VSPIWP_OUT_IDX, + .spihd_out = VSPIHD_OUT_IDX, + .spid_in = VSPID_IN_IDX, + .spiq_in = VSPIQ_IN_IDX, + .spiwp_in = VSPIWP_IN_IDX, + .spihd_in = VSPIHD_IN_IDX, + .spics_out = {VSPICS0_OUT_IDX, VSPICS1_OUT_IDX, VSPICS2_OUT_IDX}, + .spics_in = VSPICS0_IN_IDX, + .spiclk_iomux_pin = VSPI_IOMUX_PIN_NUM_CLK, + .spid_iomux_pin = VSPI_IOMUX_PIN_NUM_MOSI, + .spiq_iomux_pin = VSPI_IOMUX_PIN_NUM_MISO, + .spiwp_iomux_pin = VSPI_IOMUX_PIN_NUM_WP, + .spihd_iomux_pin = VSPI_IOMUX_PIN_NUM_HD, + .spics0_iomux_pin = VSPI_IOMUX_PIN_NUM_CS, + .irq = ETS_SPI3_INTR_SOURCE, + .irq_dma = ETS_SPI3_DMA_INTR_SOURCE, + .module = PERIPH_VSPI_MODULE, + .hw = &SPI3 + } +}; \ No newline at end of file diff --git a/components/soc/include/soc/spi_periph.h b/components/soc/include/soc/spi_periph.h new file mode 100644 index 000000000..00c5f3e13 --- /dev/null +++ b/components/soc/include/soc/spi_periph.h @@ -0,0 +1,66 @@ +// 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_SPI_PERIPH_H_ +#define _SOC_SPI_PERIPH_H_ + +#include +#include "soc/soc.h" +#include "soc/periph_defs.h" +//include soc related (generated) definitions +#include "soc/spi_pins.h" +#include "soc/spi_reg.h" +#include "soc/spi_struct.h" +#include "soc/gpio_sig_map.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + Stores a bunch of per-spi-peripheral data. +*/ +typedef struct { + const uint8_t spiclk_out; //GPIO mux output signals + const uint8_t spiclk_in; + const uint8_t spid_out; + const uint8_t spiq_out; + const uint8_t spiwp_out; + const uint8_t spihd_out; + const uint8_t spid_in; //GPIO mux input signals + const uint8_t spiq_in; + const uint8_t spiwp_in; + const uint8_t spihd_in; + const uint8_t spics_out[3]; // /CS GPIO output mux signals + const uint8_t spics_in; + const uint8_t spiclk_iomux_pin; //IO pins of IO_MUX muxed signals + const uint8_t spid_iomux_pin; + const uint8_t spiq_iomux_pin; + const uint8_t spiwp_iomux_pin; + const uint8_t spihd_iomux_pin; + const uint8_t spics0_iomux_pin; + const uint8_t irq; //irq source for interrupt mux + const uint8_t irq_dma; //dma irq source for interrupt mux + const periph_module_t module; //peripheral module, for enabling clock etc + spi_dev_t *hw; //Pointer to the hardware registers +} spi_signal_conn_t; + +extern const spi_signal_conn_t spi_periph_signal[3]; + +#ifdef __cplusplus +} +#endif + +#endif /* _SOC_SPI_PERIPH_H_ */ \ No newline at end of file From 77077196fd48b408a7d4c9e009893296fc426de1 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Fri, 8 Jun 2018 15:33:04 +0800 Subject: [PATCH 2/3] fix(spi): reset gpios that used by spi when deinited --- components/driver/gpio.c | 15 +++++++++++ components/driver/include/driver/gpio.h | 12 +++++++++ components/driver/include/driver/spi_common.h | 25 ++++++++++++++++--- components/driver/spi_common.c | 22 ++++++++++++++++ components/driver/spi_master.c | 7 ++++++ 5 files changed, 78 insertions(+), 3 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index e017cd87d..d82fae130 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -339,6 +339,21 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig) return ESP_OK; } +esp_err_t gpio_reset_pin(gpio_num_t gpio_num) +{ + assert(gpio_num >= 0 && GPIO_IS_VALID_GPIO(gpio_num)); + gpio_config_t cfg = { + .pin_bit_mask = BIT(gpio_num), + .mode = GPIO_MODE_DISABLE, + //for powersave reasons, the GPIO should not be floating, select pullup + .pull_up_en = true, + .pull_down_en = false, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&cfg); + return ESP_OK; +} + void IRAM_ATTR gpio_intr_service(void* arg) { //GPIO intr process diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index f8aa33abf..1c4828c27 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -248,6 +248,18 @@ typedef intr_handle_t gpio_isr_handle_t; */ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig); +/** + * @brief Reset an gpio to default state (select gpio function, enable pullup and disable input and output). + * + * @param gpio_num GPIO number. + * + * @note This function also configures the IOMUX for this pin to the GPIO + * function, and disconnects any other peripheral output configured via GPIO + * Matrix. + * + * @return Always return ESP_OK. + */ +esp_err_t gpio_reset_pin(gpio_num_t gpio_num); /** * @brief GPIO set interrupt trigger type diff --git a/components/driver/include/driver/spi_common.h b/components/driver/include/driver/spi_common.h index 33c701ec5..cc029db2b 100644 --- a/components/driver/include/driver/spi_common.h +++ b/components/driver/include/driver/spi_common.h @@ -144,14 +144,26 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf /** * @brief Free the IO used by a SPI peripheral - * + * @deprecated Use spicommon_bus_free_io_cfg instead. + * * @param host SPI peripheral to be freed + * * @return * - ESP_ERR_INVALID_ARG if parameter is invalid * - ESP_OK on success */ +esp_err_t spicommon_bus_free_io(spi_host_device_t host) __attribute__((deprecated)); -esp_err_t spicommon_bus_free_io(spi_host_device_t host); +/** + * @brief Free the IO used by a SPI peripheral + * + * @param bus_cfg Bus config struct which defines which pins to be used. + * + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_OK on success + */ +esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg); /** * @brief Initialize a Chip Select pin for a specific SPI peripheral @@ -168,12 +180,19 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, /** * @brief Free a chip select line + * @deprecated Use spicommon_cs_io, which inputs the gpio num rather than the cs id instead. * * @param host SPI peripheral * @param cs_num CS id to free */ -void spicommon_cs_free(spi_host_device_t host, int cs_num); +void spicommon_cs_free(spi_host_device_t host, int cs_num) __attribute__((deprecated)); +/** + * @brief Free a chip select line + * + * @param cs_gpio_num CS gpio num to free + */ +void spicommon_cs_free_io(int cs_gpio_num); /** * @brief Setup a DMA link chain diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index 1eb1ebef8..a26b14702 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -285,6 +285,22 @@ esp_err_t spicommon_bus_free_io(spi_host_device_t host) return ESP_OK; } +esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg) +{ + int pin_array[] = { + bus_cfg->mosi_io_num, + bus_cfg->miso_io_num, + bus_cfg->sclk_io_num, + bus_cfg->quadwp_io_num, + bus_cfg->quadhd_io_num, + }; + for (int i = 0; i < sizeof(pin_array)/sizeof(int); i ++) { + const int io = pin_array[i]; + if (io >= 0 && GPIO_IS_VALID_GPIO(io)) gpio_reset_pin(io); + } + return ESP_OK; +} + void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix) { if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) { @@ -307,6 +323,12 @@ void spicommon_cs_free(spi_host_device_t host, int cs_io_num) reset_func_to_gpio(spi_periph_signal[host].spics_out[cs_io_num]); } +void spicommon_cs_free_io(int cs_gpio_num) +{ + assert(cs_gpio_num>=0 && GPIO_IS_VALID_GPIO(cs_gpio_num)); + gpio_reset_pin(cs_gpio_num); +} + //Set up a list of dma descriptors. dmadesc is an array of descriptors. Data is the buffer to point to. void spicommon_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx) { diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index ec54a3bad..8fa864784 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -85,6 +85,7 @@ typedef struct { uint32_t flags; int dma_chan; int max_transfer_sz; + spi_bus_config_t bus_cfg; #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; #endif @@ -146,6 +147,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus goto cleanup; } memset(spihost[host], 0, sizeof(spi_host_t)); + memcpy( &spihost[host]->bus_cfg, bus_config, sizeof(spi_bus_config_t)); #ifdef CONFIG_PM_ENABLE err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master", &spihost[host]->pm_lock); @@ -237,6 +239,7 @@ esp_err_t spi_bus_free(spi_host_device_t host) for (x=0; xdevice[x]==NULL, "not all CSses freed", ESP_ERR_INVALID_STATE); } + spicommon_bus_free_io_cfg(&spihost[host]->bus_cfg); if ( spihost[host]->dma_chan > 0 ) { spicommon_dma_chan_free ( spihost[host]->dma_chan ); @@ -395,6 +398,10 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle) SPI_CHECK(handle->host->cur_cs == NO_CS || handle->host->device[handle->host->cur_cs]!=handle, "Have unfinished transactions", ESP_ERR_INVALID_STATE); SPI_CHECK(uxQueueMessagesWaiting(handle->ret_queue)==0, "Have unfinished transactions", ESP_ERR_INVALID_STATE); + //return + int spics_io_num = handle->cfg.spics_io_num; + if (spics_io_num >= 0) spicommon_cs_free_io(spics_io_num); + //Kill queues vQueueDelete(handle->trans_queue); vQueueDelete(handle->ret_queue); From 45d1c9207cd55d4f0c20d58621c9107d3ac6a029 Mon Sep 17 00:00:00 2001 From: michael Date: Mon, 11 Jun 2018 12:13:10 +0800 Subject: [PATCH 3/3] bugfix(spi): resolve the glitch that happens during initialization --- components/driver/spi_common.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index a26b14702..aa5495a8c 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -213,7 +213,6 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf //Use GPIO matrix 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], 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, spi_periph_signal[host].spid_out, false, false); @@ -221,9 +220,9 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT); } gpio_matrix_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], FUNC_GPIO); } if (bus_config->miso_io_num >= 0) { - 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, spi_periph_signal[host].spiq_out, false, false); @@ -231,24 +230,25 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT); } gpio_matrix_in(bus_config->miso_io_num, spi_periph_signal[host].spiq_in, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], FUNC_GPIO); } if (bus_config->quadwp_io_num >= 0) { - 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, spi_periph_signal[host].spiwp_out, false, false); gpio_matrix_in(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], FUNC_GPIO); } if (bus_config->quadhd_io_num >= 0) { - 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, spi_periph_signal[host].spihd_out, false, false); gpio_matrix_in(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], FUNC_GPIO); } if (bus_config->sclk_io_num >= 0) { - 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, spi_periph_signal[host].spiclk_out, false, false); gpio_matrix_in(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], FUNC_GPIO); } } @@ -309,9 +309,9 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, gpio_iomux_out(cs_io_num, FUNC_SPI, false); } else { //Use GPIO matrix - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO); gpio_matrix_out(cs_io_num, spi_periph_signal[host].spics_out[cs_num], false, false); if (cs_num == 0) gpio_matrix_in(cs_io_num, spi_periph_signal[host].spics_in, false); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO); } }