ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_cnecc.h File Reference

CANFD ECC (CNECC) HAL driver public API. More...

#include <stdint.h>
#include "ra8_cnecc_regs.h"
#include "ra8_err.h"
#include "ra8_isr.h"
Include dependency graph for ra8_cnecc.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_cnecc_instance_cfg_t
 Per-instance ECC configuration descriptor. More...
struct  ra8_cnecc_config_t
 Top-level driver configuration. More...
struct  ra8_cnecc_status_t
 Snapshot of one CNECC instance, returned by ra8_cnecc_get_status. More...
struct  ra8_cnecc_counters_t
 Cumulative per-instance fault counters. More...
struct  ra8_cnecc_inject_t
 Fault-injection request descriptor. More...

Typedefs

typedef void(* ra8_cnecc_error_fn_t) (void *ctx, uint8_t instance, bool is_2bit, uint16_t err_addr)
 CANFD ECC fault callback signature.

Functions

ra8_err_t ra8_cnecc_init (const ra8_cnecc_config_t *cfg)
 Initialise the CNECC driver and configure both instances.
ra8_err_t ra8_cnecc_deinit (void)
 Tear down both CNECC instances and gate the CANFD MSTP bits.
ra8_err_t ra8_cnecc_enable_instance (uint8_t instance)
 Enable error judgment for one instance only.
ra8_err_t ra8_cnecc_disable_instance (uint8_t instance)
 Disable error judgment for one instance only.
ra8_err_t ra8_cnecc_enter_standby (void)
 Software-standby preparation (HUM 42.5.1 p 2876).
ra8_err_t ra8_cnecc_exit_standby (void)
 Software-standby exit (HUM 42.5.2 p 2876).
ra8_err_t ra8_cnecc_set_irq_enables (uint8_t instance, bool irq_1bit, bool irq_2bit)
 Update the IRQ enable bits for one instance without touching any other CTL field.
ra8_err_t ra8_cnecc_set_correction_permission (uint8_t instance, bool correct_1bit)
 Update the 1-bit correction permission for one instance.
ra8_err_t ra8_cnecc_get_status (uint8_t instance, ra8_cnecc_status_t *out)
 Snapshot the current ECC state of one CNECC instance.
ra8_err_t ra8_cnecc_get_counters (uint8_t instance, ra8_cnecc_counters_t *out)
 Read the cumulative fault counters for one instance.
ra8_err_t ra8_cnecc_reset_counters (uint8_t instance)
 Zero the cumulative fault counters for one instance.
ra8_err_t ra8_cnecc_set_counter_mirror (uint8_t instance, ra8_cnecc_counters_t *mirror)
 Attach a BBR-mirrored counter triple for one instance.
ra8_err_t ra8_cnecc_clear_status (uint8_t instance)
 Clear the latched ECC fault state for one instance.
ra8_err_t ra8_cnecc_inject_fault (uint8_t instance, const ra8_cnecc_inject_t *req)
 Run the HUM Ch 42.3.2 fault-injection sequence for one instance.
ra8_err_t ra8_cnecc_test_mode_disable (uint8_t instance)
 Force EC710TMC = 0x8000 to leave fault-injection mode.
ra8_err_t ra8_cnecc_test_mode_active (uint8_t instance, bool *out)
 Query whether fault injection is currently armed.
ra8_err_t ra8_cnecc_attach_handler (ra8_cnecc_error_fn_t fn, void *ctx)
 Attach a callback for CNECC fault events.
ra8_err_t ra8_cnecc_attach_isr (uint8_t priority)
 Wire the CANn_MRAM_ERI ICU vectors to the driver dispatcher.
ra8_err_t ra8_cnecc_detach_isr (void)
 Tear down the ICU vector wiring established by ra8_cnecc_attach_isr.
void ra8_cnecc_isr_handler (void *ctx)
 Generic ICU trampoline for both CANn_MRAM_ERI vectors.
void ra8_cnecc_dispatch (uint8_t instance, bool is_2bit, uint16_t err_addr)
 Dispatch a CNECC fault event to the installed handler.
void ra8_cnecc_dispatch_overflow (uint8_t instance)
 Force-bump the overflow counter (used by the ISR trampoline).
ra8_err_t ra8_cnecc_open (void)
 One-shot CNECC bring-up using the driver's default config.
ra8_err_t ra8_cnecc_compute (uint32_t addr, uint32_t len, uint32_t *out_ecc)
 Compute a 32-bit ECC code over a (addr, len) memory region.
ra8_err_t ra8_cnecc_verify (uint32_t addr, uint32_t len, uint32_t expected_ecc)
 Verify a region's ECC tag matches an expected value.

Detailed Description

CANFD ECC (CNECC) HAL driver public API.

Tag
[Ring 3 / HAL] {World: S}

Full driver for the RA8D2 CANFD message-buffer SRAM ECC block (HUM Ch 42 "CANFD ECC (CNECC)", p 2868-2876). Two instances (ECCMB0 for CAN0, ECCMB1 for CAN1) – each one observes the 32-bit CANFD MBRAM behind its channel, attaches a 7-bit ECC code, and reports

  • 1-bit corrected errors (SEC),
  • 2-bit detected-but-uncorrected errors (DED),
  • and an overflow flag if a second fault is captured before the first is acknowledged.

