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

CAN with Flexible Data-rate driver implementation. More...

#include "ra8_canfd.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_canfd_regs.h"
#include "ra8_cgc.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_hal_internal.h"
#include "ra8_hw_err.h"
#include "ra8_log.h"
#include "ra8_mstp.h"
#include "ra8_register_protection.h"
#include "ra8_system_regs.h"
Include dependency graph for ra8_canfd.c:

Go to the source code of this file.

Enumerations

enum  ra8_canfd_internal_t : uint32_t {
  k_ra8_canfd_spin = 20000U ,
  k_ra8_canfd_ckcr_spin = 262144U
}
 Internal tunables (mode-transition + clock-handshake spin budgets). More...
enum  : uint16_t { k_ra8_canfd_afl_per_page = 16U }
 Number of AFL slots that live on page 0. More...

Functions

static ra8_err_t internal_wait_status_bit (volatile r_canfd_t *reg, uint8_t status_bit)
 Bounded wait on a CFDC[0].STS flag (reset/halt/operation ack).
ra8_err_t priv_ra8_canfd_internal_set_channel_mode (volatile r_canfd_t *reg, ra8_chmdc_mode_t mode)
 Drive CFDC[0].CTR.CHMDC and wait for the matching status bit.
static ra8_err_t internal_set_global_mode (volatile r_canfd_t *reg, uint32_t gmdc_value)
 Drive CFDGCTR.GMDC and wait for matching CFDGSTS bit.
static void internal_install_default_afl (volatile r_canfd_t *reg)
 Program a default pass-all AFL rule routed into RX FIFO 0.
static void internal_configure_rx_fifo0 (volatile r_canfd_t *reg)
 Enable RX FIFO 0 with a sensible default depth and payload.
static void internal_enable_rx_fifo0 (volatile r_canfd_t *reg)
 Enable RX FIFO 0 (RFE=1) – must run in GL_HALT or GL_OPERATION.
static ra8_err_t internal_wait_canfdcksrdy (uint8_t expected)
 Bounded wait on CANFDCKCR.CANFDCKSRDY reaching expected.
static ra8_err_t internal_canfd_clock_block_init (void)
 Block-level CANFD clock init – run BEFORE the first MSTP release.
static ra8_err_t internal_canfd_open_channel (volatile r_canfd_t *reg)
 Push the CANFD global+channel state machines into OPERATION.
ra8_err_t ra8_canfd_init (uint8_t channel)
 Take a CANFD channel out of reset into operation mode.
ra8_err_t ra8_canfd_deinit (uint8_t channel)
 Put the CANFD channel back into reset.
ra8_err_t ra8_canfd_get_status (uint8_t channel, uint32_t *out_mask)
 Read the channel status register (CFDCnSTS).
ra8_err_t ra8_canfd_clear_status (uint8_t channel, uint32_t mask)
 Clear error flags in CFDCnERFL.
ra8_err_t ra8_canfd_attach_handler (ra8_canfd_event_fn_t fn, void *ctx)
 Attach a callback for CANFD events (shared across channels).
void ra8_canfd_dispatch (uint8_t channel)
 Dispatch a CANFD event for a channel – snapshot + fire callback.
static void internal_bump_rnc0_locked (volatile r_canfd_t *reg, uint16_t filter_id)
 Bump CFDGAFLCFG0.RNC0 to cover filter_id rules on page 0.
static void internal_write_afl_slot (volatile r_canfd_t *reg, uint16_t slot, uint32_t accept_id, uint32_t mask, uint8_t dlc)
 Write one CFDGAFL slot (ID/M/P0/P1) with the loopback + FIFO-0 routing bits set.
ra8_err_t ra8_canfd_filter_set (uint16_t filter_id, uint32_t accept_id, uint32_t mask, uint8_t dlc)
 Programme one Global Acceptance-Filter-List (GAFL) entry.
ra8_err_t ra8_canfd_set_test_mode (uint8_t channel, ra8_ctms_mode_t mode)
 Enable a CFDC[0].CTR test mode (basic / listen-only / loopback).
ra8_err_t ra8_canfd_set_iso_mode (bool enable)
 Select ISO 11898-1 vs non-ISO CAN-FD framing.
ra8_err_t ra8_canfd_enter_stop (uint8_t channel)
 Put the CANFD channel into MSTP-gated stop.
ra8_err_t ra8_canfd_exit_stop (uint8_t channel)
 Exit MSTP-gated stop.

