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

SPI_B controller driver (polling + IRQ dispatch + DMA pipes). More...

#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_mstp.h"
#include "ra8_spi.h"
#include "ra8_spi_regs.h"
Include dependency graph for ra8_spi_b.c:

Go to the source code of this file.

Data Structures

struct  ra8_spi_state_t
 Per-channel dispatch state owned by this driver. More...

Enumerations

enum  ra8_spi_b_poll_t : uint32_t { k_ra8_spi_b_poll_limit = 200000U }
 Polling-loop budget. More...
enum  ra8_spi_b_default_t : uint32_t {
  k_ra8_spi_b_default_baud_hz = 1900000UL ,
  k_ra8_spi_b_default_pclka_hz = 125000000UL
}
 Default register values for the legacy ra8_spi_controller_init shim. More...
enum  ra8_spi_b_unit_bytes_t : uint8_t {
  k_ra8_spi_b_bytes_per_unit_8 = 1U ,
  k_ra8_spi_b_bytes_per_unit_16 = 2U ,
  k_ra8_spi_b_bytes_per_unit_32 = 4U
}
 Bytes-per-frame for each supported transfer width. More...
enum  ra8_spi_b_dummy_t : uint32_t {
  k_ra8_spi_b_dummy_tx_8 = 0x000000FFUL ,
  k_ra8_spi_b_dummy_tx_16 = 0x0000FFFFUL ,
  k_ra8_spi_b_dummy_tx_32 = 0xFFFFFFFFUL
}
 Dummy TX values written when ra8_spi_read has no caller payload. More...

Functions

static uint8_t internal_spbr (uint32_t baud_hz, uint32_t pclka_hz)
 Compute SPCR3.SPBR for a requested bit-rate.
static uint32_t internal_spcmd (const ra8_spi_cfg_t *cfg)
 Build SPCMD0 from a ra8_spi_cfg_t.
static uint32_t internal_spcr_controller (void)
 Build SPCR (control register 1) for controller polling mode.
static ra8_err_t internal_wait_spsr (volatile r_spi_regs_t *reg, uint32_t flag_mask)
 Wait for an SPSR flag to assert.
static void internal_spi_program_regs (volatile r_spi_regs_t *reg, const ra8_spi_cfg_t *cfg)
 Programme the polling-controller register set with SPE=0.
ra8_err_t ra8_spi_init (uint8_t channel, const ra8_spi_cfg_t *cfg)
 Initialise an SPI channel with a full config descriptor.
ra8_err_t ra8_spi_deinit (uint8_t channel)
 Tear down a channel.
ra8_err_t ra8_spi_controller_init (uint8_t channel)
 Legacy init (1.9 MHz at PCLKA = 125 MHz, mode 0).
ra8_err_t ra8_spi_xfer8 (uint8_t channel, uint8_t tx, uint8_t *rx)
 Full-duplex 8-bit exchange.
static ra8_err_t internal_unit_bytes (ra8_spi_bit_width_t bit_width, uint8_t *out_bytes)
 Map a public ra8_spi_bit_width_t to its bytes-per-unit.
static void internal_apply_bit_width (volatile r_spi_regs_t *reg, ra8_spi_bit_width_t bit_width)
 Programme SPCMD0.SPB to the requested bit-width.
static void internal_push_unit (volatile r_spi_regs_t *reg, const void *tx, uint32_t idx, ra8_spi_bit_width_t bit_width)
 Pull one TX unit out of tx (or use a dummy) and write SPDR.
static void internal_pop_unit (volatile const r_spi_regs_t *reg, void *rx, uint32_t idx, ra8_spi_bit_width_t bit_width)
 Read SPDR into rx at idx (or discard).
static ra8_err_t internal_xfer_common (uint8_t channel, const void *tx, void *rx, uint32_t len, ra8_spi_bit_width_t bit_width)
 Common engine for ra8_spi_write / ra8_spi_read / ra8_spi_write_read.
ra8_err_t ra8_spi_write (uint8_t channel, const void *tx, uint32_t len, ra8_spi_bit_width_t bit_width)
 Multi-frame TX-only polling transfer.
ra8_err_t ra8_spi_read (uint8_t channel, void *rx, uint32_t len, ra8_spi_bit_width_t bit_width)
 Multi-frame RX-only polling transfer.
ra8_err_t ra8_spi_write_read (uint8_t channel, const void *tx, void *rx, uint32_t len, ra8_spi_bit_width_t bit_width)
 Multi-frame full-duplex polling transfer.
ra8_err_t ra8_spi_set_clock (uint8_t channel, uint32_t baud_hz, uint32_t pclka_hz)
 Change the SPI clock without tearing down the channel.