The driver covers every register field documented in HUM Ch 42:

  • EC710CTL – enable / status / IRQ / clear
  • EC710TMC – decoder fault-injection control
  • EC710TED – decoder fault-injection substitute data
  • EC710EAD0 – captured faulting RAM offset

Public surface

Lifecycle:

Configuration:

Status / counters:

Fault injection (HUM 42.3.2 Figure 42.2):

IRQ wiring (HUM 42.4):

Definition in file ra8_cnecc.h.

Typedef Documentation

◆ ra8_cnecc_error_fn_t

typedef void(* ra8_cnecc_error_fn_t) (void *ctx, uint8_t instance, bool is_2bit, uint16_t err_addr)

CANFD ECC fault callback signature.

Parameters
[in]ctxCaller-supplied opaque context pointer.
[in]instanceInstance index 0..1 that raised the error.
[in]is_2bittrue for 2-bit (uncorrectable), false for 1-bit (corrected).
[in]err_addrFaulting offset (ECEAD[9:0]) inside the CANFD message buffer SRAM.

Definition at line 183 of file ra8_cnecc.h.

Function Documentation

◆ ra8_cnecc_attach_handler()

ra8_err_t ra8_cnecc_attach_handler ( ra8_cnecc_error_fn_t fn,
void * ctx )
nodiscard

Attach a callback for CNECC fault events.

Parameters
[in]fnNon-NULL handler invoked from the ECC ISR (or test code).
[in]ctxOpaque context pointer forwarded to the handler.
Returns
ra8_err_t error code.
Return values
k_ra8_okHandler installed.
k_ra8_err_null_ptrfn was NULL.
Precondition
ra8_cnecc_init has run.
Caller is in single-threaded install context (the install store is not interrupt-atomic; the dispatch read is).
Postcondition
Subsequent ra8_cnecc_dispatch calls fire fn.
Calling with the same fn twice is idempotent.
Note
Install-time is not thread-safe; the dispatch read is.
Since
0.1.0

Definition at line 641 of file ra8_cnecc.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, s_cnecc_ctx, s_cnecc_fn, and s_tag.

◆ ra8_cnecc_attach_isr()

ra8_err_t ra8_cnecc_attach_isr ( uint8_t priority)
nodiscard

Wire the CANn_MRAM_ERI ICU vectors to the driver dispatcher.

Walks both CAN0_MRAM_ERI and CAN1_MRAM_ERI ELC events (HUM 42.4 p 2875), allocates an IELSR slot for each via ra8_isr_register, and points them at ra8_cnecc_isr_handler. The handler reads the offending instance's EC710CTL to decide whether the fault was 1-bit or 2-bit, samples EC710EAD0 for the offset, calls the registered ra8_cnecc_error_fn_t callback, and then W0Cs the latched flags.

If only one CANFD channel is in use the caller can set its priority differently from the other; both vectors are wired in one shot to keep the API simple. Detach via ra8_cnecc_detach_isr.

Parameters
[in]priorityNVIC priority shared by both vectors (0..k_ra8_isr_prio_max).
Returns
ra8_err_t error code.
Return values
k_ra8_okBoth vectors wired.
k_ra8_err_invalid_argpriority out of range.
k_ra8_err_no_memNo free IELSR slot.
k_ra8_err_existsOne of the events was already routed.
Precondition
ra8_isr_init and ra8_cnecc_init have run.
Caller has registered a fault callback via ra8_cnecc_attach_handler (the dispatcher is harmless without one but the callback is the actual reason to wire).
Postcondition
Both ICU vectors enabled at the requested priority.
Subsequent ECC faults route automatically through ra8_cnecc_dispatch to the registered callback.
Note
Not thread-safe.
See also
ra8_cnecc_detach_isr
Since
0.1.0

Definition at line 649 of file ra8_cnecc.c.

References k_ra8_cnecc_instance_count, k_ra8_err_invalid_arg, k_ra8_isr_prio_max, k_ra8_ok, ra8_cnecc_isr_handler(), ra8_isr_register(), ra8_isr_unregister(), s_cnecc_event_table, and s_cnecc_isr_attached.

◆ ra8_cnecc_clear_status()

ra8_err_t ra8_cnecc_clear_status ( uint8_t instance)
nodiscard

Clear the latched ECC fault state for one instance.

Writes ECER1C | ECER2C = 1 to the instance's EC710CTL, which per HUM Ch 42.2.1 p 2870 clears ECER1F, ECER2F, ECOVFF, ECSEDF0 and ECDEDF0 in one shot. The driver's cumulative counters are NOT zeroed (use ra8_cnecc_reset_counters for that).

Parameters
[in]instanceInstance index 0..1.
Returns
ra8_err_t error code.
Return values
k_ra8_okCleared.
k_ra8_err_invalid_arginstance >= k_ra8_cnecc_instance_count.
Precondition
ra8_cnecc_init has run.
instance is a valid instance index.
Postcondition
Instance's ECER1F / ECER2F / ECOVFF / ECSEDF0 / ECDEDF0 read back as 0.
Instance's EC710EAD0 reads back as 0 (HUM 42.2.4 p 2873 "reset by clearing the status flag").
Note
Not thread-safe.
Since
0.1.0