Variables

static const char * s_tag = "CANFD"
static const ra8_mstp_t s_canfd_mstp_table []
 Channel-index -> MSTP id lookup.
static ra8_canfd_event_fn_t s_canfd_fn
static void * s_canfd_ctx

Detailed Description

CAN with Flexible Data-rate driver implementation.

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

Driver for the RA8D2 CANFD block. Mirrors the FSP r_canfd.c Open / Close / Write / Read / ModeTransition / InfoGet flow:

  • Cancel global sleep, wait for CFDGSTS.GRSTSTS/GRAMINIT, program CFDGCFG, AFL rule counts in CFDGAFLCFG0, CFDGFDCFG, CFDRMNB, CFDRFCC[].
  • Cancel channel sleep via CFDC[0].CTR.CHMDC, programme CFDC[0].NCFG (nominal bit timing) and CFDC2[0].DCFG
    • CFDC2[0].FDCFG (data-phase timing + FD config).
  • Transition global mode then channel mode to operation.
  • Queue a frame into TX message buffer 0 by writing CFDTM[0].ID, CFDTM[0].PTR, CFDTM[0].FDCTR, CFDTM[0].DF[], then asserting CFDTMC[0].TMTR.
  • Pop a frame from RX FIFO 0 by polling CFDRFSTS[0].RFEMP, reading CFDRF[0].ID/PTR/FDSTS/DF[], and writing CFDRFPCTR[0] to advance the pointer.

Every register access carries a HUM Ch 41 "CAN with Flexible Data-rate (CANFD)" citation (pages 2702..2867, chapter map row 41) or an FSP r_canfd.c line citation when the bit semantics come from the reference driver.

Definition in file ra8_canfd.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum : uint16_t

Number of AFL slots that live on page 0.

Enumerator
k_ra8_canfd_afl_per_page 

RA8 CANFD afl per page.

Definition at line 610 of file ra8_canfd.c.

◆ ra8_canfd_internal_t

enum ra8_canfd_internal_t : uint32_t

Internal tunables (mode-transition + clock-handshake spin budgets).

k_ra8_canfd_spin bounds CHLTSTS / CRSTSTS / GHLTSTS / GRSTSTS polls. The CANFD channel/global state machine completes a mode transition within a handful of CANFDCLK ticks (HUM Ch 41 "CFDCnCTR.CHMDC" p 2762 and "CFDGCTR" p 2742). At a CPU running 1 GHz and a tight 5-cycle register-read poll, 20000 iterations ~= 100 us, well above the documented worst-case wait but small enough that a stuck handshake (e.g. CANFDCLK not actually stable) surfaces as an hw_timeout in sub-millisecond time instead of bricking the HIL loop. k_ra8_canfd_ckcr_spin is the matching budget for the CANFDCKCR SREQ/SRDY handshake – shares its order of magnitude with the USB/SCI CKSRDY waits in ra8_cgc.c.

Enumerator
k_ra8_canfd_spin 

Bounded poll budget in iterations.

k_ra8_canfd_ckcr_spin 

CANFDCKCR SREQ/SRDY budget.

Definition at line 70 of file ra8_canfd.c.

Function Documentation

◆ internal_bump_rnc0_locked()

void internal_bump_rnc0_locked ( volatile r_canfd_t * reg,
uint16_t filter_id )
static

Bump CFDGAFLCFG0.RNC0 to cover filter_id rules on page 0.

Caller must already have placed the global block in GL_RESET; RNC0 is RESET-only per HUM Ch 41.2.18 p 2735.

Parameters
[in]regCANFD register block (channel 0).
[in]filter_idFilter slot index in [0, k_ra8_canfd_afl_total).
Precondition
Block is in GL_RESET.
filter_id < k_ra8_canfd_afl_per_page (page-0 only).
Postcondition
RNC0 >= filter_id + 1.
No global state outside CFDGAFLCFG0 is modified.
Note
Not thread-safe; serialise filter edits.
Since
0.1.0

Definition at line 628 of file ra8_canfd.c.

References r_canfd_t::CFDGAFLCFG0, k_ra8_canfd_afl_per_page, k_ra8_gaflcfg0_mask_rnc0, and k_ra8_gaflcfg0_shift_rnc0.

Referenced by ra8_canfd_filter_set().

◆ internal_canfd_clock_block_init()