ra8_err_t ra8_spi_get_errors (uint8_t channel, uint8_t *out_mask)
 Read the SPSR error bits (OVRF, MODERF, PERF, UDRF).
ra8_err_t ra8_spi_clear_errors (uint8_t channel)
 Clear the SPSR error flags.
ra8_err_t ra8_spi_attach_transfer_handler (uint8_t channel, ra8_spi_complete_fn_t fn, void *ctx)
 Attach a transfer-complete callback for a channel.
ra8_err_t ra8_spi_enter_stop (uint8_t channel)
 Put the channel into MSTP-gated stop state.
ra8_err_t ra8_spi_exit_stop (uint8_t channel)
 Exit MSTP-gated stop state.
void ra8_spi_dispatch_spti (uint8_t channel)
 Dispatch SPTI – advance TX state.
void ra8_spi_dispatch_spri (uint8_t channel)
 Dispatch SPRI – advance RX state.
void ra8_spi_dispatch_spei (uint8_t channel)
 Dispatch SPEI – collect + clear errors, fire callback.

Variables

static const char * s_tag = "SPI_B"
static const ra8_mstp_t s_spi_mstp_table [k_ra8_spi_b_channel_count]
 Channel-index -> MSTP id (HUM Ch 11.2.7 "MSTPCRB", p 444).
static ra8_spi_state_t s_spi_state [k_ra8_spi_b_channel_count]
 Per-channel state table indexed by channel.

Detailed Description

SPI_B controller driver (polling + IRQ dispatch + DMA pipes).

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

Implements the public ra8_spi API in ra8_spi.h against the RA8D2 SPI_B (Type-B SPI) peripheral. Mirrors the controller-mode polling flow from FSP r_spi_b.c (FSP R_SPI_B_Open / r_spi_b_hw_config / r_spi_b_start_transfer):

  • ra8_spi_init mirrors R_SPI_B_Open + r_spi_b_hw_config: enables MSTP, clears SPSR, programmes SPCR3 (SPBR), SPDECR (delays), SPCR2, SPCMD0 (CPHA/CPOL/SPB/LSBF), SPDCR, then asserts SPCR with MSTR + SPE.
  • ra8_spi_xfer8 is a single-frame full-duplex polled xfer that follows HUM Ch 43.3.13 controller-mode operation section (p 2911) and the FSP r_spi_b_transmit / r_spi_b_receive pair: wait for SPTEF, write SPDR, wait for SPRF, read SPDR, clear SPSR via SPSRC. Driver explicitly polls SPSR (HUM Ch 43.2.9 p 2898) and write-1-clears via SPSRC (HUM Ch 43.2.13 p 2905).
  • ra8_spi_set_clock rewrites SPCR3.SPBR (HUM Ch 43.2.6 p 2891).
  • ra8_spi_attach_transfer_handler registers a callback that fires from the SPEI dispatch path; SPI_B status flags are cleared via SPSRC (write-1).

The legacy 8-bit SPI block SPCR/SPPCR/SPBR/SSLND/SPND/SPCKD register set has been removed – those registers do not exist on RA8D2.

Definition in file ra8_spi_b.c.

Enumeration Type Documentation

◆ ra8_spi_b_default_t

enum ra8_spi_b_default_t : uint32_t

Default register values for the legacy ra8_spi_controller_init shim.

These are the pre-existing defaults retained so the legacy ra8_spi_controller_init API continues to work (mode 0, no LSB first, ~1.9 MHz at PCLKA = 125 MHz). FSP encodes the same concept in its default extended config.

Enumerator
k_ra8_spi_b_default_baud_hz 

RA8 SPI b default baud Hz.

k_ra8_spi_b_default_pclka_hz 

RA8 SPI b default pclka Hz.

Definition at line 82 of file ra8_spi_b.c.

◆ ra8_spi_b_dummy_t

enum ra8_spi_b_dummy_t : uint32_t

Dummy TX values written when ra8_spi_read has no caller payload.

Idle-line value matches the SD-card / SPI-flash convention of driving COPI high while only RX matters.

Enumerator
k_ra8_spi_b_dummy_tx_8 

8-bit dummy.

k_ra8_spi_b_dummy_tx_16 

16-bit dummy.

k_ra8_spi_b_dummy_tx_32 

32-bit dummy.

Definition at line 110 of file ra8_spi_b.c.

◆ ra8_spi_b_poll_t

enum ra8_spi_b_poll_t : uint32_t

Polling-loop budget.

Used to bound HW waits.

Enumerator
k_ra8_spi_b_poll_limit 

RA8 SPI b poll limit.

Definition at line 68 of file ra8_spi_b.c.

◆ ra8_spi_b_unit_bytes_t

enum ra8_spi_b_unit_bytes_t : uint8_t

