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

SPI_B DMA TX/RX pipes with Cortex-M85 cache coherency. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_cache.h"
#include "ra8_check.h"
#include "ra8_dma.h"
#include "ra8_dmac.h"
#include "ra8_err.h"
#include "ra8_spi.h"
#include "ra8_spi_regs.h"
Include dependency graph for ra8_spi_b_dma.c:

Go to the source code of this file.

Data Structures

struct  ra8_spi_dma_rx_ctx_t
 Driver-owned completion context for an RX DMA, used to bridge the cache-invalidate step onto the caller's completion callback. More...

Functions

static ra8_err_t internal_dma_args_ok (uint8_t channel, uint16_t len)
 Report whether a DMA entry point's channel index and length are usable.
static uint32_t internal_round_up_to_cache_line (uint32_t bytes)
 Round a byte count up to a whole number of D-cache lines.
static void internal_spi_dma_rx_complete (void *ctx)
 RX-DMA transfer-end wrapper: invalidate the buffer, then chain.
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.

Variables

static const char * s_tag = "SPI_B"
static ra8_spi_dma_rx_ctx_t s_spi_dma_rx_ctx [k_ra8_spi_b_channel_count]
 Per-channel RX-DMA completion bridge, indexed by SPI channel.

Detailed Description

SPI_B DMA TX/RX pipes with Cortex-M85 cache coherency.

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

Companion translation unit to ra8_spi_b.c for the RA8D2 SPI_B (Type-B SPI) driver (HUM Ch 43). Carries the DMA-pipe entry points (ra8_spi_write_dma / ra8_spi_read_dma) that stream a byte buffer to/from the SPDR FIFO front-end, together with the D-cache maintenance that keeps those engine-touched buffers coherent with the Cortex-M85 L1 data cache:

  • ra8_spi_write_dma cleans (flushes) the dirty cache lines covering the caller's TX buffer before arming the engine so the DMA reads the CPU-written bytes from memory.
  • ra8_spi_read_dma installs internal_spi_dma_rx_complete as the transfer-end hook so the RX buffer's cache lines are invalidated once the engine has finished writing memory, before the CPU (or the caller's callback) re-reads them.

The per-channel register accessor ra8_spi() and the channel-count constant k_ra8_spi_b_channel_count live in ra8_spi_regs.h; the public DMA API contract is in ra8_spi.h. No other ra8_spi_b.c statics are referenced from here.

Since
0.1.0

Definition in file ra8_spi_b_dma.c.

Function Documentation

◆ internal_dma_args_ok()

ra8_err_t internal_dma_args_ok ( uint8_t channel,
uint16_t len )
static

Report whether a DMA entry point's channel index and length are usable.

Both DMA entry points ask the same two questions of their arguments: is the channel index within k_ra8_spi_b_channel_count, and is the transfer length non-zero. Answering them here keeps each entry point to one early return for argument validation and gives the check a single exit of its own.

Parameters
[in]channelCaller-supplied SPI_B channel index.
[in]lenRequested transfer length in bytes.
Returns
ra8_err_t Argument-validation verdict.
Return values
k_ra8_okBoth the channel index and the length are usable.
k_ra8_err_invalid_argchannel is out of range, or len is zero.
Precondition
The caller has already null-checked its own pointer arguments.
k_ra8_spi_b_channel_count describes the live channel table.
Postcondition
No hardware register is read or written.
The caller's arguments are unchanged.
Note
Thread-safe; the function is pure.
Since
Version 0.1.0

Definition at line 71 of file ra8_spi_b_dma.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_spi_b_channel_count, and RA8_INTERNAL.

Referenced by ra8_spi_read_dma(), and ra8_spi_write_dma().

◆ internal_round_up_to_cache_line()

uint32_t internal_round_up_to_cache_line ( uint32_t bytes)
static

Round a byte count up to a whole number of D-cache lines.

Cache maintenance by address acts on whole cache lines (32 bytes on the Cortex-M85, reported by ra8_cache_dcache_line_bytes()). Rounding the length up to a line multiple guarantees the maintenance call covers the final partial line of the buffer instead of stopping short of it. The line size is a power of two, so the round-up uses a mask.

Parameters
[in]bytesRaw byte count to round.
Returns
bytes rounded up to the next multiple of the D-cache line size.
Return values
0bytes was 0.
Precondition
bytes is small enough that the rounded value does not overflow.
The reported line size is a non-zero power of two.
Postcondition
The result is a whole multiple of ra8_cache_dcache_line_bytes().
The result is greater than or equal to bytes.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 149 of file ra8_spi_b_dma.c.

References ra8_cache_dcache_line_bytes(), and RA8_INTERNAL.

Referenced by internal_spi_dma_rx_complete(), and ra8_spi_write_dma().

◆ internal_spi_dma_rx_complete()

void internal_spi_dma_rx_complete ( void * ctx)
static

RX-DMA transfer-end wrapper: invalidate the buffer, then chain.

Installed as req.on_complete for every ra8_spi_read_dma transfer. Runs from the DMAC transfer-end ISR (or ra8_fake_dma_complete under RA8_OFF_TARGET) once the engine has finished writing out_buf to memory. It invalidates the cache lines spanning out_buf (rounded up to a whole number of lines) so the CPU and the caller's callback re-read the engine-written bytes from memory, then invokes the caller's original completion callback, if any, with its original context. The cache call is a no-op when the D-cache is disabled.

Parameters
[in]ctxPointer to the driver's ra8_spi_dma_rx_ctx_t for the channel.
Precondition
ctx points at a ra8_spi_dma_rx_ctx_t populated by ra8_spi_read_dma.
The RX DMA for the channel has completed (transfer-end signalled).
Postcondition
The cache lines covering rx_buf have been invalidated.
The caller's user_on_complete has been invoked exactly once if set.
Note
Invoked from ISR context; must return quickly and take no locks.
See also
ra8_spi_read_dma
Since
0.1.0

Definition at line 185 of file ra8_spi_b_dma.c.

References internal_round_up_to_cache_line(), ra8_cache_dcache_invalidate_by_addr(), RA8_INTERNAL, ra8_spi_dma_rx_ctx_t::rx_buf, ra8_spi_dma_rx_ctx_t::rx_len, ra8_spi_dma_rx_ctx_t::user_ctx, and ra8_spi_dma_rx_ctx_t::user_on_complete.

Referenced by ra8_spi_read_dma().

◆ 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_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.

Variable Documentation

◆ s_spi_dma_rx_ctx

Per-channel RX-DMA completion bridge, indexed by SPI channel.

Written by ra8_spi_read_dma before arming the transfer and read by internal_spi_dma_rx_complete from ISR context on transfer end.

Note
Single-writer (init context) / single-reader (ISR) per channel.
Warning
Do not modify directly; owned by the DMA RX path.
Since
0.1.0

Definition at line 124 of file ra8_spi_b_dma.c.

Referenced by ra8_spi_read_dma().

◆ s_tag

const char* s_tag = "SPI_B"
static

Definition at line 45 of file ra8_spi_b_dma.c.