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

LIN commander + responder driver implementation on SCI_B. More...

#include "ra8_sci_lin.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_hw_err.h"
#include "ra8_log.h"
#include "ra8_sci.h"
#include "ra8_sci_regs.h"
Include dependency graph for ra8_sci_lin.c:

Go to the source code of this file.

Enumerations

enum  ra8_sci_lin_pid_shift_t : uint8_t {
  k_ra8_sci_lin_id_bit0 = 0U ,
  k_ra8_sci_lin_id_bit1 = 1U ,
  k_ra8_sci_lin_id_bit2 = 2U ,
  k_ra8_sci_lin_id_bit3 = 3U ,
  k_ra8_sci_lin_id_bit4 = 4U ,
  k_ra8_sci_lin_id_bit5 = 5U ,
  k_ra8_sci_lin_pid_p0_shift = 6U ,
  k_ra8_sci_lin_pid_p1_shift = 7U
}
 Bit positions used when packing / unpacking a LIN PID. More...
enum  ra8_sci_lin_const_t : uint8_t {
  k_ra8_sci_lin_id_mask = 0x3FU ,
  k_ra8_sci_lin_bit_mask = 0x01U ,
  k_ra8_sci_lin_sync_byte = 0x55U ,
  k_ra8_sci_lin_fold_passes = 2U ,
  k_ra8_sci_lin_data_max = 8U
}
 Byte-level masks and protocol constants for the LIN math. More...
enum  ra8_sci_lin_fold_const_t : uint16_t {
  k_ra8_sci_lin_byte_mask = 0x00FFU ,
  k_ra8_sci_lin_byte_bits = 8U
}
 16-bit masks used while folding the LIN checksum carry. More...

Functions

static void internal_lin_program_mode (volatile r_sci_regs_t *reg, ra8_sci_lin_role_t role, uint32_t tcss, uint16_t break_len)
 Program the SCI_B mode + break-field timer/detector for a LIN role.
static ra8_err_t internal_lin_wait_break_done (volatile const r_sci_regs_t *reg)
 Spin until the break-field timer (XCR1.TCST) self-clears.
static uint8_t internal_lin_fold_complement (uint16_t sum)
 Fold a LIN checksum accumulator and return its one's complement.
static ra8_err_t internal_lin_tx_buf (uint8_t channel, const uint8_t *data, uint8_t len)
 Poll-transmit len bytes of a LIN response data field.
static ra8_err_t internal_lin_rx_buf (uint8_t channel, uint8_t *buf, uint8_t len)
 Poll-receive len bytes of a LIN response data field.
ra8_err_t ra8_sci_lin_init (uint8_t channel, const ra8_sci_lin_cfg_t *cfg)
 Configure an SCI_B channel for a LIN role (commander or responder).
ra8_err_t ra8_sci_lin_send_break (uint8_t channel)
 Emit a LIN break field on the channel's TXD line.
ra8_err_t ra8_sci_lin_send_header (uint8_t channel, uint8_t id)
 Transmit a full LIN header: break + SYNC (0x55) + PID.
ra8_err_t ra8_sci_lin_break_detected (uint8_t channel, bool *out_detected)
 Report whether the responder's break-field detector has fired.
ra8_err_t ra8_sci_lin_wait_break (uint8_t channel)
 Block until the responder detects a break field (XSR0.BFDF set).
ra8_err_t ra8_sci_lin_clear_status (uint8_t channel)
 Clear the Simple-LIN status latches (XSR0) via XFCLR.
ra8_err_t ra8_sci_lin_send_response (uint8_t channel, ra8_sci_lin_checksum_mode_t mode, uint8_t pid, const uint8_t *data, uint8_t len)
 Publish a LIN response: data bytes followed by the checksum.
ra8_err_t ra8_sci_lin_read_response (uint8_t channel, uint8_t *out_data, uint8_t len, uint8_t *out_checksum)
 Read a LIN response: len data bytes plus one checksum byte.
uint8_t ra8_sci_lin_pid (uint8_t id)
 Compute the LIN protected identifier (PID) from a frame id.
ra8_err_t ra8_sci_lin_checksum (ra8_sci_lin_checksum_mode_t mode, uint8_t pid, const uint8_t *data, uint8_t len, uint8_t *out_checksum)
 Compute a classic or enhanced LIN checksum over a data field.