Definition at line 562 of file ra8_cnecc.c.

References r_cnecc_regs_t::EC710CTL, k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_clear_all, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_cnecc(), and s_tag.

◆ ra8_cnecc_compute()

ra8_err_t ra8_cnecc_compute ( uint32_t addr,
uint32_t len,
uint32_t * out_ecc )
nodiscard

Compute a 32-bit ECC code over a (addr, len) memory region.

Software fall-back used by the bootloader's anti-rollback path to derive an ECC tag for an MRAM / flash range when the hardware ECC does not expose a "compute" engine for arbitrary addresses (HUM Ch 42 only describes runtime read-side checking). The algorithm is a deterministic word-wise CRC32-style accumulator (polynomial 0xEDB88320) seeded with 0xFFFFFFFF and finalised by XOR with 0xFFFFFFFF. len is rounded down to the nearest 4-byte boundary; trailing bytes (0..3) are NOT included to keep the computation deterministic and word-aligned.

The result is suitable for "did this region change since boot" style checks; it is NOT a Hamming-style ECC and cannot correct single-bit faults. The hardware ECC behind EC710CTL remains the single point of truth for live read traffic.

Parameters
[in]addrBase address (must be 4-byte aligned).
[in]lenRegion length in bytes (rounded down to /4).
[out]out_eccReceives the 32-bit ECC tag.
Returns
ra8_err_t error code.
Return values
k_ra8_okECC computed.
k_ra8_err_null_ptraddr was 0 OR out_ecc was NULL.
k_ra8_err_invalid_argaddr not 4-byte aligned OR len < 4.
Precondition
addr is non-zero and 4-byte aligned.
out_ecc points to writable storage.
Postcondition
On success, *out_ecc is the deterministic CRC32 of the word-aligned portion of [addr, addr + len).
Hardware state is unchanged.
Note
Read-only path; safe to call from any context provided the memory at addr is mapped.
See also
ra8_cnecc_verify
Since
0.1.0

Definition at line 842 of file ra8_cnecc.c.

References internal_crc32(), k_ra8_cnecc_compute_align, k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, ra8_log_info_val, and s_tag.

Referenced by ra8_cnecc_verify().

◆ ra8_cnecc_deinit()

ra8_err_t ra8_cnecc_deinit ( void )
nodiscard

Tear down both CNECC instances and gate the CANFD MSTP bits.

Returns
ra8_err_t error code.
Return values
k_ra8_okAlways.
Precondition
Caller has stopped any CANFD traffic that depends on MBRAM.
ra8_cnecc_init was previously called (deinit is idempotent even if not).
Postcondition
Both EC710CTL.ECERVF are cleared (judgment disabled).
Both CANFDn MSTP bits are released.
Note
Not thread-safe.
See also
ra8_cnecc_init
Since
0.1.0

Definition at line 354 of file ra8_cnecc.c.

References r_cnecc_regs_t::EC710CTL, r_cnecc_regs_t::EC710TMC, k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_emca_unlock, k_ra8_cnecc_mask_test_disable, k_ra8_ok, ra8_cnecc(), ra8_cnecc_detach_isr(), ra8_mstp_disable(), s_cnecc_initialized, s_cnecc_isr_attached, s_cnecc_mstp_table, s_cnecc_one_bit_count, s_cnecc_overflow_count, and s_cnecc_two_bit_count.

◆ ra8_cnecc_detach_isr()

ra8_err_t ra8_cnecc_detach_isr ( void )
nodiscard

Tear down the ICU vector wiring established by ra8_cnecc_attach_isr.

Releases both CAN0_MRAM_ERI and CAN1_MRAM_ERI IELSR slots. After this returns, MBRAM ECC faults still latch in hardware but no callback fires until the next attach.

Returns
ra8_err_t error code.
Return values
k_ra8_okBoth vectors released (or already gone).
Precondition
ra8_cnecc_attach_isr was previously called.
Caller has masked IRQs or runs single-threaded.
Postcondition
Neither CAN0/CAN1_MRAM_ERI ELC event maps to an IELSR slot.
Driver-local callback storage is preserved.
Note
Not thread-safe.
See also
ra8_cnecc_attach_isr
Since
0.1.0

Definition at line 674 of file ra8_cnecc.c.

References k_ra8_cnecc_instance_count, k_ra8_ok, ra8_isr_unregister(), s_cnecc_event_table, and s_cnecc_isr_attached.

Referenced by ra8_cnecc_deinit().

◆ ra8_cnecc_disable_instance()

ra8_err_t ra8_cnecc_disable_instance ( uint8_t instance)
nodiscard

Disable error judgment for one instance only.

Clears ECERVF for instance (with the EMCA unlock pattern). Leaves the IRQ enable / correction-permission bits alone so the caller can re-enable later via ra8_cnecc_enable_instance.

Parameters
[in]instanceInstance index 0..1.
Returns
ra8_err_t error code.
Return values
k_ra8_okJudgment disabled.
k_ra8_err_invalid_arginstance >= k_ra8_cnecc_instance_count.
Precondition
ra8_cnecc_init has run.
Caller has masked IRQs or runs single-threaded.
Postcondition
Live EC710CTL.ECERVF reads back as 0.
All other EC710CTL bits are preserved.
Note
Not thread-safe.
See also
ra8_cnecc_enable_instance
Since
0.1.0

