48static const char*
s_tag =
"SPI_B";
68typedef enum : uint32_t {
82typedef enum : uint32_t {
96typedef enum : uint8_t {
110typedef enum : uint32_t {
169 if ((baud_hz == 0U) || (pclka_hz == 0U)) {
172 const uint32_t divisor = 2U * baud_hz;
173 const uint32_t n = pclka_hz / divisor;
177 const uint32_t result = n - 1U;
181 return (uint8_t)result;
355 if (reg ==
nullptr) {
388 if (reg ==
nullptr) {
415 if (
ra8_spi(channel) ==
nullptr) {
435 reg->
SPDR = (uint32_t)tx;
450 const uint8_t received = (uint8_t)reg->
SPDR;
528 reg->
SPCMD[0] = spcmd0;
568 value = ((
const uint32_t*)tx)[idx];
570 value = (uint32_t)((
const uint16_t*)tx)[idx];
572 value = (uint32_t)((
const uint8_t*)tx)[idx];
604 const uint32_t value = reg->
SPDR;
609 ((uint32_t*)rx)[idx] = value;
611 ((uint16_t*)rx)[idx] = (uint16_t)value;
613 ((uint8_t*)rx)[idx] = (uint8_t)value;
659 uint8_t bytes_per_unit = 0U;
668 if ((tx ==
nullptr) && (rx ==
nullptr)) {
672 if (reg ==
nullptr) {
679 (void)bytes_per_unit;
681 for (uint32_t i = 0U; i < len; i++) {
705 if ((tx ==
nullptr) && (len > 0U)) {
713 if ((rx ==
nullptr) && (len > 0U)) {
747 if (reg ==
nullptr) {
773 if (reg ==
nullptr) {
776 const uint32_t ss = reg->
SPSR;
800 if (reg ==
nullptr) {
830 if (reg ==
nullptr) {
880 if ((mask != 0U) && (cb !=
nullptr)) {
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Bounded wait-flag primitives for RA8D2 HAL drivers.
static ra8_err_t ra8_hw_wait_flag_set32(volatile const uint32_t *reg, uint32_t mask, uint32_t budget)
Spin until (*reg & mask) != 0 or budget runs out.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_spi0
MSTPB19 SPI0.
@ k_ra8_mstp_spi1
MSTPB18 SPI1.
SPI_B controller driver (RA8D2 Type-B SPI peripheral).
ra8_spi_bit_width_t
Per-frame bit width for multi-byte transfers.
@ k_ra8_spi_width_16
16-bit frame -> SPCMDn.SPB = 0b01111.
@ k_ra8_spi_width_32
32-bit frame -> SPCMDn.SPB = 0b11111.
@ k_ra8_spi_width_8
8-bit frame -> SPCMDn.SPB = 0b00111.
void(* ra8_spi_complete_fn_t)(void *ctx, uint8_t err_mask)
Transfer-complete callback signature.
@ k_ra8_spi_mode_0
CPOL=0, CPHA=0.
@ k_ra8_spi_mode_3
CPOL=1, CPHA=1.
@ k_ra8_spi_mode_1
CPOL=0, CPHA=1.
@ k_ra8_spi_mode_2
CPOL=1, CPHA=0.
@ k_ra8_spi_err_none
RA8 SPI error none.
@ k_ra8_spi_err_mode
SPSR.MODERF set.
@ k_ra8_spi_err_parity
SPSR.PERF set.
@ k_ra8_spi_err_underrun
SPSR.UDRF set.
@ k_ra8_spi_err_overrun
SPSR.OVRF set.
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.
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.
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).
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.
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_spi_b_dummy_t
Dummy TX values written when ra8_spi_read has no caller payload.
@ k_ra8_spi_b_dummy_tx_16
16-bit dummy.
@ k_ra8_spi_b_dummy_tx_8
8-bit dummy.
@ k_ra8_spi_b_dummy_tx_32
32-bit dummy.
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_spi_b_default_t
Default register values for the legacy ra8_spi_controller_init shim.
@ 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.
ra8_err_t ra8_spi_clear_errors(uint8_t channel)
Clear the SPSR error flags.
void ra8_spi_dispatch_spei(uint8_t channel)
Dispatch SPEI – collect + clear errors, fire callback.
ra8_spi_b_unit_bytes_t
Bytes-per-frame for each supported transfer width.
@ k_ra8_spi_b_bytes_per_unit_16
16-bit frame -> 2 bytes.
@ k_ra8_spi_b_bytes_per_unit_8
8-bit frame -> 1 byte.
@ k_ra8_spi_b_bytes_per_unit_32
32-bit frame -> 4 bytes.
ra8_err_t ra8_spi_enter_stop(uint8_t channel)
Put the channel into MSTP-gated stop state.
void ra8_spi_dispatch_spti(uint8_t channel)
Dispatch SPTI – advance TX state.
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 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.
ra8_err_t ra8_spi_controller_init(uint8_t channel)
Legacy init (1.9 MHz at PCLKA = 125 MHz, mode 0).
ra8_spi_b_poll_t
Polling-loop budget.
@ k_ra8_spi_b_poll_limit
RA8 SPI b poll limit.
static ra8_spi_state_t s_spi_state[k_ra8_spi_b_channel_count]
Per-channel state table indexed by 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_xfer8(uint8_t channel, uint8_t tx, uint8_t *rx)
Full-duplex 8-bit exchange.
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_exit_stop(uint8_t channel)
Exit MSTP-gated stop state.
void ra8_spi_dispatch_spri(uint8_t channel)
Dispatch SPRI – advance RX state.
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_set_clock(uint8_t channel, uint32_t baud_hz, uint32_t pclka_hz)
Change the SPI clock without tearing down the channel.
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.
ra8_err_t ra8_spi_init(uint8_t channel, const ra8_spi_cfg_t *cfg)
Initialise an SPI channel with a full config descriptor.
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 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.
ra8_err_t ra8_spi_deinit(uint8_t channel)
Tear down a channel.
static uint8_t internal_spbr(uint32_t baud_hz, uint32_t pclka_hz)
Compute SPCR3.SPBR for a requested bit-rate.
SPI_B register layout for the Renesas RA8D2.
@ k_ra8_spcmd_bit_spb_lo
Data Length [20:16] low.
@ k_ra8_spcr3_bit_spbr
SPBR field [15:8] – bit-rate divider.
@ k_ra8_spcmd_mask_cpol
RA8 spcmd mask cpol.
@ k_ra8_spcmd_mask_lsbf
RA8 spcmd mask lsbf.
@ k_ra8_spcmd_mask_cpha
RA8 spcmd mask cpha.
@ k_ra8_spcmd_mask_spb
[20:16] data length
@ k_ra8_spcr_mask_mstr
RA8 spcr mask mstr.
@ k_ra8_spcr_mask_spe
RA8 spcr mask spe.
@ k_ra8_spcr_mask_sckase
RA8 spcr mask sckase.
static volatile r_spi_regs_t * ra8_spi(uint8_t channel)
Get pointer to SPI_B channel channel (0..1).
@ k_ra8_spfcr_mask_spfrst
Reset both FIFOs.
@ k_ra8_spcr2_mask_splp2
Non-inverting loopback (rx = tx).
@ k_ra8_spcr3_mask_spbr
[15:8] bit-rate divider.
@ k_ra8_spsr_mask_ovrf
RA8 spsr mask ovrf.
@ k_ra8_spsr_mask_sprf
RA8 spsr mask sprf.
@ k_ra8_spsr_mask_udrf
RA8 spsr mask udrf.
@ k_ra8_spsr_mask_perf
RA8 spsr mask perf.
@ k_ra8_spsr_mask_modf
RA8 spsr mask modf.
@ k_ra8_spsr_mask_sptef
RA8 spsr mask sptef.
@ k_ra8_spsr_mask_errs
OVRF | MODF | PERF | UDRF.
@ k_ra8_spi_b_channel_count
SPI0 + SPI1.
@ k_ra8_spcmd_spb_8bit
0b00111 -> 8-bit frame.
@ k_ra8_spbr_max
SPBR is 8-bit unsigned.
@ k_ra8_spsrc_mask_all
Clear every flag at once.
@ k_ra8_spsrc_mask_sprfc
RA8 spsrc mask sprfc.
@ k_ra8_spsrc_mask_sptefc
RA8 spsrc mask sptefc.
SPI_B register-window mirror (matches FSP R_SPI_B0_Type, 0x70 bytes).
volatile uint32_t SPDECR
+0x04 SPI Delay Control Register.
volatile uint32_t SPSRC
+0x68 SPI Status Clear Register.
volatile uint32_t SPDCR2
+0x44 SPI Data Control Register 2.
volatile uint32_t SPCR
+0x08 SPI Control Register 1.
volatile uint32_t SPCR3
+0x10 SPI Control Register 3.
volatile uint32_t SPCMD[8]
+0x14..0x30 Command Registers SPCMD0..7.
volatile uint32_t SPFCR
+0x6C SPI FIFO Clear Register.
volatile uint32_t SPSR
+0x50 SPI Status Register.
volatile uint32_t SPDCR
+0x40 SPI Data Control Register.
volatile uint32_t SPCR2
+0x0C SPI Control Register 2.
volatile uint32_t SPDR
+0x00 SPI Data Register.
Configuration descriptor for ra8_spi_init.
bool lsb_first
True for LSB-first transfers.
bool loopback
SPCR2.SPLP=1: internal COPI->CIPO tie (no pins).
uint32_t pclka_hz
Current PCLKA in Hz (for SPBR calc).
uint32_t baud_hz
Target SPI clock in Hz.
ra8_spi_mode_t mode
CPOL / CPHA combination.
Per-channel dispatch state owned by this driver.
ra8_spi_complete_fn_t cb
Transfer-complete callback.
void * ctx
Callback context.
bool initialized
True after ra8_spi_init.