esp-idf
esp-idf copied to clipboard
CAN bus goes to Bus Off after ECU startup. (IDFGH-13672)
IDF version. esp-idf-v5.0.6
Espressif SoC revision. ESP32S3
Operating System used. Windows
How did you build your project? Command line with idf.py
If you are using Windows, please specify command line type. PowerShell
Development Kit. Custom Board
Power Supply used. External power supply
What is the expected behavior? After ECU reset CAN BusOFF shall not be triggered.
What is the actual behavior? After ECU reset CAN goes in BusOFF state. Which causes all other devices to try to recover. Also it stops running simulations.
Steps to reproduce.
- Run CAN simulation which sends a lot of CAN frames (~40% bus load).
- Restart the device
- Simulations goes to BusOFF state.
CAN configuration in the project:
static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS();
static twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
static const twai_general_config_t g_config = { .mode = TWAI_MODE_NORMAL,
.tx_io = 37,
.rx_io = 38,
.clkout_io = TWAI_IO_UNUSED,
.bus_off_io = TWAI_IO_UNUSED,
.tx_queue_len = 40,
.rx_queue_len = 40,
.alerts_enabled = TWAI_ALERT_NONE,
.clkout_divider = 0,
.intr_flags = ESP_INTR_FLAG_LEVEL2};
We found that in IDF v5.0.4 the issue doesn't exist and first occurs on v5.0.5 Also identified what causes the problem in twai_configure_gpio()
//Set TX pin
gpio_conf.mode = GPIO_MODE_OUTPUT | (io_loop_back ? GPIO_MODE_INPUT : 0);
gpio_conf.pin_bit_mask = 1ULL << tx;
gpio_config(&gpio_conf);
esp_rom_gpio_connect_out_signal(tx, twai_controller_periph_signals.controllers[controller_id].tx_sig, false, false);
https://github.com/espressif/esp-idf/blob/59e18382702b6986be3d3f55e9ac7763c1397cf7/components/driver/twai/twai.c#L296
if I change like this
//Set TX pin
gpio_conf.mode = GPIO_MODE_DISABLE | (io_loop_back ? GPIO_MODE_INPUT : 0);
gpio_conf.pin_bit_mask = 1ULL << tx;
gpio_config(&gpio_conf);
esp_rom_gpio_connect_out_signal(tx, twai_controller_periph_signals.controllers[controller_id].tx_sig, false, false);
if gpio_conf.mode is set to GPIO_MODE_DISABLE, the issue disappears, we still see some error frames due to not acknowledged frames, but the CAN doesn't go to BusOFF.
I don't understand why this change fixes the issue. Can you give me a hint what could causes it and maybe a workboard, since this code exist even on the master branch.