ra8_err_t ra8_sci_lin_check_header (uint8_t sync, uint8_t pid, uint8_t *out_id, bool *out_valid)
 Validate a received LIN header: SYNC byte + protected identifier.
ra8_err_t ra8_sci_lin_check_response (ra8_sci_lin_checksum_mode_t mode, uint8_t pid, const uint8_t *data, uint8_t len, uint8_t received, bool *out_valid)
 Verify a received LIN response checksum against the data field.

Variables

static const char * s_tag = "LIN"

Detailed Description

LIN commander + responder driver implementation on SCI_B.

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

Implements the LIN API declared in ra8_sci_lin.h on top of the SCI_B Simple-LIN sub-mode (HUM Ch 38.11 "Simple LIN Mode", p 2338). Break-field generation (commander) uses the dedicated break-field timer (XCR0.TCSS clock, XCR0.BFE, XCR2.BFLW length, XCR1.TCST start trigger); break-field detection (responder) uses Start-Frame detection (XCR1.SDST) plus bit-rate measurement (XCR1.BMEN) and polls XSR0.BFDF, clearing the LIN latches through XFCLR. The SYNC byte, protected identifier, and response data are sent / received as ordinary UART frames through ra8_sci_putc_polling / ra8_sci_getc_polling.

The base async-UART bring-up (MSTP gate, baud, framing) is delegated to ra8_sci_init so this file owns only the LIN-specific register sequence and the pure PID / checksum / header-validation math. It deliberately keeps the driver small – it does not touch the per-channel async TX/RX dispatch state owned by ra8_sci.c.

Inclusive-terminology note
The LIN commander is the bus controller; responders are the subordinate nodes. The legacy LIN node words are avoided in favour of Commander / Responder.

Definition in file ra8_sci_lin.c.

Enumeration Type Documentation

◆ ra8_sci_lin_const_t

enum ra8_sci_lin_const_t : uint8_t

Byte-level masks and protocol constants for the LIN math.

Enumerator
k_ra8_sci_lin_id_mask 

6-bit LIN frame-id mask.

k_ra8_sci_lin_bit_mask 

Single-bit extract / invert.

k_ra8_sci_lin_sync_byte 

LIN SYNC field byte (0x55).

k_ra8_sci_lin_fold_passes 

Carry-fold passes for checksum.

k_ra8_sci_lin_data_max 

Max LIN response data bytes.

Definition at line 76 of file ra8_sci_lin.c.

◆ ra8_sci_lin_fold_const_t

enum ra8_sci_lin_fold_const_t : uint16_t

16-bit masks used while folding the LIN checksum carry.

Enumerator
k_ra8_sci_lin_byte_mask 

Low-byte mask.

k_ra8_sci_lin_byte_bits 

Bits per byte (carry shift).

Definition at line 88 of file ra8_sci_lin.c.

◆ ra8_sci_lin_pid_shift_t

enum ra8_sci_lin_pid_shift_t : uint8_t

Bit positions used when packing / unpacking a LIN PID.

The frame id occupies bits 0..5; the two parity bits land in bits 6 (P0) and 7 (P1). HUM is not the source here – these are LIN protocol bit positions, not register fields.

Enumerator
k_ra8_sci_lin_id_bit0 

Frame-id bit 0 position.

k_ra8_sci_lin_id_bit1 

Frame-id bit 1 position.

k_ra8_sci_lin_id_bit2 

Frame-id bit 2 position.

k_ra8_sci_lin_id_bit3 

Frame-id bit 3 position.

k_ra8_sci_lin_id_bit4 

Frame-id bit 4 position.

k_ra8_sci_lin_id_bit5 

Frame-id bit 5 position.

k_ra8_sci_lin_pid_p0_shift 

PID parity bit P0 position.

k_ra8_sci_lin_pid_p1_shift 

PID parity bit P1 position.

Definition at line 61 of file ra8_sci_lin.c.

Function Documentation

◆ internal_lin_fold_complement()

uint8_t internal_lin_fold_complement ( uint16_t sum)
static

Fold a LIN checksum accumulator and return its one's complement.

Folds the carry bits back into the low byte to form the modulo-255 sum, then returns its inversion. Two folds cover the worst case (a PID plus up to 8 data bytes sums to less than 0x900, so one residual carry remains after the first fold).