Bytes-per-frame for each supported transfer width.

Eliminates magic numbers in the bit-width-aware load / store loops (CLAUDE.md "No Magic Numbers" rule). Each value is the number of caller-buffer bytes consumed (or produced) per shifted SPI frame.

Enumerator
k_ra8_spi_b_bytes_per_unit_8 

8-bit frame -> 1 byte.

k_ra8_spi_b_bytes_per_unit_16 

16-bit frame -> 2 bytes.

k_ra8_spi_b_bytes_per_unit_32 

32-bit frame -> 4 bytes.

Definition at line 96 of file ra8_spi_b.c.

Function Documentation

◆ internal_apply_bit_width()

void internal_apply_bit_width ( volatile r_spi_regs_t * reg,
ra8_spi_bit_width_t bit_width )
static

Programme SPCMD0.SPB to the requested bit-width.

Mirrors FSP r_spi_b_bit_width_config (lines 701-726). The SPB[20:16] field encodes N - 1 for an N-bit frame; the public ra8_spi_bit_width_t enum already carries the raw encoding so it can be shifted into place directly. The driver keeps SSL Level Keep cleared (single-segment polling transfers only); FSP's SSLKP burst handling is out of scope for this wave.

Parameters
[in]regSee implementation.
[in]bit_widthSee implementation.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 522 of file ra8_spi_b.c.

References k_ra8_spcmd_bit_spb_lo, k_ra8_spcmd_mask_spb, RA8_INTERNAL, and r_spi_regs_t::SPCMD.

Referenced by internal_xfer_common().

◆ internal_pop_unit()

void internal_pop_unit ( volatile const r_spi_regs_t * reg,
void * rx,
uint32_t idx,
ra8_spi_bit_width_t bit_width )
static

Read SPDR into rx at idx (or discard).

Mirrors FSP r_spi_b_receive (lines 939-972) – the FIFO front-end of SPDR returns the most-recently shifted-in unit, and the bit-width determines whether the caller buffer is a uint8_t, uint16_t, or uint32_t array.

Parameters
[in]regSee implementation.
[in]rxSee implementation.
[in]idxSee implementation.
[in]bit_widthSee implementation.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 598 of file ra8_spi_b.c.

References k_ra8_spi_width_16, k_ra8_spi_width_32, RA8_INTERNAL, and r_spi_regs_t::SPDR.

Referenced by internal_xfer_common().

◆ internal_push_unit()

void internal_push_unit ( volatile r_spi_regs_t * reg,
const void * tx,
uint32_t idx,
ra8_spi_bit_width_t bit_width )
static

Pull one TX unit out of tx (or use a dummy) and write SPDR.

Mirrors FSP r_spi_b_transmit (lines 981-1024) but the bit-width branch uses the public ra8_spi_bit_width_t value (already raw SPB encoding) compared against k_ra8_spi_width_*. When tx is NULL the driver writes a dummy (idle-high) value – this mirrors typical SPI-flash / SD-card RX-only conventions and differs from FSP only in the dummy magnitude (FSP writes 0).

Parameters
[in]regSee implementation.
[in]txSee implementation.
[in]idxSee implementation.
[in]bit_widthSee implementation.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 553 of file ra8_spi_b.c.

References k_ra8_spi_b_dummy_tx_16, k_ra8_spi_b_dummy_tx_32, k_ra8_spi_b_dummy_tx_8, k_ra8_spi_width_16, k_ra8_spi_width_32, RA8_INTERNAL, and r_spi_regs_t::SPDR.

Referenced by internal_xfer_common().

◆ internal_spbr()

uint8_t internal_spbr ( uint32_t baud_hz,
uint32_t pclka_hz )
static

Compute SPCR3.SPBR for a requested bit-rate.

SPI_B bit-rate equation (HUM Ch 43.2.6 p 2891 + FSP R_SPI_B_CalculateBitrate):

f_RSPCK = TCLK / (2 * (SPBR + 1) * 2^N)

where N = SPCMDn.BRDV. The bring-up driver leaves BRDV = 0 so the equation reduces to SPBR = (TCLK / (2 * baud)) - 1.

Parameters
[in]baud_hzDesired bit-rate in Hz.
[in]pclka_hzActive PCLKA frequency in Hz.
Returns
SPBR value, clamped to [0, 0xFF].
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 167 of file ra8_spi_b.c.

References k_ra8_spbr_max, and RA8_INTERNAL.

Referenced by internal_spi_program_regs(), and ra8_spi_set_clock().

◆ internal_spcmd()

uint32_t internal_spcmd ( const ra8_spi_cfg_t * cfg)
static

Build SPCMD0 from a ra8_spi_cfg_t.

