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

Code-MRAM + Extra-MRAM + Option-Setting driver implementation – DANGEROUS. More...

#include "ra8_flash.h"
#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_flash_internal.h"
#include "ra8_flash_regs.h"
#include "ra8_hw_err.h"
#include "ra8_log.h"
Include dependency graph for ra8_flash.c:

Go to the source code of this file.

Functions

static ra8_err_t internal_wait_buffer_ready (uint32_t limit)
 Wait for MRCPS.PRGBSYC = 0 and ABUFFULL = 0 (buffer ready).
ra8_err_t priv_ra8_flash_internal_wait_buffer_ready_call (uint32_t limit)
 Test-access wrapper for internal_wait_buffer_ready.
static ra8_err_t internal_wait_commit_done (uint32_t limit)
 Wait for MRCPS.ABUFEMP = 1 and PRGBSYC = 0 (commit done).
ra8_err_t priv_ra8_flash_internal_wait_commit_done_call (uint32_t limit)
 Test-access wrapper for internal_wait_commit_done.
ra8_err_t priv_ra8_flash_internal_wait_mrdy (uint32_t limit)
 Spin until MSTATR.MRDY rises or limit elapses.
static void internal_set_program_gate (ra8_flash_world_t world, bool enable)
 Open or close the per-world program-control gate.
static void internal_set_hsp_mode (bool enable)
 Toggle high-speed program mode (MRPSC.MHSPEN).
void priv_ra8_flash_internal_set_prefetch (bool enable)
 Set MRCPFB.MPFBEN to enable/disable the prefetch buffer.
void priv_ra8_flash_internal_maci_cmd8 (uint8_t byte)
 Send a single byte through the MACI command-issuing area.
void priv_ra8_flash_internal_maci_cmd16 (uint16_t half)
 Send a halfword through the MACI command-issuing area.
ra8_err_t ra8_flash_init (const ra8_flash_cfg_t *cfg)
 Initialise the MRAM controller for safe read access.
ra8_err_t ra8_flash_deinit (void)
 Deinitialise: lock all program gates and re-enable prefetch.
ra8_err_t ra8_flash_get_status (uint8_t *out_status)
 Snapshot the program-status register.
ra8_err_t ra8_flash_get_extended_status (ra8_flash_status_ext_t *out)
 Snapshot every status register the HUM exposes.
ra8_err_t ra8_flash_clear_status (uint8_t mask)
 Clear sticky program-error bits in MRCPS.
ra8_err_t ra8_flash_set_rww_disable (bool disable)
 Disable the read-while-write prefetch buffer.
bool priv_ra8_flash_internal_window_allows_pure (uintptr_t addr, uint32_t len, uintptr_t win_low, uintptr_t win_high)
 Pure (state-free) window allow/deny predicate – see priv_ra8_flash_internal_window_allows_pure in ra8_flash_internal.h for the full contract.
bool priv_ra8_flash_internal_window_allows (uintptr_t addr, uint32_t len)
 Test whether [addr, addr+len) lies inside the configured soft window.
static ra8_err_t internal_validate_write_block (uint32_t mram_addr, uint32_t len)
 Validate the write_block destination range and alignment.
static ra8_err_t internal_flash_program_window (uint32_t mram_addr, const uint8_t *src, uint32_t len, ra8_flash_world_t world)
 Steps 2-6 of the HUM block-write sequence.
ra8_err_t ra8_flash_write_block (uint32_t mram_addr, const uint8_t *src, uint32_t len, ra8_flash_world_t world)
 Program 1..32 contiguous bytes into one MRAM page.
ra8_err_t ra8_flash_erase_block (uint32_t mram_addr, ra8_flash_world_t world)
 Erase (= program to all 0xFF) one 32-byte MRAM block.
ra8_err_t ra8_flash_block_protect_set (ra8_flash_world_t world, bool lock, bool permanent)
 Set or clear the per-world block-protection lock.
ra8_err_t ra8_flash_enter_pe_mode (void)
 Enter MRAM P/E mode.
ra8_err_t ra8_flash_exit_pe_mode (void)
 Exit MRAM P/E mode (return to read mode).
ra8_err_t ra8_flash_suspend (void)
 Pause an in-flight MRAM program/erase operation.
ra8_err_t ra8_flash_resume (void)
 Resume a previously-paused MRAM operation.
ra8_err_t ra8_flash_lock_set (uintptr_t addr, uint16_t lock_bits)
 Programme MRCBPROT0/1 lock bits at addr.
ra8_err_t ra8_flash_force_stop (void)
 Issue the MACI forced stop command.
ra8_err_t ra8_flash_reset (void)
 Reset the MRAM peripheral and clear status.

Variables

const char * g_flash_tag = "FLASH"
 Shared log tag string for the ra8_flash module.
ra8_flash_runtime_t g_flash_rt = {}
 Single shared ra8_flash runtime-state instance.

Detailed Description

Code-MRAM + Extra-MRAM + Option-Setting driver implementation – DANGEROUS.

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

Implements the full HUM Ch 7 + Ch 59 surface declared in ra8_flash.h:

  • Direct STR programming of code-MRAM through MRCPC0/1 (HUM Ch 59.4.2 Figure 59.4 p 3548).
  • MACI command sequencer for configuration-set, anti-rollback, forced-stop, status-clear (HUM Ch 59.4.4 p 3550 + HUM Ch 7 p 278..299 for OFS layout).
  • Block-protection writes to MRCBPROT0/1 (HUM Ch 59 p 3604..3605).
  • Start-up area swap via MSUACR (temporary) + configuration-set (permanent) (HUM Ch 7 p 278 + HUM Ch 59 p 3593).
  • W-HUK zeroize via MREZC (HUM Ch 59 p 3565).
  • ECC encoder / decoder controls and read-error address capture (HUM Ch 59 p 3554..3558 + p 3624).
  • Per-source IRQ enables and a single-callback dispatcher.
  • Full lifecycle: init, deinit, reset, force-stop, enter_pe_mode, exit_pe_mode.
  • Update-transfer kick + status (MCTRCNTR / MCTRSTATR / MCTRLSR, HUM Ch 59 p 3580).