ra8_err_t internal_canfd_clock_block_init ( void )
static

Block-level CANFD clock init – run BEFORE the first MSTP release.

HUM Ch 11.2.8 "MSTPCRC" Note 4 (p 446) states that MSTPC26 / MSTPC27 (the per-channel CANFD module-stop bits) must be written AFTER the CANFDCLK is stable. CANFDCKCR resets to 0x01 (CANFDCKSEL = MOCO, CANFDCKSREQ = 0, CANFDCKSRDY = 0). MOCO is on at reset, but the RA8D2 CGC requires an explicit SREQ -> SRDY -> SREQ-clear handshake before the chip raises CANFDCKSRDY and declares the clock stable. Without that handshake the canfd block's internal state machine cannot reach CH_HALT after the first CFDCnCTR.CHMDC write – symptom seen on HIL: ra8_canfd_set_test_mode -> priv_ra8_canfd_internal_set_channel_mode (k_ra8_chmdc_halt) -> internal_wait_status_bit times out on CHLTSTS for can_classic_loopback / canfd_loopback / canfd_filter_demo.

Steps (mirrors FSP bsp_clocks.c CANFD CLK block + the USBCKCR pattern in ra8_cgc.c):

  1. Write CANFDCKDIVCR = 0 (/1 – documented reset value).
  2. Set CANFDCKCR.CANFDCKSREQ = 1 (request switch) while keeping the reset-default CANFDCKSEL = MOCO.
  3. Wait CANFDCKSRDY = 1.
  4. Re-write CANFDCKCR with SREQ=0, source = MOCO – commits the switch.
  5. Wait CANFDCKSRDY = 0 (handshake done).

This helper is idempotent via a static guard: only the first caller performs the handshake; subsequent ra8_canfd_init calls (e.g. for channel 1 after channel 0) skip it.

Returns
ra8_err_t outcome.
Return values
k_ra8_okCANFDCLK declared stable; safe to release MSTP.
k_ra8_err_hw_timeoutCKSRDY handshake stuck.
Precondition
Single-threaded init context (no other CGC writes in flight).
MOCO is running – chip reset default; ra8_cgc_init does not explicitly stop MOCO.
Postcondition
On k_ra8_ok the CANFD block clock is stable; MSTPC26/27 may now be released.
On error the canfd MSTP gate is NOT touched; caller decides whether to proceed with the documented "best-effort" recovery.
PRCR is re-locked.
Note
Not thread-safe.
Since
0.1.0

Definition at line 426 of file ra8_canfd.c.

References internal_wait_canfdcksrdy(), k_ra8_ok, k_ra8_prcr_unlock_cgc, k_ra8_usbckcr_bit_sreq, ra8_log_error, ra8_log_info, RA8_PROTECTED_WRITE, ra8_sys_canfdckcr(), ra8_sys_canfdckdivcr(), and s_tag.

Referenced by ra8_canfd_init().

◆ internal_canfd_open_channel()

ra8_err_t internal_canfd_open_channel ( volatile r_canfd_t * reg)
static

Push the CANFD global+channel state machines into OPERATION.

Mirrors FSP r_canfd.c lines ~311..417: cancel global sleep via GL_RESET, cancel channel sleep via CH_RESET, install a pass-all AFL + RX FIFO 0 while in GL_RESET (HUM Ch 41 p 2729..2742), then transition into GL_OPERATION and CH_OPERATION.

Parameters
[in]regCANFD register block for the target channel.
Returns
ra8_err_t outcome of the final state transition.
Return values
k_ra8_okChannel reached CH_OPERATION.
k_ra8_err_hw_timeoutGL_OPERATION or CH_OPERATION never latched.
Precondition
Clock block and MSTP for the channel are already alive.
GRAMINIT bit has cleared (caller polled).
Postcondition
On success the channel is in CH_OPERATION ready for TX/RX.
On failure the channel is left in whichever transitional state stalled; caller treats it as init-failed.
Note
Not thread-safe; caller serialises ra8_canfd_init.
Since
0.1.0

Definition at line 492 of file ra8_canfd.c.

References internal_configure_rx_fifo0(), internal_enable_rx_fifo0(), internal_install_default_afl(), internal_set_global_mode(), k_ra8_chmdc_operation, k_ra8_chmdc_reset, k_ra8_gctr_value_operation, k_ra8_gctr_value_reset, k_ra8_ok, and priv_ra8_canfd_internal_set_channel_mode().

