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

Per-device configuration record – codec, two-copy resolver, commit. More...

#include "ra8_devcfg.h"
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
Include dependency graph for ra8_devcfg.c:

Go to the source code of this file.

Enumerations

enum  ra8_devcfg_crc_t : uint32_t {
  k_ra8_devcfg_crc_init = 0xFFFFFFFFU ,
  k_ra8_devcfg_crc_poly = 0xEDB88320U
}
 IEEE 802.3 CRC-32 parameters. More...
enum  ra8_devcfg_bits_t : uint8_t {
  k_ra8_devcfg_bits_per_byte = 8U ,
  k_ra8_devcfg_byte_shift = 8U ,
  k_ra8_devcfg_byte_mask = 0xFFU ,
  k_ra8_devcfg_off_b0 = 0U ,
  k_ra8_devcfg_off_b1 = 1U ,
  k_ra8_devcfg_off_b2 = 2U ,
  k_ra8_devcfg_off_b3 = 3U
}
 Byte / word packing constants (no magic numbers). More...
enum  ra8_devcfg_state_t : uint8_t {
  k_ra8_devcfg_state_unloaded = 0U ,
  k_ra8_devcfg_state_loaded = 1U ,
  k_ra8_devcfg_state_unprovisioned = 2U
}
 Module cache state established by ra8_devcfg_load. More...

Functions

static uint32_t internal_devcfg_crc32 (const uint8_t *data, uint32_t len)
 Compute the IEEE 802.3 CRC-32 of a byte span.
static void internal_devcfg_pack_le16 (uint8_t *dst, uint16_t val)
 Store a little-endian 16-bit value into a blob.
static void internal_devcfg_pack_le32 (uint8_t *dst, uint32_t val)
 Store a little-endian 32-bit value into a blob.
static uint16_t internal_devcfg_unpack_le16 (const uint8_t *src)
 Load a little-endian 16-bit value from a blob.
static uint32_t internal_devcfg_unpack_le32 (const uint8_t *src)
 Load a little-endian 32-bit value from a blob.
static void internal_devcfg_serialize (const ra8_devcfg_record_t *rec, uint32_t seq, uint8_t *buf)
 Serialise a record into a k_ra8_devcfg_record_len byte buffer.
static void internal_devcfg_deserialize (const uint8_t *buf, ra8_devcfg_record_t *out)
 Decode a validated record buffer into a ra8_devcfg_record_t.
static bool internal_devcfg_copy_valid (const uint8_t *buf)
 Report whether a serialised copy passes every integrity gate.
static bool internal_devcfg_probe (const ra8_devcfg_store_t *store, uint32_t offset, ra8_devcfg_record_t *out)
 Read one copy through the store and validate it.
static uint32_t internal_devcfg_target (bool valid0, uint32_t seq0, bool valid1, uint32_t seq1)
 Choose the copy offset a new record overwrites (the stale slot).
static void internal_devcfg_plan (const ra8_devcfg_store_t *store, uint32_t *out_target, uint32_t *out_seq)
 Probe both copies and choose the commit target slot and next sequence.
static ra8_err_t internal_devcfg_write_record (const ra8_devcfg_store_t *store, uint32_t target, const uint8_t *buf)
 Program a serialised record to a slot with the header page written last.
ra8_err_t ra8_devcfg_load (const ra8_devcfg_store_t *store)
 Load and resolve the device configuration record from both copies.
ra8_err_t ra8_devcfg_get_vcom_mv (uint16_t *out_mv)
 Fetch the validated panel VCOM magnitude in millivolts.
ra8_err_t ra8_devcfg_get_body (const ra8_devcfg_body_t **out_body)
 Expose the decoded body of the loaded record.
bool ra8_devcfg_is_blank (void)
 Report whether neither record copy is valid (the provisioning gate).
ra8_err_t ra8_devcfg_commit (const ra8_devcfg_store_t *store, const ra8_devcfg_record_t *rec)
 Commit a new record to the stale copy slot with header-last ordering.