Every register access carries a HUM Ch 7 or Ch 59 citation. The driver does not own any global state beyond the registered IRQ callback and a one-shot init flag; the controller itself holds every meaningful state bit.

Definition in file ra8_flash.c.

Function Documentation

◆ internal_flash_program_window()

ra8_err_t internal_flash_program_window ( uint32_t mram_addr,
const uint8_t * src,
uint32_t len,
ra8_flash_world_t world )
static

Steps 2-6 of the HUM block-write sequence.

HUM Ch 59 p 3550 "Programming Sequence" + p 3601 "MRCFLR" key. Open the program gate, copy src into the MRAM window, pulse the keyed flush, wait for commit, then unconditionally tear down the gate. Returns the commit-wait result so the caller can act on timeouts without leaking the gate-open state.

Parameters
[in]mram_addrDestination address (validated by caller).
[in]srcSource bytes (non-null, validated by caller).
[in]lenLength in bytes (1..32, validated by caller).
[in]worldSecure / non-secure world selector.
Returns
k_ra8_ok on commit success, otherwise the commit-wait error.
Precondition
Caller already drained the previous transfer with internal_wait_buffer_ready.
Postcondition
Program gate, HSP mode and prefetch are restored on every exit path.
Note
Internal helper, not thread-safe.
Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Since
0.1.0
Precondition
Module/state preconditions hold (see function body).
Postcondition
Documented side effects are visible on success.

Definition at line 680 of file ra8_flash.c.

References internal_set_hsp_mode(), internal_set_program_gate(), internal_wait_commit_done(), k_ra8_flash_busy_spin_limit, k_ra8_mram_off_mrcflr, k_ra8_mrcflr_key_flush, priv_ra8_flash_internal_set_prefetch(), RA8_INTERNAL, and ra8_mram_reg16().

Referenced by ra8_flash_write_block().

◆ internal_set_hsp_mode()

void internal_set_hsp_mode ( bool enable)
static

Toggle high-speed program mode (MRPSC.MHSPEN).

Parameters
[in]enabletrue => MHSPEN=1.
Precondition
None.
Postcondition
MRPSC.MHSPEN matches enable.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Note
Thread safety: see the header declaration.
Since
0.1.0
Precondition
Module/state preconditions hold (see function body).
Postcondition
Documented side effects are visible on success.

Definition at line 270 of file ra8_flash.c.

References k_ra8_mram_off_mrpsc, k_ra8_mrpsc_mask_mhspen, RA8_INTERNAL, and ra8_mram_reg8().

Referenced by internal_flash_program_window(), ra8_flash_deinit(), and ra8_flash_init().

◆ internal_set_program_gate()

void internal_set_program_gate ( ra8_flash_world_t world,
bool enable )
static

Open or close the per-world program-control gate.

Parameters
[in]worldk_ra8_flash_world_ns -> MRCPC0; _s -> MRCPC1.
[in]enabletrue to enable program; false to lock.
Precondition
None (registers always accessible).
Postcondition
Matching MRCPCx register holds the keyed value.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Note
Thread safety: see the header declaration.
Since
0.1.0
Precondition
Module/state preconditions hold (see function body).
Postcondition
Documented side effects are visible on success.

Definition at line 232 of file ra8_flash.c.

References k_ra8_flash_world_s, k_ra8_mram_off_mrcpc0, k_ra8_mram_off_mrcpc1, k_ra8_mrcpc0_key_disable, k_ra8_mrcpc0_key_enable, k_ra8_mrcpc1_key_disable, k_ra8_mrcpc1_key_enable, RA8_INTERNAL, and ra8_mram_reg16().

Referenced by internal_flash_program_window(), ra8_flash_deinit(), and ra8_flash_init().

◆ internal_validate_write_block()

ra8_err_t internal_validate_write_block ( uint32_t mram_addr,
uint32_t len )
static

Validate the write_block destination range and alignment.

Rejects len outside [1, 32] bytes, addresses outside the 1 MiB code-MRAM window, and writes that would straddle a 32-byte page boundary (HUM Ch 59 p 3601 – writes are flushed at page granularity).

Parameters
[in]mram_addrDestination address.
[in]lenLength in bytes.
Returns
k_ra8_ok if the write is well formed.
Precondition
None.
Postcondition
No side effects.
Note
Internal helper, not thread-safe.
Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Since
0.1.0
Precondition
Module/state preconditions hold (see function body).
Postcondition
Documented side effects are visible on success.

Definition at line 625 of file ra8_flash.c.

References k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_flash_code_size, k_ra8_flash_code_start, k_ra8_mram_write_size_bytes, k_ra8_ok, priv_ra8_flash_internal_window_allows(), and RA8_INTERNAL.

Referenced by ra8_flash_write_block().

◆ internal_wait_buffer_ready()

ra8_err_t internal_wait_buffer_ready ( uint32_t limit)
static

Wait for MRCPS.PRGBSYC = 0 and ABUFFULL = 0 (buffer ready).

Parameters
[in]limitMaximum spin iterations.
Returns
k_ra8_ok if both bits cleared, else k_ra8_err_hw_timeout.
Precondition
limit > 0.
Controller is powered.
Postcondition
Buffer is observed empty or function returns timeout.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Documented side effects are visible on success.

Definition at line 93 of file ra8_flash.c.