Referenced by ra8_canfd_init().

◆ internal_configure_rx_fifo0()

void internal_configure_rx_fifo0 ( volatile r_canfd_t * reg)
static

Enable RX FIFO 0 with a sensible default depth and payload.

HUM Ch 41 "CFDRFCCa" p 2741: RFE is the last bit set in the register, RFDC selects FIFO depth, RFPLS selects per-entry payload bytes. Writing RFE = 1 while RFDC = 0 silently fails ("This bit can only be set if the configured FIFO depth is greater than 0x000").

Programmed values:

  • RFDC[10:8] = 001b (4 messages)
  • RFPLS[6:4] = 111b (64-byte CAN-FD payload)
  • RFE = 1 (FIFO enabled)
Parameters
[in]regPointer to the CANFD channel register block.
Precondition
Global block is in GL_RESET (RFDC / RFPLS only writable here).
reg is non-NULL.
Postcondition
CFDRFCC[0] reflects depth=4 / payload=64 / RFE=1.
CFDRFSTS[0].RFEMP will clear when frames arrive.
Note
Internal helper, not exported.
Since
0.1.0

< RFDC = 001b -> 4 entries.

< RFPLS = 111b -> 64-byte CAN-FD.

Definition at line 305 of file ra8_canfd.c.

References r_canfd_t::CFDRFCC.

Referenced by internal_canfd_open_channel().

◆ internal_enable_rx_fifo0()

void internal_enable_rx_fifo0 ( volatile r_canfd_t * reg)
static

Enable RX FIFO 0 (RFE=1) – must run in GL_HALT or GL_OPERATION.

Asserts CFDRFCCa.RFE on RX FIFO 0 to bring the FIFO out of the disabled / read-and-write-pointer-cleared state.

Parameters
[in]regCANFD register block.
Precondition
Global block is in GL_OPERATION (or GL_HALT).
internal_configure_rx_fifo0 already programmed depth/payload.
Postcondition
CFDRFCC[0].RFE = 1; FIFO accepts inbound frames.
No other CFDRFCCa fields are touched (RMW preserves RFDC/RFPLS).
Note
Not thread-safe; caller serialises ra8_canfd_init.
Since
0.1.0

Definition at line 335 of file ra8_canfd.c.

References r_canfd_t::CFDRFCC, and k_ra8_rfcc_bit_rfe.

Referenced by internal_canfd_open_channel(), and ra8_canfd_filter_set().

◆ internal_install_default_afl()

void internal_install_default_afl ( volatile r_canfd_t * reg)
static

Program a default pass-all AFL rule routed into RX FIFO 0.

Without at least one Acceptance-Filter-List rule active, every received frame is dropped by the controller before it reaches a destination buffer (HUM Ch 41 "Acceptance Filter List" p 2731-2740: routing is governed by the GAFLFDP0/1/8 bits in CFDGAFLP1, and CFDGAFLCFG0.RNC0 must be non-zero for any rule to be considered).

This helper installs rule 0 with mask = 0 (every ID matches) and GAFLFDP0 = 1 (route into RX FIFO 0). It must run while the global block is in GL_RESET – the documented edit window for AFL data and for CFDGAFLCFG0 (HUM Ch 41 "CFDGAFLCFG0" p 2730 and "CFDGAFLECTR" p 2729).

Parameters
[in]regPointer to the CANFD channel register block.
Precondition
Global block is in GL_RESET.
reg is non-NULL and points to a CANFD instance.
Postcondition
Rule 0 accepts every ID and routes it to RX FIFO 0.
CFDGAFLECTR is re-locked (AFLDAE clear) on return.
Note
Internal helper, not exported.
Since
0.1.0

Definition at line 259 of file ra8_canfd.c.

References r_canfd_t::CFDGAFL, r_canfd_t::CFDGAFLCFG0, r_canfd_t::CFDGAFLECTR, r_canfd_cfdgafl_t::ID, k_ra8_gaflectr_bit_afldae, r_canfd_cfdgafl_t::M, r_canfd_cfdgafl_t::P0, and r_canfd_cfdgafl_t::P1.

Referenced by internal_canfd_open_channel().

◆ internal_set_global_mode()

ra8_err_t internal_set_global_mode ( volatile r_canfd_t * reg,
uint32_t gmdc_value )
static

Drive CFDGCTR.GMDC and wait for matching CFDGSTS bit.

