fix(spi): reset gpios that used by spi when deinited
This commit is contained in:
parent
ebfda40b7c
commit
77077196fd
5 changed files with 78 additions and 3 deletions
|
@ -339,6 +339,21 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
|
||||||
return ESP_OK;
|
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)
|
void IRAM_ATTR gpio_intr_service(void* arg)
|
||||||
{
|
{
|
||||||
//GPIO intr process
|
//GPIO intr process
|
||||||
|
|
|
@ -248,6 +248,18 @@ typedef intr_handle_t gpio_isr_handle_t;
|
||||||
*/
|
*/
|
||||||
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig);
|
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
|
* @brief GPIO set interrupt trigger type
|
||||||
|
|
|
@ -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
|
* @brief Free the IO used by a SPI peripheral
|
||||||
|
* @deprecated Use spicommon_bus_free_io_cfg instead.
|
||||||
*
|
*
|
||||||
* @param host SPI peripheral to be freed
|
* @param host SPI peripheral to be freed
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* - ESP_ERR_INVALID_ARG if parameter is invalid
|
* - ESP_ERR_INVALID_ARG if parameter is invalid
|
||||||
* - ESP_OK on success
|
* - 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
|
* @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
|
* @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 host SPI peripheral
|
||||||
* @param cs_num CS id to free
|
* @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
|
* @brief Setup a DMA link chain
|
||||||
|
|
|
@ -285,6 +285,22 @@ esp_err_t spicommon_bus_free_io(spi_host_device_t host)
|
||||||
return ESP_OK;
|
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)
|
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) {
|
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]);
|
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.
|
//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)
|
void spicommon_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,6 +85,7 @@ typedef struct {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
int dma_chan;
|
int dma_chan;
|
||||||
int max_transfer_sz;
|
int max_transfer_sz;
|
||||||
|
spi_bus_config_t bus_cfg;
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
esp_pm_lock_handle_t pm_lock;
|
esp_pm_lock_handle_t pm_lock;
|
||||||
#endif
|
#endif
|
||||||
|
@ -146,6 +147,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
memset(spihost[host], 0, sizeof(spi_host_t));
|
memset(spihost[host], 0, sizeof(spi_host_t));
|
||||||
|
memcpy( &spihost[host]->bus_cfg, bus_config, sizeof(spi_bus_config_t));
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master",
|
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master",
|
||||||
&spihost[host]->pm_lock);
|
&spihost[host]->pm_lock);
|
||||||
|
@ -237,6 +239,7 @@ esp_err_t spi_bus_free(spi_host_device_t host)
|
||||||
for (x=0; x<NO_CS; x++) {
|
for (x=0; x<NO_CS; x++) {
|
||||||
SPI_CHECK(spihost[host]->device[x]==NULL, "not all CSses freed", ESP_ERR_INVALID_STATE);
|
SPI_CHECK(spihost[host]->device[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 ) {
|
if ( spihost[host]->dma_chan > 0 ) {
|
||||||
spicommon_dma_chan_free ( spihost[host]->dma_chan );
|
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(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);
|
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
|
//Kill queues
|
||||||
vQueueDelete(handle->trans_queue);
|
vQueueDelete(handle->trans_queue);
|
||||||
vQueueDelete(handle->ret_queue);
|
vQueueDelete(handle->ret_queue);
|
||||||
|
|
Loading…
Reference in a new issue