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

SCI Simple-SPI controller-mode driver (polling, full-duplex). More...

#include "ra8_sci_spi.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_hw_err.h"
#include "ra8_mstp.h"
#include "ra8_mstp_regs.h"
#include "ra8_sci_regs.h"
Include dependency graph for ra8_sci_spi.c:

Go to the source code of this file.

Enumerations

enum  ra8_sci_spi_dim_t : uint32_t {
  k_ra8_sci_spi_channel_count = 10U ,
  k_ra8_sci_spi_cks_max = 3U ,
  k_ra8_sci_spi_brr_max = 255U ,
  k_ra8_sci_spi_div_base = 4U ,
  k_ra8_sci_spi_idle_byte = 0xFFU
}
 Static dimensioning + bit-rate search constants. More...

Functions

static void internal_resolve_rate (uint32_t baud_hz, uint32_t pclk_hz, uint32_t *out_cks, uint32_t *out_brr)
 Resolve CCR2.CKS + BRR for a requested Simple-SPI bit-rate.
static void internal_apply_rate (volatile r_sci_regs_t *reg, uint32_t baud_hz, uint32_t pclk_hz)
 Write CCR2 with the resolved CKS + BRR fields.
static uint32_t internal_ccr3 (const ra8_sci_spi_cfg_t *cfg)
 Build CCR3 for Simple-SPI controller mode.
ra8_err_t ra8_sci_spi_init (uint8_t channel, const ra8_sci_spi_cfg_t *cfg)
 Bring an SCI channel up as a Simple-SPI controller.
ra8_err_t ra8_sci_spi_deinit (uint8_t channel)
 Disable the channel and release its MSTP gate.
ra8_err_t ra8_sci_spi_set_clock (uint8_t channel, uint32_t baud_hz, uint32_t pclk_hz)
 Re-program the bit-rate without otherwise reconfiguring.
ra8_err_t ra8_sci_spi_xfer8 (uint8_t channel, uint8_t tx, uint8_t *rx)
 Full-duplex single-frame transfer.
ra8_err_t ra8_sci_spi_xfer (uint8_t channel, const uint8_t *tx, uint8_t *rx, uint32_t len)
 Full-duplex multi-byte transfer.

Variables

static const char * s_tag = "SCI_SPI"
static const ra8_mstp_t s_mstp_table [k_ra8_sci_spi_channel_count]
 Channel-index -> MSTP id (HUM Ch 11 "MSTPCRB").

Detailed Description

SCI Simple-SPI controller-mode driver (polling, full-duplex).

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

Implements ra8_sci_spi.h against the RA8D2 SCI_B peripheral in Simple-SPI mode (CCR3.MOD = 011b). The flow mirrors FSP r_sci_b_spi.c: clear CCR0 (TE/RE off), programme CCR3 (mode/CHR/CPOL/CPHA/LSBF), CCR2 (CKS + BRR for the bit-rate), clear stale CSR latches, then set CCR0 = TE | RE. A frame is a write to TDR followed by a poll of CSR.TDRE then CSR.RDRF, then a read of RDR – in clock-synchronous / Simple-SPI mode every transmitted frame clocks in a received frame, so the controller is inherently full-duplex.

The chip-select is the caller's responsibility (held as a GPIO so it can span a multi-frame SD transaction); this driver never touches SSn (CCR0.SSE stays 0).

Definition in file ra8_sci_spi.c.

Enumeration Type Documentation

◆ ra8_sci_spi_dim_t

enum ra8_sci_spi_dim_t : uint32_t

Static dimensioning + bit-rate search constants.

Enumerator
k_ra8_sci_spi_channel_count 

SCI0..SCI9.

k_ra8_sci_spi_cks_max 

CKS[1:0] max (clock /64).

k_ra8_sci_spi_brr_max 

BRR is 8-bit.

k_ra8_sci_spi_div_base 

B = TCLK / (4 * 4^n * (N + 1)).

k_ra8_sci_spi_idle_byte 

Idle fill when tx is NULL.

Definition at line 45 of file ra8_sci_spi.c.

Function Documentation