References k_ra8_err_hw_timeout, k_ra8_mram_off_mrcps, k_ra8_mrcps_mask_abuffull, k_ra8_mrcps_mask_prgbsyc, k_ra8_ok, RA8_INTERNAL, and ra8_mram_reg8().

Referenced by priv_ra8_flash_internal_wait_buffer_ready_call(), and ra8_flash_write_block().

◆ internal_wait_commit_done()

ra8_err_t internal_wait_commit_done ( uint32_t limit)
static

Wait for MRCPS.ABUFEMP = 1 and PRGBSYC = 0 (commit done).

Parameters
[in]limitMaximum spin iterations.
Returns
k_ra8_ok on commit, else k_ra8_err_hw_timeout.
Precondition
limit > 0.
Controller is powered.
Postcondition
Commit observed or function returns timeout.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Documented side effects are visible on success.

Definition at line 148 of file ra8_flash.c.

References k_ra8_err_hw_timeout, k_ra8_mram_off_mrcps, k_ra8_mrcps_mask_abufemp, k_ra8_mrcps_mask_prgbsyc, k_ra8_ok, RA8_INTERNAL, and ra8_mram_reg8().

Referenced by internal_flash_program_window(), and priv_ra8_flash_internal_wait_commit_done_call().

◆ priv_ra8_flash_internal_maci_cmd16()

void priv_ra8_flash_internal_maci_cmd16 ( uint16_t half)

Send a halfword through the MACI command-issuing area.

Parameters
[in]half16-bit data.
Precondition
Controller is in P/E mode.
Postcondition
One halfword was written to MACI_CMD16.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Note
Thread safety: see the header declaration.
Since
0.1.0
Precondition
Module/state preconditions hold (see function body).
Postcondition
Documented side effects are visible on success.

Definition at line 369 of file ra8_flash.c.

References ra8_mram_cmd16().

Referenced by ra8_flash_config_set_write().

◆ priv_ra8_flash_internal_maci_cmd8()

void priv_ra8_flash_internal_maci_cmd8 ( uint8_t byte)

Send a single byte through the MACI command-issuing area.

Parameters
[in]byteCommand byte.
Precondition
Controller is in P/E mode.
Postcondition
One byte was written to MACI_CMD8.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Note
Thread safety: see the header declaration.
Since
0.1.0
Precondition
Module/state preconditions hold (see function body).
Postcondition
Documented side effects are visible on success.

Definition at line 341 of file ra8_flash.c.

References ra8_mram_cmd8().

Referenced by internal_arc_cmd(), ra8_flash_config_set_write(), ra8_flash_force_stop(), and ra8_flash_reset().

◆ priv_ra8_flash_internal_set_prefetch()

void priv_ra8_flash_internal_set_prefetch ( bool enable)

Set MRCPFB.MPFBEN to enable/disable the prefetch buffer.

Parameters
[in]enabletrue => prefetch on.
Precondition
None.
Postcondition
MRCPFB.MPFBEN matches enable.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Note
Thread safety: see the header declaration.
Since
0.1.0
Precondition
Module/state preconditions hold (see function body).
Postcondition
Documented side effects are visible on success.

Definition at line 296 of file ra8_flash.c.

References g_flash_rt, k_ra8_mram_off_mrcpfb, and ra8_mram_reg8().

Referenced by internal_flash_program_window(), ra8_flash_deinit(), ra8_flash_enter_pe_mode(), ra8_flash_exit_pe_mode(), ra8_flash_init(), ra8_flash_set_rww_disable(), and ra8_flash_update_clock_freq().

◆ priv_ra8_flash_internal_wait_buffer_ready_call()

ra8_err_t priv_ra8_flash_internal_wait_buffer_ready_call ( uint32_t limit)

Test-access wrapper for internal_wait_buffer_ready.

Direct-call test access to internal_wait_buffer_ready.

Forwards the call so tests under tests/ can drive the line-150 AND-decision directly on the production source. Production code keeps using the static helper.

Parameters
[in]limitMaximum spin iterations.
Returns
Forwarded ra8_err_t outcome.
Return values
k_ra8_okBoth bits cleared within limit iterations.
k_ra8_err_hw_timeoutLimit exhausted without success.
Precondition
Fake MRCPS register is mapped (host-test build).
limit > 0.
Postcondition
No state mutation beyond the underlying register reads.
Return value matches the production helper.
Note
Test-access only.
Since
0.1.0

Definition at line 124 of file ra8_flash.c.

References internal_wait_buffer_ready().

◆ priv_ra8_flash_internal_wait_commit_done_call()

ra8_err_t priv_ra8_flash_internal_wait_commit_done_call ( uint32_t limit)

Test-access wrapper for internal_wait_commit_done.

Direct-call test access to internal_wait_commit_done.

Forwards the call so tests under tests/ can drive the line-181 AND-decision directly on the production source. Production code keeps using the static helper.

Parameters
[in]limitMaximum spin iterations.
Returns
Forwarded ra8_err_t outcome.
Return values
k_ra8_okCommit observed within limit iterations.
k_ra8_err_hw_timeoutLimit exhausted without success.
Precondition
Fake MRCPS register is mapped (host-test build).
limit > 0.
Postcondition
No state mutation beyond the underlying register reads.
Return value matches the production helper.
Note
Test-access only.
Since
0.1.0

Definition at line 179 of file ra8_flash.c.

References internal_wait_commit_done().

◆ priv_ra8_flash_internal_wait_mrdy()

ra8_err_t priv_ra8_flash_internal_wait_mrdy ( uint32_t limit)

Spin until MSTATR.MRDY rises or limit elapses.