void ra8_devcfg_reset (void)
 Drop the cached record so a later load re-resolves from scratch.

Variables

static const char *const s_tag = "DEVCFG"
 Logging tag used by every diagnostic path in this TU.
static ra8_devcfg_state_t s_state = k_ra8_devcfg_state_unloaded
 Current cache state.
static ra8_devcfg_record_t s_record = {}
 The resolved record cached by the last successful ra8_devcfg_load.

Detailed Description

Per-device configuration record – codec, two-copy resolver, commit.

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

Implements the hardware-agnostic half of ra8_devcfg.h: a self-describing, CRC-protected record codec; a boot-time resolver that walks the two copies and picks the surviving / newest one or reports UNPROVISIONED; and a header-last commit. No HAL header is included – the durable medium is reached only through the injected ra8_devcfg_store_t seam, which is what lets every branch below run on the host. The extra-MRAM backing lives in the companion translation unit ra8_devcfg_store_extra_mram.c.

Definition in file ra8_devcfg.c.

Enumeration Type Documentation

◆ ra8_devcfg_bits_t

enum ra8_devcfg_bits_t : uint8_t

Byte / word packing constants (no magic numbers).

Enumerator
k_ra8_devcfg_bits_per_byte 

CRC inner-loop bound.

k_ra8_devcfg_byte_shift 

Bits per byte.

k_ra8_devcfg_byte_mask 

Low-byte extraction mask.

k_ra8_devcfg_off_b0 

Little-endian byte 0.

k_ra8_devcfg_off_b1 

Little-endian byte 1.

k_ra8_devcfg_off_b2 

Little-endian byte 2.

k_ra8_devcfg_off_b3 

Little-endian byte 3.

Definition at line 60 of file ra8_devcfg.c.

◆ ra8_devcfg_crc_t

enum ra8_devcfg_crc_t : uint32_t

IEEE 802.3 CRC-32 parameters.

Bit-banged rather than table-driven so the module carries no CRC table for a checksum it runs over 96 bytes a handful of times per boot. The polynomial matches ra8_epd_cal.c and ra8_touch_cal.c so every calibration record in the tree shares one CRC.

Enumerator
k_ra8_devcfg_crc_init 

CRC seed / final XOR.

k_ra8_devcfg_crc_poly 

Reversed IEEE 802.3 poly.

Definition at line 51 of file ra8_devcfg.c.

◆ ra8_devcfg_state_t

enum ra8_devcfg_state_t : uint8_t

Module cache state established by ra8_devcfg_load.

Enumerator
k_ra8_devcfg_state_unloaded 

No load attempted this boot.

k_ra8_devcfg_state_loaded 

A valid record is cached.

k_ra8_devcfg_state_unprovisioned 

Load ran; neither copy was valid.

Definition at line 91 of file ra8_devcfg.c.

Function Documentation

◆ internal_devcfg_copy_valid()

bool internal_devcfg_copy_valid ( const uint8_t * buf)
staticnodiscard

Report whether a serialised copy passes every integrity gate.

Four sequential, independent gates – magic word, known schema, expected record_len, CRC-32 over the body. Any one failing rejects the copy; all four passing accepts it. Each gate is a single condition, so the copy is accepted only on the AND of all four.

Parameters
[in]bufk_ra8_devcfg_record_len byte buffer to test; non-NULL.
Returns
true iff the copy is a valid, current-schema record.
Return values
trueAll four gates passed.
falseMagic, schema, record_len or CRC failed.
Precondition
buf holds at least k_ra8_devcfg_record_len bytes.
buf was filled by a backing-store read.
Postcondition
No state mutated.
The verdict depends only on buf.
Note
Thread-safe (pure; no statics).
Since
0.1.0

Definition at line 376 of file ra8_devcfg.c.

