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

SPI_B controller driver (RA8D2 Type-B SPI peripheral). More...

#include <stdint.h>
#include "ra8_dma.h"
#include "ra8_err.h"
Include dependency graph for ra8_spi.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_spi_cfg_t
 Configuration descriptor for ra8_spi_init. More...

Typedefs

typedef void(* ra8_spi_complete_fn_t) (void *ctx, uint8_t err_mask)
 Transfer-complete callback signature.

Enumerations

enum  ra8_spi_mode_t : uint8_t {
  k_ra8_spi_mode_0 = 0U ,
  k_ra8_spi_mode_1 = 1U ,
  k_ra8_spi_mode_2 = 2U ,
  k_ra8_spi_mode_3 = 3U
}
 CPOL / CPHA combinations. More...
enum  ra8_spi_bit_width_t : uint8_t {
  k_ra8_spi_width_8 = 7U ,
  k_ra8_spi_width_16 = 15U ,
  k_ra8_spi_width_32 = 31U
}
 Per-frame bit width for multi-byte transfers. More...
enum  ra8_spi_err_mask_t : uint8_t {
  k_ra8_spi_err_none = 0x00U ,
  k_ra8_spi_err_overrun = 0x01U ,
  k_ra8_spi_err_mode = 0x02U ,
  k_ra8_spi_err_parity = 0x04U ,
  k_ra8_spi_err_underrun = 0x08U
}
 Bit mask of SPI error flags. More...

Functions

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.
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.
ra8_err_t ra8_spi_b_target_init (uint8_t channel, const ra8_spi_cfg_t *cfg)
 Initialise an SPI_B channel in target (peripheral) mode.
ra8_err_t ra8_spi_b_target_xfer (uint8_t channel, uint8_t tx, uint8_t *rx)
 Exchange one byte as the SPI target in a polled blocking call.
ra8_err_t ra8_spi_write_dma (uint8_t channel, const uint8_t *data, uint16_t len, ra8_dma_complete_fn_t on_complete, void *ctx, uint8_t *out_dma_channel)
 Kick off a DMA-backed TX transfer on an SPI channel.
ra8_err_t ra8_spi_read_dma (uint8_t channel, uint8_t *out_buf, uint16_t len, ra8_dma_complete_fn_t on_complete, void *ctx, uint8_t *out_dma_channel)
 Kick off a DMA-backed RX transfer on an SPI channel.
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.

Detailed Description

SPI_B controller driver (RA8D2 Type-B SPI peripheral).

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

Public API for the SPI_B controller driver. Implementation lives in libs/ra8_hal/src/ra8_spi_b.c and mirrors FSP r_spi_b in polling-mode controller flow. The earlier register layout (legacy 8/16-bit SPI block) was replaced wholesale on RA8D2 – see ra8_spi_regs.h for the SPI_B register file.

API surface:

Note
On RA8D2 the SPI_B block is the only SPI peripheral instance: there is no separate legacy ra8_spi driver to demonstrate. This header is the public API and ra8_spi_b.c is its implementation; test_ra8_spi.c and test_ra8_spi_b.c both exercise it. The on-silicon example/HIL is examples/.../hil/spi_loopback (it includes this header, runs the internal-loopback path, and prints spi: pass). A separate spi_b_loopback example would link the same .c and duplicate spi_loopback verbatim, so none exists.

Definition in file ra8_spi.h.

Typedef Documentation

◆ ra8_spi_complete_fn_t

typedef void(* ra8_spi_complete_fn_t) (void *ctx, uint8_t err_mask)

Transfer-complete callback signature.

Parameters
[in]ctxCaller-supplied context.
[in]err_maskOR of k_ra8_spi_err_* bits; zero on success.

Definition at line 126 of file ra8_spi.h.

Enumeration Type Documentation

◆ ra8_spi_bit_width_t

enum ra8_spi_bit_width_t : uint8_t

Per-frame bit width for multi-byte transfers.

Mirrors the subset of FSP spi_bit_width_t that this driver supports. The enum value is the raw SPCMDn.SPB encoding written into the SPI_B command register (HUM Ch 43.2.7 "SPCMDm" p 2893): SPB[4:0] = N - 1 where N is the frame width in bits, so 8-bit frames program SPB = 0b00111, 16-bit frames program SPB = 0b01111, and 32-bit frames program SPB = 0b11111. Matching the FSP enum value lets the value flow straight into SPCMDn.SPB without a lookup table.

See also
r_spi_b_bit_width_config in FSP r_spi_b.c.
Enumerator
k_ra8_spi_width_8 

8-bit frame -> SPCMDn.SPB = 0b00111.

k_ra8_spi_width_16 

16-bit frame -> SPCMDn.SPB = 0b01111.

k_ra8_spi_width_32 

32-bit frame -> SPCMDn.SPB = 0b11111.

Definition at line 84 of file ra8_spi.h.

◆ ra8_spi_err_mask_t

enum ra8_spi_err_mask_t : uint8_t

Bit mask of SPI error flags.

