|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
CANFD ECC (CNECC) driver implementation. More...
#include "ra8_cnecc.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_cnecc_regs.h"#include "ra8_elc_regs.h"#include "ra8_err.h"#include "ra8_isr.h"#include "ra8_log.h"#include "ra8_mstp.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_cnecc_isr_const_t : uint16_t { k_ra8_cnecc_isr_ctx_inst_mask = 0x00FFU } |
| Numeric constants for ISR ctx packing. More... | |
| enum | ra8_cnecc_compute_const_t : uint32_t { k_ra8_cnecc_crc_seed = 0xFFFFFFFFUL , k_ra8_cnecc_crc_xorout = 0xFFFFFFFFUL , k_ra8_cnecc_crc_poly = 0xEDB88320UL } |
| Magic numbers used by ra8_cnecc_compute promoted to typed enums. More... | |
| enum | ra8_cnecc_compute_align_t : uint8_t { k_ra8_cnecc_compute_align = 4U , k_ra8_cnecc_compute_byte_bits = 8U , k_ra8_cnecc_compute_byte_mask = 0xFFU } |
| Alignment / size constants for the compute path. More... | |
Functions | |
| static uint32_t | internal_cnecc_ctl_value (const ra8_cnecc_instance_cfg_t *cfg) |
| Compute the EC710CTL value one instance's configuration asks for. | |
| static ra8_err_t | internal_apply_instance (uint8_t instance, const ra8_cnecc_instance_cfg_t *cfg) |
| Apply one instance's configuration. | |
| static void | internal_ctl_rmw (volatile r_cnecc_regs_t *reg, uint32_t new_bits, uint32_t mask) |
| Read-modify-write helper for EC710CTL that preserves the unlock pattern and clears RO/clear-on-write bits. | |
| 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). | |
| static uint32_t | internal_crc32 (const uint8_t *data, uint32_t bytes) |
| Reflected CRC32 (poly 0xEDB88320) over a byte buffer. | |
| 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. | |
Variables | |
| static const char * | s_tag = "CNECC" |
| Logging tag. | |
| static const ra8_mstp_t | s_cnecc_mstp_table [k_ra8_cnecc_instance_count] |
| Per-instance MSTP id used to ungate the parent CANFD block. | |
| static const ra8_elc_event_t | s_cnecc_event_table [k_ra8_cnecc_instance_count] |
| Per-instance ICU event for the shared CANn_MRAM_ERI vector. | |
| static ra8_cnecc_error_fn_t | s_cnecc_fn |
| Currently registered fault callback. | |
| static void * | s_cnecc_ctx |
| Opaque context passed to s_cnecc_fn. | |
| static uint32_t | s_cnecc_one_bit_count [k_ra8_cnecc_instance_count] |
| Cumulative 1-bit fault counter, per instance. | |
| static uint32_t | s_cnecc_two_bit_count [k_ra8_cnecc_instance_count] |
| Cumulative 2-bit fault counter, per instance. | |
| static uint32_t | s_cnecc_overflow_count [k_ra8_cnecc_instance_count] |
| Cumulative ECOVFF counter, per instance. | |
| static ra8_cnecc_counters_t * | s_cnecc_bbr_mirror [k_ra8_cnecc_instance_count] |
| Optional BBR-mirrored counter pointer, per instance. | |
| static ra8_cnecc_config_t | s_cnecc_cached_cfg |
| Last-applied configuration – replayed by exit_standby. | |
| static bool | s_cnecc_initialized |
| True between successful init and matching deinit. | |
| static bool | s_cnecc_isr_attached |
| True when ra8_cnecc_attach_isr has wired the ICU vectors. | |
CANFD ECC (CNECC) driver implementation.
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) share the same register map. The block sits behind the same module-stop bit as the CANFD it monitors, so init walks ra8_mstp_enable for both CANFDn ids before it touches any CNECC register. Every register access carries a HUM Ch 42 citation.
Every EC710CTL field (HUM 42.2.1 p 2868-2871), the EC710TMC test-mode register (HUM 42.2.2 p 2871-2872), the EC710TED substitute-data register (HUM 42.2.3 p 2872), and the EC710EAD0 captured-address register (HUM 42.2.4 p 2872-2873) are exercised. The driver also implements the Software Standby enter / exit flows from HUM 42.5.1 / 42.5.2 p 2876.
Definition in file ra8_cnecc.c.
| enum ra8_cnecc_compute_align_t : uint8_t |
Alignment / size constants for the compute path.
| Enumerator | |
|---|---|
| k_ra8_cnecc_compute_align | 4-byte alignment for addr / len. |
| k_ra8_cnecc_compute_byte_bits | Bits per byte. |
| k_ra8_cnecc_compute_byte_mask | Byte mask. |
Definition at line 789 of file ra8_cnecc.c.
| enum ra8_cnecc_compute_const_t : uint32_t |
Magic numbers used by ra8_cnecc_compute promoted to typed enums.
| Enumerator | |
|---|---|
| k_ra8_cnecc_crc_seed | Initial CRC32 register value. |
| k_ra8_cnecc_crc_xorout | Final XOR mask. |
| k_ra8_cnecc_crc_poly | Reflected CRC32 polynomial. |
Definition at line 779 of file ra8_cnecc.c.
| enum ra8_cnecc_isr_const_t : uint16_t |
Numeric constants for ISR ctx packing.
| Enumerator | |
|---|---|
| k_ra8_cnecc_isr_ctx_inst_mask | Low byte of ctx -> instance. |
Definition at line 176 of file ra8_cnecc.c.
|
static |
Apply one instance's configuration.
Walks the HUM 42.3.1 figure-42.1 procedure (p 2874): ungate the parent CANFD module, clear any latched fault state, set the IRQ enables / correction permission, then unlock and write ECERVF per cfg->enable.
| [in] | instance | Instance index already bounded. |
| [in] | cfg | Per-instance settings. |
| k_ra8_ok | Success path. |
| k_ra8_err_invalid_arg | Caller violated a precondition. |
Definition at line 255 of file ra8_cnecc.c.
References r_cnecc_regs_t::EC710CTL, r_cnecc_regs_t::EC710TMC, internal_cnecc_ctl_value(), k_ra8_cnecc_mask_clear_all, k_ra8_cnecc_mask_test_disable, k_ra8_err_hw_init_failed, k_ra8_ok, ra8_cnecc(), ra8_mstp_enable(), RA8_RETURN_ON_ERROR, s_cnecc_bbr_mirror, s_cnecc_mstp_table, s_cnecc_one_bit_count, s_cnecc_overflow_count, s_cnecc_two_bit_count, and s_tag.
Referenced by ra8_cnecc_exit_standby(), and ra8_cnecc_init().
|
static |
Compute the EC710CTL value one instance's configuration asks for.
Extracted from internal_apply_instance so the apply procedure reads as the HUM 42.3.1 figure-42.1 sequence. The register citations travel with the bits they describe, as the citation policy requires.
| [in] | cfg | Per-instance settings; already validated by the caller. |
| k_ra8_cnecc_mask_emca_unlock | Always set, so the write is honoured. |
Definition at line 202 of file ra8_cnecc.c.
References ra8_cnecc_instance_cfg_t::correct_1bit, ra8_cnecc_instance_cfg_t::enable, ra8_cnecc_instance_cfg_t::irq_1bit, ra8_cnecc_instance_cfg_t::irq_2bit, k_ra8_cnecc_mask_ec1ecp, k_ra8_cnecc_mask_ec1edic, k_ra8_cnecc_mask_ec2edic, k_ra8_cnecc_mask_ecervf, and k_ra8_cnecc_mask_emca_unlock.
Referenced by internal_apply_instance().
|
static |
Reflected CRC32 (poly 0xEDB88320) over a byte buffer.
See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.
| [in] | data | See header declaration for direction and constraints. |
| [in] | bytes | See header declaration for direction and constraints. |
| k_ra8_ok | Success path. |
| k_ra8_err_invalid_arg | Caller violated a precondition. |
Definition at line 814 of file ra8_cnecc.c.
References k_ra8_cnecc_compute_byte_bits, k_ra8_cnecc_crc_poly, k_ra8_cnecc_crc_seed, and k_ra8_cnecc_crc_xorout.
Referenced by ra8_cnecc_compute().
|
static |
Read-modify-write helper for EC710CTL that preserves the unlock pattern and clears RO/clear-on-write bits.
HUM 42.2.1 p 2870 EMCA[1:0] = 01b is required on every write that may touch ECERVF; rather than tracking which writes do, the driver always combines the unlock pattern. ECER1C / ECER2C are W1C, so we mask them to 0 in the rewrite to avoid an accidental clear, and we blank the read-only flag bits before OR-ing in the new value.
| [in] | reg | Live register pointer (non-NULL). |
| [in] | new_bits | Bits to OR into the writable subset. |
| [in] | mask | Subset of k_ra8_cnecc_mask_ctl_writable to replace; bits in mask are first cleared, then new_bits & mask is OR-ed in. |
Definition at line 320 of file ra8_cnecc.c.
References r_cnecc_regs_t::EC710CTL, k_ra8_cnecc_mask_ctl_writable, k_ra8_cnecc_mask_ecer1c, k_ra8_cnecc_mask_ecer2c, k_ra8_cnecc_mask_emca, and k_ra8_cnecc_mask_emca_unlock.
Referenced by ra8_cnecc_disable_instance(), ra8_cnecc_enable_instance(), ra8_cnecc_set_correction_permission(), and ra8_cnecc_set_irq_enables().
|
nodiscard |
Attach a callback for CNECC fault events.
| [in] | fn | Non-NULL handler invoked from the ECC ISR (or test code). |
| [in] | ctx | Opaque context pointer forwarded to the handler. |
| k_ra8_ok | Handler installed. |
| k_ra8_err_null_ptr | fn was NULL. |
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.
|
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.
| [in] | priority | NVIC priority shared by both vectors (0..k_ra8_isr_prio_max). |
| k_ra8_ok | Both vectors wired. |
| k_ra8_err_invalid_arg | priority out of range. |
| k_ra8_err_no_mem | No free IELSR slot. |
| k_ra8_err_exists | One of the events was already routed. |
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.
|
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).
| [in] | instance | Instance index 0..1. |
| k_ra8_ok | Cleared. |
| k_ra8_err_invalid_arg | instance >= k_ra8_cnecc_instance_count. |
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.
|
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.
| [in] | addr | Base address (must be 4-byte aligned). |
| [in] | len | Region length in bytes (rounded down to /4). |
| [out] | out_ecc | Receives the 32-bit ECC tag. |
| k_ra8_ok | ECC computed. |
| k_ra8_err_null_ptr | addr was 0 OR out_ecc was NULL. |
| k_ra8_err_invalid_arg | addr not 4-byte aligned OR len < 4. |
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().
|
nodiscard |
Tear down both CNECC instances and gate the CANFD MSTP bits.
| k_ra8_ok | Always. |
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.
|
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.
| k_ra8_ok | Both vectors released (or already gone). |
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().
|
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.
| [in] | instance | Instance index 0..1. |
| k_ra8_ok | Judgment disabled. |
| k_ra8_err_invalid_arg | instance >= k_ra8_cnecc_instance_count. |
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.
| 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.
| [in] | instance | Instance index 0..1 (out-of-range silently ignored). |
| [in] | is_2bit | true for uncorrectable, false for 1-bit. |
| [in] | err_addr | Faulting RAM offset (ECEAD[9: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().
| 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.
| [in] | instance | Instance index 0..1 (out-of-range silently ignored). |
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().
|
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).
| [in] | instance | Instance index 0..1. |
| k_ra8_ok | Judgment enabled. |
| k_ra8_err_invalid_arg | instance >= k_ra8_cnecc_instance_count. |
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.
|
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:
The driver-local fault counters are preserved (they survive any standby trip).
| k_ra8_ok | Always succeeds. |
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().
|
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.
| k_ra8_ok | Both instances re-armed. |
| k_ra8_err_not_initialized | ra8_cnecc_init was never called. |
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.
|
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.
| [in] | instance | Instance index 0..1. |
| [out] | out | Non-NULL counter receiver. |
| k_ra8_ok | Counters copied. |
| k_ra8_err_null_ptr | out was NULL. |
| k_ra8_err_invalid_arg | instance out of range. |
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.
|
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.
| [in] | instance | Instance index 0..1. |
| [out] | out | Non-NULL status receiver. |
| k_ra8_ok | Status copied to *out. |
| k_ra8_err_null_ptr | out was NULL. |
| k_ra8_err_invalid_arg | instance >= k_ra8_cnecc_instance_count. |
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.
|
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):
| [in] | cfg | Non-NULL configuration descriptor. |
| k_ra8_ok | Driver initialized, both instances live. |
| k_ra8_err_null_ptr | cfg was NULL. |
| k_ra8_err_hw_init_failed | MSTP ungate failed for one of the CANFD instances. |
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().
|
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.
| [in] | instance | Instance index 0..1. |
| [in] | req | Non-NULL injection descriptor. |
| k_ra8_ok | Test-mode programmed. |
| k_ra8_err_null_ptr | req was NULL. |
| k_ra8_err_invalid_arg | instance out of range. |
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.
| 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").
| [in] | ctx | Instance index packed in the low byte of the void*. Out-of-range values are silently dropped. |
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().
|
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.
| k_ra8_ok | Both instances live with defaults. |
| k_ra8_err_hw_init_failed | MSTP enable failed. |
Definition at line 827 of file ra8_cnecc.c.
References ra8_cnecc_init().
|
nodiscard |
Zero the cumulative fault counters for one instance.
| [in] | instance | Instance index 0..1. |
| k_ra8_ok | Counters zeroed (in driver and BBR mirror). |
| k_ra8_err_invalid_arg | instance out of range. |
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.
|
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).
| [in] | instance | Instance index 0..1. |
| [in] | correct_1bit | true => clear EC1ECP (HW corrects). |
| k_ra8_ok | EC1ECP updated. |
| k_ra8_err_invalid_arg | instance out of range. |
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.
|
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.
| [in] | instance | Instance index 0..1. |
| [in] | mirror | Pointer to caller-managed BBR storage, or nullptr to detach. |
| k_ra8_ok | Mirror attached / detached. |
| k_ra8_err_invalid_arg | instance out of range. |
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.
|
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).
| [in] | instance | Instance index 0..1. |
| [in] | irq_1bit | true => enable EC1EDIC. |
| [in] | irq_2bit | true => enable EC2EDIC. |
| k_ra8_ok | Mask updated. |
| k_ra8_err_invalid_arg | instance out of range. |
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.
|
nodiscard |
Query whether fault injection is currently armed.
| [in] | instance | Instance index 0..1. |
| [out] | out | Non-NULL receiver – set to true if EC710TMC.ECTMCE is asserted. |
| k_ra8_ok | Query succeeded. |
| k_ra8_err_null_ptr | out was NULL. |
| k_ra8_err_invalid_arg | instance out of range. |
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.
|
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.
| [in] | instance | Instance index 0..1. |
| k_ra8_ok | Test mode disabled. |
| k_ra8_err_invalid_arg | instance out of range. |
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.
|
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.
| [in] | addr | Base address (must be 4-byte aligned). |
| [in] | len | Region length in bytes (rounded down to /4). |
| [in] | expected_ecc | Expected ECC tag. |
| k_ra8_ok | Computed value matched. |
| k_ra8_err_crc_mismatch | Computed value did NOT match expected. |
| k_ra8_err_invalid_arg | addr not 4-byte aligned OR len < 4. |
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.
|
static |
Optional BBR-mirrored counter pointer, per instance.
If non-NULL, every increment to the driver-local counters is mirrored into the caller-supplied storage (typically a battery-backed VBTBKRn slot). Mirror lifetime is the caller's responsibility; see HUM Ch 12.2.7 p 505 for the BBR window the test pattern uses.
Definition at line 152 of file ra8_cnecc.c.
Referenced by internal_apply_instance(), ra8_cnecc_dispatch(), ra8_cnecc_dispatch_overflow(), ra8_cnecc_reset_counters(), and ra8_cnecc_set_counter_mirror().
|
static |
Last-applied configuration – replayed by exit_standby.
Definition at line 158 of file ra8_cnecc.c.
Referenced by ra8_cnecc_exit_standby(), ra8_cnecc_init(), ra8_cnecc_set_correction_permission(), and ra8_cnecc_set_irq_enables().
|
static |
Opaque context passed to s_cnecc_fn.
Definition at line 121 of file ra8_cnecc.c.
Referenced by ra8_cnecc_attach_handler(), and ra8_cnecc_dispatch().
|
static |
Per-instance ICU event for the shared CANn_MRAM_ERI vector.
HUM 42.4 p 2875 lists CAN0_MRAM_ERI for instance 0 and CAN1_MRAM_ERI for instance 1. The ELC event numbers themselves live in ra8_elc_regs.h.
Definition at line 105 of file ra8_cnecc.c.
Referenced by ra8_cnecc_attach_isr(), and ra8_cnecc_detach_isr().
|
static |
Currently registered fault callback.
Definition at line 115 of file ra8_cnecc.c.
Referenced by ra8_cnecc_attach_handler(), and ra8_cnecc_dispatch().
|
static |
True between successful init and matching deinit.
Definition at line 164 of file ra8_cnecc.c.
Referenced by ra8_cnecc_deinit(), ra8_cnecc_exit_standby(), and ra8_cnecc_init().
|
static |
True when ra8_cnecc_attach_isr has wired the ICU vectors.
Definition at line 170 of file ra8_cnecc.c.
Referenced by ra8_cnecc_attach_isr(), ra8_cnecc_deinit(), and ra8_cnecc_detach_isr().
|
static |
Per-instance MSTP id used to ungate the parent CANFD block.
HUM 11.2.8 p 447 places MSTPC26 over CANFD1 and MSTPC27 over CANFD0 (HUM 42.1 overview p 2868 also notes the ECC sits inside the CANFD module so it shares the parent gate).
Definition at line 91 of file ra8_cnecc.c.
Referenced by internal_apply_instance(), and ra8_cnecc_deinit().
|
static |
Cumulative 1-bit fault counter, per instance.
Definition at line 127 of file ra8_cnecc.c.
Referenced by internal_apply_instance(), ra8_cnecc_deinit(), ra8_cnecc_dispatch(), ra8_cnecc_get_counters(), ra8_cnecc_get_status(), ra8_cnecc_reset_counters(), and ra8_cnecc_set_counter_mirror().
|
static |
Cumulative ECOVFF counter, per instance.
Definition at line 139 of file ra8_cnecc.c.
Referenced by internal_apply_instance(), ra8_cnecc_deinit(), ra8_cnecc_dispatch_overflow(), ra8_cnecc_get_counters(), ra8_cnecc_get_status(), ra8_cnecc_reset_counters(), and ra8_cnecc_set_counter_mirror().
|
static |
Cumulative 2-bit fault counter, per instance.
Definition at line 133 of file ra8_cnecc.c.
Referenced by internal_apply_instance(), ra8_cnecc_deinit(), ra8_cnecc_dispatch(), ra8_cnecc_get_counters(), ra8_cnecc_get_status(), ra8_cnecc_reset_counters(), and ra8_cnecc_set_counter_mirror().
|
static |
Logging tag.
Definition at line 80 of file ra8_cnecc.c.