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

CANFD frame transmit / receive data path (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 "ra8_hw_err.h"
Include dependency graph for ra8_canfd_frame.c:

Go to the source code of this file.

Enumerations

enum  ra8_canfd_frame_spin_t : uint32_t { k_ra8_canfd_tx_spin = 100000U }
 TX-completion poll budget owned by the frame data path. More...
enum  ra8_canfd_buffer_idx_t : uint8_t {
  k_ra8_canfd_tx_mb_default = 0U ,
  k_ra8_canfd_rx_fifo_default = 0U
}
 Indices the driver currently owns within the channel block. More...

Functions

static ra8_err_t internal_validate_frame (const ra8_canfd_frame_t *frame)
 Range-check a ra8_canfd_frame_t against the protocol limits.
static void internal_write_tx_data (volatile r_canfd_t *reg, const ra8_canfd_frame_t *frame)
 Copy the frame payload into CFDTM[0].DF[].
static uint32_t internal_tx_id (const ra8_canfd_frame_t *frame)
 Assemble the CFDTM[0].ID word (raw ID plus IDE flag).
static uint32_t internal_tx_fdctr (const ra8_canfd_frame_t *frame)
 Assemble the CFDTM[0].FDCTR word (FDF/BRS/ESI flags).
static void internal_wait_tx_complete (volatile r_canfd_t *reg)
 Best-effort bounded spin until CFDTMSTSj.TMTRF reads "complete".
ra8_err_t ra8_canfd_transmit (uint8_t channel, const ra8_canfd_frame_t *frame)
 Queue a frame into the TX message buffer and trigger transmission.
static void internal_read_rx_data (volatile r_canfd_t *reg, ra8_canfd_frame_t *out)
 Copy 64 bytes of RX FIFO data from CFDRF[0].DF[] into the caller buffer.
static void internal_decode_rx_header (uint32_t id_word, uint32_t ptr_word, uint32_t fdsts_word, ra8_canfd_frame_t *out)
 Decode the raw CFDRF[0].ID/PTR/FDSTS into out.
ra8_err_t ra8_canfd_receive (uint8_t channel, ra8_canfd_frame_t *out_frame)
 Poll the RX FIFO for the next available frame.
ra8_err_t ra8_canfd_get_error_state (uint8_t channel, uint8_t *tx_err, uint8_t *rx_err)
 Read the TX and RX error counters.

Variables

static const char * s_tag = "CANFD"

Detailed Description

CANFD frame transmit / receive data path (split from ra8_canfd.c).

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

Frame-level 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 TX/RX message-buffer path:

  • Range-check a ra8_canfd_frame_t against the protocol limits, assemble the CFDTM[0].ID/PTR/FDCTR words, copy the payload into CFDTM[0].DF[] and assert CFDTMC[0].TMTR.
  • Pop a frame from RX FIFO 0 by polling CFDRFSTS[0].RFEMP, reading CFDRF[0].ID/PTR/FDSTS/DF[], decoding the header, and writing CFDRFPCTR[0] to advance the pointer.
  • Read TEC/REC out of CFDC[0].STS for the error-state query.

This TU compiles the identical register sequence on every build; host unit tests stage the RAM-backed CFDRF[0] receive buffer and the CFDRFSTS[0] empty flag directly (the values the silicon RX engine would have latched) and drive the real receive path against them.

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.

Since
0.1.0

Definition in file ra8_canfd_frame.c.

Enumeration Type Documentation

◆ ra8_canfd_buffer_idx_t

enum ra8_canfd_buffer_idx_t : uint8_t

Indices the driver currently owns within the channel block.

Enumerator
k_ra8_canfd_tx_mb_default 

Driver uses TX MB 0 for fire-and-forget.

k_ra8_canfd_rx_fifo_default 

Driver uses RX FIFO 0 for poll-receive.

Definition at line 66 of file ra8_canfd_frame.c.

◆ ra8_canfd_frame_spin_t

enum ra8_canfd_frame_spin_t : uint32_t

TX-completion poll budget owned by the frame data path.

Private copy of the matching constant in ra8_canfd.c; this TU only needs the TX-completion budget. Bounds the back-to-back TMTRF poll in ra8_canfd_transmit. k_ra8_canfd_tx_spin is a read-only compile-time constant, so each translation unit keeps its own copy rather than promoting it to external linkage.

Enumerator
k_ra8_canfd_tx_spin 

TX-completion poll: 500 us @ 1 GHz / 5 cyc.

Definition at line 58 of file ra8_canfd_frame.c.

Function Documentation

◆ internal_decode_rx_header()

void internal_decode_rx_header ( uint32_t id_word,
uint32_t ptr_word,
uint32_t fdsts_word,
ra8_canfd_frame_t * out )
static

Decode the raw CFDRF[0].ID/PTR/FDSTS into out.

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

Parameters
[in]id_wordSee header declaration for direction and constraints.
[in]ptr_wordSee header declaration for direction and constraints.
[in]fdsts_wordSee header declaration for direction and constraints.
[in]outSee 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.
Since
0.1.0

Definition at line 311 of file ra8_canfd_frame.c.

References ra8_canfd_frame_t::dlc, ra8_canfd_frame_t::id, ra8_canfd_frame_t::is_brs, ra8_canfd_frame_t::is_extended, ra8_canfd_frame_t::is_fd, k_ra8_canfd_fd_brs, k_ra8_canfd_fd_fdf, k_ra8_canfd_id_ext_mask, k_ra8_canfd_id_ide, k_ra8_canfd_id_std_mask, k_ra8_canfd_ptr_mask_dlc, and k_ra8_canfd_ptr_shift_dlc.

Referenced by ra8_canfd_receive().

◆ internal_read_rx_data()

void internal_read_rx_data ( volatile r_canfd_t * reg,
ra8_canfd_frame_t * out )
static

Copy 64 bytes of RX FIFO data from CFDRF[0].DF[] into the caller buffer.

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

Parameters
[in]regSee header declaration for direction and constraints.
[in]outSee 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.
Since
0.1.0

Definition at line 286 of file ra8_canfd_frame.c.

References r_canfd_t::CFDRF, ra8_canfd_frame_t::data, r_canfd_cfdrf_t::DF, k_ra8_canfd_data_bytes_max, and k_ra8_canfd_rx_fifo_default.

Referenced by ra8_canfd_receive().

◆ internal_tx_fdctr()

uint32_t internal_tx_fdctr ( const ra8_canfd_frame_t * frame)
static

Assemble the CFDTM[0].FDCTR word (FDF/BRS/ESI flags).

FSP r_canfd.c line ~676: p_frame->options & 7 packs ESI/BRS/FDF directly into bits [2:0]. We model the same here.

Parameters
[in]frameSee 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 176 of file ra8_canfd_frame.c.

References ra8_canfd_frame_t::is_brs, ra8_canfd_frame_t::is_fd, k_ra8_canfd_fd_brs, and k_ra8_canfd_fd_fdf.

Referenced by ra8_canfd_transmit().

◆ internal_tx_id()

uint32_t internal_tx_id ( const ra8_canfd_frame_t * frame)
static

Assemble the CFDTM[0].ID word (raw ID plus IDE flag).

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

Parameters
[in]frameSee 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 150 of file ra8_canfd_frame.c.

References ra8_canfd_frame_t::id, ra8_canfd_frame_t::is_extended, k_ra8_canfd_id_ext_mask, k_ra8_canfd_id_ide, and k_ra8_canfd_id_std_mask.

Referenced by ra8_canfd_transmit().

◆ internal_validate_frame()

ra8_err_t internal_validate_frame ( const ra8_canfd_frame_t * frame)
static

Range-check a ra8_canfd_frame_t against the protocol limits.

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

Parameters
[in]frameSee 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 89 of file ra8_canfd_frame.c.

References ra8_canfd_frame_t::dlc, ra8_canfd_frame_t::id, ra8_canfd_frame_t::is_brs, ra8_canfd_frame_t::is_extended, ra8_canfd_frame_t::is_fd, k_ra8_canfd_dlc_max, k_ra8_canfd_id_ext_mask, k_ra8_canfd_id_std_mask, k_ra8_err_invalid_arg, and k_ra8_ok.

Referenced by ra8_canfd_transmit().

◆ internal_wait_tx_complete()

void internal_wait_tx_complete ( volatile r_canfd_t * reg)
static

Best-effort bounded spin until CFDTMSTSj.TMTRF reads "complete".

Waits for CFDTMSTSj.TMTRF[1:0] to read "transmission complete" (10b) – HUM Ch 41 "CFDTMSTSj.TMTRF" p ~2756. The previous mask (0x06) also matched 01b ("transmission requested"), which on back-to-back TX calls let the second call clobber CFDTMSTS while the first frame was still in flight; the chip then silently dropped the second TX and canfd_filter_demo's mask sub-round (sent immediately after the exact sub-round) saw the frame disappear. Mask 0x04 keys on TMTRF[1] only, which is only set once the TX is actually on the wire and the MB is free. 500 kbit/s + 8 bytes = ~240 us; k_ra8_canfd_tx_spin (~500 us at 1 GHz / 5 cycles per iter) covers it with margin. The wait is best-effort by design (no error on exhaustion); on host tests the loop-exit decision comes from the ra8_fake_mmio seam so the retry and full-budget legs run there too.

Parameters
[in]regCANFD register block for the transmitting channel.
Precondition
reg is non-NULL (validated by the caller).
TXREQ was just asserted on the default TX mailbox.
Postcondition
At most k_ra8_canfd_tx_spin polls have been issued.
No register state is modified (read-only poll).
Note
Not thread-safe; fire-and-forget TX path only.
Since
0.1.0

< RA8 tmsts tmtrf done.

Definition at line 216 of file ra8_canfd_frame.c.

References r_canfd_t::CFDTMSTS, k_ra8_canfd_tx_mb_default, and k_ra8_canfd_tx_spin.

Referenced by ra8_canfd_transmit().

◆ internal_write_tx_data()

void internal_write_tx_data ( volatile r_canfd_t * reg,
const ra8_canfd_frame_t * frame )
static

Copy the frame payload into CFDTM[0].DF[].

Unused bytes left intact.

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

Parameters
[in]regSee header declaration for direction and constraints.
[in]frameSee 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.
Since
0.1.0

Definition at line 125 of file ra8_canfd_frame.c.

References r_canfd_t::CFDTM, ra8_canfd_frame_t::data, r_canfd_cfdtm_t::DF, k_ra8_canfd_data_bytes_max, and k_ra8_canfd_tx_mb_default.

Referenced by ra8_canfd_transmit().

◆ ra8_canfd_get_error_state()

ra8_err_t ra8_canfd_get_error_state ( uint8_t channel,
uint8_t * tx_err,
uint8_t * rx_err )
nodiscard

Read the TX and RX error counters.

Parameters
[in]channelChannel index (0..1).
[out]tx_errTEC counter value. Must not be NULL.
[out]rx_errREC counter value. Must not be NULL.
Returns
k_ra8_err_null_ptr if any pointer is NULL or channel out of range.
k_ra8_ok on success.
Since
0.1.0

Definition at line 350 of file ra8_canfd_frame.c.

References r_canfd_t::CFDC, k_ra8_cnsts_bit_rec, k_ra8_cnsts_bit_tec, k_ra8_cnsts_mask_rec, k_ra8_cnsts_mask_tec, k_ra8_ok, ra8_canfd(), RA8_CHECK_NULL_PTR, s_tag, and r_canfd_cfdc_t::STS.

◆ ra8_canfd_receive()

ra8_err_t ra8_canfd_receive ( uint8_t channel,
ra8_canfd_frame_t * out_frame )
nodiscard

Poll the RX FIFO for the next available frame.

Non-blocking: on an empty FIFO the call returns k_ra8_err_no_data immediately. On success the frame is popped (by writing the pointer control register) before returning.

Parameters
[in]channelChannel index (0..1).
[out]out_frameDestination frame. Must not be NULL.
Returns
k_ra8_err_null_ptr if channel out of range or out_frame == NULL.
k_ra8_err_no_data if the RX FIFO is empty.
k_ra8_ok on success.
Since
0.1.0

Definition at line 326 of file ra8_canfd_frame.c.

References r_canfd_t::CFDRF, r_canfd_t::CFDRFPCTR, r_canfd_t::CFDRFSTS, r_canfd_cfdrf_t::FDSTS, r_canfd_cfdrf_t::ID, internal_decode_rx_header(), internal_read_rx_data(), k_ra8_canfd_rx_fifo_default, k_ra8_err_no_data, k_ra8_ok, k_ra8_rfpctr_value_ack, k_ra8_rfsts_bit_empty, r_canfd_cfdrf_t::PTR, ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_can_demo_one_round_trip(), internal_canfd_demo_one_round_trip(), internal_canfd_filter_one_round(), internal_thread_rx_entry(), and main().

◆ ra8_canfd_transmit()

ra8_err_t ra8_canfd_transmit ( uint8_t channel,
const ra8_canfd_frame_t * frame )
nodiscard

Queue a frame into the TX message buffer and trigger transmission.

Fire-and-forget: the routine validates every field, writes the ID / DLC / FD-status / payload into the TX message-buffer registers, then asserts TMTR in CFDTMC. No completion callback is raised.

Parameters
[in]channelChannel index (0..1).
[in]frameFrame descriptor. Must not be NULL.
Returns
k_ra8_err_null_ptr if channel out of range or frame == NULL.
k_ra8_err_invalid_arg on bad DLC, oversized ID, or inconsistent flags.
k_ra8_ok on success.
Since
0.1.0

Definition at line 235 of file ra8_canfd_frame.c.

References r_canfd_t::CFDTM, r_canfd_t::CFDTMC, r_canfd_t::CFDTMSTS, ra8_canfd_frame_t::dlc, r_canfd_cfdtm_t::FDCTR, r_canfd_cfdtm_t::ID, internal_tx_fdctr(), internal_tx_id(), internal_validate_frame(), internal_wait_tx_complete(), internal_write_tx_data(), k_ra8_canfd_ptr_mask_dlc, k_ra8_canfd_ptr_shift_dlc, k_ra8_canfd_tmc_txreq, k_ra8_canfd_tx_mb_default, k_ra8_ok, r_canfd_cfdtm_t::PTR, ra8_canfd(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_can_demo_one_round_trip(), internal_canfd_demo_one_round_trip(), internal_canfd_filter_one_round(), and internal_thread_tx_entry().

Variable Documentation

◆ s_tag

const char* s_tag = "CANFD"
static

Definition at line 45 of file ra8_canfd_frame.c.