Bit-mapping (HUM Ch 43.2.7 p 2893, FSP r_spi_b_hw_config):

  • CPHA (bit 0) from cfg->mode.
  • CPOL (bit 1) from cfg->mode.
  • LSBF (bit 12) from cfg->lsb_first.
  • SPB [20:16] set to 8-bit frame (k_ra8_spcmd_spb_8bit).
  • Delay enables (SPNDEN/SLNDEN/SCKDEN) are left clear; the bring-up driver does not gate delay registers.
Parameters
[in]cfgSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 206 of file ra8_spi_b.c.

References k_ra8_spcmd_bit_spb_lo, k_ra8_spcmd_mask_cpha, k_ra8_spcmd_mask_cpol, k_ra8_spcmd_mask_lsbf, k_ra8_spcmd_mask_spb, k_ra8_spcmd_spb_8bit, k_ra8_spi_mode_1, k_ra8_spi_mode_2, k_ra8_spi_mode_3, ra8_spi_cfg_t::lsb_first, ra8_spi_cfg_t::mode, and RA8_INTERNAL.

Referenced by internal_spi_program_regs().

◆ internal_spcr_controller()

uint32_t internal_spcr_controller ( void )
static

Build SPCR (control register 1) for controller polling mode.

Mirrors the controller-mode subset of FSP r_spi_b_hw_config (lines 525-670). Sets MSTR + SCKASE + SPE; leaves IRQ-enable bits (SPRIE/SPTIE/SPEIE/CENDIE) clear because the polling driver services SPSR directly.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 242 of file ra8_spi_b.c.

References k_ra8_spcr_mask_mstr, k_ra8_spcr_mask_sckase, k_ra8_spcr_mask_spe, and RA8_INTERNAL.

Referenced by ra8_spi_init().

◆ internal_spi_program_regs()

void internal_spi_program_regs ( volatile r_spi_regs_t * reg,
const ra8_spi_cfg_t * cfg )
static

Programme the polling-controller register set with SPE=0.

Writes SPCR3 / SPDECR / SPCR2 / SPCMD0 / SPDCR(2) / SPFCR in the order the HUM allows while SPE is still 0. SPCR2 carries the loopback knob (SPLP2 non-inverting); SPSR flags are cleared once before and once after SPFRST so the first ra8_spi_xfer8 sees a clean SPRF.

Parameters
[in]regChannel's register block.
[in]cfgCaller-supplied config (already null-checked).
Precondition
SPCR.SPE has been cleared.
MSTP is already enabled for the channel.
Postcondition
All control registers programmed; SPSR flags clear.
SPE is still 0 – caller writes SPCR with SPE=1.
Note
Not thread-safe; caller must serialize access to the channel.
Since
0.1.0

Definition at line 313 of file ra8_spi_b.c.

References ra8_spi_cfg_t::baud_hz, internal_spbr(), internal_spcmd(), k_ra8_spcr2_mask_splp2, k_ra8_spcr3_bit_spbr, k_ra8_spcr3_mask_spbr, k_ra8_spfcr_mask_spfrst, k_ra8_spsrc_mask_all, ra8_spi_cfg_t::loopback, ra8_spi_cfg_t::pclka_hz, RA8_INTERNAL, r_spi_regs_t::SPCMD, r_spi_regs_t::SPCR2, r_spi_regs_t::SPCR3, r_spi_regs_t::SPDCR, r_spi_regs_t::SPDCR2, r_spi_regs_t::SPDECR, r_spi_regs_t::SPFCR, and r_spi_regs_t::SPSRC.

Referenced by ra8_spi_init().

◆ internal_unit_bytes()

ra8_err_t internal_unit_bytes ( ra8_spi_bit_width_t bit_width,
uint8_t * out_bytes )
static

Map a public ra8_spi_bit_width_t to its bytes-per-unit.

Parameters
[in]bit_widthPublic width enum.
[out]out_bytesBytes per shifted frame (1, 2, or 4).
Return values
k_ra8_ok*out_bytes written.
k_ra8_err_invalid_argbit_width not one of the supported widths.

See implementation.

Returns
Result code.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 485 of file ra8_spi_b.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_spi_b_bytes_per_unit_16, k_ra8_spi_b_bytes_per_unit_32, k_ra8_spi_b_bytes_per_unit_8, k_ra8_spi_width_16, k_ra8_spi_width_32, k_ra8_spi_width_8, and RA8_INTERNAL.

Referenced by internal_xfer_common().

◆ internal_wait_spsr()

ra8_err_t internal_wait_spsr ( volatile r_spi_regs_t * reg,
uint32_t flag_mask )
static

Wait for an SPSR flag to assert.