Parameters
[in]limitMaximum spin iterations.
Returns
k_ra8_ok if MRDY observed, else k_ra8_err_hw_timeout.
Precondition
limit > 0.
Controller is in P/E mode (MRDY only meaningful then).
Postcondition
MRDY observed high or function returns timeout.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Documented side effects are visible on success.

Definition at line 203 of file ra8_flash.c.

References k_ra8_err_hw_timeout, k_ra8_mram_off_mstatr, k_ra8_mstatr_mask_mrdy, k_ra8_ok, and ra8_mram_reg32().

Referenced by internal_arc_cmd(), ra8_flash_config_set_write(), ra8_flash_force_stop(), and ra8_flash_reset().

◆ priv_ra8_flash_internal_window_allows()

bool priv_ra8_flash_internal_window_allows ( uintptr_t addr,
uint32_t len )

Test whether [addr, addr+len) lies inside the configured soft window.

Test whether [addr, addr+len) lies inside the soft window.

The soft window mirrors the FSP accessWindowSet surface but is stored in driver state rather than in the silicon (RA8D2 has no FAWMON / FAWMR; HUM Ch 59 substitutes block-protect bits). A window with win_low == win_high == 0 is treated as disabled (allow all). Forwards to priv_ra8_flash_internal_window_allows_pure.

Parameters
[in]addrStart address of the candidate operation.
[in]lenLength in bytes (must be > 0 if the caller is writing).
Returns
true if the operation is permitted, false if blocked.
Return values
trueRegion permitted (or no window installed).
falseRegion overlaps outside the installed window.
Precondition
None.
None.
Postcondition
No side effects.
Return value depends solely on addr / len and module state.
Note
Internal helper, not thread-safe.
Since
0.1.0

Definition at line 588 of file ra8_flash.c.

References g_flash_rt, and priv_ra8_flash_internal_window_allows_pure().

Referenced by internal_validate_range(), and internal_validate_write_block().

◆ priv_ra8_flash_internal_window_allows_pure()

bool priv_ra8_flash_internal_window_allows_pure ( uintptr_t addr,
uint32_t len,
uintptr_t win_low,
uintptr_t win_high )

Pure (state-free) window allow/deny predicate – see priv_ra8_flash_internal_window_allows_pure in ra8_flash_internal.h for the full contract.

Pure (state-free) reimplementation of internal_window_allows.

Promoted as a pure helper so the win_low == 0U && win_high == 0U AND-decision can be driven directly by host MC/DC tests with synthetic inputs rather than mutating module state. The state-reading wrapper priv_ra8_flash_internal_window_allows simply forwards.

Parameters
[in]addrStart address of the candidate region.
[in]lenLength in bytes of the candidate region.
[in]win_lowInclusive lower bound of the allow window.
[in]win_highExclusive upper bound of the allow window.
Returns
true if the region is permitted, false if blocked.
Return values
trueRegion permitted (or no window installed).
falseRegion overlaps outside the installed window.
Precondition
None.
None.
Postcondition
No side effects.
Return value depends solely on the four inputs.
Note
Pure function; thread-safe.
Since
0.1.0

Definition at line 544 of file ra8_flash.c.

Referenced by priv_ra8_flash_internal_window_allows().

◆ ra8_flash_block_protect_set()

ra8_err_t ra8_flash_block_protect_set ( ra8_flash_world_t world,
bool lock,
bool permanent )
nodiscard

Set or clear the per-world block-protection lock.

Wraps the keyed write to MRCBPROT0 (NS) / MRCBPROT1 (S) documented at HUM Ch 59 p 3604..3605. The protection bit, once set, blocks all subsequent MRCPC*-gated stores to the matching half of MRAM. permanent requests a fuse-style write: the bit cannot be cleared after the next reset.

Parameters
[in]worldWhich half to lock (NS or S).
[in]locktrue => block writes; false => unlock.
[in]permanenttrue => one-shot fuse; false => RW-lockable.
Returns
ra8_err_t error code.
Return values
k_ra8_okBit applied.
k_ra8_err_invalid_argCannot pass permanent + unlock.
Precondition
Caller has run ra8_flash_init.
Caller understands that permanent=true is irreversible.
Postcondition
On success, MRCBPROTx reflects the requested state.
Other MRAM controller registers untouched.
Note
Thread-safe: no.
Warning
permanent=true is irreversible. Re-flashing the part will not clear the fuse.
See also
ra8_flash_write_block
Since
0.1.0

Definition at line 753 of file ra8_flash.c.

References g_flash_tag, k_ra8_err_invalid_arg, k_ra8_flash_world_s, k_ra8_mram_off_mrcbprot0, k_ra8_mram_off_mrcbprot1, k_ra8_mrcbprot0_key_lock, k_ra8_mrcbprot0_key_unlock, k_ra8_mrcbprot1_key_lock, k_ra8_mrcbprot1_key_unlock, k_ra8_ok, ra8_log_warn, and ra8_mram_reg16().

◆ ra8_flash_clear_status()

ra8_err_t ra8_flash_clear_status ( uint8_t mask)
nodiscard

Clear sticky program-error bits in MRCPS.

Writes the W1C mask to MRCPS so that PRGERRC and ECCERRC are cleared. The flow-control bits (busy / buffer empty / buffer full) are not affected – they are read-only.

Parameters
[in]maskBits to clear; typically k_ra8_mrcps_mask_errors.
Returns
ra8_err_t error code.
Return values
k_ra8_okBits cleared (or no-op if mask=0).
k_ra8_err_invalid_argmask had bits set outside the clearable region.
Precondition
mask & ~k_ra8_mrcps_mask_errors == 0.
No program operation in progress.
Postcondition
Bits identified by mask are 0 in MRCPS.
Other MRCPS bits unchanged.
Note
Thread-safe: no.
Since
0.1.0

Definition at line 494 of file ra8_flash.c.

