81static_assert(
sizeof(
k_er_wordmark) == 6U,
"k_er_wordmark size pins the er_read_sb_render advance");
91const char*
const k_er_nav_items[] = {
"Library",
"Store",
"Notes",
"Settings"};
93 "k_er_nav_count must match k_er_nav_items");
97 {
"The Time Machine",
"H. G. Wells", 5U},
98 {
"Frankenstein",
"Mary Shelley", 100U},
99 {
"Pride and Prejudice",
"Jane Austen", 42U},
100 {
"Moby-Dick",
"Herman Melville", 12U},
101 {
"The Republic",
"Plato", 68U},
102 {
"Meditations",
"M. Aurelius", 30U},
105 "k_er_book_count must match k_er_books");
111 "The Time Traveller (for so it will be convenient to speak of him)",
112 "was expounding a recondite matter to us. His pale grey eyes shone",
113 "and twinkled, and his usually pale face was flushed and animated.",
115 "The fire burnt brightly, and the soft radiance of the incandescent",
116 "lights in the lilies of silver caught the bubbles that flashed and",
117 "passed in our glasses. Our chairs, being his patents, embraced and",
118 "caressed us rather than submitted to be sat upon -- there was that",
119 "luxurious after-dinner atmosphere when thought roams gracefully free",
120 "of the trammels of precision.",
124 "k_er_body_line_count must match k_er_body_lines");
134 "<html><head><style>h1 { text-align: center; color: maroon; }"
135 ".byline { text-align: right; text-decoration: underline; color: #808080; font-size: 14px; }"
136 ".lead { font-size: 130%; } .draft { display: none; }"
137 " p.lead { color: navy; }</style></head>"
138 "<body><h1>The Time Machine</h1>"
139 "<p class=\"draft\">INTERNAL DRAFT -- NOT FOR DISTRIBUTION</p>"
140 "<p class=\"byline\">by H. G. Wells</p>"
141 "<img src=\"logo.svg\"/>"
142 "<p class=\"lead\">The Time Traveller (for so it will be convenient to speak of him) was "
143 "expounding a recondite matter to us. See the "
144 "<a href=\"#note\">editor's note</a> for context. His pale grey eyes shone "
145 "and twinkled, and his usually pale face was flushed and animated.</p>"
146 "<p>The fire burnt brightly, and the soft radiance of the incandescent lights "
147 "in the lilies of silver caught the bubbles that flashed and passed in our "
148 "glasses. Our chairs, being his patents, embraced and caressed us rather than "
149 "submitted to be sat upon, and thought roamed gracefully free of the trammels "
151 "<p id=\"note\">Editor's note: this passage introduces the frame narrator "
152 "before the Traveller's account begins. <a href=\"ch2.xhtml\">Continue to "
153 "Chapter II</a>.</p></body></html>";
157 "<html><body><h1>Chapter II</h1>"
158 "<p>The Machine, said the Time Traveller, holding the lamp aloft, is the thing "
159 "I have been at work upon these many years; and now at last it is built.</p>"
160 "<p>He took one of the small octahedral things from the table and handed it to "
161 "us. <a href=\"ch1.xhtml\">Back to Chapter I</a>.</p></body></html>";
168 (uint32_t)(
sizeof(
"ch1.xhtml") - 1U)},
172 (uint32_t)(
sizeof(
"ch2.xhtml") - 1U)},
175 "k_er_spine_count must match k_er_spine");
320 __asm__
volatile(
"wfi");
339 uint32_t cpuclk0_hz = 0U;
474 .filename =
"FONT.OTF",
475 .provision_blob =
nullptr,
486#ifdef RA8_APP_SETTINGS
500static void er_render_settings(
void)
526#ifdef RA8_APP_SETTINGS
541#ifdef RA8_APP_SETTINGS
543 er_render_settings();
576#ifdef RA8_APP_SETTINGS
void main(void)
Secure fallback main entry point.
static uint32_t s_pclka_hz
Pure page-turn + input-region decisions for the e-reader (#78).
E-reader UI chrome – shared contract between main.c and the per-aspect helper translation units (scre...
@ k_er_spine_count
Number of chapters in k_er_spine.
bool s_have_font
True once an SD font is loaded.
const char k_er_count_text[]
Book-count chip text.
@ k_er_paper
Page background (g15).
@ k_er_ink
Primary text / glyphs (g0).
@ k_er_fb_w
Framebuffer width (pixels).
@ k_er_fb_h
Framebuffer height (pixels).
void er_poll_buttons(void)
Poll SW1/SW2 and turn a page on a fresh press (#78).
bool s_reflow_open
True while the engine holds a layout.
const char k_er_search_hint[]
Search placeholder.
ra8_ui_target_t s_targets[]
Tap targets for the current screen.
reflow_t s_reflow_engine
reflow engine for the body.
ra8_kbd_layout_t s_kb
On-screen keyboard grid.
ra8_kbd_text_t s_query
Live search query.
@ k_er_img_arena
SDRAM image-decode scratch.
@ k_er_font_cap
Max font read off the card (bytes).
@ k_er_spi_chan
Pmod2 / J25 = SCI0 Simple-SPI.
const char *const k_er_body_lines[]
Reading-view body paragraph lines (pre-wrapped for the font).
uint32_t s_chapter_idx
Reading chapter index.
uint16_t s_target_count
Tap targets currently populated.
uint32_t s_reflow_chapter
Chapter laid out (cache key).
bool s_nag_region_only
True when a tap only toggled the nag.
volatile uint32_t g_er_turns
Count of page turns applied since boot.
const char *const k_er_nav_items[]
Bottom-nav destinations (Library / Store / Notes / Settings).
@ k_er_page_back_cap
Footnote-jump back-stack depth.
@ k_er_max_targets
Max collected tap targets.
const char k_er_page_label[]
Reading page label.
@ k_er_statusbar_h
Top status-bar band height.
@ k_er_touch_max_points
One contact = one tap.
display_turn_event_t s_pending_event
Pending refresh event for next flush.
void er_render_reading(void)
Render the full Reading screen (status bar, body, footer).
int32_t s_reflow_w
Body width the layout used.
const char k_er_book_title[]
Reading title text.
uint8_t s_img_arena_buf[]
Image-decode bump arena in SDRAM.
@ k_er_nav_count
Number of bottom-nav destinations.
void er_nag_render(ra8_widget_t *w)
Nag banner overlay widget: a centered low-battery toast over the screen.
ra8_batt_monitor_t s_batt_mon
Low-battery nag policy state.
volatile uint32_t g_er_last_hint
Last display_refresh_hint_t flushed.
@ k_er_nag_margin
Banner inset from the screen sides.
@ k_er_nag_h
Banner height (px).
@ k_er_nag_top
Banner top y (clear of the status bar).
const char k_er_status_right[]
Status-bar right text.
int32_t s_reflow_h
Body height the layout used.
uint32_t s_loc_back_count
Entries used in s_loc_back.
er_loc_t s_loc_back[]
Reading back-stack for link jumps.
uint32_t s_reading_pages
Reading total reflow pages (>= 1).
const char k_er_chapter[]
Bitmap-fallback heading.
ra8_batt_nag_t s_batt_nag
Nag currently shown over the chrome.
const char k_er_wordmark[6]
Wordmark / status text.
uint32_t s_reading_page
Reading current reflow page.
const er_chapter_t k_er_spine[]
Two-chapter mock spine for in-content cross-chapter navigation (#110).
const er_book_t k_er_books[]
Demo shelf (public-domain works).
void er_poll_battery(void)
Poll the fuel gauge, fold it into the nag policy, and toggle the banner.
const char k_er_lib_heading[]
Library heading text.
@ k_er_book_count
Number of demo books.
@ k_er_chapter_none
s_reflow_chapter when nothing is laid out.
@ k_er_body_line_count
Number of pre-wrapped body lines.
void er_render_keyboard(void)
Render the on-screen keyboard screen + collect its key targets.
@ k_er_screen_reading
Reading view.
@ k_er_screen_keyboard
On-screen keyboard (search entry).
@ k_er_screen_library
Library / home grid.
@ k_er_screen_settings
Settings (optional app, if RA8_APP_SETTINGS).
uint8_t s_batt_soc
Last fuel-gauge SOC percent.
uint32_t s_font_len
Bytes of font read off the card.
void er_poll_touch(void)
Poll the touch controller and dispatch a tap on a fresh press.
@ k_er_settle_ms
PLL / SDRAM / panel-POR settle.
@ k_er_frame_ms
Input poll period (ms): touch / button cadence.
@ k_er_led_every
Toggle the heartbeat LED every Nth frame.
volatile uint32_t g_er_cur_page
SWD / --dump-sym telemetry for the headless page-turn HIL (#78).
void er_render_library(void)
Render the full Library screen.
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 uint8_t s_font_buf[k_pc_font_cap]
Font blob read off the card.
static void app_bringup_touch(void)
Open the GT911 touch controller (best-effort, polled; non-fatal).
static void app_bringup_clocks(void)
Bring up clocks, MSTP, SysTick, the SCI8 console and both LEDs.
static void app_bringup_panel(void)
Bring up external SDRAM + the GLCDC panel, then cache the FB.
static void app_panic_halt(void)
Halt forever with the red board LED on (visual sign of fatal init).
static void app_bringup_gfx(void)
Bind ra8_gfx to the panel framebuffer.
static ra8_app_nav_t s_nav
Navigation back-stack layered over s_reg.
static display_policy_t s_policy
Refresh-cadence policy driving e-ink page-turn waveforms (#78).
static ra8_app_t s_app_library
Library / Reading / Keyboard (+ optional Settings) app instances.
static void er_try_load_font(void)
Best-effort: load FONT.OTF off the Pmod2 SD card into s_font_buf.
volatile uint32_t g_er_loop_ticks
Free-running main-loop counter – HIL liveness.
static const ra8_app_vtable_t k_er_app_vt
Vtable shared by every screen-app (render-only; nav owns transitions).
static const ra8_widget_vtable_t k_er_nag_vt
Nag banner overlay widget vtable (renderer lives in the input TU).
static void er_app_render(const ra8_app_t *a)
App render trampoline: dispatch to the screen render by app id.
static void er_apps_init(void)
Register the e-reader screen-apps into s_app_reg.
static ra8_app_t s_app_reader
static const ra8_port_pin_t k_er_pin_sck
Pmod2 SPI pins (J25) – SCI0 Simple-SPI, per sd_font_render.
static ra8_app_t * s_app_slots[4]
App registry storage (4 slots: 3 core + an optional Settings).
void er_flush_event(display_turn_event_t event)
Flush the panel for a refresh event through the cadence policy (#78).
static const ra8_port_pin_t k_er_pin_copi
@ k_er_clean_every
Er clean every.
static const char k_er_chapter2_xhtml[]
Reading-view chapter two (cross-chapter <a href> link target).
static const char k_er_chapter_xhtml[]
Reading-view chapter as XHTML, reflowed by reflow when an SD font is present (the same prose as k_er_...
static const ra8_port_pin_t k_er_pin_cs
void er_render_current(void)
Render whichever screen is on top of the navigation stack.
static const ra8_port_pin_t k_er_pin_cipo
static ra8_app_t s_app_keyboard
void er_render_nag_region(void)
Repaint only the low-battery banner rect (dirty-region update).
static const display_cfg_t k_er_display_cfg
Display PAL config – LCD/GLCDC backend over the SDRAM buffer.
static ra8_app_registry_t s_app_reg
Declaration of the Latin-1 Literata font baked into internal flash.
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_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).
Bounded, allocation-free low-battery nag policy.
ra8_batt_nag_t
The low-battery warning a single ra8_batt_update step raises.
@ k_ra8_batt_nag_none
No new warning this step.
ra8_err_t ra8_batt_monitor_init(ra8_batt_monitor_t *mon)
Reset a nag monitor to the un-nagged, fully-armed state.
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_led_toggle(ra8_board_led_id_t led)
Toggle led's output state.
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_pmod2_spi_cipo
Pmod2.3 CIPO (CIPO0_B), P602.
@ k_ra8_board_pmod2_spi_cs
Pmod2.1 CS (SS0_B), P604.
@ k_ra8_board_pmod2_spi_copi
Pmod2.2 COPI (COPI0_B), P603.
@ k_ra8_board_pmod2_spi_sck
Pmod2.4 SCK (SCK0_B), P601.
@ k_ra8_board_sw1
SW1, P009, IRQ13-DS (jumper E31).
@ k_ra8_board_sw2
SW2, P008, IRQ12-DS (jumper E32).
ra8_err_t ra8_board_led_init(ra8_board_led_id_t led)
Configure led as a digital output, initial level low (off).
ra8_err_t ra8_board_led_on(ra8_board_led_id_t led)
Drive led HIGH (light it).
@ k_ra8_board_led_blue
Convenience aliases by colour.
@ k_ra8_board_led_red
RA8 board led red.
One-call bring-up of the EK-RA8D2 panel's GoodIX GT911 touch controller.
ra8_err_t ra8_board_touch_open(const ra8_board_touch_cfg_t *cfg)
Bring the on-board GT911 up and open the touch driver against it.
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.
@ k_ra8_clock_id_pclka
PCLKA.
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.
Pluggable page-turn refresh-cadence policy for bistable (e-ink) panels.
ra8_err_t display_policy_init(display_policy_t *p, display_policy_kind_t kind, uint16_t clean_every)
Initialise a refresh-cadence policy.
@ k_display_policy_fast_clean
A2 partial, periodic GC16 clean (default).
display_turn_event_t
The page-transition event the policy reacts to.
@ k_display_event_chapter
Chapter-boundary turn – wants a clean refresh.
@ k_display_event_open
Book/first page opened – wants a clean INIT.
ra8_err_t display_policy_full_rect(uint16_t w, uint16_t h, display_rect_t *out)
Build the full-page damage rectangle for a page turn.
ra8_err_t display_policy_decide(display_policy_t *p, display_turn_event_t event, display_policy_decision_t *out)
Decide the flush parameters for one page-transition event.
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_reset_clip(void)
Reset the clip rectangle to the whole framebuffer.
ra8_err_t ra8_gfx_set_clip(int32_t x, int32_t y, int32_t w, int32_t h)
Restrict all subsequent drawing to a rectangle (dirty-region updates).
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_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.
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.
#define RA8_BOARD_PANEL_FRAMEBUFFER(name)
Declare a correctly aligned, sized and placed RGB565 framebuffer for the on-board panel.
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.
High-level GPIO helpers on top of the PORT + PFS register layer.
Load a TTF/OTF font off a Pmod SD card, self-provisioning if absent.
ra8_err_t ra8_sdfont_load(const ra8_sdfont_cfg_t *cfg, uint8_t *buf, uint32_t cap, uint32_t *out_len, ra8_sdfont_source_t *out_source)
Mount the Pmod SD card and load a font, provisioning it if absent.
External SDRAM controller driver (framework).
ra8_err_t ra8_sdramc_init(void)
Initialise the external SDRAM at k_ra8_sdram_base_addr.
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.
Multi-touch input driver – GoodIX GT911 backend.
@ k_ra8_touch_irq_pin_unset
Sentinel for "no IRQ pin attached".
Bounded UI interaction core: hit-testing, screen stack, paging.
ra8_err_t ra8_ui_nav_init(ra8_ui_nav_t *nav, uint16_t root_screen)
Initialise a navigation stack with a root screen.
ra8_err_t ra8_ui_nav_top(const ra8_ui_nav_t *nav, uint16_t *out_screen)
Read the current (top) screen id.
HTML / CSS reflow + paginate engine for the ra8d2 ereader.
Configuration descriptor passed into display_init.
Framebuffer descriptor returned by display_get_framebuffer.
What the app should pass to display_flush for this event.
display_refresh_hint_t hint
Waveform intent (fast/quality/init).
Caller-owned policy state (zero heap; init once, decide per turn).
Rectangle in framebuffer coordinates passed into display_flush.
One library entry: title, author, reading progress percent.
One mock-spine chapter: its XHTML, length, and resolving href.
A reading location (chapter + page) for the navigation back-stack.
Fixed table of registered apps + the focused index.
One app instance + its metadata (caller-owned, static).
App lifecycle callbacks (shared by all instances of one app).
Caller-owned nag state carried across ra8_batt_update calls.
The two touch settings that are an APPLICATION choice, not a board fact.
The key grid for the active layer, plus SHIFT / layer / frame state.
The typed query buffer + commit state.
SD-card font-store bus description + provisioning policy.
Fixed-depth screen-id stack (caller-owned).
One tap target: a rectangle bound to an opaque action id.
Reflow / pagination engine state.