Mirrors FSP global-mode transition. GMDC is bits [1:0] of CFDGCTR and clearing GSLPR (bit 2) is required to leave global sleep (HUM Ch 41 p 2742 "CFDGCTR").

Parameters
[in]regSee header declaration for direction and constraints.
[in]gmdc_valueSee header declaration for direction and constraints.
Returns
ra8_err_t error code (or void if the signature returns void).
Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Precondition
Driver state has been initialized by the matching *_init.
Caller has validated all pointer parameters.
Postcondition
Side effects are limited to those documented in the header.
No global state is modified on the error path.
Note
Thread safety: see the header declaration.
Since
0.1.0

Definition at line 204 of file ra8_canfd.c.

References r_canfd_t::CFDGCTR, r_canfd_t::CFDGSTS, k_ra8_canfd_spin, k_ra8_gctr_mask_gmdc, k_ra8_gctr_mask_gslpr, k_ra8_gctr_value_halt, k_ra8_gctr_value_reset, k_ra8_gsts_bit_ghltsts, k_ra8_gsts_bit_grststs, ra8_hw_wait_flag_clear32(), and ra8_hw_wait_flag_set32().

Referenced by internal_canfd_open_channel(), and ra8_canfd_filter_set().

◆ internal_wait_canfdcksrdy()

ra8_err_t internal_wait_canfdcksrdy ( uint8_t expected)
static

Bounded wait on CANFDCKCR.CANFDCKSRDY reaching expected.

Mirrors internal_wait_usbcksrdy in ra8_cgc.c. Polls CANFDCKCR bit 7 (CANFDCKSRDY) until it equals expected or the bounded budget k_ra8_canfd_ckcr_spin elapses.

Parameters
[in]expected0U after the SREQ-clear write, 1U after SREQ=1.
Returns
ra8_err_t outcome.
Return values
k_ra8_okCKSRDY reached expected.
k_ra8_err_hw_timeoutSRDY never matched within the budget.
Precondition
Caller holds the CGC-PRCR unlock window (PRCR=0xA501).
expected is 0 or 1.
Postcondition
No register state is modified – this is a read-only poll.
On timeout the caller relocks PRCR.
Note
Not thread-safe; init context only.
Since
0.1.0

Definition at line 364 of file ra8_canfd.c.

References k_ra8_canfd_ckcr_spin, k_ra8_usbckcr_bit_srdy, ra8_hw_wait_flag_clear8(), ra8_hw_wait_flag_set8(), and ra8_sys_canfdckcr().

Referenced by internal_canfd_clock_block_init().

◆ internal_wait_status_bit()

ra8_err_t internal_wait_status_bit ( volatile r_canfd_t * reg,
uint8_t status_bit )
static

Bounded wait on a CFDC[0].STS flag (reset/halt/operation ack).

HUM Ch 41 p 2766 "CFDCnSTS" – after CHMDC is written the matching status bit (CRSTSTS / CHLTSTS / etc) latches once the channel state machine reaches the requested mode.

Parameters
[in]regSee header declaration for direction and constraints.
[in]status_bitSee header declaration for direction and constraints.
Returns
ra8_err_t error code (or void if the signature returns void).
Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Precondition
Driver state has been initialized by the matching *_init.
Caller has validated all pointer parameters.
Postcondition
Side effects are limited to those documented in the header.
No global state is modified on the error path.
Note
Thread safety: see the header declaration.
Since
0.1.0

Definition at line 96 of file ra8_canfd.c.

References r_canfd_t::CFDC, k_ra8_canfd_spin, ra8_hw_wait_flag_set32(), and r_canfd_cfdc_t::STS.

Referenced by priv_ra8_canfd_internal_set_channel_mode().

◆ internal_write_afl_slot()

void internal_write_afl_slot ( volatile r_canfd_t * reg,
uint16_t slot,
uint32_t accept_id,
uint32_t mask,
uint8_t dlc )
static

Write one CFDGAFL slot (ID/M/P0/P1) with the loopback + FIFO-0 routing bits set.

Mask register OR-includes GAFLLB (bit 29) so the entry is valid under Self-test mode 0/1 (HUM Ch 41.5.5 Table 41.22); P1 OR-includes GAFLFDP0 so matched frames land in RX FIFO 0 (HUM Ch 41.2.22 p 2740).