Parameters
[in]sumRunning byte sum (PID optionally pre-added).
Returns
The inverted modulo-255 sum (the LIN checksum byte).
Return values
0x00..0xFFOne's complement of the folded modulo-255 sum.
Precondition
sum is the unfolded accumulator of a LIN frame.
The frame had at most 8 data bytes (standard LIN).
Postcondition
The result is the one's complement of the modulo-255 sum.
No state outside the function is modified.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 219 of file ra8_sci_lin.c.

References k_ra8_sci_lin_byte_bits, k_ra8_sci_lin_byte_mask, k_ra8_sci_lin_fold_passes, and RA8_INTERNAL.

Referenced by ra8_sci_lin_checksum().

◆ internal_lin_program_mode()

void internal_lin_program_mode ( volatile r_sci_regs_t * reg,
ra8_sci_lin_role_t role,
uint32_t tcss,
uint16_t break_len )
static

Program the SCI_B mode + break-field timer/detector for a LIN role.

Runs after ra8_sci_init has set up baud / framing. Drops CCR0 to take the transmitter offline, switches CCR3.MOD to Simple LIN while preserving the framing bits, programs the break-field timer clock and length, sets the role-specific XCR1 (commander: idle; responder: SDST + BMEN), and re-enables TE + RE. Called once during init under an IRQ-masked or single-threaded context, so no register guard is needed.

Parameters
[in,out]regChannel register bank, non-NULL.
[in]roleCommander (generate) or responder (detect).
[in]tcssXCR0.TCSS timer-clock encoding (1..3).
[in]break_lenXCR2.BFLW break-field length value.
Precondition
reg is the canonical bank pointer for the active channel.
ra8_sci_init has already programmed CCR1..CCR4.
Postcondition
CCR3.MOD == Simple LIN; XCR0/XCR2 hold the break-field config.
XCR1 reflects role; CCR0.TE and CCR0.RE are set.
Note
Not thread-safe.
Since
0.1.0

Definition at line 122 of file ra8_sci_lin.c.

References r_sci_regs_t::CCR0, r_sci_regs_t::CCR3, k_ra8_sci_ccr0_bit_re, k_ra8_sci_ccr0_bit_te, k_ra8_sci_ccr3_mask_mod, k_ra8_sci_ccr3_mod_simple_lin, k_ra8_sci_ccr3_shift_mod, k_ra8_sci_lin_role_responder, k_ra8_sci_xcr0_bit_bfe, k_ra8_sci_xcr0_shift_tcss, k_ra8_sci_xcr1_bit_bmen, k_ra8_sci_xcr1_bit_sdst, k_ra8_sci_xcr2_shift_bflw, RA8_INTERNAL, r_sci_regs_t::XCR0, r_sci_regs_t::XCR1, and r_sci_regs_t::XCR2.

Referenced by ra8_sci_lin_init().

◆ internal_lin_rx_buf()

ra8_err_t internal_lin_rx_buf ( uint8_t channel,
uint8_t * buf,
uint8_t len )
static

Poll-receive len bytes of a LIN response data field.

Drains len bytes from RDR into buf[0..len-1] through ra8_sci_getc_polling, returning the first error if any byte's RDRF poll times out. Factored out of ra8_sci_lin_read_response to keep that public function within the NASA Rule 4 length budget.

Parameters
[in]channelSCI channel number (0..9).
[out]bufNon-NULL destination for len bytes.
[in]lenNumber of bytes to read (1..8, validated by caller).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll len bytes drained.
k_ra8_err_null_ptrbuf was NULL.
k_ra8_err_hw_timeoutAn RDRF poll timed out mid-frame.
Precondition
buf is non-NULL.
The caller already validated channel and len.
Postcondition
On success buf[0..len-1] hold the received bytes.
No control register is modified.
Note
Not thread-safe.
Since
0.1.0

Definition at line 291 of file ra8_sci_lin.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_RETURN_ON_ERROR, ra8_sci_getc_polling(), and s_tag.

Referenced by ra8_sci_lin_read_response().

◆ internal_lin_tx_buf()

ra8_err_t internal_lin_tx_buf ( uint8_t channel,
const uint8_t * data,
uint8_t len )
static

Poll-transmit len bytes of a LIN response data field.

Clocks data[0..len-1] out through ra8_sci_putc_polling, returning the first error if any byte's TDRE poll times out. Factored out of ra8_sci_lin_send_response to keep that public function within the NASA Rule 4 length budget.