Enumerator
k_ra8_spi_err_none 

RA8 SPI error none.

k_ra8_spi_err_overrun 

SPSR.OVRF set.

k_ra8_spi_err_mode 

SPSR.MODERF set.

k_ra8_spi_err_parity 

SPSR.PERF set.

k_ra8_spi_err_underrun 

SPSR.UDRF set.

Definition at line 111 of file ra8_spi.h.

◆ ra8_spi_mode_t

enum ra8_spi_mode_t : uint8_t

CPOL / CPHA combinations.

Enumerator
k_ra8_spi_mode_0 

CPOL=0, CPHA=0.

k_ra8_spi_mode_1 

CPOL=0, CPHA=1.

k_ra8_spi_mode_2 

CPOL=1, CPHA=0.

k_ra8_spi_mode_3 

CPOL=1, CPHA=1.

Definition at line 61 of file ra8_spi.h.

Function Documentation

◆ 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_b_target_init()

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

Initialise an SPI_B channel in target (peripheral) mode.

Configures the SPI_B peripheral to act as a target device: the external controller drives RSPCK and asserts SSL (CS); the MCU responds on CIPO and receives on COPI. Implementation lives in libs/ra8_hal/src/ra8_spi_b_target.c.

Register-level effect (HUM Ch 43.2.4 "SPCR" p 2884):

  • SPCR is written with MSTR=0 (peripheral/target), MODFEN=1, SPE=1.
  • SCKASE is NOT set – it is valid only in controller mode.
  • SPBR (SPCR3) is set to zero because the clock is external.
  • SPCMD0 is programmed from cfg (CPHA, CPOL, LSBF) for 8-bit frames.

The baud_hz and pclka_hz fields of cfg are accepted but ignored – the bit-rate is determined by the external controller.

Parameters
[in]channelSPI channel (0 or 1).
[in]cfgConfiguration descriptor (non-NULL).
Returns
ra8_err_t error code.
Return values
k_ra8_okChannel configured in target mode; awaiting external controller frames.
k_ra8_err_null_ptrcfg is NULL.
k_ra8_err_invalid_argchannel is out of range.
k_ra8_err_hw_errorra8_mstp_enable failed.
Precondition
IRQs masked or single-threaded init context.
ra8_mstp_init has been called.
Postcondition
On success, SPCR.SPE=1 and SPCR.MSTR=0 (target mode is active).
SPDCR, SPDCR2, SPCR2, and SPCR3 are cleared; SPSR flags are clear.
Note
Thread safety: not thread-safe.
To deinitialise a channel opened in target mode, call ra8_spi_deinit(channel) from ra8_spi.h.
See also
ra8_spi_b_target_xfer Exchange one byte after init.
ra8_spi_init Initialise the same channel in controller mode.
Since
0.1.0

Definition at line 301 of file ra8_spi_b_target.c.

References internal_target_program_regs(), internal_target_spcr(), 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_tag, and r_spi_regs_t::SPCR.

◆ ra8_spi_b_target_xfer()

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

Exchange one byte as the SPI target in a polled blocking call.

Performs a full-duplex single-byte exchange in target (peripheral) role:

  1. Waits for SPSR.SPTEF (TX buffer empty) – confirms it is safe to pre-load tx without overwriting a pending outgoing byte.
  2. Writes tx to SPDR (CIPO data – what this peripheral sends to the external controller on the next controller-initiated frame).
  3. Waits for SPSR.SPRF (RX buffer full) – asserted when the external controller has completed clocking one SPI frame.
  4. Reads SPDR into *rx (the COPI byte received from the controller).

Under RA8_OFF_TARGET the SPSR wait reduces to a single-shot register read: pre-seed the register as shown below.

Example:
// Off-target (or pre-staged hardware test):
uint8_t rx = 0U;
ra8_spi_b_target_xfer(0, 0xA5U, &rx);
ra8_err_t ra8_spi_b_target_xfer(uint8_t channel, uint8_t tx, uint8_t *rx)
Exchange one byte as the SPI target in a polled blocking call.
static volatile r_spi_regs_t * ra8_spi(uint8_t channel)
Get pointer to SPI_B channel channel (0..1).
@ k_ra8_spsr_mask_sprf
RA8 spsr mask sprf.
@ k_ra8_spsr_mask_sptef
RA8 spsr mask sptef.
volatile uint32_t SPSR
+0x50 SPI Status Register.
Parameters
[in]channelSPI channel (0 or 1).
[in]txByte to send on CIPO (Controller In Peripheral Out).
[out]rxPointer to receive the COPI byte; may be NULL if the received byte is not needed.
Returns
ra8_err_t error code.
Return values
k_ra8_okFrame exchange completed.
k_ra8_err_null_ptrchannel is out of range (ra8_spi() returned NULL).
k_ra8_err_hw_timeoutSPSR.SPTEF or SPSR.SPRF never asserted within k_spi_b_target_poll_limit iterations.
Precondition
Channel previously initialised via ra8_spi_b_target_init.
SPCR.SPE is set.
Postcondition
On k_ra8_ok, tx was loaded into SPDR and (if rx != NULL) *rx holds the byte received on COPI from the controller.
SPSR.SPTEF and SPSR.SPRF have been cleared via SPSRC.
Note
Thread safety: not thread-safe.
The SPI_B SPDR register backs TX and RX through separate FIFO queues on hardware; they share a single address in the fake's plain-RAM model, so the fake echoes tx back as *rx.
See also
ra8_spi_b_target_init Initialise the channel first.
ra8_spi_xfer8 Controller-mode equivalent.
Since
0.1.0