Parameters
[in]regCANFD register block.
[in]slotSlot index inside the unlocked page (0..15).
[in]accept_id11/29-bit accept ID.
[in]mask11/29-bit ID mask (caller-provided bits only).
[in]dlcDLC value 0..15.
Precondition
Global block is in GL_RESET (CFDGAFL entries are RESET-only).
Caller holds the AFL data window unlock (CFDGAFLECTR.AFLDAE=1).
Postcondition
CFDGAFL[slot] reflects the caller's accept_id / mask / dlc with GAFLLB and GAFLFDP0 set.
No other AFL slot is modified.
Note
Not thread-safe; caller serialises AFL edits.
Since
0.1.0

Definition at line 664 of file ra8_canfd.c.

References r_canfd_t::CFDGAFL, r_canfd_cfdgafl_t::ID, k_ra8_canfd_ptr_mask_dlc, k_ra8_canfd_ptr_shift_dlc, k_ra8_gaflm_bit_gafllb, k_ra8_gaflp1_bit_gaflfdp0, r_canfd_cfdgafl_t::M, r_canfd_cfdgafl_t::P0, and r_canfd_cfdgafl_t::P1.

Referenced by ra8_canfd_filter_set().

◆ priv_ra8_canfd_internal_set_channel_mode()

ra8_err_t priv_ra8_canfd_internal_set_channel_mode ( volatile r_canfd_t * reg,
ra8_chmdc_mode_t mode )

Drive CFDC[0].CTR.CHMDC and wait for the matching status bit.

Mirrors r_canfd_mode_ctr_set + r_canfd_mode_transition from FSP r_canfd.c. The CHMDC field is bits [1:0] of CTR (FSP R_CANFD_CFDC_CTR_b.CHMDC). After a write the channel state machine drives CRSTSTS / CHLTSTS / CSLPSTS in CFDC[0].STS.

Parameters
[in]regSee header declaration for direction and constraints.
[in]modeSee header declaration for direction and constraints.
Returns
ra8_err_t error code (or void if the signature returns void).
Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Precondition
Driver state has been initialized by the matching *_init.
Caller has validated all pointer parameters.
Postcondition
Side effects are limited to those documented in the header.
No global state is modified on the error path.
Note
Thread safety: see the header declaration.
Since
0.1.0

Definition at line 138 of file ra8_canfd.c.

References r_canfd_t::CFDC, r_canfd_cfdc_t::CTR, internal_wait_status_bit(), k_ra8_canfd_spin, k_ra8_chmdc_halt, k_ra8_chmdc_reset, k_ra8_cnctr_mask_chmdc, k_ra8_cnctr_mask_cslpr, k_ra8_cnsts_bit_chltst, k_ra8_cnsts_bit_crstst, ra8_hw_wait_flag_clear32(), and r_canfd_cfdc_t::STS.

Referenced by internal_canfd_open_channel(), ra8_canfd_deinit(), ra8_canfd_set_bitrate(), ra8_canfd_set_tdc(), and ra8_canfd_set_test_mode().

◆ ra8_canfd_attach_handler()

ra8_err_t ra8_canfd_attach_handler ( ra8_canfd_event_fn_t fn,
void * ctx )
nodiscard

Attach a callback for CANFD events (shared across channels).

Since
0.1.0

Definition at line 585 of file ra8_canfd.c.

References k_ra8_ok, s_canfd_ctx, and s_canfd_fn.

◆ ra8_canfd_clear_status()

ra8_err_t ra8_canfd_clear_status ( uint8_t channel,
uint32_t mask )
nodiscard

Clear error flags in CFDCnERFL.

Since
0.1.0

Definition at line 574 of file ra8_canfd.c.

References r_canfd_t::CFDC, r_canfd_cfdc_t::ERFL, k_ra8_ok, ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_canfd_deinit()

ra8_err_t ra8_canfd_deinit ( uint8_t channel)
nodiscard

Put the CANFD channel back into reset.

Parameters
[in]channelChannel index (0..1).
Returns
k_ra8_ok on success, k_ra8_err_null_ptr if channel out of range.
Since
0.1.0

Definition at line 546 of file ra8_canfd.c.

References k_ra8_chmdc_reset, k_ra8_ok, priv_ra8_canfd_internal_set_channel_mode(), ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_canfd_dispatch()

void ra8_canfd_dispatch ( uint8_t channel)

Dispatch a CANFD event for a channel – snapshot + fire callback.

