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

CANFD Acceptance-Filter-List (AFL) configuration (split from ra8_canfd.c). More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_canfd.h"
#include "ra8_canfd_regs.h"
#include "ra8_check.h"
#include "ra8_err.h"
Include dependency graph for ra8_canfd_afl.c:

Go to the source code of this file.

Enumerations

enum  ra8_canfd_afl_local_t : uint32_t { k_ra8_canfd_afl_page0 = 0U }
 Local constants owned by the AFL list-config path. More...

Functions

static ra8_err_t internal_afl_validate_rule (const ra8_canfd_afl_rule_t *rule)
 Range-check one ra8_canfd_afl_rule_t against the protocol limits.
static uint32_t internal_afl_id_word (const ra8_canfd_afl_rule_t *rule)
 Assemble the CFDGAFLID word: accept ID plus IDE / RTR flags.
static uint32_t internal_afl_mask_word (const ra8_canfd_afl_rule_t *rule)
 Assemble the CFDGAFLM word: ID mask plus IDE / RTR compare-enables.
static uint32_t internal_afl_p1_word (const ra8_canfd_afl_rule_t *rule)
 Assemble the CFDGAFLP1 word: route a match into RX FIFO target_rx.
static void internal_afl_write_slot (volatile r_canfd_t *reg, uint8_t slot, const ra8_canfd_afl_rule_t *rule)
 Write one CFDGAFL slot (ID / M / P0 / P1) from a rule.
static void internal_afl_set_rule_count (volatile r_canfd_t *reg, uint8_t count)
 Set CFDGAFLCFG0.RNC0 to count so the AFL consults count rules.
static ra8_err_t internal_afl_validate_all (const ra8_canfd_afl_rule_t *rules, uint8_t count)
 Validate every rule in rules before any register is touched.
ra8_err_t ra8_canfd_set_accept_filter (uint8_t channel, const ra8_canfd_afl_rule_t *rules, uint8_t count)
 Program the channel Acceptance-Filter-List from a rule array.

Variables

static const char * s_tag = "CANFD"

Detailed Description

CANFD Acceptance-Filter-List (AFL) configuration (split from ra8_canfd.c).

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

Acceptance-filter half of the RA8D2 CANFD driver, split out of ra8_canfd.c purely to satisfy the per-file size cap. This translation unit owns the list-oriented AFL programming path used to hardware-match received CAN / CAN-FD frames by ID and mask and route them into a receive FIFO instead of accepting everything in software:

  • Assemble each ra8_canfd_afl_rule_t into the paged GAFL register quartet (CFDGAFLID / CFDGAFLM / CFDGAFLP0 / CFDGAFLP1).
  • Drive the documented edit transaction: select the AFL page and unlock the data window via CFDGAFLECTR (AFLPN + AFLDAE), set the page-0 rule count via CFDGAFLCFG0.RNC0, write each rule, then re-lock by clearing CFDGAFLECTR.

The single-rule ra8_canfd_filter_set (which wraps the GL_RESET transition itself) lives in ra8_canfd.c; this file provides the list-config primitive that runs inside a caller-managed GL_RESET window.

Every register access carries a HUM Ch 41 "CAN with Flexible Data-rate (CANFD)" citation (pages 2702..2867, chapter map row 41).

Since
0.1.0

Definition in file ra8_canfd_afl.c.

Enumeration Type Documentation

◆ ra8_canfd_afl_local_t

enum ra8_canfd_afl_local_t : uint32_t

Local constants owned by the AFL list-config path.

k_ra8_canfd_afl_page0 is the AFLPN page index this API targets – all rules land in the single 16-entry page 0, matching the k_ra8_canfd_afl_rule_capacity cap in the public header. It is a read-only compile-time constant so this translation unit keeps its own named value rather than reaching for a bare literal in the CFDGAFLECTR write. HUM Ch 41.2.17 "CFDGAFLECTR : AFL Entry Control Register" p 2734 (AFLPN field).

Enumerator
k_ra8_canfd_afl_page0 

AFLPN page index used by this API.