References internal_devcfg_crc32(), internal_devcfg_unpack_le16(), internal_devcfg_unpack_le32(), k_ra8_devcfg_body_bytes, k_ra8_devcfg_hdr_bytes, k_ra8_devcfg_magic, k_ra8_devcfg_off_crc, k_ra8_devcfg_off_magic, k_ra8_devcfg_off_reclen, k_ra8_devcfg_off_schema, k_ra8_devcfg_record_len, and k_ra8_devcfg_schema_ver.

Referenced by internal_devcfg_probe().

◆ internal_devcfg_crc32()

uint32_t internal_devcfg_crc32 ( const uint8_t * data,
uint32_t len )
staticnodiscard

Compute the IEEE 802.3 CRC-32 of a byte span.

Bit-banged reflected-polynomial form; no lookup table. Used for the record body checksum stored in the header.

Parameters
[in]dataBytes to checksum; non-NULL.
[in]lenNumber of bytes.
Returns
The CRC-32 of data[0 .. len).
Return values
0xFFFFFFFF..0x00000000The reflected CRC-32 over the span.
Precondition
data holds at least len readable bytes.
len is the exact span length to checksum.
Postcondition
No state mutated.
The result depends only on data and len.
Note
Thread-safe (pure; no statics).
Since
0.1.0

Definition at line 139 of file ra8_devcfg.c.

References k_ra8_devcfg_bits_per_byte, k_ra8_devcfg_crc_init, and k_ra8_devcfg_crc_poly.

Referenced by internal_devcfg_copy_valid(), and internal_devcfg_serialize().

◆ internal_devcfg_deserialize()

void internal_devcfg_deserialize ( const uint8_t * buf,
ra8_devcfg_record_t * out )
static

Decode a validated record buffer into a ra8_devcfg_record_t.

Inverse of internal_devcfg_serialize; unpacks each body field and the header discriminators. Assumes the buffer already passed validation, so no integrity check is repeated here.

Parameters
[in]bufValidated k_ra8_devcfg_record_len byte buffer; non-NULL.
[out]outReceives the decoded record; non-NULL.
Precondition
buf passed internal_devcfg_copy_valid.
out is a writable record sink.
Postcondition
out mirrors the body, flags, seq and schema of buf.
No integrity gate is re-evaluated.
Note
Not thread-safe; called only from the resolver.
Since
0.1.0

Definition at line 331 of file ra8_devcfg.c.

References ra8_devcfg_record_t::body, ra8_devcfg_record_t::flags, internal_devcfg_unpack_le16(), internal_devcfg_unpack_le32(), k_ra8_devcfg_off_fixture, k_ra8_devcfg_off_flags, k_ra8_devcfg_off_hw_rev, k_ra8_devcfg_off_key_id, k_ra8_devcfg_off_mfg_date, k_ra8_devcfg_off_panel_lut, k_ra8_devcfg_off_panel_serial, k_ra8_devcfg_off_schema, k_ra8_devcfg_off_seq, k_ra8_devcfg_off_serial, k_ra8_devcfg_off_touch_cal, k_ra8_devcfg_off_vcom, k_ra8_devcfg_panel_lut_len, k_ra8_devcfg_panel_serial_len, k_ra8_devcfg_serial_len, k_ra8_devcfg_touch_cal_len, memcpy(), ra8_devcfg_record_t::schema_version, and ra8_devcfg_record_t::seq.

Referenced by internal_devcfg_probe().

◆ internal_devcfg_pack_le16()

void internal_devcfg_pack_le16 ( uint8_t * dst,
uint16_t val )
static

Store a little-endian 16-bit value into a blob.

The record is serialised byte-at-a-time in an explicit byte order so a blob written on the host deserialises identically on the target.

Parameters
[out]dstDestination for two bytes; non-NULL.
[in]valValue to pack.
Precondition
dst has room for two bytes.
dst points inside the serialisation blob.
Postcondition
dst holds val little-endian.
Exactly two bytes are written.
Note
Not thread-safe; called only from the serialiser.
Since
0.1.0

Definition at line 170 of file ra8_devcfg.c.

References k_ra8_devcfg_byte_mask, k_ra8_devcfg_byte_shift, k_ra8_devcfg_off_b0, and k_ra8_devcfg_off_b1.

