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

SD-card font store with self-provisioning – implementation. More...

#include "ra8_sdfont.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_fs.h"
#include "ra8_gpio_constants.h"
#include "ra8_port_utils.h"
#include "ra8_sci_spi.h"
#include "ra8_sdmmc_spi.h"
#include "ra8_spi.h"
Include dependency graph for ra8_sdfont.c:

Go to the source code of this file.

Data Structures

struct  sdfont_ctx_t
 Bus context handed to the ra8_sdmmc_spi transport callbacks. More...

Enumerations

enum  sdfont_limits_t : uint32_t { k_sdfont_min_bytes = 16U }
 Sanity floors for a loaded font. More...

Functions

static ra8_err_t internal_set_clock (void *ctx, uint32_t hz)
 Transport set-clock callback: retune the SCI baud divider.
static ra8_err_t internal_cs (void *ctx, bool asserted)
 Transport chip-select callback: drive CS low (asserted) or high.
static ra8_err_t internal_xfer (void *ctx, const uint8_t *tx, uint8_t *rx, uint32_t len)
 Transport transfer callback: full-duplex byte exchange.
static ra8_err_t internal_bringup_spi (const ra8_sdfont_cfg_t *cfg)
 Route the Pmod SPI pins to SCI Simple-SPI and init the channel.
static ra8_err_t internal_mount (ra8_fs_mount_t **out_mount)
 Run SD identification and mount the FAT volume.
static ra8_err_t internal_open_or_provision (const ra8_sdfont_cfg_t *cfg, ra8_fs_mount_t *mount, const char *name, ra8_fs_file_t **out_file, ra8_sdfont_source_t *out_source)
 Open the font for reading, provisioning from the blob if absent.
static ra8_err_t internal_read_font (ra8_fs_file_t *file, uint8_t *buf, uint32_t cap, uint32_t *out_len)
 Read an open font into the caller buffer and validate its length.
static ra8_err_t internal_validate (const ra8_sdfont_cfg_t *cfg, const uint8_t *buf, const uint32_t *out_len, uint32_t cap)
 Validate the public load arguments (precondition gate).
ra8_err_t ra8_sdfont_load (const ra8_sdfont_cfg_t *cfg, uint8_t *buf, uint32_t cap, uint32_t *out_len, ra8_sdfont_source_t *out_source)
 Mount the Pmod SD card and load a font, provisioning it if absent.

Variables

static const char * s_tag = "SDFONT"
 Log tag for diagnostics emitted by this module.
static const char * s_default_name = "FONT.OTF"
 Default 8.3 font filename used when the caller passes NULL.
static sdfont_ctx_t s_ctx
 Single-shot transport context for the SD bus shim.

Detailed Description

SD-card font store with self-provisioning – implementation.

Tag
[Ring 4 / SDFont] {World: NS}

Implementation of the helper declared in ra8_sdfont.h. The flow is a thin orchestration above three lower-ring drivers and carries no register access of its own:

  1. Route the four Pmod SPI pins (ra8_pfs_route_peripheral + a GPIO CS) and bring up the SCI channel in Simple-SPI mode (ra8_sci_spi).
  2. Run the SD identification sequence and bind a FAT backend (ra8_sdmmc_spi), then mount it (ra8_fs).
  3. Open the font for reading; on k_ra8_err_not_found with a provisioning blob configured, write the blob (ra8_fs_write_file) and re-open – so the bytes returned are always the on-card copy.

The ra8_sdmmc_spi transport callbacks are owned here and read their bus context from a single file-scope s_ctx populated at the top of ra8_sdfont_load (single-shot, init-context helper). Error propagation uses the project's dominant light if (err != k_ra8_ok) idiom rather than the logging RA8_RETURN_ON_ERROR: each lower call already logs at its own tag.

Definition in file ra8_sdfont.c.

Enumeration Type Documentation

◆ sdfont_limits_t

enum sdfont_limits_t : uint32_t

Sanity floors for a loaded font.

Since
0.1.0
Enumerator
k_sdfont_min_bytes 

Smallest plausible TTF/OTF header – guards a truncated read.

Definition at line 66 of file ra8_sdfont.c.

Function Documentation

◆ internal_bringup_spi()

ra8_err_t internal_bringup_spi ( const ra8_sdfont_cfg_t * cfg)
static

Route the Pmod SPI pins to SCI Simple-SPI and init the channel.

Caches the bus context into s_ctx for the transport shim, muxes SCK/CIPO/COPI to SCI async and claims CS as a GPIO output held high, then initialises the SCI channel at the SD power-on clock.