Definition at line 57 of file ra8_canfd_afl.c.

Function Documentation

◆ internal_afl_id_word()

uint32_t internal_afl_id_word ( const ra8_canfd_afl_rule_t * rule)
static

Assemble the CFDGAFLID word: accept ID plus IDE / RTR flags.

Masks the ID to the std / ext field and OR-includes GAFLIDE (bit 31) for extended rules and GAFLRTR (bit 30) for remote-frame rules, matching the shared message-ID layout used by the TX / RX paths.

Parameters
[in]ruleNon-NULL validated rule descriptor.
Returns
uint32_t CFDGAFLID register value.
Return values
0Standard data frame with ID and flags all zero.
Precondition
rule is non-NULL and already range-checked.
rule->id fits the field selected by rule->extended.
Postcondition
No register state is modified (pure assembly).
The returned IDE bit matches rule->extended.
Note
Internal helper, not exported. Not thread-safe.
Since
0.1.0

Definition at line 131 of file ra8_canfd_afl.c.

References ra8_canfd_afl_rule_t::extended, ra8_canfd_afl_rule_t::id, k_ra8_canfd_id_ext_mask, k_ra8_canfd_id_ide, k_ra8_canfd_id_rtr, k_ra8_canfd_id_std_mask, and ra8_canfd_afl_rule_t::rtr.

Referenced by internal_afl_write_slot().

◆ internal_afl_mask_word()

uint32_t internal_afl_mask_word ( const ra8_canfd_afl_rule_t * rule)
static

Assemble the CFDGAFLM word: ID mask plus IDE / RTR compare-enables.

Masks the caller mask to the std / ext field and always OR-includes GAFLIDEM (bit 31) and GAFLRTRM (bit 30) so the IDE and RTR flags are part of the acceptance match – otherwise rule->extended and rule->rtr would be programmed into the ID word but never compared.

Parameters
[in]ruleNon-NULL validated rule descriptor.
Returns
uint32_t CFDGAFLM register value.
Return values
0Never returned: the IDEM / RTRM compare bits are always set.
Precondition
rule is non-NULL and already range-checked.
rule->mask fits the field selected by rule->extended.
Postcondition
No register state is modified (pure assembly).
The returned word always asserts GAFLIDEM and GAFLRTRM.
Note
Internal helper, not exported. Not thread-safe.
Since
0.1.0

Definition at line 168 of file ra8_canfd_afl.c.

References ra8_canfd_afl_rule_t::extended, k_ra8_canfd_id_ext_mask, k_ra8_canfd_id_std_mask, k_ra8_gaflm_bit_gaflidem, k_ra8_gaflm_bit_gaflrtrm, and ra8_canfd_afl_rule_t::mask.

Referenced by internal_afl_write_slot().

◆ internal_afl_p1_word()

uint32_t internal_afl_p1_word ( const ra8_canfd_afl_rule_t * rule)
static

Assemble the CFDGAFLP1 word: route a match into RX FIFO target_rx.

GAFLFDP0 (bit 0) routes a matched frame into RX FIFO 0; the per-FIFO routing bits are contiguous, so shifting that base bit left by rule->target_rx selects RX FIFO target_rx. At least one routing bit must be set or the match is dropped instead of stored.

Parameters
[in]ruleNon-NULL validated rule descriptor.
Returns
uint32_t CFDGAFLP1 register value (single routing bit set).
Return values
1target_rx == 0: route into RX FIFO 0.
Precondition
rule is non-NULL and already range-checked.
rule->target_rx < k_ra8_canfd_rx_fifo_count.
Postcondition
No register state is modified (pure assembly).
Exactly one GAFLFDP routing bit is set.
Note
Internal helper, not exported. Not thread-safe.
Since
0.1.0

Definition at line 198 of file ra8_canfd_afl.c.

References k_ra8_gaflp1_bit_gaflfdp0, and ra8_canfd_afl_rule_t::target_rx.

Referenced by internal_afl_write_slot().

◆ internal_afl_set_rule_count()

void internal_afl_set_rule_count ( volatile r_canfd_t * reg,
uint8_t count )
static