Referenced by internal_devcfg_serialize().

◆ internal_devcfg_pack_le32()

void internal_devcfg_pack_le32 ( uint8_t * dst,
uint32_t val )
static

Store a little-endian 32-bit value into a blob.

The 32-bit counterpart of internal_devcfg_pack_le16, used for the magic word, sequence, CRC and flags. Same explicit byte order.

Parameters
[out]dstDestination for four bytes; non-NULL.
[in]valValue to pack.
Precondition
dst has room for four bytes.
dst points inside the serialisation blob.
Postcondition
dst holds val little-endian.
Exactly four bytes are written.
Note
Not thread-safe; called only from the serialiser.
Since
0.1.0

Definition at line 195 of file ra8_devcfg.c.

References k_ra8_devcfg_byte_mask, k_ra8_devcfg_byte_shift, k_ra8_devcfg_off_b0, k_ra8_devcfg_off_b1, k_ra8_devcfg_off_b2, and k_ra8_devcfg_off_b3.

Referenced by internal_devcfg_serialize().

◆ internal_devcfg_plan()

void internal_devcfg_plan ( const ra8_devcfg_store_t * store,
uint32_t * out_target,
uint32_t * out_seq )
static

Probe both copies and choose the commit target slot and next sequence.

Reads the two existing copies to find the newest valid sequence (0 when neither is valid), stamps the new record one past it, and selects the stale slot via internal_devcfg_target so the newest good copy is never the write target.

Parameters
[in]storeStore seam; non-NULL with non-NULL read.
[out]out_targetReceives the slot offset to program; non-NULL.
[out]out_seqReceives the sequence to stamp; non-NULL.
Precondition
store->read is callable.
out_target and out_seq are writable sinks.
Postcondition
*out_seq exceeds every valid copy's sequence.
*out_target is the stale / free slot offset.
Note
Not thread-safe; provisioning path only.
Since
0.1.0

Definition at line 494 of file ra8_devcfg.c.

References internal_devcfg_probe(), internal_devcfg_target(), k_ra8_devcfg_copy0_off, k_ra8_devcfg_copy1_off, and ra8_devcfg_record_t::seq.

Referenced by ra8_devcfg_commit().

◆ internal_devcfg_probe()

bool internal_devcfg_probe ( const ra8_devcfg_store_t * store,
uint32_t offset,
ra8_devcfg_record_t * out )
staticnodiscard

Read one copy through the store and validate it.

Reads k_ra8_devcfg_record_len bytes at offset through the store seam and runs the integrity gate. A read fault or blank window is treated as "copy absent" so the resolver falls through rather than failing the whole load.

Parameters
[in]storeStore seam; non-NULL with non-NULL read.
[in]offsetCopy offset in the devcfg region.
[out]outReceives the decoded record when valid; non-NULL.
Returns
true when the copy read and validated; false otherwise.
Return values
trueout holds the decoded copy.
falseRead fault, blank window, or failed integrity gate.
Precondition
store->read is callable.
out is a writable record sink.
Postcondition
On true out holds the decoded copy; on false out is untouched.
No backing store is programmed.
Note
Not thread-safe; boot / provisioning path only.
Since
0.1.0

Definition at line 422 of file ra8_devcfg.c.

References internal_devcfg_copy_valid(), internal_devcfg_deserialize(), k_ra8_devcfg_record_len, k_ra8_ok, and ra8_devcfg_store_t::read.

Referenced by internal_devcfg_plan(), and ra8_devcfg_load().

◆ internal_devcfg_serialize()

void internal_devcfg_serialize ( const ra8_devcfg_record_t * rec,
uint32_t seq,
uint8_t * buf )
static

Serialise a record into a k_ra8_devcfg_record_len byte buffer.

Writes the body at its field offsets, then the header (magic, schema, record_len, seq, CRC over the body, flags). The CRC covers only the body span, matching the header-last commit discipline.