Definition at line 395 of file ra8_cnecc.c.

References internal_ctl_rmw(), k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_ecervf, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_cnecc(), and s_tag.

◆ ra8_cnecc_dispatch()

void ra8_cnecc_dispatch ( uint8_t instance,
bool is_2bit,
uint16_t err_addr )

Dispatch a CNECC fault event to the installed handler.

Drives the registered ra8_cnecc_error_fn_t callback and bumps the matching cumulative SEC / DED counter for the instance. Direct entry point for unit tests and integrators that want to drive the dispatcher manually instead of going through ra8_cnecc_isr_handler.

Parameters
[in]instanceInstance index 0..1 (out-of-range silently ignored).
[in]is_2bittrue for uncorrectable, false for 1-bit.
[in]err_addrFaulting RAM offset (ECEAD[9:0]).
Precondition
instance < k_ra8_cnecc_instance_count OR the call is dropped.
Caller is the ISR or a test harness mimicking it.
Postcondition
If a handler is registered AND instance is valid, the handler runs to completion before this returns.
The matching cumulative counter for instance is bumped by 1 (also in the BBR mirror if attached).
Note
Safe to call from NMI/ISR context provided the registered handler is itself NMI-safe.
Since
0.1.0

Definition at line 728 of file ra8_cnecc.c.

References k_ra8_cnecc_instance_count, s_cnecc_bbr_mirror, s_cnecc_ctx, s_cnecc_fn, s_cnecc_one_bit_count, and s_cnecc_two_bit_count.

Referenced by ra8_cnecc_isr_handler().

◆ ra8_cnecc_dispatch_overflow()

void ra8_cnecc_dispatch_overflow ( uint8_t instance)

Force-bump the overflow counter (used by the ISR trampoline).

Called by ra8_cnecc_isr_handler when ECOVFF is set so the software counters remain in sync with the hardware overflow flag even when the underlying SEC / DED bit was already latched.

Parameters
[in]instanceInstance index 0..1 (out-of-range silently ignored).
Precondition
instance < k_ra8_cnecc_instance_count OR the call is dropped.
Caller is the ISR or a test harness mimicking it.
Postcondition
The overflow counter for instance (and BBR mirror) is bumped by 1.
No callback is invoked; only the counter changes.
Note
Re-entrant.
Since
0.1.0

Definition at line 752 of file ra8_cnecc.c.

References k_ra8_cnecc_instance_count, s_cnecc_bbr_mirror, and s_cnecc_overflow_count.

Referenced by ra8_cnecc_isr_handler().

◆ ra8_cnecc_enable_instance()

ra8_err_t ra8_cnecc_enable_instance ( uint8_t instance)
nodiscard

Enable error judgment for one instance only.

Performs the ECERVF = 1 step of the HUM 42.3.1 procedure for one instance; the other instance is left untouched. The write goes through the EMCA = 01b unlock pattern in the same store (HUM 42.2.1 p 2870 EMCA notes).

Parameters
[in]instanceInstance index 0..1.
Returns
ra8_err_t error code.
Return values
k_ra8_okJudgment enabled.
k_ra8_err_invalid_arginstance >= k_ra8_cnecc_instance_count.
Precondition
ra8_cnecc_init has run.
Caller has masked IRQs or runs single-threaded.
Postcondition
Live EC710CTL.ECERVF reads back as 1.
Other configuration bits in EC710CTL are preserved.
Note
Not thread-safe.
See also
ra8_cnecc_disable_instance
Since
0.1.0

Definition at line 383 of file ra8_cnecc.c.

References internal_ctl_rmw(), k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_ecervf, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_cnecc(), and s_tag.

◆ ra8_cnecc_enter_standby()

ra8_err_t ra8_cnecc_enter_standby ( void )
nodiscard

Software-standby preparation (HUM 42.5.1 p 2876).

Per HUM Ch 42.5.1 the firmware MUST clear the ECC error flags and disable judgment before entering Software Standby. This helper:

  1. Clears ECER1F / ECER2F / ECOVFF / ECSEDF0 / ECDEDF0 via the ECER1C | ECER2C bundle.
  2. Clears ECERVF via the EMCA = 01b unlock pattern.

The driver-local fault counters are preserved (they survive any standby trip).

Returns
ra8_err_t error code.
Return values
k_ra8_okAlways succeeds.
Precondition
ra8_cnecc_init has run.
All CANFD traffic on the parent channels is stopped.
Postcondition
Both instances' ECERVF read 0.
Both instances' status flags read 0.
Note
Not thread-safe.
See also
ra8_cnecc_exit_standby
Since
0.1.0

Definition at line 407 of file ra8_cnecc.c.

References r_cnecc_regs_t::EC710CTL, k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_clear_all, k_ra8_cnecc_mask_emca_unlock, k_ra8_ok, and ra8_cnecc().

◆ ra8_cnecc_exit_standby()

ra8_err_t ra8_cnecc_exit_standby ( void )
nodiscard

Software-standby exit (HUM 42.5.2 p 2876).

Restores ECERVF = 1 for both instances after a wakeup from Software Standby. Re-uses the cached configuration from the last ra8_cnecc_init call so per-instance correct_1bit / irq_1bit / irq_2bit survive across the standby trip.

