fix: guard TWAI tx against bus-off and fix recovery state machine
Three bugs blocked CAN forwarding when UART commands were received: 1. vesc_can_send_rpm had no g_twai_bus_off guard, flooding failed twai_transmit calls during BUS_OFF/RECOVERING states. 2. Recovery only handled TWAI_STATE_BUS_OFF; RECOVERING and STOPPED states were unhandled, leaving g_twai_bus_off=false while TWAI was still unusable. 3. No startup delay after twai_start() — VESC not yet ready to ACK caused immediate TEC runup to BUS_OFF at boot. Fix: bus-off guard in send_rpm, full state machine in rx_task (BUS_OFF→initiate, STOPPED→start, RECOVERING→wait), 200ms post- start delay in vesc_can_init(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dd52982a03
commit
34a937628d
@ -39,17 +39,22 @@ void vesc_can_init(void)
|
|||||||
twai_timing_config_t tcfg = TWAI_TIMING_CONFIG_500KBITS();
|
twai_timing_config_t tcfg = TWAI_TIMING_CONFIG_500KBITS();
|
||||||
twai_filter_config_t fcfg = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
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_ERROR_CHECK(twai_driver_install(&gcfg, &tcfg, &fcfg));
|
||||||
ESP_LOGI(TAG, "TWAI: driver installed OK");
|
ESP_LOGI(TAG, "TWAI: driver installed OK");
|
||||||
|
|
||||||
ESP_LOGI(TAG, "TWAI: twai_start");
|
|
||||||
ESP_ERROR_CHECK(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");
|
ESP_LOGI(TAG, "TWAI: started OK — bus active");
|
||||||
}
|
}
|
||||||
|
|
||||||
void vesc_can_send_rpm(uint8_t vesc_id, int32_t erpm)
|
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;
|
uint32_t ext_id = ((uint32_t)VESC_PKT_SET_RPM << 8u) | vesc_id;
|
||||||
twai_message_t msg = {
|
twai_message_t msg = {
|
||||||
.extd = 1,
|
.extd = 1,
|
||||||
@ -81,12 +86,29 @@ void vesc_can_rx_task(void *arg)
|
|||||||
}
|
}
|
||||||
twai_status_info_t si;
|
twai_status_info_t si;
|
||||||
if (twai_get_status_info(&si) == ESP_OK) {
|
if (twai_get_status_info(&si) == ESP_OK) {
|
||||||
g_twai_bus_off = (si.state == TWAI_STATE_BUS_OFF);
|
/* Mark bus-off for ANY non-running state so vesc_can_send_rpm
|
||||||
if (g_twai_bus_off) {
|
* won't flood with failed transmits during recovery. */
|
||||||
ESP_LOGE(TAG, "TWAI BUS OFF — tx_err=%lu rx_err=%lu",
|
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);
|
(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;
|
continue;
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "twai_receive OK id=0x%08" PRIx32 " dlc=%u", msg.identifier, msg.data_length_code);
|
ESP_LOGI(TAG, "twai_receive OK id=0x%08" PRIx32 " dlc=%u", msg.identifier, msg.data_length_code);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user