◆ internal_apply_rate()

void internal_apply_rate ( volatile r_sci_regs_t * reg,
uint32_t baud_hz,
uint32_t pclk_hz )
static

Write CCR2 with the resolved CKS + BRR fields.

Resolves the divider via internal_resolve_rate and stores it in CCR2.CKS / CCR2.BRR, preserving MDDR at its reset value (modulation off).

Parameters
[in]regChannel register block.
[in]baud_hzDesired bit-rate (Hz).
[in]pclk_hzBaud-clock source (Hz).
Precondition
TE = RE = 0 (CCR2 written only while disabled or via set_clock).
reg is a valid SCI channel register block.
Postcondition
CCR2.CKS / CCR2.BRR encode the closest reachable rate.
No other CCR2 field is disturbed beyond MDDR's reset value.
Note
Not thread-safe.
Since
0.1.0

Definition at line 138 of file ra8_sci_spi.c.

References r_sci_regs_t::CCR2, internal_resolve_rate(), k_ra8_sci_ccr2_mask_brr_field, k_ra8_sci_ccr2_mask_cks_field, k_ra8_sci_ccr2_shift_brr, k_ra8_sci_ccr2_shift_cks, k_ra8_sci_ccr2_shift_mddr, and k_ra8_sci_mddr_default.

Referenced by ra8_sci_spi_init(), and ra8_sci_spi_set_clock().

◆ internal_ccr3()

uint32_t internal_ccr3 ( const ra8_sci_spi_cfg_t * cfg)
static

Build CCR3 for Simple-SPI controller mode.

MOD = Simple SPI, CHR = 8-bit, CKE = 00 (internal clock, SCKn drives the bus), BPEN = 0 (input synchroniser active). CPOL / CPHA come from the SPI mode; LSBF from the config.

Parameters
[in]cfgCaller config (already null-checked).
Returns
CCR3 register value.
Return values
non-zeroThe assembled CCR3 word (MOD field is always set).
Precondition
cfg is non-NULL.
cfg->mode is one of ra8_spi_mode_t (0..3).
Postcondition
No register is written; the value is returned to the caller.
cfg is unmodified.
Note
Not thread-safe.
Since
0.1.0

Definition at line 168 of file ra8_sci_spi.c.

References k_ra8_sci_ccr3_bit_cpha, k_ra8_sci_ccr3_bit_cpol, k_ra8_sci_ccr3_bit_lsbf, k_ra8_sci_ccr3_chr_8bit, k_ra8_sci_ccr3_mod_simple_spi, k_ra8_sci_ccr3_shift_chr, k_ra8_sci_ccr3_shift_mod, k_ra8_spi_mode_1, k_ra8_spi_mode_2, ra8_sci_spi_cfg_t::lsb_first, ra8_sci_spi_cfg_t::mode, and RA8_INTERNAL.

Referenced by ra8_sci_spi_init().

◆ internal_resolve_rate()

void internal_resolve_rate ( uint32_t baud_hz,
uint32_t pclk_hz,
uint32_t * out_cks,
uint32_t * out_brr )
static

Resolve CCR2.CKS + BRR for a requested Simple-SPI bit-rate.

Clock-synchronous / Simple-SPI rate (HUM Table 38.7, BGDM = 0): B = TCLK / (4 * 4^n * (N + 1)) with n = CKS and N = BRR. Picks the smallest n that keeps N <= 255; clamps to the slowest setting when the rate is unreachably low.

Parameters
[in]baud_hzDesired bit-rate (Hz), already checked non-zero.
[in]pclk_hzBaud-clock source (Hz), already checked non-zero.
[out]out_cksResolved CKS value (0..3).
[out]out_brrResolved BRR value (0..255).
Precondition
baud_hz and pclk_hz are non-zero.
out_cks and out_brr are non-NULL.
Postcondition
*out_cks / *out_brr hold the closest reachable rate.
No register is written; the caller applies the result.
Note
Not thread-safe.
Since
0.1.0

Definition at line 97 of file ra8_sci_spi.c.

References k_ra8_sci_spi_brr_max, k_ra8_sci_spi_cks_max, and k_ra8_sci_spi_div_base.

