arduino / arduino/ArduinoCore-renesas
`R7FA6M5_CAN`: CAN error interrupt handler incomplete — device stuck in infinite ISR loop on bus error
- Dominant language
- C
- Stars
- 193
- Forks
- 112
- PR merge metrics
- No merged PRs in 30d
Description
## Description
The CAN error interrupt callback `onCanFDCallback` in [`R7FA6M5_CAN.cpp`](https://github.com/arduino/ArduinoCore-renesas/blob/00910fde8314e299a737f617a2c7cbd727b3a545/libraries/Arduino_CAN/src/R7FA6M5_CAN.cpp#L247-L281) is incomplete. When a CAN error occurs (e.g. the remote node disappears, causing the controller to enter error passive or bus-off state), the device becomes stuck in an infinite interrupt loop, making the CAN peripheral and the entire application unresponsive.
## Root Cause
The error cases in `onCanFDCallback` only record the error in software:
```cpp
_is_error = true;
_err_code = p_args->event;
```
However, they do **not** clear the hardware error flag register (`CFDC_ERFL`). Since these flags remain asserted, the interrupt line stays active and the ISR re-fires immediately upon returning, creating an infinite loop.
Unlike TX/RX complete events which are edge-triggered and cleared by the FSP layer, error conditions such as `CAN_EVENT_ERR_PASSIVE` and `CAN_EVENT_ERR_BUS_OFF` require explicit flag clearing in the handler.
## Steps to Reproduce
1. Set up a Portenta C33 transmitting CAN messages with `error_interrupts` enabled (i.e. the original value of `CANFD_CFG_EXTENDED_CFG` — not `0`)
2. Disconnect the remote CAN node or terminate the bus while the C33 is transmitting
3. Observe the device hanging completely — no further code executes
## Current Workaround
The only current workaround is to disable all error interrupts entirely in the extended config:
```cpp
.error_interrupts = 0, // All errors are DISABLED
```
This prevents the hang but also means bus errors are never surfaced to the application, which is unacceptable for production use.
## Expected Behaviour
Error interrupts should be handled correctly. At minimum the handler should:
1. Clear the relevant hardware error flags (`CFDC_ERFL`) to de-assert the interrupt line and prevent re-entry
2. For `CAN_EVENT_ERR_BUS_OFF` specifically, either temporarily mask the bus-off interrupt (`BOEIE`) and re-enable it upon `CAN_EVENT_BUS_RECOVERY`, or initiate a hardware recovery sequence
3. Continue to notify the application layer via `_is_error` and `_err_code` as currently implemented
## Environment
- **Board:** Arduino Portenta C33
- **Core:** ArduinoCore-renesas
- **Commit:** `00910fde`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in libraries/Arduino_CAN/src/R7FA6M5_CAN.cpp at onCanFDCallback, especially the error-event handling around lines 247-281, and review CANFD_CFG_EXTENDED_CFG and the CFDC_ERFL/BOEIE behavior described in the issue. Reproduce the Portenta C33 bus-error scenario with error interrupts enabled; done means the interrupt no longer loops, bus-off behavior is handled, and _is_error and _err_code still notify the application.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100