Parameters
[in]channelSCI channel number (0..9).
[in]dataNon-NULL data-field byte buffer.
[in]lenNumber of bytes to send (1..8, validated by caller).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll len bytes clocked out.
k_ra8_err_null_ptrdata was NULL.
k_ra8_err_hw_timeoutA TDRE poll timed out mid-frame.
Precondition
data is non-NULL.
The caller already validated channel and len.
Postcondition
On success every data byte has reached TDR.
No control register is modified.
Note
Not thread-safe.
Since
0.1.0

Definition at line 255 of file ra8_sci_lin.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_RETURN_ON_ERROR, ra8_sci_putc_polling(), and s_tag.

Referenced by ra8_sci_lin_send_response().

◆ internal_lin_wait_break_done()

ra8_err_t internal_lin_wait_break_done ( volatile const r_sci_regs_t * reg)
static

Spin until the break-field timer (XCR1.TCST) self-clears.

On the target, TCST holds 1 while the break field is on the wire and self-clears when the BFLW-programmed dominant time completes. On the host (RA8_OFF_TARGET) the timer drain is not modelled, so the routine short-circuits to success.

Parameters
[in]regChannel register bank, non-NULL.
Returns
ra8_err_t error code.
Return values
k_ra8_okTCST observed clear (or fake stub).
k_ra8_err_hw_timeoutTCST did not clear within the budget.
Precondition
reg is non-NULL.
A break field was just started via XCR1.TCST.
Postcondition
On success, the break-field timer is idle.
No data register is touched.
Note
Not thread-safe.
Since
0.1.0

Definition at line 187 of file ra8_sci_lin.c.

References k_ra8_hw_budget_long, k_ra8_sci_xcr1_bit_tcst, ra8_hw_wait_flag_clear32(), RA8_INTERNAL, and r_sci_regs_t::XCR1.

Referenced by ra8_sci_lin_send_break().

◆ ra8_sci_lin_break_detected()

ra8_err_t ra8_sci_lin_break_detected ( uint8_t channel,
bool * out_detected )
nodiscard

Report whether the responder's break-field detector has fired.

Reads XSR0.BFDF once (non-blocking) and writes its state to *out_detected. On a responder channel the Simple-LIN Start-Frame detector sets BFDF when it sees a dominant span at least as long as the configured break-field length; the flag stays set until cleared through ra8_sci_lin_clear_status. Reads no data and modifies no hardware.

Parameters
[in]channelSCI channel number (0..9).
[out]out_detectedReceives true if XSR0.BFDF is set, else false.
Returns
ra8_err_t error code.
Return values
k_ra8_okFlag state written to *out_detected.
k_ra8_err_null_ptrout_detected is NULL or channel out of range.
Precondition
out_detected is non-NULL.
Channel previously configured as a responder via ra8_sci_lin_init.
Postcondition
*out_detected reflects the current XSR0.BFDF bit.
No hardware register is modified.
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_wait_break
Since
0.1.0

Definition at line 367 of file ra8_sci_lin.c.

References k_ra8_ok, k_ra8_sci_xsr0_bit_bfdf, RA8_CHECK_NULL_PTR, ra8_sci(), s_tag, and r_sci_regs_t::XSR0.

◆ ra8_sci_lin_check_header()

ra8_err_t ra8_sci_lin_check_header ( uint8_t sync,
uint8_t pid,
uint8_t * out_id,
bool * out_valid )
nodiscard

Validate a received LIN header: SYNC byte + protected identifier.

A responder accepts a header only when BOTH the SYNC field equals 0x55 AND the received PID's parity bits match the parity recomputed from its low 6 bits. This pure predicate performs exactly that compound check, writing the extracted 6-bit frame id to *out_id and the accept decision to *out_valid. Pure: touches no hardware register.

Parameters
[in]syncThe received SYNC field byte (must be 0x55).
[in]pidThe received protected-identifier byte.
[out]out_idReceives the low 6 bits of pid (the frame id).
[out]out_validReceives true iff SYNC == 0x55 and PID parity is OK.
Returns
ra8_err_t error code.
Return values
k_ra8_okDecision written to *out_valid / *out_id.
k_ra8_err_null_ptrout_id or out_valid is NULL.
Precondition
out_id is non-NULL.
out_valid is non-NULL.
Postcondition
*out_id == pid & 0x3F.
*out_valid is true only for a well-formed SYNC + PID pair.
Note
Thread safety: pure function; safe to call concurrently.
See also
ra8_sci_lin_pid
Since
0.1.0