References k_ra8_err_invalid_arg, k_ra8_mram_off_mrcps, k_ra8_mrcps_mask_errors, k_ra8_ok, and ra8_mram_reg8().

◆ ra8_flash_deinit()

ra8_err_t ra8_flash_deinit ( void )
nodiscard

Deinitialise: lock all program gates and re-enable prefetch.

Inverse of ra8_flash_init: the controller is left in the safest possible state – prefetch on, both MRCPC* registers locked, high-speed program disabled. Status sticky bits are cleared. Also exits P/E mode if the controller is currently in it.

Returns
ra8_err_t error code.
Return values
k_ra8_okAlways (no failure path).
Precondition
No write/erase operation in progress (caller waits).
Postcondition
Controller is in pure read mode.
All program-status error bits are cleared.
Note
Thread-safe: no.
See also
ra8_flash_init
Since
0.1.0

Definition at line 446 of file ra8_flash.c.

References g_flash_rt, internal_set_hsp_mode(), internal_set_program_gate(), k_ra8_flash_world_ns, k_ra8_flash_world_s, k_ra8_mentryr_read_mode, k_ra8_mram_off_mentryr, k_ra8_mram_off_mrcps, k_ra8_mrcps_mask_errors, k_ra8_ok, priv_ra8_flash_internal_set_prefetch(), ra8_mram_reg16(), and ra8_mram_reg8().

Referenced by ra8_flash_close().

◆ ra8_flash_enter_pe_mode()

ra8_err_t ra8_flash_enter_pe_mode ( void )
nodiscard

Enter MRAM P/E mode.

Writes MENTRYR:= 0xAA80 and waits for MENTRYR.MENTRY to go to 1 (HUM Ch 59 p 3582). Exposed so callers can batch multiple MACI commands without paying the per-command transition cost.

Returns
ra8_err_t error code.
Return values
k_ra8_okEntered P/E.
k_ra8_err_hw_timeoutMENTRY never went to 1.
Precondition
Controller is powered.
Postcondition
Controller is in P/E mode.
Note
Thread-safe: no.
See also
ra8_flash_exit_pe_mode
Since
0.1.0

Definition at line 793 of file ra8_flash.c.

References k_ra8_err_hw_timeout, k_ra8_flash_pe_spin_limit, k_ra8_mentryr_mask_pe_mode, k_ra8_mentryr_pe_enter, k_ra8_mram_off_mentryr, k_ra8_ok, priv_ra8_flash_internal_set_prefetch(), and ra8_mram_reg16().

Referenced by ra8_flash_arc_increment(), ra8_flash_arc_read(), ra8_flash_extra_mram_write(), ra8_flash_reset(), and ra8_flash_set_startup_area().

◆ ra8_flash_erase_block()

ra8_err_t ra8_flash_erase_block ( uint32_t mram_addr,
ra8_flash_world_t world )
nodiscard

Erase (= program to all 0xFF) one 32-byte MRAM block.

MRAM does not have a distinct erase command – the natural "erased" state is all-ones, and "erase" is implemented as a page-aligned write of 32 0xFF bytes. This wraps ra8_flash_write_block with that fixed payload to keep callers out of having to construct the buffer themselves.

Parameters
[in]mram_addr32-byte aligned destination inside the MRAM window.
[in]worldSame semantics as ra8_flash_write_block.
Returns
ra8_err_t error code.
Return values
k_ra8_okBlock erased.
k_ra8_err_invalid_argmram_addr not 32-byte aligned or outside the MRAM window.
k_ra8_err_hw_errorController reported a program error.
Precondition
mram_addr is 32-byte aligned.
mram_addr + 32 <= k_ra8_flash_code_start + k_ra8_flash_code_size.
Postcondition
Block reads as all 0xFF.
Program-control gate left locked.
Note
Thread-safe: no.
Warning
Same brick warning as ra8_flash_write_block.
See also
ra8_flash_write_block
Since
0.1.0

Definition at line 734 of file ra8_flash.c.

References k_ra8_err_invalid_arg, k_ra8_mram_block_size_bytes, and ra8_flash_write_block().

Referenced by ra8_flash_erase().

◆ ra8_flash_exit_pe_mode()

ra8_err_t ra8_flash_exit_pe_mode ( void )
nodiscard

Exit MRAM P/E mode (return to read mode).

Writes MENTRYR:= 0xAA00 and waits for the register to fall to zero. Restores the prefetch buffer to its previous state.