Parameters
[in]recRecord whose body and flags are serialised; non-NULL.
[in]seqSequence number to stamp into the header.
[out]bufDestination of k_ra8_devcfg_record_len bytes; non-NULL.
Precondition
buf has room for k_ra8_devcfg_record_len bytes.
rec points at a fully-populated record.
Postcondition
buf holds a CRC-valid serialised record with sequence seq.
The header CRC matches the serialised body span.
Note
Not thread-safe; called only from the commit path.
Since
0.1.0

Definition at line 284 of file ra8_devcfg.c.

References ra8_devcfg_record_t::body, ra8_devcfg_record_t::flags, internal_devcfg_crc32(), internal_devcfg_pack_le16(), internal_devcfg_pack_le32(), k_ra8_devcfg_body_bytes, k_ra8_devcfg_hdr_bytes, k_ra8_devcfg_magic, k_ra8_devcfg_off_crc, k_ra8_devcfg_off_fixture, k_ra8_devcfg_off_flags, k_ra8_devcfg_off_hw_rev, k_ra8_devcfg_off_key_id, k_ra8_devcfg_off_magic, k_ra8_devcfg_off_mfg_date, k_ra8_devcfg_off_panel_lut, k_ra8_devcfg_off_panel_serial, k_ra8_devcfg_off_reclen, k_ra8_devcfg_off_schema, k_ra8_devcfg_off_seq, k_ra8_devcfg_off_serial, k_ra8_devcfg_off_touch_cal, k_ra8_devcfg_off_vcom, k_ra8_devcfg_panel_lut_len, k_ra8_devcfg_panel_serial_len, k_ra8_devcfg_record_len, k_ra8_devcfg_schema_ver, k_ra8_devcfg_serial_len, k_ra8_devcfg_touch_cal_len, memcpy(), and memset().

Referenced by ra8_devcfg_commit().

◆ internal_devcfg_target()

uint32_t internal_devcfg_target ( bool valid0,
uint32_t seq0,
bool valid1,
uint32_t seq1 )
staticnodiscard

Choose the copy offset a new record overwrites (the stale slot).

Prefers an invalid slot so a valid record is never clobbered; when both are valid, targets the lower seq so the newest survives the write window.

Parameters
[in]valid0Copy-0 validity.
[in]seq0Copy-0 sequence (meaningful only when valid0).
[in]valid1Copy-1 validity.
[in]seq1Copy-1 sequence (meaningful only when valid1).
Returns
The offset of the slot to program.
Return values
k_ra8_devcfg_copy0_offCopy 0 is the stale / free slot.
k_ra8_devcfg_copy1_offCopy 1 is the stale / free slot.
Precondition
seqN reflects a read copy when validN is true.
At least one slot is available to program.
Postcondition
No state mutated.
The chosen slot is never the sole newest valid copy.
Note
Thread-safe (pure; no statics).
Since
0.1.0

Definition at line 461 of file ra8_devcfg.c.

References k_ra8_devcfg_copy0_off, and k_ra8_devcfg_copy1_off.

Referenced by internal_devcfg_plan().

◆ internal_devcfg_unpack_le16()

uint16_t internal_devcfg_unpack_le16 ( const uint8_t * src)
staticnodiscard

Load a little-endian 16-bit value from a blob.

Inverse of internal_devcfg_pack_le16; reads the two bytes in the explicit record byte order.

Parameters
[in]srcTwo source bytes; non-NULL.
Returns
The unpacked value.
Return values
0x0000..0xFFFFThe little-endian value at src.
Precondition
src holds at least two readable bytes.
src points inside a serialised record.
Postcondition
No state mutated.
The result depends only on src[0..1].
Note
Thread-safe (pure; no statics).
Since
0.1.0

Definition at line 224 of file ra8_devcfg.c.

References k_ra8_devcfg_byte_shift, k_ra8_devcfg_off_b0, and k_ra8_devcfg_off_b1.

Referenced by internal_devcfg_copy_valid(), and internal_devcfg_deserialize().