Returns
ra8_err_t error code.
Return values
k_ra8_okBoth instances re-armed.
k_ra8_err_not_initializedra8_cnecc_init was never called.
Precondition
ra8_cnecc_init has run at least once before standby.
CPU has just returned from Software Standby.
Postcondition
Both instances reflect the original cfg (ECERVF=1 if so configured).
Driver-local counters are preserved.
Note
Not thread-safe.
See also
ra8_cnecc_enter_standby
Since
0.1.0

Definition at line 423 of file ra8_cnecc.c.

References internal_apply_instance(), k_ra8_cnecc_instance_count, k_ra8_err_not_initialized, k_ra8_ok, RA8_RETURN_ON_ERROR, s_cnecc_cached_cfg, s_cnecc_initialized, and s_tag.

◆ ra8_cnecc_get_counters()

ra8_err_t ra8_cnecc_get_counters ( uint8_t instance,
ra8_cnecc_counters_t * out )
nodiscard

Read the cumulative fault counters for one instance.

Lightweight accessor for callers that don't need the full ra8_cnecc_get_status snapshot. Returns the same counters that ra8_cnecc_dispatch increments and that the optional BBR mirror tracks.

Parameters
[in]instanceInstance index 0..1.
[out]outNon-NULL counter receiver.
Returns
ra8_err_t error code.
Return values
k_ra8_okCounters copied.
k_ra8_err_null_ptrout was NULL.
k_ra8_err_invalid_arginstance out of range.
Precondition
out points to writable storage.
instance is a valid index.
Postcondition
*out matches the driver-local counter triple for instance.
Hardware state is unchanged.
Note
Read-only; safe to call concurrently with the dispatcher provided the host's 32-bit aligned writes are atomic (true on Cortex-M85).
Since
0.1.0

Definition at line 518 of file ra8_cnecc.c.

References k_ra8_cnecc_instance_count, k_ra8_err_invalid_arg, k_ra8_ok, ra8_cnecc_counters_t::one_bit_count, ra8_cnecc_counters_t::overflow_count, RA8_CHECK_NULL_PTR, s_cnecc_one_bit_count, s_cnecc_overflow_count, s_cnecc_two_bit_count, s_tag, and ra8_cnecc_counters_t::two_bit_count.

◆ ra8_cnecc_get_status()

ra8_err_t ra8_cnecc_get_status ( uint8_t instance,
ra8_cnecc_status_t * out )
nodiscard

Snapshot the current ECC state of one CNECC instance.

Reads EC710CTL, EC710TMC and EC710EAD0 for instance and returns a decoded view through out. The cumulative SEC / DED / overflow counts are driver-local (incremented by ra8_cnecc_dispatch) – the hardware only carries the "at least one happened" booleans.

Parameters
[in]instanceInstance index 0..1.
[out]outNon-NULL status receiver.
Returns
ra8_err_t error code.
Return values
k_ra8_okStatus copied to *out.
k_ra8_err_null_ptrout was NULL.
k_ra8_err_invalid_arginstance >= k_ra8_cnecc_instance_count.
Precondition
out points to writable memory of at least sizeof(ra8_cnecc_status_t) bytes.
ra8_cnecc_init has run.
Postcondition
out->raw_ctl matches the live EC710CTL value.
out->last_addr <= k_ra8_cnecc_ead_max (10-bit field, HUM 42.2.4 p 2872).
Note
Read-only path; safe to call from any context whose memory barriers cover the underlying MMIO.
Since
0.1.0

Definition at line 480 of file ra8_cnecc.c.

References ra8_cnecc_status_t::addr_is_1bit, ra8_cnecc_status_t::addr_is_2bit, ra8_cnecc_status_t::correct_enabled, r_cnecc_regs_t::EC710CTL, r_cnecc_regs_t::EC710EAD0, r_cnecc_regs_t::EC710TMC, ra8_cnecc_status_t::err_1bit, ra8_cnecc_status_t::err_2bit, ra8_cnecc_status_t::err_present, ra8_cnecc_status_t::irq1_enabled, ra8_cnecc_status_t::irq2_enabled, ra8_cnecc_status_t::judgment_active, k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_ec1ecp, k_ra8_cnecc_mask_ec1edic, k_ra8_cnecc_mask_ec2edic, k_ra8_cnecc_mask_ecdedf0, k_ra8_cnecc_mask_ecead, k_ra8_cnecc_mask_ecemf, k_ra8_cnecc_mask_ecer1f, k_ra8_cnecc_mask_ecer2f, k_ra8_cnecc_mask_ecervf, k_ra8_cnecc_mask_ecovff, k_ra8_cnecc_mask_ecsedf0, k_ra8_cnecc_mask_ectmce, k_ra8_err_invalid_arg, k_ra8_ok, ra8_cnecc_status_t::last_addr, ra8_cnecc_status_t::one_bit_count, ra8_cnecc_status_t::overflow, ra8_cnecc_status_t::overflow_count, RA8_CHECK_NULL_PTR, ra8_cnecc(), ra8_cnecc_status_t::raw_ctl, ra8_cnecc_status_t::raw_tmc, ra8_cnecc_status_t::reserved0, ra8_cnecc_status_t::reserved1, s_cnecc_one_bit_count, s_cnecc_overflow_count, s_cnecc_two_bit_count, s_tag, ra8_cnecc_status_t::test_mode, and ra8_cnecc_status_t::two_bit_count.