Since
0.1.0

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Parameters
[in]channelSee header declaration for direction and constraints.
Precondition
Driver state has been initialized by the matching *_init.
Caller has validated all pointer parameters.
Postcondition
Side effects are limited to those documented in the header.
No global state is modified on the error path.
Note
Thread safety: see the header declaration.

Definition at line 593 of file ra8_canfd.c.

References r_canfd_t::CFDC, r_canfd_cfdc_t::ERFL, ra8_canfd(), s_canfd_ctx, and s_canfd_fn.

◆ ra8_canfd_enter_stop()

ra8_err_t ra8_canfd_enter_stop ( uint8_t channel)
nodiscard

Put the CANFD channel into MSTP-gated stop.

Since
0.1.0

Definition at line 777 of file ra8_canfd.c.

References k_ra8_canfd_instance_count, k_ra8_err_invalid_arg, ra8_mstp_disable(), and s_canfd_mstp_table.

◆ ra8_canfd_exit_stop()

ra8_err_t ra8_canfd_exit_stop ( uint8_t channel)
nodiscard

Exit MSTP-gated stop.

Since
0.1.0

Definition at line 786 of file ra8_canfd.c.

References k_ra8_canfd_instance_count, k_ra8_err_invalid_arg, ra8_mstp_enable(), and s_canfd_mstp_table.

◆ ra8_canfd_filter_set()

ra8_err_t ra8_canfd_filter_set ( uint16_t filter_id,
uint32_t accept_id,
uint32_t mask,
uint8_t dlc )
nodiscard

Programme one Global Acceptance-Filter-List (GAFL) entry.

Selects the AFL page that contains filter_id (each page holds 16 entries) by writing CFDGAFLECTR.AFLPN with the page index and unlocking the data window with CFDGAFLECTR.AFLDAE. Then writes CFDGAFL[idx].ID with the accept ID, CFDGAFL[idx].M with the bit mask, and CFDGAFL[idx].P1 with the DLC field used to gate fast RX-FIFO routing. See HUM Ch 41 "CFDGAFLECTR / CFDGAFL" pp 2702-2867.

Parameters
[in]filter_idFilter index (0..k_ra8_canfd_afl_total - 1).
[in]accept_idRaw arbitration ID to accept (11- or 29-bit).
[in]maskBit mask – bits clear are "don't care".
[in]dlcDLC code packed into CFDGAFL.P1 (0..15).
Returns
ra8_err_t outcome.
Return values
k_ra8_okFilter slot programmed.
k_ra8_err_invalid_argfilter_id, accept_id, or dlc out of range.
Precondition
Channel is initialized; controller is in global-reset mode.
Caller is single-threaded init context.
Postcondition
CFDGAFL[entry].ID/M/P1 reflect the requested rule.
CFDGAFLECTR.AFLDAE re-locked when the call returns.
Note
Not thread-safe.
Since
0.1.0

Definition at line 689 of file ra8_canfd.c.

References r_canfd_t::CFDGAFLECTR, internal_bump_rnc0_locked(), internal_enable_rx_fifo0(), internal_set_global_mode(), internal_write_afl_slot(), k_ra8_canfd_afl_per_page, k_ra8_canfd_afl_total, k_ra8_canfd_dlc_max, k_ra8_canfd_id_ext_mask, k_ra8_err_invalid_arg, k_ra8_gaflectr_bit_afldae, k_ra8_gaflectr_mask_aflpn, k_ra8_gctr_value_operation, k_ra8_gctr_value_reset, k_ra8_ok, ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_canfd_filter_program_slots().

◆ ra8_canfd_get_status()

ra8_err_t ra8_canfd_get_status ( uint8_t channel,
uint32_t * out_mask )
nodiscard

Read the channel status register (CFDCnSTS).

Since
0.1.0

Definition at line 564 of file ra8_canfd.c.

References r_canfd_t::CFDC, k_ra8_ok, ra8_canfd(), RA8_CHECK_NULL_PTR, s_tag, and r_canfd_cfdc_t::STS.

◆ ra8_canfd_init()

ra8_err_t ra8_canfd_init ( uint8_t channel)
nodiscard

◆ ra8_canfd_set_iso_mode()

ra8_err_t ra8_canfd_set_iso_mode ( bool enable)
nodiscard

Select ISO 11898-1 vs non-ISO CAN-FD framing.

