arduino / arduino/ArduinoCore-renesas

`R7FA6M5_CAN`: CAN error interrupt handler incomplete — device stuck in infinite ISR loop on bus error

Open
#532 0 comments 0 reactions 0 assignees View on GitHub
topic: code type: imperfection
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.