Definition at line 494 of file ra8_sci_lin.c.

References k_ra8_ok, k_ra8_sci_lin_id_mask, k_ra8_sci_lin_sync_byte, RA8_CHECK_NULL_PTR, ra8_sci_lin_pid(), and s_tag.

◆ ra8_sci_lin_check_response()

ra8_err_t ra8_sci_lin_check_response ( ra8_sci_lin_checksum_mode_t mode,
uint8_t pid,
const uint8_t * data,
uint8_t len,
uint8_t received,
bool * out_valid )
nodiscard

Verify a received LIN response checksum against the data field.

Recomputes the classic or enhanced checksum over data (and pid for the enhanced mode) with ra8_sci_lin_checksum and compares it to the received checksum byte, writing the match result to *out_valid. Pure: touches no hardware register. Pair with ra8_sci_lin_read_response to validate an inbound response.

Parameters
[in]modeClassic (data only) or enhanced (PID + data).
[in]pidProtected identifier, folded in for enhanced mode.
[in]dataData-field byte buffer; non-NULL when len > 0.
[in]lenNumber of data bytes (0..8).
[in]receivedThe checksum byte received on the wire.
[out]out_validReceives true iff the recomputed checksum matches.
Returns
ra8_err_t error code.
Return values
k_ra8_okDecision written to *out_valid.
k_ra8_err_null_ptrout_valid is NULL, or data NULL with len > 0.
k_ra8_err_invalid_argmode is not a defined checksum mode.
Precondition
out_valid is non-NULL.
data is non-NULL whenever len > 0.
Postcondition
*out_valid is true only when the checksum recomputes exactly.
No input buffer is modified.
Note
Thread safety: pure function; safe to call concurrently.
See also
ra8_sci_lin_read_response
ra8_sci_lin_checksum
Since
0.1.0

Definition at line 509 of file ra8_sci_lin.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, ra8_sci_lin_checksum(), and s_tag.

◆ ra8_sci_lin_checksum()

ra8_err_t ra8_sci_lin_checksum ( ra8_sci_lin_checksum_mode_t mode,
uint8_t pid,
const uint8_t * data,
uint8_t len,
uint8_t * out_checksum )
nodiscard

Compute a classic or enhanced LIN checksum over a data field.

Sums the data bytes (and, for k_ra8_sci_lin_checksum_enhanced, the protected identifier pid) into an accumulator, folds the carry bits back into the low byte to form the modulo-255 sum, and returns the one's complement of that sum. Pure: touches no hardware register.

Parameters
[in]modeClassic (data only) or enhanced (PID + data).
[in]pidProtected identifier, folded in only when mode == k_ra8_sci_lin_checksum_enhanced.
[in]dataData-field byte buffer; may be NULL only when len == 0.
[in]lenNumber of data bytes (0..8 for standard LIN).
[out]out_checksumReceives the 8-bit checksum on success.
Returns
ra8_err_t error code.
Return values
k_ra8_okChecksum computed.
k_ra8_err_null_ptrout_checksum is NULL, or data is NULL while len > 0.
k_ra8_err_invalid_argmode is not a defined checksum mode.
Precondition
out_checksum is non-NULL.
data is non-NULL whenever len > 0.
Postcondition
On success, *out_checksum holds the inverted modulo-255 sum.
No input buffer is modified.
Note
Thread safety: pure function; safe to call concurrently.
See also
ra8_sci_lin_pid
Since
0.1.0

Definition at line 465 of file ra8_sci_lin.c.