Bounded polling loop (NASA P10 Rule 2). The SPI_B SPSR flags SPTEF (TX empty) and SPRF (RX full) are clear-on-write through SPSRC – callers are responsible for clearing after acting on them.

Delegates to ra8_hw_wait_flag_set32, whose loop is consulted by the host-test MMIO fault seam (ra8_fake_mmio_*): a test pre-staging SPSR = SPTEF|SPRF succeeds on the first poll (seam transparent), fail_wait drives the timeout leg, and satisfy_after(n) steps the loop's continuation branch for MC/DC. Both the success and timeout legs therefore run on host, unlike the deleted RA8_OFF_TARGET single-shot short-circuit (T1-01).

Parameters
[in]regSee implementation.
[in]flag_maskSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 279 of file ra8_spi_b.c.

References k_ra8_spi_b_poll_limit, ra8_hw_wait_flag_set32(), RA8_INTERNAL, and r_spi_regs_t::SPSR.

Referenced by internal_xfer_common(), and ra8_spi_xfer8().

◆ internal_xfer_common()

ra8_err_t internal_xfer_common ( uint8_t channel,
const void * tx,
void * rx,
uint32_t len,
ra8_spi_bit_width_t bit_width )
static

Common engine for ra8_spi_write / ra8_spi_read / ra8_spi_write_read.

Mirrors FSP r_spi_b_write_read_common (lines 795-930) with the polling transfer loop spelled out instead of dispatched through the SPTI/SPRI interrupts. The bound is the existing k_ra8_spi_b_poll_limit budget per SPSR wait, which already tracks the canonical k_ra8_timeout_default_ms budget at the NS-world tick rate the driver is wired against.

Per FSP, exactly one of tx or rx may be NULL but never both. Length 0 returns success without touching the bus.

NASA Power of 10 Compliance:
  • Rule 2: Outer loop bounded by len (caller-supplied); inner SPSR wait bounded by k_ra8_spi_b_poll_limit.
  • Rule 5: 4 preconditions, 2 postconditions.
Parameters
[in]channelSee implementation.
[in]txSee implementation.
[in]rxSee implementation.
[in]lenSee implementation.
[in]bit_widthSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 650 of file ra8_spi_b.c.