Set CFDGAFLCFG0.RNC0 to count so the AFL consults count rules.

Read-modify-write of the RNC0 field (page-0 rule count) so the surrounding CFDGAFLCFG0 bits are preserved. RNC0 is RESET-only, so the caller must already hold the global block in GL_RESET.

Parameters
[in]regNon-NULL CANFD register block for the target channel.
[in]countRule count, 1..k_ra8_canfd_afl_rule_capacity.
Precondition
reg is non-NULL and the global block is in GL_RESET.
count <= k_ra8_canfd_afl_rule_capacity (fits the 5-bit field).
Postcondition
CFDGAFLCFG0.RNC0 == count.
No CFDGAFLCFG0 bits outside RNC0 are modified.
Note
Internal helper, not exported. Not thread-safe.
Since
0.1.0

Definition at line 257 of file ra8_canfd_afl.c.

References r_canfd_t::CFDGAFLCFG0, k_ra8_gaflcfg0_mask_rnc0, and k_ra8_gaflcfg0_shift_rnc0.

Referenced by ra8_canfd_set_accept_filter().

◆ internal_afl_validate_all()

ra8_err_t internal_afl_validate_all ( const ra8_canfd_afl_rule_t * rules,
uint8_t count )
static

Validate every rule in rules before any register is touched.

Bounded loop over the caller array, delegating per-rule range checks to internal_afl_validate_rule. Validating up front keeps the register write phase all-or-nothing – a bad rule never lands a partial edit.

Parameters
[in]rulesNon-NULL array of count rule descriptors.
[in]countNumber of rules, already capacity-checked by the caller.
Returns
ra8_err_t error code.
Return values
k_ra8_okAll rules are in range.
k_ra8_err_invalid_argThe first failing rule's error.
Precondition
rules is non-NULL with at least count elements.
count <= k_ra8_canfd_afl_rule_capacity (loop bound).
Postcondition
No register or global state is modified (pure predicate).
On k_ra8_ok every rule passed internal_afl_validate_rule.
Note
Internal helper, not exported. Not thread-safe.
Since
0.1.0

Definition at line 290 of file ra8_canfd_afl.c.

References internal_afl_validate_rule(), and k_ra8_ok.

Referenced by ra8_canfd_set_accept_filter().

◆ internal_afl_validate_rule()

ra8_err_t internal_afl_validate_rule ( const ra8_canfd_afl_rule_t * rule)
static

Range-check one ra8_canfd_afl_rule_t against the protocol limits.

Splits the std-vs-ext and routing checks into nested guards (no compound decisions) so each condition is independently reachable. A standard rule must keep id and mask inside the 11-bit field; an extended rule inside the 29-bit field. The routing target must name an existing RX FIFO.

Parameters
[in]ruleNon-NULL rule descriptor to validate.
Returns
ra8_err_t error code.
Return values
k_ra8_okRule fields are all in range.
k_ra8_err_invalid_argid / mask overflow or target_rx out of range.
Precondition
rule is non-NULL (the caller dereferenced it already).
rule->target_rx is the caller-supplied routing index.
Postcondition
No register or global state is modified (pure predicate).
On k_ra8_ok every field fits its documented range.
Note
Internal helper, not exported. Not thread-safe.
Since
0.1.0

Definition at line 86 of file ra8_canfd_afl.c.

References ra8_canfd_afl_rule_t::extended, ra8_canfd_afl_rule_t::id, k_ra8_canfd_id_ext_mask, k_ra8_canfd_id_std_mask, k_ra8_canfd_rx_fifo_count, k_ra8_err_invalid_arg, k_ra8_ok, ra8_canfd_afl_rule_t::mask, and ra8_canfd_afl_rule_t::target_rx.

Referenced by internal_afl_validate_all().

◆ internal_afl_write_slot()

void internal_afl_write_slot ( volatile r_canfd_t * reg,
uint8_t slot,
const ra8_canfd_afl_rule_t * rule )
static

Write one CFDGAFL slot (ID / M / P0 / P1) from a rule.

