79typedef enum : uint32_t {
89typedef enum : uint32_t {
98typedef enum : uint8_t {
109typedef enum : uint8_t {
122typedef enum : uint32_t {
144static void banner_append(
char* dst, uint32_t* off, uint32_t cap,
const char* src)
146 if (dst ==
nullptr) {
149 if (off ==
nullptr) {
152 if (src ==
nullptr) {
156 for (uint32_t i = 0U; i < cap; i++) {
157 const char c = src[i];
161 if (*off >= (cap - 1U)) {
190 if (dst ==
nullptr) {
193 if (off ==
nullptr) {
196 static const char digits[] =
"0123456789ABCDEF";
199 if (*off >= (cap - 1U)) {
203 const uint32_t nibble = (value >> shift) & (uint32_t)
k_nibble_mask;
204 dst[*off] = digits[nibble];
233 if (dst ==
nullptr) {
236 if (off ==
nullptr) {
244 tmp[count] = (char)(
'0' + (
char)(v % (uint32_t)
k_dec_radix));
252 for (uint32_t i = 0U; i < count; i++) {
253 if (*off >= (cap - 1U)) {
256 dst[*off] = tmp[count - 1U - i];
292 __asm
volatile(
"dsb" :::
"memory");
294 __asm
volatile(
"dsb" :::
"memory");
346 if (mb->
done == 1U) {
435typedef enum : uint8_t {
527 .clear_status =
true,
576 .opa_bus_keep =
true,
644 __asm
volatile(
"wfi" :::
"memory");
756 __asm
volatile(
"dsb" :::
"memory");
825 ra8_log_info(
"M85",
"entering #150 mode-switch cycle; M33 holds the page + polls touch");
827 bool done_ok =
false;
831 bool verdict =
false;
857 ra8_log_info(
"M85",
"M85 parked in low-power WFI; M33 holds the page");
860 __asm
volatile(
"wfi");
880 __asm
volatile(
"nop");
904 ra8_log_info(
"M85",
"==== RA8D2 ereader_m33 demo (#150 M85-park / M33-hold) ====");
906 ra8_log_info(
"M85",
"M33 renders a held page into external SDRAM (0x68000000)");
916 ra8_log_info(
"M85",
"IPC0 receive IRQ armed -- M85 can WFI-wake on a page turn");
918 ra8_log_info(
"M85",
"IPC wake arm failed -- page-turn WFI falls back to bounded poll");
922 ra8_log_info(
"M85",
"releasing Cortex-M33 secondary core ...");
933 ra8_log_info(
"M85",
"M33 signature not seen -- did it boot?");
936 ra8_log_info(
"M85",
"M85 idle; waiting for the M33 to render the held page ...");
938 ra8_log_info(
"M85",
"M33 done flag not seen -- timed out");
941 __asm
volatile(
"dsb" :::
"memory");
void main(void)
Secure fallback main entry point.
Shared contract for the "render a held e-reader page on the M33" demo.
@ k_erm33_status_running
status: M33 is rendering the page.
@ k_erm33_status_ok
status: page rendered + published.
@ k_erm33_fb_format_rgb565
Published fb_format (RGB565).
@ k_erm33_magic
"ERM3" – M85 stamps it when ready.
@ k_erm33_m33_sig
"RDR3" boot sentinel written by M33.
@ k_erm33_sdram_base
External SDRAM window base.
@ k_erm33_sdram_end
External SDRAM window end (+64 MiB).
@ k_erm33_fb_stride
Bytes per pixel row (width * bpp).
@ k_erm33_fb_height
Plane height in pixels (4 glyph rows of 16).
@ k_erm33_fb_width
Plane width in pixels.
@ k_erm33_max_turns
Page-turn handoffs the cycle exercises.
static volatile erm33_mailbox_t * erm33_mailbox(void)
Typed pointer to the fixed-address shared progress mailbox.
uint32_t g_ra8_ls_cpu1_mram_start
static void park_forever(void)
Park the M85 forever after an unrecoverable startup failure.
static volatile bool s_m33_woke
Set by the IPC0 receive callback when the M33 signals compile-done.
m85_ipc_t
IPC channel the M85 watches for the M33's compile-done wake.
@ k_ipc_wake_channel
IPC0 channel 0 (CPU1 -> CPU0 receive side).
static bool wait_for_m33_sig(const volatile com33_mailbox_t *mb)
Poll the mailbox until the M33 stamps its boot signature.
static bool arm_ipc_wake(void)
Arm the IPC0 receive interrupt so the M85 can WFI-idle for the M33.
static void prep_mailbox(volatile com33_mailbox_t *mb)
Publish the mailbox, stage the source .epub, and post the compile job.
static void ipc_wake_handler(void *ctx, uint8_t channel, ra8_ipc_irq_event_id_t event_id)
IPC0 receive event callback: record that the M33's wake poke arrived.
m85_poll_t
Bounded iteration limits for the M85 polling loops.
@ k_m85_done_poll_budget
Max iters waiting for M33 done flag.
@ k_m85_sig_poll_budget
Max iters waiting for M33 signature.
static void ipc0_receive_isr(void *ctx)
IPC0 receive ISR trampoline: decode the channel's pending events.
static bool wait_for_done(const volatile com33_mailbox_t *mb)
Idle in WFI until the M33's IPC poke signals the done flag.
static void m85_lpm_configure(void)
Configure the LPM block once so a plain WFI is a CPU Sleep.
static void emit_cycle_verdict(const volatile erm33_mailbox_t *mb, bool pass)
Assemble and log the single deterministic handoff-cycle verdict banner.
static void banner_append_hex(char *dst, uint32_t *off, uint32_t cap, uint32_t value)
Append value as 8 uppercase hex digits into the banner buffer.
static bool m85_wait_turn_done(const volatile erm33_mailbox_t *mb, uint32_t turn)
Bounded-poll the mailbox until the M33 republishes through turn.
static bool m85_wait_turn(const volatile erm33_mailbox_t *mb, uint32_t turn)
Park in Sleep-mode WFI until the M33 requests page turn turn.
static void emit_verdict(uint32_t crc, bool pass)
Assemble and log the single deterministic verdict banner.
static void banner_append_u32(char *dst, uint32_t *off, uint32_t cap, uint32_t value)
Append value as decimal digits (no leading zeros) into the banner.
static void run_mode_switch(volatile erm33_mailbox_t *mb)
Run the #150 mode-switch and log its verdict.
m85_hex_t
Constants for formatting a 32-bit value as 8 uppercase hex digits.
@ k_nibble_bits
Bits per hex nibble.
@ k_hex_nibbles
Hex digits in a 32-bit value.
static void park_low_power(void)
Park the M85 in low-power WFI after the M33 owns the page.
static uint32_t m85_heavy_work(uint32_t turn)
Deterministic stand-in for the M85's heavy next-page work.
static bool run_handoff_cycle(volatile erm33_mailbox_t *mb)
Run the #150 mode-switch cycle: park, wake on a page turn, repeat.
static bool verify_page(const volatile erm33_mailbox_t *mb)
Validate the M33's published held-page descriptor.
m85_dec_t
Constants for formatting a 32-bit value as decimal digits.
@ k_dec_digits_max
Decimal digits in a 32-bit value (4294967295).
@ k_dec_radix
Base-10 radix for the digit extraction.
m85_work_t
Bound for the M85's deterministic "heavy next-page work" stand-in.
@ k_heavy_work_iters
Iterations of the placeholder next-page fold.
m85_banner_t
Capacity of the verdict banner the M85 assembles in a stack buffer.
@ k_banner_cap
Bytes reserved for the assembled verdict line.
static void banner_append(char *dst, uint32_t *off, uint32_t cap, const char *src)
Append a NUL-terminated string into a bounded banner buffer.
static void m85_gate_hoco(bool stop)
Gate or restore the HOCO via the LPM clock-stop matrix (CGC OCR write).
uint32_t g_ra8_ls_cpu1_stack_top
Annotation-attribute framework macros for ra8-firmware.
#define RA8_LOOP_BOUND(ceiling)
NASA Power-of-10 Rule 2: bind ONE loop to a compile-time ceiling.
Boot entry points shared between a vector table and its startup code.
Dual-core (CPU0 / CPU1) lifecycle helper – public API.
ra8_err_t ra8_cpu1_release(void *entry, void *sp)
Release CPU1 (Cortex-M33) from reset and start it executing.
ra8_elc_event_t
Partial list of ELC events (populate as drivers need them).
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
@ k_nibble_mask
Nibble mask.
Inter-Processor Communication (IPC) HAL driver – public API.
@ k_ra8_ipc_elc_event_irq0
Receiving-side IRQ for IPC0_*.
void ra8_ipc_dispatch(uint8_t channel)
Drive the event callback for one channel.
ra8_err_t ra8_ipc_attach_event_handler(uint8_t channel, ra8_ipc_irq_event_id_t event_id, ra8_ipc_irq_fn_t fn, void *ctx)
Attach a callback for a single IRQ event line on a channel.
ra8_ipc_irq_event_id_t
Index of an IRQ event line within a channel (0..7).
@ k_ra8_ipc_irq_event_0
RA8 ipc IRQ event 0.
@ k_ra8_ipc_event_irq0
Maskable IRQ event line 0.
ra8_err_t ra8_ipc_init(const ra8_ipc_config_t *cfg)
Initialise one IPC channel.
NVIC + ICU IELSR allocator.
@ k_ra8_isr_prio_default
Middle priority.
ra8_err_t ra8_isr_init(void)
Initialise the ra8_isr table.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
ra8_err_t ra8_isr_register(ra8_elc_event_t event, ra8_isr_handler_t handler, void *ctx, uint8_t priority, uint16_t *out_slot)
Allocate an IELSR slot for an ELC event + handler.
Lightweight Logging Interface for ra8-firmware.
void ra8_log_init(void)
Initialise the logging backend.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
#define ra8_log_info(tag, message)
RA8 log info.
Low Power Mode (LPM) HAL driver – public API.
ra8_err_t ra8_lpm_init(const ra8_lpm_config_t *cfg)
Initialise the LPM block from a config descriptor.
@ k_ra8_lpm_clock_hoco
High-Speed On-Chip Oscillator.
ra8_err_t ra8_lpm_prcr_relock(void)
Re-lock PRCR.PRC1 after protected writes.
ra8_err_t ra8_lpm_prcr_unlock(void)
Unlock PRCR.PRC1 to permit writes to LPM control registers.
ra8_err_t ra8_lpm_set_clock_stop(ra8_lpm_clock_t clock, bool stop)
Set or clear the per-oscillator stop bit before sleep entry.
Cross-core progress block backed by a fixed shared-SRAM address.
volatile uint32_t magic
M85 stamps k_erm33_magic when ready.
volatile uint32_t turn_done
M33->M85: re-render published for that turn.
volatile uint32_t fb_base
M33-published SDRAM framebuffer base address.
volatile uint32_t done
Set to 1 by the M33 once the page is published.
volatile uint32_t fb_crc
M33-folded CRC-32 over the rendered pixels.
volatile uint32_t turn_ack
M85->M33: heavy-work ack for the matching turn.
volatile uint32_t fb_format
M33-published ra8_gfx_format_t (RGB565).
volatile uint32_t turn_req
M33->M85: page-turn request, bumped per touch.
volatile uint32_t glyph_count
Characters the M33 laid onto the held page.
volatile uint32_t fb_stride
M33-published framebuffer stride in bytes.
volatile uint32_t m33_sig
M33 stamps k_erm33_m33_sig on boot.
volatile uint32_t status
Render status (erm33_const_t status codes).
volatile uint32_t fb_height
M33-published framebuffer height in pixels.
volatile uint32_t fb_width
M33-published framebuffer width in pixels.
Per-channel configuration descriptor passed to ra8_ipc_init.
Configuration descriptor for ra8_lpm_init.