◆ internal_devcfg_unpack_le32()

uint32_t internal_devcfg_unpack_le32 ( const uint8_t * src)
staticnodiscard

Load a little-endian 32-bit value from a blob.

Inverse of internal_devcfg_pack_le32; reads the four bytes in the explicit record byte order.

Parameters
[in]srcFour source bytes; non-NULL.
Returns
The unpacked value.
Return values
0x00000000..0xFFFFFFFFThe little-endian value at src.
Precondition
src holds at least four readable bytes.
src points inside a serialised record.
Postcondition
No state mutated.
The result depends only on src[0..3].
Note
Thread-safe (pure; no statics).
Since
0.1.0

Definition at line 250 of file ra8_devcfg.c.

References k_ra8_devcfg_byte_shift, k_ra8_devcfg_off_b0, k_ra8_devcfg_off_b1, k_ra8_devcfg_off_b2, and k_ra8_devcfg_off_b3.

Referenced by internal_devcfg_copy_valid(), and internal_devcfg_deserialize().

◆ internal_devcfg_write_record()

ra8_err_t internal_devcfg_write_record ( const ra8_devcfg_store_t * store,
uint32_t target,
const uint8_t * buf )
staticnodiscard

Program a serialised record to a slot with the header page written last.

Writes the body span first and the 32-byte header page last, so a power cut before the header lands leaves that slot header-invalid and the other copy the sole survivor – there is never a window with zero valid records.

Parameters
[in]storeStore seam; non-NULL with non-NULL write.
[in]targetSlot offset to program.
[in]bufSerialised k_ra8_devcfg_record_len byte record; non-NULL.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBody and header both programmed.
otherForwarded from the first failing store->write.
Precondition
buf holds a CRC-valid serialised record.
store->write is callable.
Postcondition
On k_ra8_ok the slot holds the full record with its header last.
On error the slot may be partially written; the other copy is untouched.
Note
Not thread-safe; provisioning path only.
Since
0.1.0

Definition at line 533 of file ra8_devcfg.c.

References k_ra8_devcfg_body_bytes, k_ra8_devcfg_hdr_bytes, k_ra8_ok, RA8_RETURN_ON_ERROR, s_tag, and ra8_devcfg_store_t::write.

Referenced by ra8_devcfg_commit().

◆ ra8_devcfg_commit()

ra8_err_t ra8_devcfg_commit ( const ra8_devcfg_store_t * store,
const ra8_devcfg_record_t * rec )
nodiscard

Commit a new record to the stale copy slot with header-last ordering.