Returns
ra8_err_t error code.
Return values
k_ra8_okReturned to read mode.
k_ra8_err_hw_timeoutMENTRYR never went to 0.
Precondition
Controller was in P/E mode (no harm if it wasn't – the write is idempotent).
Postcondition
Controller back in read mode.
Note
Thread-safe: no.
See also
ra8_flash_enter_pe_mode
Since
0.1.0

Definition at line 814 of file ra8_flash.c.

References g_flash_rt, k_ra8_err_hw_timeout, k_ra8_flash_pe_spin_limit, k_ra8_mentryr_mask_pe_mode, k_ra8_mentryr_read_mode, k_ra8_mram_off_mentryr, k_ra8_ok, priv_ra8_flash_internal_set_prefetch(), and ra8_mram_reg16().

Referenced by ra8_flash_arc_increment(), ra8_flash_arc_read(), ra8_flash_extra_mram_write(), ra8_flash_reset(), and ra8_flash_set_startup_area().

◆ ra8_flash_force_stop()

ra8_err_t ra8_flash_force_stop ( void )
nodiscard

Issue the MACI forced stop command.

Aborts any in-flight MACI sequence (HUM Ch 59 p 3589 + FSP mram_stop). After the call, the controller is left in P/E mode but with the command queue idle. Callers usually pair this with ra8_flash_exit_pe_mode.

Returns
ra8_err_t error code.
Return values
k_ra8_okCommand accepted, MRDY observed.
k_ra8_err_hw_timeoutMRDY never came back.
k_ra8_err_hw_errorMASTAT.CMDLK still set.
Precondition
Controller is powered.
Caller is prepared for the in-flight operation to be aborted.
Postcondition
MACI command queue is empty.
MASTAT.CMDLK == 0 on success.
Note
Thread-safe: no.
Since
0.1.0

Definition at line 921 of file ra8_flash.c.

References k_ra8_err_hw_error, k_ra8_flash_maci_spin_limit, k_ra8_maci_cmd_forced_stop, k_ra8_mastat_mask_cmdlk, k_ra8_mram_off_mastat, k_ra8_ok, priv_ra8_flash_internal_maci_cmd8(), priv_ra8_flash_internal_wait_mrdy(), and ra8_mram_reg8().

Referenced by ra8_flash_reset().

◆ ra8_flash_get_extended_status()

ra8_err_t ra8_flash_get_extended_status ( ra8_flash_status_ext_t * out)
nodiscard

Snapshot every status register the HUM exposes.

Reads MRCPS, MASTAT, MREZS, MCMDR, MSTATR in one call so the caller sees a coherent picture of the controller. The fields cite the source register in their docstrings.

Parameters
[out]outNon-NULL destination structure.
Returns
ra8_err_t error code.
Return values
k_ra8_okStatus snapshot copied.
k_ra8_err_null_ptrout was NULL.
Precondition
out non-null.
Controller is powered (always true after reset).
Postcondition
*out reflects the registers at the moment of the call.
Note
Thread-safe: pure reads; not atomic across registers.
Since
0.1.0

Definition at line 478 of file ra8_flash.c.

References g_flash_tag, k_ra8_mram_off_mastat, k_ra8_mram_off_mcmdr, k_ra8_mram_off_mrcps, k_ra8_mram_off_mrezs, k_ra8_mram_off_mstatr, k_ra8_ok, ra8_flash_status_ext_t::mastat, ra8_flash_status_ext_t::mcmdr, ra8_flash_status_ext_t::mrcps, ra8_flash_status_ext_t::mrezs, ra8_flash_status_ext_t::mstatr, RA8_CHECK_NULL_PTR, ra8_mram_reg16(), ra8_mram_reg32(), and ra8_mram_reg8().

◆ ra8_flash_get_status()

ra8_err_t ra8_flash_get_status ( uint8_t * out_status)
nodiscard

Snapshot the program-status register.

Wraps MRCPS (HUM Ch 59 register layout p 3601). The returned value is a copy of the 8-bit register; callers should test against k_ra8_mrcps_mask_* from ra8_flash_regs.h.

Parameters
[out]out_statusNon-NULL destination for the status byte.
Returns
ra8_err_t error code.
Return values
k_ra8_okStatus copied.
k_ra8_err_null_ptrout_status was NULL.
Precondition
out_status non-null.
MRAM controller is powered (always true after reset).
Postcondition
*out_status reflects the last-read value of MRCPS.
No state change in the controller.
Note
Thread-safe: read-only, single-register access.
Since
0.1.0

Definition at line 470 of file ra8_flash.c.

References g_flash_tag, k_ra8_mram_off_mrcps, k_ra8_ok, RA8_CHECK_NULL_PTR, and ra8_mram_reg8().

◆ ra8_flash_init()

ra8_err_t ra8_flash_init ( const ra8_flash_cfg_t * cfg)
nodiscard

Initialise the MRAM controller for safe read access.

Performs the bring-up dance described in HUM Ch 59.4.3 Figure 59.6 p 3550 (frequency-down procedure) in its safe direction:

  1. Disable the prefetch buffer (MRCPFB <- 0).
  2. Write the keyed MRCFREQ and MREFREQ notifications so the controller knows the wait-state count to apply.
  3. Apply ECC encoder / decoder enables from the cfg.
  4. Optionally re-enable prefetch.
  5. Lock both program-control gates (MRCPC0 / MRCPC1 <- KEY+disable) so a stray store cannot trigger an accidental program.
  6. Clear sticky ECC + program error flags so the new run starts from a known state.
Parameters
[in]cfgNon-NULL configuration descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okController initialized, in read mode.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_invalid_argcfg->mrcfreq_mhz > 0x0FA or cfg->mrefreq_mhz > 0x07D.
Precondition
IRQs masked or single-threaded init context.
Caller is not currently executing out of MRAM that will be programmed (SRAM-resident init code is the safe pattern).
Postcondition
MRCPC0 and MRCPC1 are both in their write-disabled (KEY-only) state.
MRPSC.MHSPEN is 0 (high-speed program disabled).
Note
Thread-safe: no, single-threaded init only.
Warning
Calling this function while another bus initiator is actively reading MRAM may produce one wait-state of read corruption – do it during boot only.
See also
ra8_flash_deinit
Since
0.1.0

Definition at line 386 of file ra8_flash.c.

References ra8_flash_cfg_t::ecc_decoder_enable, ra8_flash_cfg_t::ecc_encoder_enable, g_flash_rt, g_flash_tag, internal_set_hsp_mode(), internal_set_program_gate(), k_ra8_err_invalid_arg, k_ra8_flash_freq_key_shift, k_ra8_flash_max_mrcfreq_mhz, k_ra8_flash_max_mrefreq_mhz, k_ra8_flash_mrcfreq_key, k_ra8_flash_mrefreq_key, k_ra8_flash_world_ns, k_ra8_flash_world_s, k_ra8_mram_off_mrcdecc, k_ra8_mram_off_mrceecc, k_ra8_mram_off_mrcfreq, k_ra8_mram_off_mrcps, k_ra8_mram_off_mrcraes, k_ra8_mram_off_mrefreq, k_ra8_mram_off_mreraes, k_ra8_mrcdecc_key_shift, k_ra8_mrcdecc_mask_dececen, k_ra8_mrceecc_key_shift, k_ra8_mrceecc_mask_eccen, k_ra8_mrcps_mask_errors, k_ra8_ok, ra8_flash_cfg_t::mrcfreq_mhz, ra8_flash_cfg_t::mrefreq_mhz, ra8_flash_cfg_t::prefetch_en, priv_ra8_flash_internal_set_prefetch(), RA8_CHECK_NULL_PTR, ra8_log_info_val, ra8_mram_reg16(), ra8_mram_reg32(), and ra8_mram_reg8().

Referenced by app_setup(), demo_open(), internal_demo_open(), and ra8_flash_open().

◆ ra8_flash_lock_set()

ra8_err_t ra8_flash_lock_set ( uintptr_t addr,
uint16_t lock_bits )
nodiscard

Programme MRCBPROT0/1 lock bits at addr.

Writes the keyed value lock_bits into MRCBPROT0 (when addr falls in the non-secure code-MRAM half) or MRCBPROT1 (secure half). See HUM Ch 59 "MRCBPROT0" p 3604 and "MRCBPROT1" p 3605.

Parameters
[in]addrAddress inside the code-MRAM window. Bit 19 selects secure (MRCBPROT1) vs non-secure (MRCBPROT0).
[in]lock_bitsKeyed 16-bit value to programme.
Returns
ra8_err_t outcome.
Return values
k_ra8_okLock register updated.
k_ra8_err_invalid_argaddr outside code-MRAM, or lock_bits has an invalid key byte.
Precondition
ra8_flash_init has been called.
Caller is in single-threaded init context.
Postcondition
Selected MRCBPROTx register reflects lock_bits.
Note
Not thread-safe.
Since
0.1.0

< RA8 mrcbprot key byte mask.

< RA8 mrcbprot key ns.

< RA8 mrcbprot key s.

< Address bit 19.

Definition at line 880 of file ra8_flash.c.

References k_ra8_err_invalid_arg, k_ra8_flash_code_size, k_ra8_flash_code_start, k_ra8_mram_off_mrcbprot0, k_ra8_mram_off_mrcbprot1, k_ra8_ok, and ra8_mram_reg16().

◆ ra8_flash_reset()

ra8_err_t ra8_flash_reset ( void )
nodiscard

Reset the MRAM peripheral and clear status.

Mirrors R_MRAM_Reset (FSP mram_reset): enter P/E, issue forced-stop, status-clear, exit to read. Clears every sticky error flag the MRCPS, MRCRAES, MRERAES, MASTAT, MSTATR registers carry.

Returns
ra8_err_t error code.
Return values
k_ra8_okController reset.
k_ra8_err_hw_timeoutMACI never returned MRDY.
k_ra8_err_hw_errorMASTAT.CMDLK still set after the reset.
Precondition
ra8_flash_init has been called.
Postcondition
All sticky error bits cleared.
Controller back in read mode.
Note
Thread-safe: no.
Since
0.1.0

Definition at line 938 of file ra8_flash.c.

References g_flash_rt, g_flash_tag, k_ra8_flash_maci_spin_limit, k_ra8_maci_cmd_status_clear, k_ra8_ok, priv_ra8_flash_internal_maci_cmd8(), priv_ra8_flash_internal_wait_mrdy(), ra8_flash_enter_pe_mode(), ra8_flash_exit_pe_mode(), ra8_flash_force_stop(), and RA8_VALIDATE_INIT.

◆ ra8_flash_resume()

ra8_err_t ra8_flash_resume ( void )
nodiscard

Resume a previously-paused MRAM operation.

Drives MENTRYR with the resume key (KEY=0xAA, MENTRY=1, PCKA=0). See HUM Ch 59 "MENTRYR" pp 3582+.

Returns
ra8_err_t outcome.
Return values
k_ra8_okOperation resumed (or no-op).
k_ra8_err_hw_timeoutMENTRYR.PCKA never went to 0.
Precondition
ra8_flash_init has been called.
Caller is in IRQ-masked or single-threaded context.
Postcondition
Programming continues on the next clock.
Note
Not thread-safe.
See also
ra8_flash_suspend
Since
0.1.0

Definition at line 858 of file ra8_flash.c.

References k_ra8_err_hw_timeout, k_ra8_flash_pe_spin_limit, k_ra8_mentryr_mask_pcka, k_ra8_mentryr_pe_resume, k_ra8_mram_off_mentryr, k_ra8_ok, and ra8_mram_reg16().

◆ ra8_flash_set_rww_disable()

ra8_err_t ra8_flash_set_rww_disable ( bool disable)
nodiscard

Disable the read-while-write prefetch buffer.

The HUM (Ch 59.5.1 MRCPFB p 3551) requires the prefetch buffer to be cleared before any code-MRAM frequency change and is the safe setting while a programming sequence is in flight. This wrapper exposes the bit to callers that need to coordinate with their own write loops.

Parameters
[in]disabletrue -> MRCPFB.MPFBEN:= 0 (prefetch off). false -> MRCPFB.MPFBEN:= 1 (prefetch on).
Returns
ra8_err_t error code.
Return values
k_ra8_okAlways.
Precondition
None (the register is always accessible).
Postcondition
MRCPFB.MPFBEN matches the inverse of disable.
Note
Thread-safe: no.
Since
0.1.0

Definition at line 505 of file ra8_flash.c.

References k_ra8_ok, and priv_ra8_flash_internal_set_prefetch().

◆ ra8_flash_suspend()

ra8_err_t ra8_flash_suspend ( void )
nodiscard

Pause an in-flight MRAM program/erase operation.

Drives the MENTRYR pause-key (KEY=0xAA, MENTRY=1, plus the project- internal PCKA "Pause-Code MRAM Access" bit, see HUM Ch 59 "MENTRYR : Extra MRAM Program-Mode Entry" pp 3582+). The controller halts the currently-running MACI command after the next 32-byte page boundary. Resume with ra8_flash_resume.

Returns
ra8_err_t outcome.
Return values
k_ra8_okSuspend latched.
k_ra8_err_hw_timeoutMENTRYR.PCKA never went to 1.
Precondition
ra8_flash_init has been called.
Caller is in IRQ-masked or single-threaded context.
Postcondition
Programming halts at the next page boundary.
Note
Not thread-safe.
See also
ra8_flash_resume
Since
0.1.0

Definition at line 835 of file ra8_flash.c.

References k_ra8_err_hw_timeout, k_ra8_flash_pe_spin_limit, k_ra8_mentryr_mask_pcka, k_ra8_mentryr_pe_pause, k_ra8_mram_off_mentryr, k_ra8_ok, and ra8_mram_reg16().

◆ ra8_flash_write_block()

ra8_err_t ra8_flash_write_block ( uint32_t mram_addr,
const uint8_t * src,
uint32_t len,
ra8_flash_world_t world )
nodiscard

Program 1..32 contiguous bytes into one MRAM page.

Implements the HUM Ch 59.4.2 Figure 59.4 procedure (page 3548):

  1. Wait for PRGBSYC == 0 and ABUFFULL == 0.
  2. Open the appropriate program gate (MRCPC0 for NS, MRCPC1 for S).
  3. Set MRPSC.MHSPEN = 1 (high-speed program mode).
  4. Issue STR instructions to write len bytes to mram_addr.
  5. Memory-barrier, then write the keyed flush to MRCFLR to commit the partial-page buffer.
  6. Wait for ABUFEMP == 1 and PRGBSYC == 0.
  7. Close the program gate and clear MHSPEN.
  8. Check PRGERRC / ECCERRC for errors.

Writes that span a 32-byte boundary are rejected with k_ra8_err_invalid_arg – the caller must split such writes into per-page calls. This matches the FSP mram_write_data loop which works one page at a time.

Parameters
[in]mram_addrDestination address inside the MRAM window (k_ra8_flash_code_start.. k_ra8_flash_code_start + k_ra8_flash_code_size).
[in]srcNon-NULL source buffer of at least len bytes.
[in]lenNumber of bytes to write, 1..32.
[in]worldk_ra8_flash_world_ns for the non-secure half, k_ra8_flash_world_s for the secure half.
Returns
ra8_err_t error code.
Return values
k_ra8_okWrite completed and committed.
k_ra8_err_null_ptrsrc was NULL.
k_ra8_err_invalid_arglen was 0 or > 32, mram_addr outside the MRAM window, or the write spans a 32-byte page boundary.
k_ra8_err_hw_errorController reported PRGERRC / ECCERRC after the flush.
Precondition
src non-null and len in [1, 32].
mram_addr and mram_addr + len - 1 are both inside the MRAM window and the same 32-byte page.
ra8_flash_init has been called.
Caller's program counter is not in MRAM, or at least not in the same memory the write targets.
Postcondition
On success, the destination bytes hold the source data and the program-control gate is re-locked.
On error, the program-control gate is re-locked even on the failure path.
Note
Thread-safe: no, must run with IRQs masked or with cooperative guarantee that no other writer exists.
Warning
The driver does NOT verify that mram_addr is outside the running image's .text. Caller bears full responsibility for not bricking the part.
See also
ra8_flash_erase_block
Since
0.1.0

Definition at line 709 of file ra8_flash.c.

References g_flash_tag, internal_flash_program_window(), internal_validate_write_block(), internal_wait_buffer_ready(), k_ra8_err_hw_error, k_ra8_flash_busy_spin_limit, k_ra8_mram_off_mrcps, k_ra8_mrcps_mask_errors, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error_val, ra8_mram_reg8(), and RA8_RETURN_ON_ERROR.

Referenced by priv_dfu_write_secure(), ra8_flash_erase_block(), and ra8_flash_write().

Variable Documentation

◆ g_flash_rt

ra8_flash_runtime_t g_flash_rt = {}

Single shared ra8_flash runtime-state instance.

Cleared at init. Used by the IRQ dispatcher to find the registered callback and to detect callers that try to use APIs before init. This is the sole definition of the cross-TU state declared in ra8_flash_internal.h; the configuration and IRQ TUs reference it via the extern there.

Note
Not thread-safe; mutated only from single-threaded init / ISR.
Warning
Do not redefine; this is the sole owner of the state.
Since
0.1.0

Defined exactly once in ra8_flash.c; the configuration and IRQ TUs reference this extern. Module-unique name keeps the symbol link-unique within libra_hal.

Note
Not thread-safe; mutated only from single-threaded init / ISR.
Warning
Do not redefine; this is the sole owner of the state.
Since
0.1.0

Definition at line 67 of file ra8_flash.c.

Referenced by internal_deliver(), priv_ra8_flash_internal_set_prefetch(), priv_ra8_flash_internal_window_allows(), ra8_flash_arc_increment(), ra8_flash_arc_read(), ra8_flash_callback_set(), ra8_flash_deinit(), ra8_flash_erase(), ra8_flash_exit_pe_mode(), ra8_flash_init(), ra8_flash_reset(), ra8_flash_set_window(), ra8_flash_update_clock_freq(), ra8_flash_write(), and ra8_flash_zeroize_huk().

◆ g_flash_tag