Stamps the four paged AFL words for slot inside the unlocked page-0 window. P0 is left zero (no RX message-buffer routing – the match goes to an RX FIFO via P1).

Parameters
[in]regNon-NULL CANFD register block for the target channel.
[in]slotSlot index inside the unlocked page (0..15).
[in]ruleNon-NULL validated rule descriptor.
Precondition
reg is non-NULL and the AFL window is unlocked (AFLDAE = 1).
The global block is in GL_RESET (CFDGAFL entries are RESET-only).
Postcondition
CFDGAFL[slot] reflects the rule's id / mask / routing.
No other AFL slot is modified.
Note
Internal helper, not exported. Not thread-safe.
Since
0.1.0

Definition at line 225 of file ra8_canfd_afl.c.

References r_canfd_t::CFDGAFL, r_canfd_cfdgafl_t::ID, internal_afl_id_word(), internal_afl_mask_word(), internal_afl_p1_word(), r_canfd_cfdgafl_t::M, r_canfd_cfdgafl_t::P0, and r_canfd_cfdgafl_t::P1.

Referenced by ra8_canfd_set_accept_filter().

◆ ra8_canfd_set_accept_filter()

ra8_err_t ra8_canfd_set_accept_filter ( uint8_t channel,
const ra8_canfd_afl_rule_t * rules,
uint8_t count )
nodiscard

Program the channel Acceptance-Filter-List from a rule array.

Installs count hardware acceptance rules into AFL page 0 for channel, replacing the single pass-all rule that ra8_canfd_init installs. The routine follows the documented AFL edit transaction exactly:

  1. Unlock the AFL data window and select page 0 by writing CFDGAFLECTR.AFLPN + CFDGAFLECTR.AFLDAE.
  2. Set the page-0 rule count in CFDGAFLCFG0.RNC0.
  3. Write each rule's CFDGAFLID / CFDGAFLM / CFDGAFLP0 / CFDGAFLP1.
  4. Re-lock the window by clearing CFDGAFLECTR.

For a rule, IDE and RTR are added to the match (CFDGAFLM.GAFLIDEM / GAFLRTRM) so extended and rtr are honoured, and CFDGAFLP1 routes the match into RX FIFO rule.target_rx.

Parameters
[in]channelCANFD channel index (0..1).
[in]rulesArray of count rules. Must not be NULL.
[in]countNumber of rules, 1..k_ra8_canfd_afl_rule_capacity.
Returns
ra8_err_t outcome.
Return values
k_ra8_okAll count rules programmed and re-locked.
k_ra8_err_null_ptrchannel out of range or rules NULL.
k_ra8_err_invalid_argcount is zero or above capacity, a rule's id/mask overflows the std/ext range, or a rule's target_rx is out of range.
Precondition
rules points to at least count valid rule descriptors.
The global block is in GL_RESET: RNC0 and the CFDGAFL entries are RESET-only, and the AFL lookup engine only resamples the list on the next GL_RESET -> GL_OPERATION transition (HUM Ch 41.2.18 p 2735, Ch 41.2.17 p 2734).
Postcondition
On success CFDGAFLCFG0.RNC0 == count and the first count CFDGAFL slots reflect the supplied rules.
CFDGAFLECTR.AFLDAE is cleared (window re-locked) on every return that reaches the write stage.
Note
Not thread-safe; single-threaded init / reconfigure context only.
See also
ra8_canfd_filter_set() Single-rule variant that wraps the GL_RESET transition itself.
Since
0.1.0

Definition at line 302 of file ra8_canfd_afl.c.

References r_canfd_t::CFDGAFLECTR, internal_afl_set_rule_count(), internal_afl_validate_all(), internal_afl_write_slot(), k_ra8_canfd_afl_page0, k_ra8_canfd_afl_rule_capacity, k_ra8_err_invalid_arg, k_ra8_gaflectr_bit_afldae, k_ra8_gaflectr_mask_aflpn, k_ra8_ok, ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

Variable Documentation

◆ s_tag

const char* s_tag = "CANFD"
static

Definition at line 42 of file ra8_canfd_afl.c.