Parameters
[in]cfgNon-NULL bus descriptor.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPins routed, CS claimed, SCI channel up.
k_ra8_err_null_ptrcfg is NULL.
otherPropagated from ra8_pfs_route_peripheral / ra8_sci_spi_init.
Precondition
ra8_cgc_init has run; cfg->pclka_hz is the live PCLKA rate.
The Pmod2 pins are free (not routed to another peripheral).
Postcondition
On success the four pins are muxed and the SCI channel is configured.
s_ctx holds the channel / PCLKA / CS for the transport callbacks.
Note
CS is a plain GPIO output (SD SPI-mode holds CS across a frame).
Since
0.1.0

Definition at line 188 of file ra8_sdfont.c.

References ra8_sdfont_cfg_t::cipo, ra8_sdfont_cfg_t::copi, ra8_sdfont_cfg_t::cs, k_ra8_level_high, k_ra8_ok, k_ra8_psel_sci_async, k_ra8_sdmmc_spi_clock_init_hz, k_ra8_spi_mode_0, ra8_sdfont_cfg_t::pclka_hz, RA8_CHECK_NULL_PTR, ra8_gpio_output_init(), RA8_INTERNAL, ra8_pfs_route_peripheral(), ra8_sci_spi_init(), s_ctx, s_tag, ra8_sdfont_cfg_t::sck, and ra8_sdfont_cfg_t::spi_channel.

Referenced by ra8_sdfont_load().

◆ internal_cs()

ra8_err_t internal_cs ( void * ctx,
bool asserted )
static

Transport chip-select callback: drive CS low (asserted) or high.

Thin DI shim bound into the ra8_sdmmc_spi transport: drives the chip-select GPIO from the bus context (active-low select).

Parameters
[in]ctxBus context (sdfont_ctx_t*); must be non-NULL.
[in]assertedtrue to select (CS low), false to release (CS high).
Returns
ra8_err_t passthrough from ra8_gpio_write.
Return values
k_ra8_err_null_ptrctx is NULL.
Precondition
ctx points to the live s_ctx.
The CS pin was claimed as a GPIO output by internal_bringup_spi.
Postcondition
The CS pin reflects asserted on success.
No other pin or bus state changes.
Note
ISR-unsafe. ctx is non-const to match the transport function-pointer type (constParameterCallback suppressed in-tree).
Since
0.1.0

Definition at line 134 of file ra8_sdfont.c.

References sdfont_ctx_t::cs, k_ra8_level_high, k_ra8_level_low, RA8_CHECK_NULL_PTR, ra8_gpio_write(), RA8_INTERNAL, and s_tag.

Referenced by internal_mount().

◆ internal_mount()

ra8_err_t internal_mount ( ra8_fs_mount_t ** out_mount)
static

Run SD identification and mount the FAT volume.

Builds the ra8_sdmmc_spi transport over the module shims (bound to s_ctx), runs the SPI-mode card identification sequence, binds a FAT backend, and mounts it through ra8_fs.

Parameters
[out]out_mountNon-NULL; receives the mounted volume handle.
Returns
ra8_err_t Error code.
Return values
k_ra8_okCard identified and FAT volume mounted.
k_ra8_err_null_ptrout_mount is NULL.
otherPropagated from ra8_sdmmc_spi_* / ra8_fs_mount.
Precondition
internal_bringup_spi returned k_ra8_ok and s_ctx is populated.
A FAT-formatted card is seated in the Pmod2 slot.
Postcondition
On success *out_mount is a usable FAT mount on the SD card.
On failure no FAT volume is left mounted.
Note
Blocking, polled SD bring-up.
Since
0.1.0

Definition at line 238 of file ra8_sdfont.c.

