From 26226967726a4820924cb353472f2871acb2d05e Mon Sep 17 00:00:00 2001 From: Sebastien Vayrette Date: Mon, 20 Apr 2026 13:56:11 -0400 Subject: [PATCH] fix: Make TWAI init non-fatal + add recovery backoff TWAI init now logs error and sets g_twai_bus_off instead of panicking. Bus-off recovery loop increased from 100ms to 1000ms to prevent watchdog reset when no CAN transceiver is connected. Co-Authored-By: Claude Opus 4.6 --- esp32s3/balance/main/vesc_can.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/esp32s3/balance/main/vesc_can.c b/esp32s3/balance/main/vesc_can.c index 2de13df..e77b1e5 100644 --- a/esp32s3/balance/main/vesc_can.c +++ b/esp32s3/balance/main/vesc_can.c @@ -35,19 +35,25 @@ void vesc_can_init(void) (gpio_num_t)VESC_CAN_RX_GPIO, TWAI_MODE_NORMAL); gcfg.rx_queue_len = VESC_CAN_RX_QUEUE; + gcfg.tx_queue_len = 5; twai_timing_config_t tcfg = TWAI_TIMING_CONFIG_500KBITS(); twai_filter_config_t fcfg = TWAI_FILTER_CONFIG_ACCEPT_ALL(); - gcfg.tx_queue_len = 5; - ESP_LOGI(TAG, "TWAI: installing driver tx=%d rx=%d 500kbps", VESC_CAN_TX_GPIO, VESC_CAN_RX_GPIO); - ESP_ERROR_CHECK(twai_driver_install(&gcfg, &tcfg, &fcfg)); - ESP_LOGI(TAG, "TWAI: driver installed OK"); + esp_err_t err = twai_driver_install(&gcfg, &tcfg, &fcfg); + if (err != ESP_OK) { + ESP_LOGE(TAG, "TWAI install failed (0x%x) — CAN disabled", err); + g_twai_bus_off = true; + return; + } - ESP_ERROR_CHECK(twai_start()); - /* Wait for VESC to join the bus before drive_task begins TX — prevents - * immediate TEC runup and BUS_OFF if VESC CAN isn't ready at ESP32 boot. */ + err = twai_start(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "TWAI start failed (0x%x) — CAN disabled", err); + g_twai_bus_off = true; + return; + } vTaskDelay(pdMS_TO_TICKS(200)); ESP_LOGI(TAG, "TWAI: started OK — bus active"); } @@ -94,17 +100,15 @@ void vesc_can_rx_task(void *arg) ESP_LOGE(TAG, "TWAI BUS OFF tx_err=%lu rx_err=%lu — recovering", (unsigned long)si.tx_error_counter, (unsigned long)si.rx_error_counter); twai_initiate_recovery(); - /* Driver auto-transitions RECOVERING→STOPPED after 128 recessive - * bit occurrences (~3 ms min at 500kbps); 100 ms is safe headroom. */ - vTaskDelay(pdMS_TO_TICKS(100)); + vTaskDelay(pdMS_TO_TICKS(1000)); } else if (si.state == TWAI_STATE_STOPPED) { - /* Recovery completed — restart the driver. */ esp_err_t serr = twai_start(); if (serr == ESP_OK) { g_twai_bus_off = false; ESP_LOGI(TAG, "TWAI recovered — bus active"); } else { - ESP_LOGE(TAG, "TWAI restart failed 0x%x", serr); + ESP_LOGE(TAG, "TWAI restart failed 0x%x — backing off", serr); + vTaskDelay(pdMS_TO_TICKS(2000)); } } /* TWAI_STATE_RECOVERING: initiation already called, just wait. */