From a4388a332162dbe80cdb66e5bc20638fb5971c9f Mon Sep 17 00:00:00 2001 From: wanlei Date: Wed, 25 Oct 2023 12:42:39 +0800 Subject: [PATCH] fix(twai): twai example crash using usb-serial-jtag pins Calling gpio_hal_iomux_func_sel() via gpio_config() may disconnects/disables any influence from USJ when using USJ pins --- components/driver/twai.c | 42 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/components/driver/twai.c b/components/driver/twai.c index cb9a14a315..0c3d89ee34 100644 --- a/components/driver/twai.c +++ b/components/driver/twai.c @@ -276,19 +276,30 @@ TWAI_ISR_ATTR static void twai_intr_handler_main(void *arg) } /* -------------------------- Helper functions ----------------------------- */ - -static void twai_configure_gpio(gpio_num_t tx, gpio_num_t rx, gpio_num_t clkout, gpio_num_t bus_status) +static esp_err_t twai_configure_gpio(gpio_num_t tx, gpio_num_t rx, gpio_num_t clkout, gpio_num_t bus_status) { - //Set TX pin - gpio_set_pull_mode(tx, GPIO_FLOATING); - esp_rom_gpio_connect_out_signal(tx, TWAI_TX_IDX, false, false); - esp_rom_gpio_pad_select_gpio(tx); - + esp_err_t ret = ESP_FAIL; + assert(tx >= 0 && rx >= 0); + // if TX and RX set to the same GPIO, which means we want to create a loop-back in the GPIO matrix + bool io_loop_back = (tx == rx); + gpio_config_t gpio_conf = { + .intr_type = GPIO_INTR_DISABLE, + .pull_down_en = false, + .pull_up_en = false, + }; //Set RX pin - gpio_set_pull_mode(rx, GPIO_FLOATING); + gpio_conf.mode = GPIO_MODE_INPUT | (io_loop_back ? GPIO_MODE_OUTPUT : 0); + gpio_conf.pin_bit_mask = 1ULL << rx; + ret = gpio_config(&gpio_conf); + TWAI_CHECK(ESP_OK == ret, ret); esp_rom_gpio_connect_in_signal(rx, TWAI_RX_IDX, false); - esp_rom_gpio_pad_select_gpio(rx); - gpio_set_direction(rx, GPIO_MODE_INPUT); + + //Set TX pin + gpio_conf.mode = GPIO_MODE_OUTPUT | (io_loop_back ? GPIO_MODE_INPUT : 0); + gpio_conf.pin_bit_mask = 1ULL << tx; + ret = gpio_config(&gpio_conf); + TWAI_CHECK(ESP_OK == ret, ret); + esp_rom_gpio_connect_out_signal(tx, TWAI_TX_IDX, false, false); //Configure output clock pin (Optional) if (clkout >= 0 && clkout < GPIO_NUM_MAX) { @@ -303,6 +314,7 @@ static void twai_configure_gpio(gpio_num_t tx, gpio_num_t rx, gpio_num_t clkout, esp_rom_gpio_connect_out_signal(bus_status, TWAI_BUS_OFF_ON_IDX, false, false); esp_rom_gpio_pad_select_gpio(bus_status); } + return ESP_OK; } static void twai_free_driver_obj(twai_obj_t *p_obj) @@ -424,6 +436,13 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_ p_twai_obj_dummy->mode = g_config->mode; p_twai_obj_dummy->alerts_enabled = g_config->alerts_enabled; + //Allocate GPIO + ret = twai_configure_gpio(g_config->tx_io, g_config->rx_io, g_config->clkout_io, g_config->bus_off_io); + if (ESP_OK != ret) { + ESP_LOGE(TWAI_TAG, "init gpio for twai failed"); + goto err; + } + //Initialize TWAI peripheral registers, and allocate interrupt TWAI_ENTER_CRITICAL(); if (p_twai_obj == NULL) { @@ -442,8 +461,7 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_ twai_hal_configure(&twai_context, t_config, f_config, DRIVER_DEFAULT_INTERRUPTS, g_config->clkout_divider); TWAI_EXIT_CRITICAL(); - //Allocate GPIO and Interrupts - twai_configure_gpio(g_config->tx_io, g_config->rx_io, g_config->clkout_io, g_config->bus_off_io); + //Allocate Interrupts ESP_ERROR_CHECK(esp_intr_alloc(ETS_TWAI_INTR_SOURCE, g_config->intr_flags, twai_intr_handler_main, NULL, &p_twai_obj->isr_handle)); #ifdef CONFIG_PM_ENABLE