◆ ra8_cnecc_init()

ra8_err_t ra8_cnecc_init ( const ra8_cnecc_config_t * cfg)
nodiscard

Initialise the CNECC driver and configure both instances.

Programs both EC710CTL instances per cfg, walking the HUM 42.3.1 procedure (figure 42.1, p 2874):

  1. Ungate the parent CANFD module-stop bits so register accesses reach the CNECC block (the ECC sits behind the same clock as the CANFD it monitors – HUM 42.1 overview p 2868).
  2. Clear any latched error state with ECER1C | ECER2C.
  3. Optionally enable 1-bit-error correction and per-fault IRQs.
  4. Unlock ECERVF via EMCA = 01b and set ECERVF per cfg->instances[i].enable.
Parameters
[in]cfgNon-NULL configuration descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okDriver initialized, both instances live.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_hw_init_failedMSTP ungate failed for one of the CANFD instances.
Precondition
ra8_mstp_init has run.
Caller is in single-threaded init context (writes to the EMCA-protected ECERVF bit are not thread-safe).
Postcondition
Both instances' EC710CTL.ECERVF reflect cfg.
Both instances' SEC + DED + overflow counters are zeroed.
Note
Not thread-safe.
See also
ra8_cnecc_deinit
ra8_cnecc_get_status
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 5: 2 preconditions, 2 postconditions
  • Rule 7: returns ra8_err_t, marked [[nodiscard]]

Definition at line 340 of file ra8_cnecc.c.

References ra8_cnecc_config_t::instances, internal_apply_instance(), k_ra8_cnecc_instance_count, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_info, RA8_RETURN_ON_ERROR, s_cnecc_cached_cfg, s_cnecc_initialized, and s_tag.

Referenced by ra8_cnecc_open().

◆ ra8_cnecc_inject_fault()

ra8_err_t ra8_cnecc_inject_fault ( uint8_t instance,
const ra8_cnecc_inject_t * req )
nodiscard

Run the HUM Ch 42.3.2 fault-injection sequence for one instance.

Executes the four-step procedure from Figure 42.2 (p 2875). After this returns, the caller should perform an MBRAM read at the target address; the read will route through the test substitute data and trigger the decoder fault path. The captured offset will appear in EC710EAD0 and the matching ECER1F / ECER2F flag will latch as if a real ECC fault had occurred.

Call ra8_cnecc_test_mode_disable after the test to restore normal operation.

Parameters
[in]instanceInstance index 0..1.
[in]reqNon-NULL injection descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okTest-mode programmed.
k_ra8_err_null_ptrreq was NULL.
k_ra8_err_invalid_arginstance out of range.
Precondition
ra8_cnecc_init has run with the matching instance enabled.
Caller has stopped CANFD traffic on the parent channel.
Postcondition
Live EC710TMC reads back as 0x8082.
Live EC710TED reads back as req->substitute.
Note
Not thread-safe. Fault injection is destructive to live traffic and must only run on a quiesced channel.
See also
ra8_cnecc_test_mode_disable
Since
0.1.0

Definition at line 578 of file ra8_cnecc.c.

References r_cnecc_regs_t::EC710TED, r_cnecc_regs_t::EC710TMC, k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_test_disable, k_ra8_cnecc_mask_test_enable, k_ra8_cnecc_mask_test_subst, k_ra8_err_invalid_arg, k_ra8_ok, ra8_cnecc_inject_t::one_bit_flip, RA8_CHECK_NULL_PTR, ra8_cnecc(), s_tag, and ra8_cnecc_inject_t::substitute.

◆ ra8_cnecc_isr_handler()

void ra8_cnecc_isr_handler ( void * ctx)

Generic ICU trampoline for both CANn_MRAM_ERI vectors.

Shared between the two ICU slots set up by ra8_cnecc_attach_isr; ctx carries the instance index cast to a void*. Reads the instance's EC710CTL / EC710EAD0, decides between 1-bit, 2-bit, or pure-overflow, forwards to ra8_cnecc_dispatch, then W0Cs the latched flags (HUM 42.3.1 figure 42.1 p 2874 closing steps "Clear ECC Error flag" and "Clear Interrupt Request flag").

Parameters
[in]ctxInstance index packed in the low byte of the void*. Out-of-range values are silently dropped.
Precondition
Called from Cortex-M85 handler mode (the ICU dispatcher invokes it).
ra8_cnecc_init has run.
Postcondition
Latched ECER1F / ECER2F / ECOVFF / ECSEDF0 / ECDEDF0 are cleared for the instance.
The ICU IELSR.IR bit is cleared by the surrounding ra8_isr_dispatch.
Note
Re-entrant.
See also
ra8_cnecc_attach_isr
Since
0.1.0

Definition at line 685 of file ra8_cnecc.c.