Referenced by internal_apply_rate().

◆ ra8_sci_spi_deinit()

ra8_err_t ra8_sci_spi_deinit ( uint8_t channel)
nodiscard

Disable the channel and release its MSTP gate.

Parameters
[in]channelSCI channel index (0..9).
Return values
k_ra8_okChannel disabled.
k_ra8_err_invalid_argchannel out of range.
Precondition
ra8_sci_spi_init succeeded for this channel.
Postcondition
TE/RE are cleared and the MSTP gate is released.
Since
0.1.0

Definition at line 216 of file ra8_sci_spi.c.

References r_sci_regs_t::CCR0, k_ra8_err_invalid_arg, k_ra8_sci_spi_channel_count, ra8_mstp_disable(), ra8_sci(), and s_mstp_table.

Referenced by c6_probe_sweep_mode(), priv_ra8_esp_hosted_spi_close(), and priv_ra8_esp_hosted_spi_open().

◆ ra8_sci_spi_init()

ra8_err_t ra8_sci_spi_init ( uint8_t channel,
const ra8_sci_spi_cfg_t * cfg )
nodiscard

Bring an SCI channel up as a Simple-SPI controller.

Parameters
[in]channelSCI channel index (0..9).
[in]cfgConfiguration; must be non-NULL.
Return values
k_ra8_okChannel is enabled (TE+RE) and ready to transfer.
k_ra8_err_null_ptrcfg is NULL.
k_ra8_err_invalid_argchannel out of range or baud 0.
Precondition
The SCKn / CIPOn / COPIn pins are routed to the SCI function (PSEL = 00100b) and the chip-select is owned as a GPIO.
Postcondition
The SCI MSTP gate is enabled and the channel is in Simple-SPI controller mode at the requested bit-rate.
Note
Not thread-safe; serialize access to a channel.
Since
0.1.0

Definition at line 185 of file ra8_sci_spi.c.