Writes CFDGFDCFG.NISO – when the bit is clear the controller uses the ISO 11898-1 stuff-count + CRC; when set it falls back to the original Bosch non-ISO framing. See HUM Ch 41 "CFDGFDCFG" pp 2702-2867.

Parameters
[in]enabletrue -> ISO mode, false -> non-ISO mode.
Returns
ra8_err_t outcome.
Return values
k_ra8_okMode bit updated.
Precondition
At least one CANFD channel is initialized.
Controller is in global-reset before flipping the bit.
Postcondition
CFDGFDCFG.NISO reflects enable.
Subsequent CAN-FD frames use the selected framing.
Note
Not thread-safe.
Since
0.1.0

Definition at line 761 of file ra8_canfd.c.

References r_canfd_t::CFDGFDCFG, k_ra8_gfdcfg_bit_niso, k_ra8_ok, ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_canfd_set_test_mode()

ra8_err_t ra8_canfd_set_test_mode ( uint8_t channel,
ra8_ctms_mode_t mode )
nodiscard

Enable a CFDC[0].CTR test mode (basic / listen-only / loopback).

Stamps CTME (bit 24) and CTMS[1:0] (bits [26:25]) in CFDC[0].CTR. Per HUM Ch 41 "CFDCnCTR" p 2710 these bits are only writable while the channel is in CH_HALT mode, so the helper:

  1. Drives the channel from CH_OPERATION (the post-init steady state) into CH_HALT via CHMDC = 10b and waits for CHLTSTS.
  2. Writes CTME=1 with the requested CTMS value.
  3. Returns the channel to CH_OPERATION via CHMDC = 00b.

The internal-loopback mode (k_ra8_ctms_self_test_1, 11b) is the documented way to validate the CANFD IP without a transceiver – the controller routes every TX frame straight to its own RX acceptance filter (HUM Ch 41 "Self-test mode 1 (Internal Loopback mode)" p 2710).

Parameters
[in]channelChannel index (0..1).
[in]modeDesired CTMS selector (ra8_ctms_mode_t).
Returns
ra8_err_t outcome.
Return values
k_ra8_okTest mode latched, channel back in operation.
k_ra8_err_invalid_argchannel or mode out of range.
k_ra8_err_hw_timeoutHalt/operation status bit never asserted.
Precondition
ra8_canfd_init has returned k_ra8_ok for channel.
No outstanding TX/RX is in flight on channel.
Postcondition
CFDC[0].CTR.CTME=1 and CTMS=mode.
Channel is back in CH_OPERATION ready to TX/RX.
Note
Not thread-safe; caller must serialize with TX/RX.
Since
0.1.0

Definition at line 731 of file ra8_canfd.c.

References r_canfd_t::CFDC, r_canfd_cfdc_t::CTR, k_ra8_chmdc_halt, k_ra8_chmdc_operation, k_ra8_cnctr_bit_ctms, k_ra8_cnctr_mask_ctme, k_ra8_cnctr_mask_ctms, k_ra8_ctms_self_test_1, k_ra8_err_invalid_arg, k_ra8_ok, priv_ra8_canfd_internal_set_channel_mode(), ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_can_demo_enable_internal_loopback(), internal_canfd_demo_enable_internal_loopback(), internal_canfd_filter_loopback(), and main().

Variable Documentation

◆ s_canfd_ctx

void* s_canfd_ctx
static

Definition at line 562 of file ra8_canfd.c.

Referenced by ra8_canfd_attach_handler(), and ra8_canfd_dispatch().

◆ s_canfd_fn

ra8_canfd_event_fn_t s_canfd_fn
static

Definition at line 561 of file ra8_canfd.c.

Referenced by ra8_canfd_attach_handler(), and ra8_canfd_dispatch().

◆ s_canfd_mstp_table

const ra8_mstp_t s_canfd_mstp_table[]
static
Initial value:
= {
}
@ k_ra8_mstp_canfd1
MSTPC26 CANFD1.
@ k_ra8_mstp_canfd0
MSTPC27 CANFD0.

Channel-index -> MSTP id lookup.

CANFD0/1 have separate MSTPC bits (HUM Ch 11.2.8 "MSTPCRC", page 447 chapter map row 11).

Definition at line 112 of file ra8_canfd.c.

Referenced by ra8_canfd_enter_stop(), ra8_canfd_exit_stop(), and ra8_canfd_init().

◆ s_tag

const char* s_tag = "CANFD"
static

Definition at line 51 of file ra8_canfd.c.