References r_cnecc_regs_t::EC710CTL, r_cnecc_regs_t::EC710EAD0, k_ra8_cnecc_instance_count, k_ra8_cnecc_isr_ctx_inst_mask, k_ra8_cnecc_mask_clear_all, k_ra8_cnecc_mask_ecead, k_ra8_cnecc_mask_ecer1f, k_ra8_cnecc_mask_ecer2f, k_ra8_cnecc_mask_ecovff, ra8_cnecc(), ra8_cnecc_dispatch(), and ra8_cnecc_dispatch_overflow().

Referenced by ra8_cnecc_attach_isr().

◆ ra8_cnecc_open()

ra8_err_t ra8_cnecc_open ( void )
nodiscard

One-shot CNECC bring-up using the driver's default config.

Convenience wrapper that calls ra8_cnecc_init with both instances configured to enable correction, irq_1bit, irq_2bit and judgment. Used by the boot-time fault monitor that just wants the ECC active without having to spell out a config struct.

Returns
ra8_err_t error code.
Return values
k_ra8_okBoth instances live with defaults.
k_ra8_err_hw_init_failedMSTP enable failed.
Precondition
ra8_mstp_init has run.
Caller is in single-threaded init context.
Postcondition
Both instances' ECERVF / EC1EDIC / EC2EDIC are set.
Both instances' EC1ECP is cleared (correction enabled).
Note
Not thread-safe.
See also
ra8_cnecc_init
Since
0.1.0

Definition at line 827 of file ra8_cnecc.c.

References ra8_cnecc_init().

◆ ra8_cnecc_reset_counters()

ra8_err_t ra8_cnecc_reset_counters ( uint8_t instance)
nodiscard

Zero the cumulative fault counters for one instance.

Parameters
[in]instanceInstance index 0..1.
Returns
ra8_err_t error code.
Return values
k_ra8_okCounters zeroed (in driver and BBR mirror).
k_ra8_err_invalid_arginstance out of range.
Precondition
ra8_cnecc_init has run.
IRQs masked or single-threaded context.
Postcondition
One-bit / two-bit / overflow counters for instance read back as 0.
Hardware status flags are NOT cleared (use ra8_cnecc_clear_status for that).
Note
Not thread-safe.
Since
0.1.0

Definition at line 530 of file ra8_cnecc.c.

References k_ra8_cnecc_instance_count, k_ra8_err_invalid_arg, k_ra8_ok, s_cnecc_bbr_mirror, s_cnecc_one_bit_count, s_cnecc_overflow_count, and s_cnecc_two_bit_count.

◆ ra8_cnecc_set_correction_permission()

ra8_err_t ra8_cnecc_set_correction_permission ( uint8_t instance,
bool correct_1bit )
nodiscard

Update the 1-bit correction permission for one instance.

Per HUM Ch 42.2.1 p 2870, EC1ECP = 0 means "correction executed", EC1ECP = 1 means "correction NOT executed". The argument follows the natural semantic (correct_1bit = true => correction enabled, EC1ECP cleared).

Parameters
[in]instanceInstance index 0..1.
[in]correct_1bittrue => clear EC1ECP (HW corrects).
Returns
ra8_err_t error code.
Return values
k_ra8_okEC1ECP updated.
k_ra8_err_invalid_arginstance out of range.
Precondition
ra8_cnecc_init has run.
Caller has masked IRQs or runs single-threaded.
Postcondition
Live EC710CTL.EC1ECP reads back per !correct_1bit.
Other EC710CTL bits are preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 461 of file ra8_cnecc.c.

References internal_ctl_rmw(), k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_ec1ecp, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_cnecc(), s_cnecc_cached_cfg, and s_tag.

◆ ra8_cnecc_set_counter_mirror()

ra8_err_t ra8_cnecc_set_counter_mirror ( uint8_t instance,
ra8_cnecc_counters_t * mirror )
nodiscard

Attach a BBR-mirrored counter triple for one instance.

The driver keeps SEC / DED / overflow counters in plain SRAM that does not survive a reset. Production health-monitor pipelines often want the counters in battery-backed RAM (e.g. one of the 32 VBTBKRn words exposed by ra8_bkup) so the lifetime counts persist across cold boots. Callers allocate a ra8_cnecc_counters_t in BBR memory, hand the pointer to this function, and the driver mirrors every ra8_cnecc_dispatch / ra8_cnecc_reset_counters write into it.

Pass NULL to detach the mirror without resetting.

Parameters
[in]instanceInstance index 0..1.
[in]mirrorPointer to caller-managed BBR storage, or nullptr to detach.
Returns
ra8_err_t error code.
Return values
k_ra8_okMirror attached / detached.
k_ra8_err_invalid_arginstance out of range.
Precondition
ra8_cnecc_init has run.
Caller manages the lifetime of *mirror; the driver does not copy it.
Postcondition
Subsequent ra8_cnecc_dispatch calls update both the driver-local counter and *mirror.
Subsequent ra8_cnecc_reset_counters calls zero both.
Note
Not thread-safe at install time; the runtime mirror update is plain word writes (atomic on Cortex-M85).
Since
0.1.0

Definition at line 546 of file ra8_cnecc.c.

References k_ra8_cnecc_instance_count, k_ra8_err_invalid_arg, k_ra8_ok, ra8_cnecc_counters_t::one_bit_count, ra8_cnecc_counters_t::overflow_count, s_cnecc_bbr_mirror, s_cnecc_one_bit_count, s_cnecc_overflow_count, s_cnecc_two_bit_count, and ra8_cnecc_counters_t::two_bit_count.

