ESP32-C6 TWAI bus-off recovery
Posted: Sun May 17, 2026 6:22 am
Hi! I have not been able to find clarifications regarding some parts of the TWAI implementation. For reference, I am using ESP-IDF v6.0.0, with esp_twai.h and esp_twai_onchip.h.
1. When TWAI enters bus-off state, the TRM states the controller enters Reset mode. About Reset mode, the TRM states that "any transmission in progress is immediately terminated". So this means that if there is a transmission in progress when bus-off occurs, it is immediately aborted and the on_tx_done callback is not invoked, right? If you rely on that callback for freeing resources (since this version of the driver needs the buffer to remain valid until transmission is complete), this doesn't seem ideal. So what is the proper procedure to handle bus-off while sending?
2. The API reference states you must call twai_node_recover() from task context. It seems like all it does is clear and set a bit in its state_flags and enters Operation mode by setting the register TWAI_RESET_MODE to 0. Which part of this is unsafe to execute in ISR context? Apart from the ESP_RETURN_ON_FALSE check which would probably panic if it tries to print the log message.
3. Upon finishing recovery, it will immediately start transmitting whatever frame is left inside tx_mount_queue. So, let's say you try sending two frames, for the first one the hardware is idle so it starts transmitting immediately, and the second one gets queued. Then, bus-off happens while sending the first one, so it is aborted. Then, after recovery, it starts sending the second frame, from the queue. Effectively, the first frame is lost. And there is no way to get rid of the queue, i.e. set tx_queue_depth to 0.
Am I missing something? Thanks.
1. When TWAI enters bus-off state, the TRM states the controller enters Reset mode. About Reset mode, the TRM states that "any transmission in progress is immediately terminated". So this means that if there is a transmission in progress when bus-off occurs, it is immediately aborted and the on_tx_done callback is not invoked, right? If you rely on that callback for freeing resources (since this version of the driver needs the buffer to remain valid until transmission is complete), this doesn't seem ideal. So what is the proper procedure to handle bus-off while sending?
2. The API reference states you must call twai_node_recover() from task context. It seems like all it does is clear and set a bit in its state_flags and enters Operation mode by setting the register TWAI_RESET_MODE to 0. Which part of this is unsafe to execute in ISR context? Apart from the ESP_RETURN_ON_FALSE check which would probably panic if it tries to print the log message.
3. Upon finishing recovery, it will immediately start transmitting whatever frame is left inside tx_mount_queue. So, let's say you try sending two frames, for the first one the hardware is idle so it starts transmitting immediately, and the second one gets queued. Then, bus-off happens while sending the first one, so it is aborted. Then, after recovery, it starts sending the second frame, from the queue. Effectively, the first frame is lost. And there is no way to get rid of the queue, i.e. set tx_queue_depth to 0.
Am I missing something? Thanks.