References ra8_sci_spi_cfg_t::baud_hz, r_sci_regs_t::CCR0, r_sci_regs_t::CCR1, r_sci_regs_t::CCR3, r_sci_regs_t::CCR4, r_sci_regs_t::CFCLR, internal_apply_rate(), internal_ccr3(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_sci_ccr0_bit_re, k_ra8_sci_ccr0_bit_te, k_ra8_sci_cfclr_default, k_ra8_sci_spi_channel_count, ra8_sci_spi_cfg_t::pclk_hz, RA8_CHECK_NULL_PTR, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, ra8_sci(), s_mstp_table, and s_tag.

Referenced by c6_probe_sweep_mode(), eoh_setup_or_halt(), etoc_setup_or_halt(), fs_fmt_setup_or_halt(), internal_bringup_spi(), internal_pc_setup_or_halt(), internal_sci_transport_bringup(), microsd_sd_spi_open(), priv_ra8_esp_hosted_spi_open(), sd_demo_setup_or_halt(), and sh_sd_bus_init().

◆ ra8_sci_spi_set_clock()

ra8_err_t ra8_sci_spi_set_clock ( uint8_t channel,
uint32_t baud_hz,
uint32_t pclk_hz )
nodiscard

Re-program the bit-rate without otherwise reconfiguring.

Parameters
[in]channelSCI channel index (0..9).
[in]baud_hzDesired SCK bit-rate (Hz), non-zero.
[in]pclk_hzSCI baud-clock source (PCLKA, Hz).
Return values
k_ra8_okBit-rate updated.
k_ra8_err_invalid_argchannel out of range or baud 0.
Precondition
ra8_sci_spi_init succeeded for this channel.
Postcondition
CCR2.CKS/BRR reflect the new rate; the channel stays enabled.
Since
0.1.0

Definition at line 230 of file ra8_sci_spi.c.

References r_sci_regs_t::CCR0, internal_apply_rate(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_sci_spi_channel_count, and ra8_sci().

Referenced by eoh_spi_set_clock(), etoc_spi_set_clock(), fs_fmt_spi_set_clock(), internal_pc_spi_set_clock(), internal_sci_spi_set_clock(), internal_sci_transport_set_clock(), internal_set_clock(), microsd_spi_set_clock(), sd_demo_spi_set_clock(), and sh_sd_set_clock().

◆ ra8_sci_spi_xfer()

ra8_err_t ra8_sci_spi_xfer ( uint8_t channel,
const uint8_t * tx,
uint8_t * rx,
uint32_t len )
nodiscard

Full-duplex multi-byte transfer.

Either buffer may be NULL: a NULL tx shifts idle (0xFF) bytes (SD/flash read convention); a NULL rx discards the received bytes. len == 0 is a no-op success.

Parameters
[in]channelSCI channel index (0..9).
[in]txBytes to shift out, or NULL for idle fill.
[out]rxBuffer for received bytes, or NULL to discard.
[in]lenNumber of bytes to transfer.
Return values
k_ra8_okAll bytes transferred.
k_ra8_err_invalid_argchannel out of range.
k_ra8_err_hw_timeoutA per-frame poll expired.
Precondition
ra8_sci_spi_init succeeded for this channel.
Postcondition
len frames were clocked.
Since
0.1.0

Definition at line 281 of file ra8_sci_spi.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_sci_spi_channel_count, k_ra8_sci_spi_idle_byte, and ra8_sci_spi_xfer8().

Referenced by eoh_spi_xfer(), etoc_spi_xfer(), fs_fmt_spi_xfer(), internal_pc_spi_xfer(), internal_sci_spi_write_read(), internal_sci_transport_xfer(), internal_transfer(), internal_xfer(), microsd_spi_xfer(), sd_demo_spi_xfer(), and sh_sd_xfer().

◆ ra8_sci_spi_xfer8()

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

Full-duplex single-frame transfer.

Parameters
[in]channelSCI channel index (0..9).
[in]txByte shifted out on COPI.
[out]rxByte shifted in on CIPO; may be NULL to discard.
Return values
k_ra8_okFrame completed.
k_ra8_err_invalid_argchannel out of range.
k_ra8_err_hw_timeoutThe TX-empty or RX-full poll expired.
Precondition
ra8_sci_spi_init succeeded for this channel.
Postcondition
One frame was clocked; *rx holds the received byte.
Since
0.1.0

Definition at line 250 of file ra8_sci_spi.c.

References r_sci_regs_t::CFCLR, r_sci_regs_t::CSR, k_ra8_hw_budget_long, k_ra8_ok, k_ra8_sci_cfclr_bit_rdrfc, k_ra8_sci_csr_bit_rdrf, k_ra8_sci_csr_bit_tdre, k_ra8_sci_rdr_mask_data8, RA8_CHECK_NULL_PTR, ra8_hw_wait_flag_set32(), ra8_sci(), r_sci_regs_t::RDR, s_tag, and r_sci_regs_t::TDR.

Referenced by internal_sci_spi_xfer8(), and ra8_sci_spi_xfer().

Variable Documentation

◆ s_mstp_table

const ra8_mstp_t s_mstp_table[k_ra8_sci_spi_channel_count]
static
Initial value:
= {
}
@ k_ra8_mstp_sci2
MSTPB29 SCI2.
@ k_ra8_mstp_sci4
MSTPB27 SCI4.
@ k_ra8_mstp_sci7
MSTPB24 SCI7.
@ k_ra8_mstp_sci9
MSTPB22 SCI9.
@ k_ra8_mstp_sci0
MSTPB31 SCI0.
@ k_ra8_mstp_sci5
MSTPB26 SCI5.
@ k_ra8_mstp_sci1
MSTPB30 SCI1.
@ k_ra8_mstp_sci6
MSTPB25 SCI6.
@ k_ra8_mstp_sci8
MSTPB23 SCI8.
@ k_ra8_mstp_sci3
MSTPB28 SCI3.

Channel-index -> MSTP id (HUM Ch 11 "MSTPCRB").

Definition at line 57 of file ra8_sci_spi.c.

◆ s_tag

const char* s_tag = "SCI_SPI"
static

Definition at line 39 of file ra8_sci_spi.c.