◆ ra8_cnecc_set_irq_enables()

ra8_err_t ra8_cnecc_set_irq_enables ( uint8_t instance,
bool irq_1bit,
bool irq_2bit )
nodiscard

Update the IRQ enable bits for one instance without touching any other CTL field.

Read-modify-writes EC710CTL so the EC1EDIC / EC2EDIC bits reflect the new flags while ECERVF, EC1ECP, latched status, and EMCA are preserved. The write re-asserts the EMCA = 01b unlock pattern so the same store does not accidentally clear ECERVF (HUM 42.2.1 p 2870 EMCA notes).

Parameters
[in]instanceInstance index 0..1.
[in]irq_1bittrue => enable EC1EDIC.
[in]irq_2bittrue => enable EC2EDIC.
Returns
ra8_err_t error code.
Return values
k_ra8_okMask updated.
k_ra8_err_invalid_arginstance out of range.
Precondition
ra8_cnecc_init has run.
Caller has masked IRQs or runs single-threaded.
Postcondition
Live EC710CTL.EC1EDIC matches irq_1bit.
Live EC710CTL.EC2EDIC matches irq_2bit.
Note
Not thread-safe.
Since
0.1.0

Definition at line 439 of file ra8_cnecc.c.

References internal_ctl_rmw(), k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_ec1edic, k_ra8_cnecc_mask_ec2edic, k_ra8_cnecc_mask_irq_all, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_cnecc(), s_cnecc_cached_cfg, and s_tag.

◆ ra8_cnecc_test_mode_active()

ra8_err_t ra8_cnecc_test_mode_active ( uint8_t instance,
bool * out )
nodiscard

Query whether fault injection is currently armed.

Parameters
[in]instanceInstance index 0..1.
[out]outNon-NULL receiver – set to true if EC710TMC.ECTMCE is asserted.
Returns
ra8_err_t error code.
Return values
k_ra8_okQuery succeeded.
k_ra8_err_null_ptrout was NULL.
k_ra8_err_invalid_arginstance out of range.
Precondition
out points to writable storage.
instance is a valid index.
Postcondition
*out reflects the live ECTMCE bit.
Hardware state is unchanged.
Note
Read-only; safe to call from any context.
Since
0.1.0

Definition at line 628 of file ra8_cnecc.c.

References r_cnecc_regs_t::EC710TMC, k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_ectmce, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_cnecc(), and s_tag.

◆ ra8_cnecc_test_mode_disable()

ra8_err_t ra8_cnecc_test_mode_disable ( uint8_t instance)
nodiscard

Force EC710TMC = 0x8000 to leave fault-injection mode.

Direct wrapper for the "Disable ECC test mode" step in Figure 42.2 (HUM p 2875). Restores the decoder to use the live MBRAM data instead of EC710TED. Per HUM 42.2.2 p 2872 ECDCS is automatically cleared when ECTMCE is cleared, so the single 16-bit write is enough to fully exit test mode.

Parameters
[in]instanceInstance index 0..1.
Returns
ra8_err_t error code.
Return values
k_ra8_okTest mode disabled.
k_ra8_err_invalid_arginstance out of range.
Precondition
ra8_cnecc_init has run.
Caller has masked IRQs or runs single-threaded.
Postcondition
Live EC710TMC.ECTMCE reads back as 0.
Live EC710TMC.ECDCS reads back as 0.
Note
Not thread-safe.
See also
ra8_cnecc_inject_fault
Since
0.1.0

Definition at line 616 of file ra8_cnecc.c.

References r_cnecc_regs_t::EC710TMC, k_ra8_cnecc_instance_count, k_ra8_cnecc_mask_test_disable, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_cnecc(), and s_tag.

◆ ra8_cnecc_verify()

ra8_err_t ra8_cnecc_verify ( uint32_t addr,
uint32_t len,
uint32_t expected_ecc )
nodiscard

Verify a region's ECC tag matches an expected value.

Computes the CRC32 over [addr, addr + len) via ra8_cnecc_compute and compares against expected_ecc. Returns k_ra8_err_crc_mismatch on mismatch so callers can route the failure into the same telemetry path as a hardware ECC fault.

Parameters
[in]addrBase address (must be 4-byte aligned).
[in]lenRegion length in bytes (rounded down to /4).
[in]expected_eccExpected ECC tag.
Returns
ra8_err_t error code.
Return values
k_ra8_okComputed value matched.
k_ra8_err_crc_mismatchComputed value did NOT match expected.
k_ra8_err_invalid_argaddr not 4-byte aligned OR len < 4.
Precondition
addr is non-zero and 4-byte aligned.
len is at least 4 bytes.
Postcondition
Hardware state is unchanged.
On success the verification result is logged at INFO level; on mismatch it is logged at ERROR level.
Note
Read-only path.
See also
ra8_cnecc_compute
Since
0.1.0

Definition at line 864 of file ra8_cnecc.c.

References k_ra8_err_crc_mismatch, k_ra8_ok, ra8_cnecc_compute(), ra8_log_error_val, RA8_RETURN_ON_ERROR, and s_tag.