The provisioning-writer primitive (consumed by #317). Serialises rec (its body, flags and a seq one past the newest existing copy), then programs the target slot – the older / invalid copy, so the newest good record is never overwritten – body bytes first and the header page LAST. A power cut before the header lands leaves that slot header-invalid, so the other copy still resolves; there is never a window with zero valid records. The caller must ra8_devcfg_load again to adopt the committed record.

Parameters
[in]storeBacking-store vtable; non-NULL, both members non-NULL.
[in]recRecord to persist (rec->seq is ignored and recomputed); non-NULL.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBody and header programmed to the target slot.
k_ra8_err_null_ptrstore, a member, or rec is NULL.
otherA backing write faulted; persistence is not assured.
Precondition
store->write is callable and targets storage outside both DFU banks.
The boot / provisioning path is single-threaded.
Postcondition
On k_ra8_ok the target slot holds a CRC-valid record with a seq strictly greater than every previously valid copy.
On error the target slot may be partially written; the other copy is untouched and still resolves.
Note
Not thread-safe: programs the backing store. Call from a single-threaded provisioning context.
See also
ra8_devcfg_load
Since
0.1.0

Definition at line 609 of file ra8_devcfg.c.

References internal_devcfg_plan(), internal_devcfg_serialize(), internal_devcfg_write_record(), k_ra8_devcfg_record_len, RA8_CHECK_NULL_PTR, ra8_devcfg_store_t::read, s_tag, and ra8_devcfg_store_t::write.

◆ ra8_devcfg_get_body()

ra8_err_t ra8_devcfg_get_body ( const ra8_devcfg_body_t ** out_body)
nodiscard

Expose the decoded body of the loaded record.

Gives consumers read access to the per-unit fields (serial, touch calibration, panel identity) after a successful ra8_devcfg_load. The returned pointer aliases module-static cache storage and stays valid until the next ra8_devcfg_load / ra8_devcfg_reset; the caller must not modify or free it.

Parameters
[out]out_bodyReceives a pointer to the cached body; non-NULL.
Returns
ra8_err_t Error code.
Return values
k_ra8_ok*out_body points at the cached body.
k_ra8_err_null_ptrout_body is NULL.
k_ra8_err_not_initializedNo record is loaded (never loaded or UNPROVISIONED).
Precondition
out_body is a writable pointer slot.
ra8_devcfg_load returned k_ra8_ok this boot.
Postcondition
On k_ra8_ok *out_body is non-NULL and read-only.
On any error *out_body is left unchanged.
Note
Thread-safe for readers once loaded; not safe against a concurrent load.
See also
ra8_devcfg_load
Since
0.1.0

Definition at line 594 of file ra8_devcfg.c.

References k_ra8_devcfg_state_loaded, k_ra8_err_not_initialized, k_ra8_ok, RA8_CHECK_NULL_PTR, s_record, s_state, and s_tag.

◆ ra8_devcfg_get_vcom_mv()

ra8_err_t ra8_devcfg_get_vcom_mv ( uint16_t * out_mv)
nodiscard

Fetch the validated panel VCOM magnitude in millivolts.

The entry point the e-paper driver uses. It succeeds only when a record loaded cleanly, k_ra8_devcfg_flag_vcom_valid is set, and the stored value lies inside [k_ra8_devcfg_vcom_min_mv, k_ra8_devcfg_vcom_max_mv]. Any error means INV-VCOM-1 forbids driving the panel – leave the rail off and the controller in reset. Refusing to draw is recoverable; a wrong VCOM is not, because panel damage accumulates with time under bias.

Parameters
[out]out_mvReceives the magnitude (sign is implicitly negative).
Returns
ra8_err_t Error code.
Return values
k_ra8_okValue validated and safe to program.
k_ra8_err_null_ptrout_mv is NULL.
k_ra8_err_not_initializedra8_devcfg_load has not succeeded.
k_ra8_err_validation_failedNo valid VCOM: unprovisioned, the valid flag is clear, or the value is out of range. Refuse the panel.
Precondition
out_mv is a writable uint16_t.
ra8_devcfg_load was called on this boot.
Postcondition
On k_ra8_ok *out_mv is in the plausible range.
On any error *out_mv is left unchanged.
Note
Thread-safe for concurrent readers once ra8_devcfg_load completed (reads immutable cache); not safe against a concurrent load.
See also
ra8_devcfg_load
Since
0.1.0

Definition at line 575 of file ra8_devcfg.c.

References k_ra8_devcfg_flag_vcom_valid, k_ra8_devcfg_state_loaded, k_ra8_devcfg_vcom_max_mv, k_ra8_devcfg_vcom_min_mv, k_ra8_err_not_initialized, k_ra8_err_validation_failed, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, s_record, s_state, and s_tag.

◆ ra8_devcfg_is_blank()

bool ra8_devcfg_is_blank ( void )
nodiscard

Report whether neither record copy is valid (the provisioning gate).

True exactly when the most recent ra8_devcfg_load found neither copy valid (UNPROVISIONED), and also before any load has run. One half of the provisioning-mode entry condition; the other half (a factory token) lives with the writer (#317). Blank-alone is not a sufficient gate while the debug port is open (#244).

Returns
bool True iff the unit is UNPROVISIONED (or load never ran).
Return values
trueBoth copies were invalid, or ra8_devcfg_load never ran.
falseA valid record is loaded.
Precondition
None (safe to call before ra8_devcfg_load; reports true).
Postcondition
No state is mutated.
Note
Thread-safe for readers once loaded.
See also
ra8_devcfg_load
Since
0.1.0

Definition at line 604 of file ra8_devcfg.c.

References k_ra8_devcfg_state_loaded, and s_state.

◆ ra8_devcfg_load()

ra8_err_t ra8_devcfg_load ( const ra8_devcfg_store_t * store)
nodiscard

Load and resolve the device configuration record from both copies.

Probes copy 0 and copy 1 through store; validates each (magic, schema known, record_len sane, CRC-32); selects the valid copy, or the higher seq when both are valid; and caches the winner for ra8_devcfg_get_vcom_mv / ra8_devcfg_get_body / ra8_devcfg_is_blank. A per-copy read fault or blank window marks that copy absent rather than failing the load, so a fresh unit resolves cleanly to UNPROVISIONED. This call is read-only: it never programs the backing.

Parameters
[in]storeBacking-store vtable; non-NULL, both members non-NULL.
Returns
ra8_err_t Error code.
Return values
k_ra8_okA valid record is loaded and cached.
k_ra8_err_null_ptrstore or a member is NULL.
k_ra8_err_validation_failedNeither copy is valid – the unit is UNPROVISIONED. Not a soft failure: the panel must not be driven and provisioning mode becomes reachable.
Precondition
store->read is callable for the duration of the call.
The boot path is single-threaded.
Postcondition
On k_ra8_ok the cached state is "loaded" and the record is decoded.
On k_ra8_err_validation_failed the cached state is "unprovisioned".
Note
Not thread-safe: mutates module-static cache state. Call from the single-threaded boot path.
See also
ra8_devcfg_get_vcom_mv
ra8_devcfg_commit
Since
0.1.0

Definition at line 549 of file ra8_devcfg.c.

References internal_devcfg_probe(), k_ra8_devcfg_copy0_off, k_ra8_devcfg_copy1_off, k_ra8_devcfg_state_loaded, k_ra8_devcfg_state_unprovisioned, k_ra8_err_validation_failed, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_warn, ra8_devcfg_store_t::read, s_record, s_state, s_tag, and ra8_devcfg_record_t::seq.

◆ ra8_devcfg_reset()

void ra8_devcfg_reset ( void )

Drop the cached record so a later load re-resolves from scratch.

Returns the module to the "never loaded" state. Used by the re-provisioning flow (write a new record, then reset and reload) and by host tests that need a pristine cache between cases. Touches no backing store.

Returns
void
Precondition
None – safe to call at any time, including before the first load.
The boot / provisioning path is single-threaded.
Postcondition
ra8_devcfg_is_blank reports true and ra8_devcfg_get_vcom_mv reports k_ra8_err_not_initialized until the next successful load.
No backing store is accessed.
Note
Not thread-safe: mutates module-static cache state.
See also
ra8_devcfg_load
Since
0.1.0

Definition at line 626 of file ra8_devcfg.c.

References k_ra8_devcfg_state_unloaded, s_record, and s_state.

Variable Documentation

◆ s_record

ra8_devcfg_record_t s_record = {}
static

The resolved record cached by the last successful ra8_devcfg_load.

Warning
Valid only while s_state is k_ra8_devcfg_state_loaded.
Since
0.1.0

Definition at line 111 of file ra8_devcfg.c.

Referenced by ra8_devcfg_get_body(), ra8_devcfg_get_vcom_mv(), ra8_devcfg_load(), and ra8_devcfg_reset().

◆ s_state

Current cache state.

Warning
Boot / provisioning path only; not thread-safe.
Since
0.1.0

Definition at line 103 of file ra8_devcfg.c.

◆ s_tag

const char* const s_tag = "DEVCFG"
static

Logging tag used by every diagnostic path in this TU.

File-private component identifier for ra8_log_* / RA8_CHECK_*.

Warning
Do not modify.
Since
0.1.0

Definition at line 39 of file ra8_devcfg.c.