References internal_apply_bit_width(), internal_pop_unit(), internal_push_unit(), internal_unit_bytes(), internal_wait_spsr(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, k_ra8_spi_b_channel_count, k_ra8_spsr_mask_sprf, k_ra8_spsr_mask_sptef, k_ra8_spsrc_mask_sprfc, k_ra8_spsrc_mask_sptefc, RA8_INTERNAL, ra8_spi(), and r_spi_regs_t::SPSRC.

Referenced by ra8_spi_read(), ra8_spi_write(), and ra8_spi_write_read().

◆ ra8_spi_attach_transfer_handler()

ra8_err_t ra8_spi_attach_transfer_handler ( uint8_t channel,
ra8_spi_complete_fn_t fn,
void * ctx )
nodiscard

Attach a transfer-complete callback for a channel.

Parameters
[in]channelSPI channel.
[in]fnCallback fired on transfer end / error.
[in]ctxContext passed to the callback.
Returns
ra8_err_t error code.
Since
0.1.0

Definition at line 809 of file ra8_spi_b.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_spi_b_channel_count, and s_spi_state.

◆ ra8_spi_clear_errors()

ra8_err_t ra8_spi_clear_errors ( uint8_t channel)
nodiscard

Clear the SPSR error flags.

Parameters
[in]channelSPI channel.
Returns
ra8_err_t error code.
Since
0.1.0

Definition at line 794 of file ra8_spi_b.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_spi_b_channel_count, k_ra8_spsr_mask_errs, ra8_spi(), and r_spi_regs_t::SPSRC.

Referenced by ra8_spi_dispatch_spei().

◆ ra8_spi_controller_init()

ra8_err_t ra8_spi_controller_init ( uint8_t channel)
nodiscard

Legacy init (1.9 MHz at PCLKA = 125 MHz, mode 0).

Parameters
[in]channelSPI channel (0 or 1).
Returns
ra8_err_t error code.
Since
0.1.0

Definition at line 405 of file ra8_spi_b.c.

References k_ra8_err_null_ptr, k_ra8_spi_b_default_baud_hz, k_ra8_spi_b_default_pclka_hz, k_ra8_spi_mode_0, ra8_spi(), and ra8_spi_init().

◆ ra8_spi_deinit()

ra8_err_t ra8_spi_deinit ( uint8_t channel)
nodiscard

Tear down a channel.

Parameters
[in]channelSPI channel.
Returns
k_ra8_ok / k_ra8_err_invalid_arg.
Postcondition
SPE is cleared; MSTP reference released.
Since
0.1.0

Definition at line 382 of file ra8_spi_b.c.

References k_ra8_err_invalid_arg, k_ra8_spi_b_channel_count, ra8_mstp_disable(), ra8_spi(), s_spi_mstp_table, s_spi_state, and r_spi_regs_t::SPCR.

◆ ra8_spi_dispatch_spei()

void ra8_spi_dispatch_spei ( uint8_t channel)

Dispatch SPEI – collect + clear errors, fire callback.

Invoked from the SPEIn IRQ trampoline. Reads and clears the error status bits in SPSR (HUM Ch 36.2.5 "SPSR : SPI Status Register", p 1530) – mode-fault (MODF), overrun (OVRF), parity (PERF) – then invokes the registered error callback with the collected mask.

Parameters
[in]channelSPI channel index (0..1).
Precondition
ra8_spi_init(channel, ...) succeeded.
Called from ISR context (or unit-test driver).
Postcondition
All error bits in SPSR are cleared for channel.
Error callback invoked exactly once with the captured mask.
Note
Thread safety: ISR context only; not re-entrant per channel.
Since
0.1.0

Definition at line 871 of file ra8_spi_b.c.

References k_ra8_spi_b_channel_count, ra8_spi_clear_errors(), ra8_spi_get_errors(), and s_spi_state.

◆ ra8_spi_dispatch_spri()

void ra8_spi_dispatch_spri ( uint8_t channel)

Dispatch SPRI – advance RX state.

Invoked from the SPRIn IRQ trampoline when the receive FIFO/holding register has new data. Reads SPDR (HUM Ch 36.2.7, p 1532) into the caller-supplied RX buffer and, when the byte count reaches zero, invokes the registered completion callback.

Parameters
[in]channelSPI channel index (0..1).
Precondition
ra8_spi_init(channel, ...) succeeded.
Called from ISR context (or unit-test driver).
Postcondition
Either one RX word was consumed or the completion callback ran.
No state change if channel is out of range.
Note
Thread safety: ISR context only; not re-entrant per channel.
Since
0.1.0

Definition at line 862 of file ra8_spi_b.c.

References k_ra8_spi_b_channel_count, and s_spi_state.

◆ ra8_spi_dispatch_spti()

void ra8_spi_dispatch_spti ( uint8_t channel)

Dispatch SPTI – advance TX state.

Invoked from the SPTIn IRQ trampoline when the transmit FIFO/holding register is ready for the next word. Loads the next byte from the caller-supplied TX buffer into SPDR (HUM Ch 36.2.7 "SPDR : SPI Data Register", p 1532) and decrements the remaining count. Silently returns if the channel is out of range or no transfer is in progress.

Parameters
[in]channelSPI channel index (0..1).
Precondition
ra8_spi_init(channel, ...) succeeded.
Called from ISR context (or unit-test driver).
Postcondition
Either one TX word was written or the transfer is complete.
No state change if channel is out of range.
Note
Thread safety: ISR context only; not re-entrant per channel.
Since
0.1.0

Definition at line 853 of file ra8_spi_b.c.

References k_ra8_spi_b_channel_count, and s_spi_state.

◆ ra8_spi_enter_stop()

ra8_err_t ra8_spi_enter_stop ( uint8_t channel)
nodiscard

Put the channel into MSTP-gated stop state.

Since
0.1.0

Definition at line 824 of file ra8_spi_b.c.

References k_ra8_err_invalid_arg, k_ra8_spi_b_channel_count, ra8_mstp_disable(), ra8_spi(), s_spi_mstp_table, and r_spi_regs_t::SPCR.

◆ ra8_spi_exit_stop()

ra8_err_t ra8_spi_exit_stop ( uint8_t channel)
nodiscard

Exit MSTP-gated stop state.

Since
0.1.0

Definition at line 839 of file ra8_spi_b.c.

References k_ra8_err_invalid_arg, k_ra8_spi_b_channel_count, ra8_mstp_enable(), and s_spi_mstp_table.

◆ ra8_spi_get_errors()

ra8_err_t ra8_spi_get_errors ( uint8_t channel,
uint8_t * out_mask )
nodiscard

Read the SPSR error bits (OVRF, MODERF, PERF, UDRF).

Parameters
[in]channelSPI channel.
[out]out_maskOR of k_ra8_spi_err_*.
Returns
ra8_err_t error code.
Since
0.1.0

Definition at line 766 of file ra8_spi_b.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_spi_b_channel_count, k_ra8_spi_err_mode, k_ra8_spi_err_none, k_ra8_spi_err_overrun, k_ra8_spi_err_parity, k_ra8_spi_err_underrun, k_ra8_spsr_mask_modf, k_ra8_spsr_mask_ovrf, k_ra8_spsr_mask_perf, k_ra8_spsr_mask_udrf, RA8_CHECK_NULL_PTR, ra8_spi(), s_tag, and r_spi_regs_t::SPSR.

Referenced by ra8_spi_dispatch_spei().

◆ ra8_spi_init()

ra8_err_t ra8_spi_init ( uint8_t channel,
const ra8_spi_cfg_t * cfg )
nodiscard

Initialise an SPI channel with a full config descriptor.

Parameters
[in]channelSPI channel (0 or 1).
[in]cfgConfiguration descriptor.
Returns
ra8_err_t error code.
Precondition
IRQs masked or single-threaded init context.
ra8_mstp_init has been called.
Postcondition
On success, SPE is set and the channel is ready to xfer.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 348 of file ra8_spi_b.c.

References internal_spcr_controller(), internal_spi_program_regs(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_spi_b_channel_count, RA8_CHECK_NULL_PTR, ra8_log_info_val, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, ra8_spi(), s_spi_mstp_table, s_spi_state, s_tag, and r_spi_regs_t::SPCR.

Referenced by ep_bringup_panel_bus(), internal_setup_or_halt(), ra8_nsc_spi_init(), and ra8_spi_controller_init().

◆ ra8_spi_read()

ra8_err_t ra8_spi_read ( uint8_t channel,
void * rx,
uint32_t len,
ra8_spi_bit_width_t bit_width )
nodiscard

Multi-frame RX-only polling transfer.

Mirrors FSP R_SPI_B_Read (delegates to r_spi_b_write_read_common with p_src = NULL). For each of len units the driver writes a dummy 0xFF / 0xFFFF / 0xFFFFFFFF to SPDR (matching common SD-card / SPI-flash idle patterns) and then captures one unit into rx.

Parameters
[in]channelSPI channel (0 or 1).
[out]rxDestination buffer (len units of bit_width); non-NULL.
[in]lenNumber of units to receive; 0 is a no-op success.
[in]bit_widthPer-frame width: 8, 16, or 32 bits.
Returns
ra8_err_t error code.
Return values
k_ra8_okTransfer completed.
k_ra8_err_null_ptrrx is NULL with len > 0.
k_ra8_err_invalid_argChannel or bit_width invalid.
k_ra8_err_hw_timeoutPolling SPSR flag never asserted.
Precondition
Channel previously initialized via ra8_spi_init.
Caller-supplied buffer alignment matches bit_width.
Postcondition
On success, rx[0..len-1] contains the bytes / words shifted in on CIPO during len dummy clock cycles.
Note
Thread safety: not thread-safe.
Since
0.1.0
See also
ra8_spi_write
ra8_spi_write_read

Definition at line 711 of file ra8_spi_b.c.

References internal_xfer_common(), and k_ra8_err_null_ptr.

Referenced by ra8_nsc_spi_read().

◆ ra8_spi_set_clock()

ra8_err_t ra8_spi_set_clock ( uint8_t channel,
uint32_t baud_hz,
uint32_t pclka_hz )
nodiscard

Change the SPI clock without tearing down the channel.

Parameters
[in]channelSPI channel.
[in]baud_hzTarget bit-rate in Hz.
[in]pclka_hzCurrent PCLKA frequency.
Returns
ra8_err_t error code.
Since
0.1.0

Definition at line 741 of file ra8_spi_b.c.

References internal_spbr(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_spcr3_bit_spbr, k_ra8_spcr3_mask_spbr, k_ra8_spi_b_channel_count, ra8_spi(), and r_spi_regs_t::SPCR3.

Referenced by internal_spi_b_set_clock().

◆ ra8_spi_write()

ra8_err_t ra8_spi_write ( uint8_t channel,
const void * tx,
uint32_t len,
ra8_spi_bit_width_t bit_width )
nodiscard

Multi-frame TX-only polling transfer.

Mirrors FSP R_SPI_B_Write (delegates to r_spi_b_write_read_common with p_dest = NULL). For each of len units the driver:

  1. Waits for SPSR.SPTEF (TX buffer empty).
  2. Writes one unit (1, 2, or 4 bytes from tx) to SPDR.
  3. Waits for SPSR.SPRF (RX buffer full).
  4. Reads SPDR and discards the result.

Polling is bounded so the driver cannot spin forever on a stuck bus (NASA P10 Rule 2). Default timeout budget tracks k_ra8_timeout_default_ms.

Parameters
[in]channelSPI channel (0 or 1).
[in]txSource buffer (len units of bit_width); must be non-NULL.
[in]lenNumber of units to transfer; 0 is a no-op success.
[in]bit_widthPer-frame width: 8, 16, or 32 bits.
Returns
ra8_err_t error code.
Return values
k_ra8_okTransfer completed.
k_ra8_err_null_ptrtx is NULL with len > 0.
k_ra8_err_invalid_argChannel or bit_width invalid.
k_ra8_err_hw_timeoutSPSR.SPTEF / SPSR.SPRF never asserted.
Precondition
Channel previously initialized via ra8_spi_init.
Caller-supplied buffer alignment matches bit_width (16 / 32 bit access requires properly aligned pointers).
Postcondition
On success, every requested unit has shifted out on COPI and SPSR.SPRF / SPSR.SPTEF have been cleared via SPSRC.
Note
Thread safety: not thread-safe.
Since
0.1.0
See also
ra8_spi_read
ra8_spi_write_read

Definition at line 703 of file ra8_spi_b.c.

References internal_xfer_common(), and k_ra8_err_null_ptr.

Referenced by ra8_nsc_spi_write().

◆ ra8_spi_write_read()

ra8_err_t ra8_spi_write_read ( uint8_t channel,
const void * tx,
void * rx,
uint32_t len,
ra8_spi_bit_width_t bit_width )
nodiscard

Multi-frame full-duplex polling transfer.

Mirrors FSP R_SPI_B_WriteRead (delegates to r_spi_b_write_read_common with both buffers non-NULL). Per unit: wait SPTEF -> push tx[i] into SPDR -> wait SPRF -> read SPDR into rx[i]. tx and rx may be the same buffer (in-place exchange).

Parameters
[in]channelSPI channel (0 or 1).
[in]txSource buffer (len units of bit_width); non-NULL.
[out]rxDestination buffer (len units of bit_width); non-NULL.
[in]lenNumber of units to exchange; 0 is a no-op success.
[in]bit_widthPer-frame width: 8, 16, or 32 bits.
Returns
ra8_err_t error code.
Return values
k_ra8_okTransfer completed.
k_ra8_err_null_ptrtx or rx is NULL with len > 0.
k_ra8_err_invalid_argChannel or bit_width invalid.
k_ra8_err_hw_timeoutPolling SPSR flag never asserted.
Precondition
Channel previously initialized via ra8_spi_init.
Postcondition
On success, every unit has been exchanged in both directions.
Note
Thread safety: not thread-safe.
Since
0.1.0
See also
ra8_spi_write
ra8_spi_read

Definition at line 719 of file ra8_spi_b.c.

References internal_xfer_common(), and k_ra8_err_null_ptr.

Referenced by internal_spi_b_write_read(), and ra8_nsc_spi_write_read().

◆ ra8_spi_xfer8()

ra8_err_t ra8_spi_xfer8 ( uint8_t channel,
uint8_t tx,
uint8_t * rx )
nodiscard

Full-duplex 8-bit exchange.

Parameters
[in]channelSPI channel (0 or 1).
[in]txByte to transmit.
[out]rxPointer to receive the shifted-in byte (may be NULL).
Returns
ra8_err_t error code.
Since
0.1.0

Definition at line 421 of file ra8_spi_b.c.

References internal_wait_spsr(), k_ra8_ok, k_ra8_spsr_mask_sprf, k_ra8_spsr_mask_sptef, k_ra8_spsrc_mask_sprfc, k_ra8_spsrc_mask_sptefc, RA8_CHECK_NULL_PTR, ra8_spi(), s_tag, r_spi_regs_t::SPDR, and r_spi_regs_t::SPSRC.

Referenced by internal_round_trip_ok(), internal_spi_b_xfer8(), and ra8_nsc_spi_xfer8().

Variable Documentation

◆ s_spi_mstp_table

const ra8_mstp_t s_spi_mstp_table[k_ra8_spi_b_channel_count]
static
Initial value:
= {
}
@ k_ra8_mstp_spi0
MSTPB19 SPI0.
@ k_ra8_mstp_spi1
MSTPB18 SPI1.

Channel-index -> MSTP id (HUM Ch 11.2.7 "MSTPCRB", p 444).

Definition at line 59 of file ra8_spi_b.c.

Referenced by ra8_spi_b_target_init(), ra8_spi_deinit(), ra8_spi_enter_stop(), ra8_spi_exit_stop(), and ra8_spi_init().

◆ s_spi_state

Per-channel state table indexed by channel.

Definition at line 135 of file ra8_spi_b.c.

Referenced by ra8_spi_attach_transfer_handler(), ra8_spi_deinit(), ra8_spi_dispatch_spei(), ra8_spi_dispatch_spri(), ra8_spi_dispatch_spti(), and ra8_spi_init().

◆ s_tag

const char* s_tag = "SPI_B"
static

Definition at line 48 of file ra8_spi_b.c.