References internal_cs(), internal_set_clock(), internal_xfer(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_fs_mount(), RA8_INTERNAL, ra8_sdmmc_spi_bind_fs_backend(), ra8_sdmmc_spi_init(), s_ctx, and s_tag.

Referenced by ra8_sdfont_load().

◆ internal_open_or_provision()

ra8_err_t internal_open_or_provision ( const ra8_sdfont_cfg_t * cfg,
ra8_fs_mount_t * mount,
const char * name,
ra8_fs_file_t ** out_file,
ra8_sdfont_source_t * out_source )
static

Open the font for reading, provisioning from the blob if absent.

Opens name read-only; if that returns k_ra8_err_not_found and a non-empty provisioning blob is configured, writes the blob to the card and re-opens it – so the returned handle is always the on-card copy. The provisioning conditions are separate single-condition guards (no compound decision) so each branch is independently covered.

Parameters
[in]cfgNon-NULL bus + provisioning descriptor.
[in]mountNon-NULL mounted FAT volume.
[in]nameNon-NULL 8.3 filename.
[out]out_fileNon-NULL; receives the opened read handle.
[out]out_sourceNon-NULL (caller-guaranteed); set to card vs provisioned.
Returns
ra8_err_t Error code.
Return values
k_ra8_okFile open for reading.
k_ra8_err_null_ptrcfg, mount, or out_file is NULL.
k_ra8_err_not_foundFile absent and provisioning disabled.
otherPropagated from ra8_fs_open / ra8_fs_write_file.
Precondition
mount is a live FAT volume.
out_source points to caller-owned storage.
Postcondition
On success *out_file is readable and *out_source is set.
On a provisioning write the blob exists on the card as name.
Note
Provisioning writes the blob only on a k_ra8_err_not_found open.
Since
0.1.0

Definition at line 284 of file ra8_sdfont.c.

References k_ra8_err_not_found, k_ra8_fs_mode_read, k_ra8_ok, k_ra8_sdfont_source_card, k_ra8_sdfont_source_provisioned, ra8_sdfont_cfg_t::provision_blob, ra8_sdfont_cfg_t::provision_len, RA8_CHECK_NULL_PTR, ra8_fs_open(), ra8_fs_write_file(), RA8_INTERNAL, and s_tag.

Referenced by ra8_sdfont_load().

◆ internal_read_font()

ra8_err_t internal_read_font ( ra8_fs_file_t * file,
uint8_t * buf,
uint32_t cap,
uint32_t * out_len )
static

Read an open font into the caller buffer and validate its length.

Reads up to cap bytes, closes the handle on every path, and rejects a truncated read (shorter than a usable font header) so the caller never hands a stub blob to ra8_reflow_init.

Parameters
[in]fileNon-NULL open read handle (closed before return).
[out]bufNon-NULL destination buffer.
[in]capCapacity of buf in bytes.
[out]out_lenNon-NULL; receives the bytes read.
Returns
ra8_err_t Error code.
Return values
k_ra8_okFont read; *out_len in [16, cap].
k_ra8_err_null_ptrA required pointer is NULL.
k_ra8_err_no_dataRead fewer than a usable font header.
otherPropagated from ra8_fs_read.
Precondition
file is open for reading.
buf has room for cap bytes.
Postcondition
file is closed on every return path.
On k_ra8_ok *out_len holds the byte count read.
Note
Blocking read.
Since
0.1.0

Definition at line 339 of file ra8_sdfont.c.

References k_ra8_err_no_data, k_ra8_ok, k_sdfont_min_bytes, RA8_CHECK_NULL_PTR, ra8_fs_close(), ra8_fs_read(), and s_tag.

Referenced by ra8_sdfont_load().

◆ internal_set_clock()

ra8_err_t internal_set_clock ( void * ctx,
uint32_t hz )
static

Transport set-clock callback: retune the SCI baud divider.

Thin DI shim bound into the ra8_sdmmc_spi transport: recovers the SCI channel + PCLKA from the bus context and retunes the baud divider.

Parameters
[in]ctxBus context (sdfont_ctx_t*); must be non-NULL.
[in]hzTarget SPI clock in Hz.
Returns
ra8_err_t passthrough from ra8_sci_spi_set_clock.
Return values
k_ra8_err_null_ptrctx is NULL.
Precondition
ctx points to the live s_ctx.
ra8_sci_spi_init has configured the SCI channel.
Postcondition
The SCI channel clock is retuned to hz on success.
No bus transaction is issued (clock configuration only).
Note
ISR-unsafe; blocking. ctx is non-const to match the transport function-pointer type (constParameterCallback suppressed in-tree).
Since
0.1.0

Definition at line 111 of file ra8_sdfont.c.

References sdfont_ctx_t::channel, sdfont_ctx_t::pclka_hz, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_sci_spi_set_clock(), and s_tag.

Referenced by internal_mount().

◆ internal_validate()

ra8_err_t internal_validate ( const ra8_sdfont_cfg_t * cfg,
const uint8_t * buf,
const uint32_t * out_len,
uint32_t cap )
static

Validate the public load arguments (precondition gate).

Centralises the null-pointer and capacity checks for ra8_sdfont_load so the orchestrator stays within the per-function statement budget while keeping the contract explicit.

Parameters
[in]cfgBus + provisioning descriptor.
[in]bufDestination buffer.
[in]out_lenLength output.
[in]capBuffer capacity in bytes.
Returns
ra8_err_t Error code.
Return values
k_ra8_okAll arguments valid.
k_ra8_err_null_ptrcfg, buf, or out_len is NULL.
k_ra8_err_invalid_argcap is 0.
Precondition
Called first from ra8_sdfont_load, before any bus access.
cfg / buf / out_len are the caller's load arguments.
Postcondition
On k_ra8_ok every pointer is non-NULL and cap > 0.
No side effects on any path (pure gate).
Note
Reentrant and stateless; safe to call from any context.
Since
0.1.0

Definition at line 378 of file ra8_sdfont.c.

References k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, and s_tag.

Referenced by ra8_sdfont_load().

◆ internal_xfer()

ra8_err_t internal_xfer ( void * ctx,
const uint8_t * tx,
uint8_t * rx,
uint32_t len )
static

Transport transfer callback: full-duplex byte exchange.

Thin DI shim bound into the ra8_sdmmc_spi transport: forwards a full-duplex byte exchange to the SCI channel from the bus context.

Parameters
[in]ctxBus context (sdfont_ctx_t*); must be non-NULL.
[in]txTX bytes, or NULL to shift idle 0xFF.
[out]rxRX buffer, or NULL to discard.
[in]lenByte count; must be > 0.
Returns
ra8_err_t passthrough from ra8_sci_spi_xfer.
Return values
k_ra8_err_null_ptrctx is NULL.
Precondition
ctx points to the live s_ctx.
ra8_sci_spi_init has configured the channel and CS is asserted.
Postcondition
len bytes are clocked on the bus on success.
rx holds the received bytes when non-NULL.
Note
ISR-unsafe; blocking. ctx is non-const to match the transport function-pointer type (constParameterCallback suppressed in-tree).
Since
0.1.0

Definition at line 159 of file ra8_sdfont.c.

References sdfont_ctx_t::channel, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_sci_spi_xfer(), and s_tag.

Referenced by internal_mount().

◆ ra8_sdfont_load()

ra8_err_t ra8_sdfont_load ( const ra8_sdfont_cfg_t * cfg,
uint8_t * buf,
uint32_t cap,
uint32_t * out_len,
ra8_sdfont_source_t * out_source )
nodiscard

Mount the Pmod SD card and load a font, provisioning it if absent.

Routes the configured SPI pins to SCI Simple-SPI, claims chip-select as a GPIO output, brings up the card through ra8_sdmmc_spi, mounts the FAT volume through ra8_fs, and opens ra8_sdfont_cfg_t::filename for reading. If the file is absent and ra8_sdfont_cfg_t::provision_blob is non-NULL, the blob is written to the card with ra8_fs_write_file, then re-opened and read back – so the returned bytes are always the on-card copy, byte-for-byte identical to what a later boot will read. The font is copied into buf and the FAT volume is unmounted before return.

Parameters
[in]cfgNon-NULL bus + provisioning descriptor.
[out]bufNon-NULL destination buffer for the font bytes.
[in]capCapacity of buf in bytes; must be > 0.
[out]out_lenNon-NULL; receives the number of bytes loaded.
[out]out_sourceOptional (may be NULL); receives whether the font came from the card or was provisioned this boot.
Returns
ra8_err_t Error code.
Return values
k_ra8_okFont loaded; *out_len holds its length.
k_ra8_err_null_ptrcfg, buf, or out_len is NULL.
k_ra8_err_invalid_argcap is 0.
k_ra8_err_not_foundFile absent and provisioning disabled (NULL blob).
k_ra8_err_no_dataFile present but shorter than a usable font header.
otherPropagated from ra8_sci_spi, ra8_sdmmc_spi, or ra8_fs (no card, mount failure, write failure...).
Precondition
ra8_cgc_init has run and ra8_sdfont_cfg_t::pclka_hz is the live PCLKA rate.
buf points to at least cap writable bytes (SDRAM-backed for big fonts).
Postcondition
On success *out_len is in [16, cap] and buf holds the font.
On any return the FAT volume opened here is unmounted.
Note
Not thread-safe and not ISR-safe: blocking, polled SPI; single-shot module state backs the transport shim. Call once from init context.
See also
ra8_sdfont_source_t
Since
0.1.0

Definition at line 392 of file ra8_sdfont.c.

References ra8_sdfont_cfg_t::filename, internal_bringup_spi(), internal_mount(), internal_open_or_provision(), internal_read_font(), internal_validate(), k_ra8_ok, k_ra8_sdfont_source_card, ra8_fs_unmount(), and s_default_name.

Referenced by er_try_load_font(), and sfr_load_font_or_halt().

Variable Documentation

◆ s_ctx

sdfont_ctx_t s_ctx
static

Single-shot transport context for the SD bus shim.

Warning
Mutated at the top of ra8_sdfont_load; not thread-safe.
Since
0.1.0

Definition at line 88 of file ra8_sdfont.c.

Referenced by internal_bringup_spi(), internal_mount(), and main().

◆ s_default_name

const char* s_default_name = "FONT.OTF"
static

Default 8.3 font filename used when the caller passes NULL.

Note
File-scope, read-only.
Since
0.1.0

Definition at line 59 of file ra8_sdfont.c.

Referenced by ra8_sdfont_load().

◆ s_tag

const char* s_tag = "SDFONT"
static

Log tag for diagnostics emitted by this module.

Note
File-scope, read-only after init.
Since
0.1.0

Definition at line 51 of file ra8_sdfont.c.