71#ifndef WA_APP_SETTINGS
73#define WA_APP_SETTINGS (1)
81typedef enum : uint16_t {
96typedef enum : uint32_t {
114typedef enum : uint16_t {
125typedef enum : uint16_t {
135typedef enum : uint16_t {
148typedef enum : uint32_t {
230 "The Time Machine H. G. Wells",
231 "Frankenstein M. Shelley",
232 "Pride and Prejudice J. Austen",
233 "Open with SW2; browse with SW1/SW2.",
237 "The Time Traveller (for so it will be",
238 "convenient to speak of him) was",
239 "expounding a recondite matter to us.",
244 "Refresh cadence fast (A2)",
247 "This app is removable (WA_APP_SETTINGS).",
255static const uint8_t
k_wd_msg_fchk[] =
"widget-app-demo: FAIL selfcheck\r\n";
268static void wd_print(
const uint8_t* msg, uint32_t len)
278 __asm__
volatile(
"wfi");
304 buf[n] = (uint8_t)(
'0' + (value % (uint32_t)
k_wd_dec_ten));
308 for (uint32_t i = 0U; i < n; i++) {
319 for (
size_t i = 0U; i < n; i++) {
337 if (act ==
nullptr) {
349 const int32_t tx = w->rect.x + (int32_t)
k_wd_pad;
358 "SW1 < prev SW2 next > tap a tab",
368 (void)
ra8_gfx_rect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, c->
bg,
true);
369 const int32_t tx = w->rect.x + (int32_t)
k_wd_pad;
370 int32_t ty = w->rect.y + (int32_t)
k_wd_pad;
373 for (uint16_t i = 0U; i < c->
nlines; i++) {
392 const int32_t tabw = w->rect.w / (int32_t)n;
393 for (uint16_t i = 0U; i < n; i++) {
398 const int32_t cx = w->rect.x + ((int32_t)i * tabw);
399 const bool on = ((int32_t)i == ch->
reg->
active);
408 w->rect.y + (w->rect.h / 2) - ((int32_t)
k_wd_line_h / 2),
430 const int32_t tabw = w->rect.w / (int32_t)n;
434 const int32_t col = (ev->
x - w->rect.x) / tabw;
438 if (col >= (int32_t)n) {
452 .on_input =
nullptr};
455 .on_input =
nullptr};
475 int32_t cur = (int32_t)
s_reg.active;
479 const int32_t nx = (cur + dir + (int32_t)n) % (int32_t)n;
484 return (int16_t)app->id;
505 bool handled =
false;
525 for (uint16_t i = 0U; i < (uint16_t)
k_wd_w_count; i++) {
555 const char*
const* lines,
659 .button_id = (uint16_t)btn,
662 bool handled =
false;
703 if (act !=
nullptr) {
704 if (act->id == (uint16_t)want) {
780 const int32_t tabw = tb->rect.w / (int32_t)n;
784 .x = tb->rect.x + (tabw / 2),
785 .y = tb->rect.y + (tb->rect.h / 2)};
787 bool handled =
false;
856 uint32_t cpuclk0_hz = 0U;
916 uint32_t lib_crc = 0U;
917 uint32_t rdr_crc = 0U;
void main(void)
Secure fallback main entry point.
static display_handle_t * s_display
static uint16_t s_framebuffer[(size_t) k_panel_height_px *(size_t) k_panel_width_px]
1024x600 RGB565 framebuffer in external SDRAM (GLCDC scans this).
static bool s_chrome
True while the status bar + scroll rail chrome is shown.
static bool s_was_sw1
Edge-detect: was SW1 held on the previous button poll.
static bool s_was_sw2
Edge-detect: was SW2 held on the previous button poll.
static mg_reader_t s_reader
The pan/zoom viewer over the tiled page.
static wa_app_state_t s_library
static bool wd_tabbar_on_input(ra8_widget_t *w, const ra8_widget_event_t *ev)
Tab-bar input: map a touch column to an app id (request a launch).
static const uint8_t k_wd_msg_fchk[]
wd_widget_idx_t
Index of each widget within an app's tree.
@ k_wd_box_cap
ra8_box scratch (count + 1).
@ k_wd_w_tabbar
Tab bar (fixed).
@ k_wd_w_content
Content (flex).
@ k_wd_w_count
Widgets per app.
@ k_wd_w_status
Status bar (fixed).
static const display_cfg_t k_wd_display_cfg
Display PAL config: GLCDC LCD backend bound to the SRAM framebuffer.
static void wd_app_enter(ra8_app_t *a)
static void wd_route_button(wd_btn_t btn)
Route a navigation button through the focused app (#146).
static void wd_status_render(ra8_widget_t *w)
Status-bar render: fill + active app name + the button hint.
static const uint8_t k_wd_msg_rdr[]
static const uint8_t k_wd_msg_fpanl[]
static const uint8_t k_wd_msg_boot[]
static const uint8_t k_wd_msg_route[]
static void wd_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
wd_app_id_t
Registered app ids (launch keys).
@ k_wd_app_settings
Settings app (optional).
@ k_wd_app_reader
EPUB reader app.
@ k_wd_app_library
Library / home app.
static const uint8_t k_wd_msg_freg[]
static void wd_setup_or_halt(void)
Bring up clocks/MSTP/time, the console, and the SW1/SW2 inputs.
static bool wd_selfcheck(uint32_t *out_lib, uint32_t *out_rdr)
Run the whole deterministic surface; return the two composites' hashes.
static const char *const k_wd_rdr_lines[]
static void wd_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
static void wd_render_active(void)
Render the focused app and flush the whole panel.
static void wd_print_banner(uint32_t lib_crc, uint32_t rdr_crc)
Emit the PASS banner once the self-check holds.
wd_btn_t
Navigation button ids carried in a button widget event.
@ k_wd_btn_next
SW2: focus the next app.
@ k_wd_btn_prev
SW1: focus the previous app.
static void wd_print_hex(uint32_t value)
Print value as 8 uppercase hex digits.
static void wd_flush_full(void)
Push the whole composited frame to the panel (GC16-quality).
static volatile int16_t g_wd_request
App id an input handler asked to focus, or k_ra8_app_none.
static bool wd_register_apps(ra8_app_t *library, ra8_app_t *reader, ra8_app_t *settings)
Initialise app state, the registry, and register every app.
wd_geom_t
Framebuffer + band geometry (no magic numbers).
@ k_wd_tab_inset
Tab cell inset from the band, pixels.
@ k_wd_fb_h
Framebuffer height, pixels.
@ k_wd_tabbar_h
Tab-bar band height, pixels.
@ k_wd_status_h
Status-bar band height, pixels.
@ k_wd_line_h
Text line pitch (16px glyph + 2).
@ k_wd_pad
Inner text padding, pixels.
@ k_wd_fb_w
Framebuffer width, pixels.
static const ra8_app_vtable_t k_wd_app_vt
Shared app lifecycle vtable (every app behaves the same way).
static void wd_content_render(ra8_widget_t *w)
Content render: fill + title over the app's body lines.
static void wd_fail_halt(const uint8_t *msg, uint32_t len)
Print a fail banner and park forever in WFI.
static uint32_t wd_framebuffer_hash(void)
FNV-1a-32 over the composited framebuffer bytes.
static bool wd_panel_up(void)
Bring up the GLCDC panel and bind ra8_gfx to its framebuffer.
static const char *const k_wd_set_lines[]
static bool wd_sw_pressed(ra8_port_pin_t pin)
Read a user switch (active-low); true == pressed.
static const uint8_t k_wd_msg_lib[]
static ra8_port_pin_t s_wd_sw1_pin
SW1 (previous app) port pin, sourced from the board layer at init.
static const ra8_widget_vtable_t k_wd_content_vt
wd_color_t
0xRRGGBB palette (ra8_gfx packs to RGB565).
@ k_wd_col_set_bg
Settings content (deep green).
@ k_wd_col_lib_bg
Library content (deep blue).
@ k_wd_col_tab_off
Idle tab cell (gray).
@ k_wd_col_tabbar_bg
Tab-bar fill (dark).
@ k_wd_col_rdr_bg
Reader content (warm brown).
@ k_wd_col_status_bg
Status-bar fill (slate).
@ k_wd_col_text
Primary text (white).
@ k_wd_col_dim
Secondary text (gray).
@ k_wd_col_clear
Whole-frame clear (near black).
@ k_wd_col_tab_on
Active tab cell (blue).
static bool wd_check_damage(void)
Assert status-bar-only invalidation yields exactly its rect, fast.
static void wd_tabbar_render(ra8_widget_t *w)
Tab-bar render: one cell per app, the active one highlighted.
static void wd_app_render(const ra8_app_t *a)
App render: clear, lay out the tree, mark all dirty, composite.
static bool wd_app_on_input(ra8_app_t *a, const ra8_widget_event_t *ev)
App input: SW button -> neighbour app; touch -> widget dispatch.
static int16_t wd_neighbor_id(int32_t dir)
Resolve the app id at (active + dir), wrapped, or k_ra8_app_none.
static const uint8_t k_wd_msg_pre[]
static const ra8_widget_vtable_t k_wd_status_vt
Status / content widgets ignore input (NULL handler never consumes).
static const char * wd_active_name(const ra8_app_registry_t *reg)
Name of the focused app, or a placeholder if none.
static const ra8_widget_vtable_t k_wd_tabbar_vt
static ra8_port_pin_t s_wd_sw2_pin
SW2 (next app) port pin, sourced from the board layer at init.
wd_console_t
Console baud + text-format constants.
@ k_wd_frame_ms
Input poll period (ms).
@ k_wd_hex_nibbles
Hex digits per 32-bit.
@ k_wd_dec_ten
Hex/decimal split + buf.
@ k_wd_fnv_prime
FNV-1a-32 prime.
@ k_wd_nibble_bits
Bits per hex nibble.
@ k_wd_nibble_mask
Low-nibble mask.
@ k_wd_fnv_offset
FNV-1a-32 offset basis.
@ k_wd_uart_baud
Console baud.
static void wd_app_leave(ra8_app_t *a)
static void wd_state_init(wa_app_state_t *st, const char *title, const char *const *lines, uint16_t nlines, uint32_t bg)
Build one app's widget tree: status (fixed) / content (flex) / tabs (fixed).
static bool wd_check_touch_dispatch(void)
Drive a synthetic touch on the Library tab while Reader is focused.
static const uint8_t k_wd_msg_pass[]
static wa_app_state_t s_settings
Settings app state (optional).
static const char *const k_wd_lib_lines[]
static void wd_service_request(void)
Apply a pending app-switch request: launch + re-composite if changed.
static const uint8_t k_wd_msg_finit[]
static void wd_poll_buttons(void)
Poll SW1/SW2 (edge-triggered) and route a fresh press as a button.
Zero-heap app framework: lifecycle + static registry + launcher (#146).
ra8_err_t ra8_app_launch(ra8_app_registry_t *reg, uint16_t id)
Launch (focus) the app with id, running the focus lifecycle.
ra8_err_t ra8_app_register(ra8_app_registry_t *reg, ra8_app_t *app)
Register an app (calls its init once) and add it to the registry.
ra8_err_t ra8_app_count(const ra8_app_registry_t *reg, uint16_t *out_count)
Number of registered apps (for the launcher to list).
@ k_ra8_app_none
No active app / not found.
ra8_err_t ra8_app_at(const ra8_app_registry_t *reg, uint16_t idx, ra8_app_t **out_app)
Get the app at registry index idx (launcher enumeration).
ra8_err_t ra8_app_route_input(ra8_app_registry_t *reg, const ra8_widget_event_t *ev, bool *out_handled)
Route an input event to the focused app.
ra8_err_t ra8_app_active(const ra8_app_registry_t *reg, ra8_app_t **out_app)
Get the currently focused app.
ra8_err_t ra8_app_render(ra8_app_registry_t *reg)
Run the focused app's render (on-target; no-op if none / NULL).
ra8_err_t ra8_app_registry_init(ra8_app_registry_t *reg, ra8_app_t **storage, uint16_t cap)
Bind a registry to caller-owned pointer storage (empty, no focus).
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_sw_pin(ra8_board_sw_id_t sw, ra8_port_pin_t *out_pin)
Translate a board switch id into its underlying ra8_port_pin_t.
ra8_err_t ra8_board_sw_init(ra8_board_sw_id_t sw)
Configure a switch pin as an input with internal pull-up.
@ k_ra8_board_sw1
SW1, P009, IRQ13-DS (jumper E31).
@ k_ra8_board_sw2
SW2, P008, IRQ12-DS (jumper E32).
ra8_board_eth_pin_t pin
Pin.
ra8_err_t ra8_board_uart_console_write(const uint8_t *data, size_t len)
Polled blocking write to the J-Link OB VCOM console.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
Boot entry points shared between a vector table and its startup code.
Bounded, allocation-free box-model layout for e-reader chrome.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_get_clock_hz(ra8_clock_id_t id, uint32_t *out_hz)
Query the current frequency of a clock-tree domain.
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Display Platform Abstraction Layer for the RA8D2.
@ k_display_pixfmt_rgb565
16 bpp, 5/6/5 packed.
display_rect_t display_full_rect(const display_handle_t *d)
Convenience helper returning the rect covering the whole framebuffer.
ra8_err_t display_get_framebuffer(const display_handle_t *d, display_fb_t *out)
Return the framebuffer descriptor the backend is targeting.
ra8_err_t display_flush(const display_handle_t *d, display_rect_t rect, display_refresh_hint_t hint)
Commit pending framebuffer changes to the panel.
struct display_handle display_handle_t
ra8_err_t display_init(const display_cfg_t *cfg, display_handle_t **out_handle)
Initialise the display PAL and bring the selected backend up to a state where display_flush succeeds.
@ k_display_refresh_quality
Prioritise final quality.
LCD backend (ra8_glcdc) for the display PAL.
const display_backend_iface_t k_display_backend_lcd_ra8_glcdc
LCD backend vtable – pass its address through display_cfg_t.iface to drive the EK-RA8D2 panel.
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Software 2D graphics primitives layered on top of a caller-ownedframebuffer (DRW / D/AVE 2D / GLCDC r...
@ k_ra8_gfx_format_rgb565
16-bit RGB565, little-endian in memory.
ra8_err_t ra8_gfx_clear(uint32_t color)
Fill the bound framebuffer's clip region with a single colour.
ra8_err_t ra8_gfx_text_out(int32_t x, int32_t y, const char *str, const ra8_gfx_font_t *font, uint32_t fg_color, uint32_t bg_color)
Render a NUL-terminated ASCII string.
ra8_err_t ra8_gfx_init(void *fb, uint16_t width, uint16_t height, ra8_gfx_format_t format)
Bind ra8_gfx to a caller-owned framebuffer.
ra8_err_t ra8_gfx_rect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color, bool filled)
Draw an axis-aligned rectangle.
Bitmap font descriptor + bundled font handles for ra8_gfx.
const ra8_gfx_font_t ra8_gfx_font_8x16
Bundled 8x16 IBM PC VGA bitmap font, ASCII 0x20..0x7E.
Graphics LCD Controller driver (two-layer with alpha blending).
static const ra8_io_fsfmt_t * s_reg[(uint32_t) k_ra8_io_fsfmt_max]
Registered formats, in probe priority order.
static ra8_isr_slot_t s_slots[k_ra8_isr_slot_count]
Per-slot dispatch table.
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_init(void)
Re-establish the ra8_mstp ref-count table from current hardware state.
Active display-panel descriptor for the EK-RA8D2 (ER-TFT070-6).
@ k_ra8_board_fb_align_bytes
GLCDC AXI burst alignment, in bytes.
EK-RA8D2 panel timing as the HAL's ra8_glcdc_timing_t (ER-TFT070-6).
static const ra8_glcdc_timing_t s_ra8_panel_ek_ra8d2_timing
EK-RA8D2 ER-TFT070-6 RGB timing for ra8_glcdc_init / the LCD backend.
Typed Port / Pin Constants for the RA8D2 IOPORT Module.
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
@ k_ra8_pin_none
Sentinel: no pin selected.
ra8_level_t
Digital output / input level.
@ k_ra8_level_high
Drive or read 1.
@ k_ra8_level_low
Drive or read 0.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_gpio_read(ra8_port_pin_t pin, ra8_level_t *out_level)
Read a previously-configured input.
SysTick-based tick counter, delay and timestamp helpers.
ra8_err_t ra8_time_init(uint32_t cpu_hz)
Initialise SysTick for a 1 kHz tick interrupt.
void ra8_delay_ms(uint32_t ms)
Busy-wait for at least ms milliseconds.
Bounded UI interaction core: hit-testing, screen stack, paging.
Configuration descriptor passed into display_init.
Framebuffer descriptor returned by display_get_framebuffer.
void * pixels
Base of pixel data (RGB565 unless noted).
Fixed table of registered apps + the focused index.
int16_t active
Focused app index, or k_ra8_app_none.
One app instance + its metadata (caller-owned, static).
App lifecycle callbacks (shared by all instances of one app).
One node in a box tree (caller-owned).
Axis-aligned rectangle in framebuffer pixel coordinates.
int32_t h
Height (pixels, >= 0).
Per-app state: its widget tree + a focus-lifecycle counter.
uint32_t enters
Times on_enter fired.
uint32_t leaves
Times on_leave fired.
wa_content_t content
Content widget state.
ra8_widget_t widgets[2]
[0] status bar, [1] content.
Shared chrome state: the registry the status bar + tab bar read.
ra8_app_registry_t * reg
Registry (active index + app names).
Per-app content widget state: a title over a list of text lines.
const char *const * lines
Body lines (each NUL-term).
uint32_t bg
Content background colour.
const char * title
Heading line.
uint16_t nlines
Number of body lines.