diff --git a/esp32s3/balance/main/vesc_can.c b/esp32s3/balance/main/vesc_can.c index 290993a..2de13df 100644 --- a/esp32s3/balance/main/vesc_can.c +++ b/esp32s3/balance/main/vesc_can.c @@ -39,17 +39,22 @@ void vesc_can_init(void) twai_timing_config_t tcfg = TWAI_TIMING_CONFIG_500KBITS(); twai_filter_config_t fcfg = TWAI_FILTER_CONFIG_ACCEPT_ALL(); - ESP_LOGI(TAG, "TWAI: twai_driver_install tx=%d rx=%d 500kbps", VESC_CAN_TX_GPIO, VESC_CAN_RX_GPIO); + 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_LOGI(TAG, "TWAI: twai_start"); 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. */ + vTaskDelay(pdMS_TO_TICKS(200)); ESP_LOGI(TAG, "TWAI: started OK — bus active"); } void vesc_can_send_rpm(uint8_t vesc_id, int32_t erpm) { + if (g_twai_bus_off) { return; } uint32_t ext_id = ((uint32_t)VESC_PKT_SET_RPM << 8u) | vesc_id; twai_message_t msg = { .extd = 1, @@ -81,11 +86,28 @@ void vesc_can_rx_task(void *arg) } twai_status_info_t si; if (twai_get_status_info(&si) == ESP_OK) { - g_twai_bus_off = (si.state == TWAI_STATE_BUS_OFF); - if (g_twai_bus_off) { - ESP_LOGE(TAG, "TWAI BUS OFF — tx_err=%lu rx_err=%lu", + /* Mark bus-off for ANY non-running state so vesc_can_send_rpm + * won't flood with failed transmits during recovery. */ + g_twai_bus_off = (si.state != TWAI_STATE_RUNNING); + + if (si.state == TWAI_STATE_BUS_OFF) { + 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)); + } 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); + } } + /* TWAI_STATE_RECOVERING: initiation already called, just wait. */ } continue; }