References internal_lin_fold_complement(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, k_ra8_sci_lin_checksum_enhanced, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ra8_sci_lin_check_response(), and ra8_sci_lin_send_response().

◆ ra8_sci_lin_clear_status()

ra8_err_t ra8_sci_lin_clear_status ( uint8_t channel)
nodiscard

Clear the Simple-LIN status latches (XSR0) via XFCLR.

Writes the clear-all-LIN mask to XFCLR, which clears every W1C XSR0 latch (BFDF, AEDF, COF, bus-conflict, and the control-field match flags). A responder calls this after consuming one frame's break / sync detection so the detector is armed clean for the next header.

Parameters
[in]channelSCI channel number (0..9).
Returns
ra8_err_t error code.
Return values
k_ra8_okLIN status latches cleared.
k_ra8_err_null_ptrchannel out of range.
Precondition
Channel previously configured via ra8_sci_lin_init.
IRQs masked or single-threaded context.
Postcondition
XSR0.BFDF and the other LIN latches read back clear.
No data register is touched.
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_wait_break
Since
0.1.0

Definition at line 391 of file ra8_sci_lin.c.

References k_ra8_ok, k_ra8_sci_xfclr_default, RA8_CHECK_NULL_PTR, ra8_sci(), s_tag, and r_sci_regs_t::XFCLR.

◆ ra8_sci_lin_init()

ra8_err_t ra8_sci_lin_init ( uint8_t channel,
const ra8_sci_lin_cfg_t * cfg )
nodiscard

Configure an SCI_B channel for a LIN role (commander or responder).

First brings the channel up as an async UART (ra8_sci_init with cfg->uart: MSTP gate, baud, framing, TE/RE). It then drops CCR0, switches CCR3.MOD to Simple LIN (110b) while preserving the framing bits the base init programmed, programs the break-field timer clock (XCR0.TCSS) and break-field enable (XCR0.BFE), sets the break-field length (XCR2.BFLW), and re-enables CCR0.TE + CCR0.RE. The XCR1 program depends on cfg->role: a commander leaves XCR1 idle (TCST is pulsed per frame by ra8_sci_lin_send_break); a responder sets XCR1.SDST (Start-Frame detection) and XCR1.BMEN (bit-rate measurement) so the hardware flags an inbound break in XSR0.BFDF (HUM Ch 38.11.2 p 2341).

Parameters
[in]channelSCI channel number (0..9).
[in]cfgNon-NULL LIN configuration descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okChannel configured for the requested role.
k_ra8_err_null_ptrcfg was NULL or channel out of range.
k_ra8_err_invalid_argrole undefined, timer_clk not a defined divider, or break_field_len exceeds 0xFFFE.
k_ra8_err_hw_init_failedThe underlying ra8_sci_init failed.
Precondition
IRQs masked or single-threaded init context.
ra8_mstp_init has been called.
Postcondition
On success, CCR3.MOD == Simple LIN and the break-field timer is programmed from cfg.
On success, CCR0.TE and CCR0.RE are set, and XCR1 reflects the role.
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_send_header
ra8_sci_lin_wait_break
Since
0.1.0

Definition at line 306 of file ra8_sci_lin.c.

References ra8_sci_lin_cfg_t::break_field_len, internal_lin_program_mode(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_sci_lin_clk_div4, k_ra8_sci_lin_clk_div64, k_ra8_sci_lin_role_responder, k_ra8_sci_xcr2_bflw_max, RA8_CHECK_NULL_PTR, ra8_log_info_val, RA8_RETURN_ON_ERROR, ra8_sci(), ra8_sci_init(), ra8_sci_lin_cfg_t::role, s_tag, ra8_sci_lin_cfg_t::timer_clk, and ra8_sci_lin_cfg_t::uart.

Referenced by lin_hil_setup_or_halt().

◆ ra8_sci_lin_pid()

uint8_t ra8_sci_lin_pid ( uint8_t id)
nodiscard

Compute the LIN protected identifier (PID) from a frame id.

The PID packs the 6-bit frame id in bits 0..5 plus two parity bits: P0 = ID0 ^ ID1 ^ ID2 ^ ID4 in bit 6, and P1 = NOT(ID1 ^ ID3 ^ ID4 ^ ID5) in bit 7 (LIN 2.x parity). Any caller bits above bit 5 are masked off before the parity is computed, so the function is total. Pure: touches no hardware register.

Parameters
[in]idLIN frame identifier; only the low 6 bits are significant.
Returns
The 8-bit protected identifier.
Precondition
id is a LIN frame identifier (low 6 bits significant).
No hardware preconditions (pure function).
Postcondition
The low 6 bits of the result equal id & 0x3F.
Bits 6 and 7 hold the computed parity bits P0 and P1.
Note
Thread safety: pure function; safe to call concurrently.
See also
ra8_sci_lin_send_header
Since
0.1.0

Definition at line 446 of file ra8_sci_lin.c.

References k_ra8_sci_lin_bit_mask, k_ra8_sci_lin_id_bit0, k_ra8_sci_lin_id_bit1, k_ra8_sci_lin_id_bit2, k_ra8_sci_lin_id_bit3, k_ra8_sci_lin_id_bit4, k_ra8_sci_lin_id_bit5, k_ra8_sci_lin_id_mask, k_ra8_sci_lin_pid_p0_shift, and k_ra8_sci_lin_pid_p1_shift.

Referenced by lin_hil_send_frame(), ra8_sci_lin_check_header(), and ra8_sci_lin_send_header().

◆ ra8_sci_lin_read_response()

ra8_err_t ra8_sci_lin_read_response ( uint8_t channel,
uint8_t * out_data,
uint8_t len,
uint8_t * out_checksum )
nodiscard

Read a LIN response: len data bytes plus one checksum byte.

Drains len data bytes into out_data and the trailing checksum byte into *out_checksum, each via ra8_sci_putc_polling's receive peer ra8_sci_getc_polling. This is a thin I/O primitive: it does NOT validate the checksum – the caller passes out_data / *out_checksum to ra8_sci_lin_check_response to verify. Used by the receiving node of a frame (the subscriber).

Parameters
[in]channelSCI channel number (0..9).
[out]out_dataBuffer receiving len data bytes.
[in]lenNumber of data bytes to read (1..8).
[out]out_checksumReceives the trailing checksum byte.
Returns
ra8_err_t error code.
Return values
k_ra8_oklen data bytes + checksum read.
k_ra8_err_null_ptrchannel out of range, or out_data / out_checksum is NULL.
k_ra8_err_invalid_arglen is 0 or > 8.
k_ra8_err_hw_timeoutAn RDRF poll timed out mid-frame.
Precondition
Channel previously configured via ra8_sci_lin_init.
out_data holds at least len bytes; out_checksum non-NULL.
Postcondition
On success, out_data[0..len-1] and *out_checksum are filled.
No hardware control register is modified.
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_check_response
Since
0.1.0

Definition at line 428 of file ra8_sci_lin.c.

References internal_lin_rx_buf(), k_ra8_err_invalid_arg, k_ra8_sci_lin_data_max, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, ra8_sci(), ra8_sci_getc_polling(), and s_tag.

◆ ra8_sci_lin_send_break()

ra8_err_t ra8_sci_lin_send_break ( uint8_t channel)
nodiscard

Emit a LIN break field on the channel's TXD line.

Writes 1 to XCR1.TCST, which starts the hardware break-field timer; the SCI_B holds TXD dominant for the (BFLW + 1) x timer-clock period set at init and self-clears TCST when the field completes. The call then blocks (bounded spin) until TCST reads back clear. On the host (RA8_OFF_TARGET) the timer drain is not modelled, so the wait returns success immediately.

Parameters
[in]channelSCI channel number (0..9).
Returns
ra8_err_t error code.
Return values
k_ra8_okBreak field emitted (or fake stub).
k_ra8_err_null_ptrchannel out of range.
k_ra8_err_hw_timeoutTCST did not self-clear within the budget.
Precondition
Channel previously configured via ra8_sci_lin_init.
IRQs masked or single-threaded transmit context.
Postcondition
On success, the break-field timer is idle (XCR1.TCST clear).
No data byte has been pushed to TDR by this call.
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_send_header
Since
0.1.0

Definition at line 332 of file ra8_sci_lin.c.

References internal_lin_wait_break_done(), k_ra8_sci_xcr1_bit_tcst, RA8_CHECK_NULL_PTR, ra8_sci(), s_tag, and r_sci_regs_t::XCR1.

Referenced by ra8_sci_lin_send_header().

◆ ra8_sci_lin_send_header()

ra8_err_t ra8_sci_lin_send_header ( uint8_t channel,
uint8_t id )
nodiscard

Transmit a full LIN header: break + SYNC (0x55) + PID.

Emits the break field (ra8_sci_lin_send_break), then sends the SYNC byte 0x55 and the protected identifier as two ordinary UART frames via ra8_sci_putc_polling. The PID is computed from id with ra8_sci_lin_pid (6-bit id plus the two LIN parity bits).

Parameters
[in]channelSCI channel number (0..9).
[in]id6-bit LIN frame identifier (0..63).
Returns
ra8_err_t error code.
Return values
k_ra8_okHeader transmitted.
k_ra8_err_null_ptrchannel out of range.
k_ra8_err_invalid_argid exceeds 63.
k_ra8_err_hw_timeoutA TDRE poll or the break wait timed out.
Precondition
Channel previously configured via ra8_sci_lin_init.
id <= k_ra8_sci_lin_id_max.
Postcondition
On success, the break field, SYNC, and PID have been clocked out.
TDR holds the protected identifier (the final byte written).
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_pid
ra8_sci_lin_send_break
Since
0.1.0

Definition at line 344 of file ra8_sci_lin.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_sci_lin_id_max, k_ra8_sci_lin_sync_byte, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, ra8_sci(), ra8_sci_lin_pid(), ra8_sci_lin_send_break(), ra8_sci_putc_polling(), and s_tag.

Referenced by lin_hil_send_frame().

◆ ra8_sci_lin_send_response()

ra8_err_t ra8_sci_lin_send_response ( uint8_t channel,
ra8_sci_lin_checksum_mode_t mode,
uint8_t pid,
const uint8_t * data,
uint8_t len )
nodiscard

Publish a LIN response: data bytes followed by the checksum.

Computes the classic or enhanced checksum over data (folding pid in for the enhanced mode) via ra8_sci_lin_checksum, then clocks the len data bytes and the checksum byte out as ordinary UART frames with ra8_sci_putc_polling. Used by the transmitting node of a frame: the commander for a commander-to-responder frame, or a responder for a responder-to-commander frame. The caller must already have sent (as commander) or detected (as responder) the header.

Parameters
[in]channelSCI channel number (0..9).
[in]modeClassic (data only) or enhanced (PID + data) checksum.
[in]pidProtected identifier, folded into the enhanced sum.
[in]dataData-field byte buffer; non-NULL when len > 0.
[in]lenNumber of data bytes (1..8 for standard LIN).
Returns
ra8_err_t error code.
Return values
k_ra8_okData + checksum clocked out.
k_ra8_err_null_ptrchannel out of range, or data NULL with len > 0.
k_ra8_err_invalid_argmode undefined or len is 0 or > 8.
k_ra8_err_hw_timeoutA TDRE poll timed out mid-frame.
Precondition
Channel previously configured via ra8_sci_lin_init.
data is non-NULL and len is in 1..8.
Postcondition
On success, the data bytes and the checksum byte have been sent.
TDR holds the checksum (the final byte written).
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_read_response
ra8_sci_lin_checksum
Since
0.1.0

Definition at line 401 of file ra8_sci_lin.c.

References internal_lin_tx_buf(), k_ra8_err_invalid_arg, k_ra8_sci_lin_data_max, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, ra8_sci(), ra8_sci_lin_checksum(), ra8_sci_putc_polling(), and s_tag.

Referenced by lin_hil_send_frame().

◆ ra8_sci_lin_wait_break()

ra8_err_t ra8_sci_lin_wait_break ( uint8_t channel)
nodiscard

Block until the responder detects a break field (XSR0.BFDF set).

Spins on XSR0.BFDF with a bounded budget; returns as soon as the break field is detected. On the host (RA8_OFF_TARGET) the poll runs against the programmable MMIO seam, so a test pre-stages BFDF or arms a timeout. Does not clear the flag – call ra8_sci_lin_clear_status before waiting for the next frame.

Parameters
[in]channelSCI channel number (0..9).
Returns
ra8_err_t error code.
Return values
k_ra8_okA break field was detected within the budget.
k_ra8_err_null_ptrchannel out of range.
k_ra8_err_hw_timeoutNo break field detected within the budget.
Precondition
Channel previously configured as a responder via ra8_sci_lin_init.
IRQs masked or single-threaded receive context.
Postcondition
On success, XSR0.BFDF was observed set (still latched).
No data register is touched.
Note
Thread safety: not thread-safe.
See also
ra8_sci_lin_break_detected
ra8_sci_lin_clear_status
Since
0.1.0

Definition at line 379 of file ra8_sci_lin.c.

References k_ra8_hw_budget_long, k_ra8_sci_xsr0_bit_bfdf, RA8_CHECK_NULL_PTR, ra8_hw_wait_flag_set32(), ra8_sci(), s_tag, and r_sci_regs_t::XSR0.

Variable Documentation

◆ s_tag

const char* s_tag = "LIN"
static

Definition at line 46 of file ra8_sci_lin.c.