Definition at line 332 of file ra8_spi_b_target.c.

References internal_target_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.

◆ 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_read_dma()

ra8_err_t ra8_spi_read_dma ( uint8_t channel,
uint8_t * out_buf,
uint16_t len,
ra8_dma_complete_fn_t on_complete,
void * ctx,
uint8_t * out_dma_channel )
nodiscard

Kick off a DMA-backed RX transfer on an SPI channel.

Programmes the ra8_dma substrate to copy len bytes from the channel's SPDR register into out_buf[].

Parameters
[in]channelSPI channel.
[out]out_bufDestination buffer. Must outlive transfer.
[in]lenNumber of bytes; non-zero.
[in]on_completeCompletion callback. May be NULL.
[in]ctxContext passed to on_complete.
[out]out_dma_channelAllocated DMAC channel on success.
Returns
ra8_err_t error code.
Return values
k_ra8_okTransfer armed.
k_ra8_err_null_ptrout_buf / out_dma_channel NULL.
k_ra8_err_invalid_argChannel or len invalid.
k_ra8_err_no_memAll DMAC channels in use.
k_ra8_err_hw_errorra8_dma_request failed.
Precondition
Channel previously initialized with 8-bit frames.
ra8_dma_init has been called.
Postcondition
On success, DMAC channel is armed.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 234 of file ra8_spi_b_dma.c.

References ra8_dma_request_t::count, ra8_dma_request_t::ctx, ra8_dma_request_t::dst_addr, ra8_dma_request_t::dst_inc, internal_dma_args_ok(), internal_spi_dma_rx_complete(), k_ra8_dmac_width_byte, k_ra8_err_invalid_arg, k_ra8_ok, ra8_dma_request_t::on_complete, RA8_CHECK_NULL_PTR, ra8_dma_request(), ra8_spi(), ra8_spi_dma_rx_ctx_t::rx_buf, ra8_spi_dma_rx_ctx_t::rx_len, s_spi_dma_rx_ctx, s_tag, r_spi_regs_t::SPDR, ra8_dma_request_t::src_addr, ra8_dma_request_t::src_inc, ra8_dma_request_t::trigger, ra8_spi_dma_rx_ctx_t::user_ctx, ra8_spi_dma_rx_ctx_t::user_on_complete, and ra8_dma_request_t::width.

◆ 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_dma()

ra8_err_t ra8_spi_write_dma ( uint8_t channel,
const uint8_t * data,
uint16_t len,
ra8_dma_complete_fn_t on_complete,
void * ctx,
uint8_t * out_dma_channel )
nodiscard

Kick off a DMA-backed TX transfer on an SPI channel.

Programmes the ra8_dma substrate to copy len bytes from data[] into the channel's SPDR register. The SPI block must be configured for 8-bit frames via the cfg passed to ra8_spi_init; wider-frame DMA streaming is a future wave.

Parameters
[in]channelSPI channel.
[in]dataSource buffer. Must outlive transfer.
[in]lenNumber of bytes; non-zero.
[in]on_completeCompletion callback. May be NULL.
[in]ctxContext passed to on_complete.
[out]out_dma_channelAllocated DMAC channel on success.
Returns
ra8_err_t error code.
Return values
k_ra8_okTransfer armed.
k_ra8_err_null_ptrdata / out_dma_channel NULL.
k_ra8_err_invalid_argChannel or len invalid.
k_ra8_err_no_memAll DMAC channels in use.
k_ra8_err_hw_errorra8_dma_request failed.
Precondition
Channel previously initialized with 8-bit frames.
ra8_dma_init has been called.
Postcondition
On success, DMAC channel is armed.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 197 of file ra8_spi_b_dma.c.

References ra8_dma_request_t::count, ra8_dma_request_t::ctx, ra8_dma_request_t::dst_addr, ra8_dma_request_t::dst_inc, internal_dma_args_ok(), internal_round_up_to_cache_line(), k_ra8_dmac_width_byte, k_ra8_err_invalid_arg, k_ra8_ok, ra8_dma_request_t::on_complete, ra8_cache_dcache_clean_by_addr(), RA8_CHECK_NULL_PTR, ra8_dma_request(), ra8_spi(), s_tag, r_spi_regs_t::SPDR, ra8_dma_request_t::src_addr, ra8_dma_request_t::src_inc, ra8_dma_request_t::trigger, and ra8_dma_request_t::width.

◆ 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().