51typedef enum : uint32_t {
80static const uint8_t
k_msg_fail[] =
"ereader-shelf: FAIL init\r\n";
83static void sh_print(
const uint8_t* msg, uint32_t len)
94 for (
size_t i = 0U; i < bytes; ++i) {
116 const char* pre =
"ereader-shelf: books=";
117 for (
const char* s = pre; *s !=
'\0'; ++s) {
121 const char* mid =
" sd=";
122 for (
const char* s = mid; *s !=
'\0'; ++s) {
126 const char* fbp =
" fb=";
127 for (
const char* s = fbp; *s !=
'\0'; ++s) {
137 const char* end =
" ok\r\n";
138 for (
const char* s = end; *s !=
'\0'; ++s) {
141 sh_print((
const uint8_t*)b, (uint32_t)p);
148 __asm__
volatile(
"bkpt #0");
150 __asm__
volatile(
"wfi");
163 size_t in_n = src_len;
164 size_t out_n = dst_cap;
165 const tinfl_status st = tinfl_decompress(
167 (
const mz_uint8*)src,
172 (mz_uint32)(TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF));
173 if (st != TINFL_STATUS_DONE) {
188 g_sh.book_count = 0U;
189 for (uint16_t i = 0U;
227 "Loading from SD card...",
247 if (
g_sh.entry[idx].from_sd) {
331 const bool header = (y < (int32_t)
k_sh_bar_h);
332 switch (
g_sh.screen) {
359 if (
g_sh.loupe_active) {
360 int32_t cx =
g_sh.loupe_cx;
361 int32_t cy =
g_sh.loupe_cy;
366 *out_lens_only =
true;
377 g_sh.loupe_active =
true;
396static bool sh_cover_gesture(
bool down, int32_t x, int32_t y,
bool was_down,
bool* out_lens_only)
398 *out_lens_only =
false;
399 if (down && !was_down) {
401 g_sh.touch_down_x = x;
402 g_sh.touch_down_y = y;
408 if (was_down &&
g_sh.loupe_active) {
409 g_sh.loupe_active =
false;
423 switch (
g_sh.screen) {
425 if (
g_sh.book_count == 0U) {
431 g_sh.selected = (uint16_t)((
g_sh.selected +
g_sh.book_count - 1U) %
g_sh.book_count);
455 switch (
g_sh.screen) {
458 if (
g_sh.loupe_active) {
509 uint32_t cpuclk0_hz = 0U;
590 bool changed =
false;
592 bool lens_only =
false;
597 const bool down = (got > 0U);
598 const bool was_down = (*prev_touch > 0U);
602 const int32_t x = down ? (int32_t)pts[0].x :
g_sh.touch_down_x;
603 const int32_t y = down ? (int32_t)pts[0].y :
g_sh.touch_down_y;
605 acted = down || was_down;
606 }
else if (down && !was_down) {
608 changed =
sh_handle_tap((int32_t)pts[0].x, (int32_t)pts[0].y);
639typedef enum : uint32_t {
658 if (
g_sh.book_count == 0U) {
711 uint8_t prev_touch = 0U;
715 uint32_t demo_ticks = 0U;
716 uint32_t demo_step = 0U;
722 const bool acted =
sh_pump_input(&prev_touch, &prev1, &prev2);
void main(void)
Secure fallback main entry point.
static const uint8_t k_msg_fail[]
static int32_t sh_center_x(const char *s)
Centre a string horizontally for the bitmap font.
static bool sh_handle_tap(int32_t x, int32_t y)
Route a touch tap to the active screen; returns whether to repaint.
static void sh_demo_step(uint32_t step)
Advance the idle self-demo one step (shelf -> cover -> TOC -> read ...).
static void sh_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
static display_handle_t * s_display
static void sh_run(void)
Run the reader superloop – input pump, opt-in self-demo, watchdog, backlight idle-dim.
static void sh_start_reading(void)
Start the reader at the book's first prose chapter (past front matter).
sh_demo_t
Idle-demo step indices (one screen transition each).
@ k_sh_demo_cover0
Open book 0 on its cover.
@ k_sh_demo_read2
Read book 2.
@ k_sh_demo_cover1
Open book 1 cover.
@ k_sh_demo_cover2
Open book 2 cover.
@ k_sh_demo_turn
Turn one page.
@ k_sh_demo_toc0
Book 0 table of contents.
@ k_sh_demo_read0
Read book 0.
@ k_sh_demo_toc1
Book 1 table of contents.
static bool sh_handle_button(bool is_sw2)
Route an SW1/SW2 edge to the active screen; returns whether to repaint.
static void sh_seed_baked(void)
Seed the shelf with the MRAM-baked library books.
static void sh_present(void)
Re-render the active screen and push it to the panel.
static bool sh_pump_input(uint8_t *prev_touch, ra8_board_sw_state_t *prev1, ra8_board_sw_state_t *prev2)
Poll touch + buttons once; re-present on any change.
static bool sh_tap_toc(int32_t x, int32_t y, bool header)
Handle a TOC-screen tap; returns whether to repaint.
static bool sh_select_book(uint16_t idx)
Open the selected book and move to the cover screen; ignore on failure.
static bool sh_tap_reader(int32_t x, int32_t y, bool header)
Handle a reader-screen tap (header back / edge page turn).
ra8_err_t sh_inflate(const void *src, size_t src_len, void *dst, size_t dst_cap, size_t *out_len)
Heap-free zlib inflater matching book_inflate_fn (miniz; main.c).
static void sh_wdt_arm_or_halt(void)
Arm WDT0 to reset a wedged reader loop; fatal on failure.
static void sh_panic_halt(void)
Print the fail banner and trap (ra8_emulator halts on the BKPT).
static bool sh_loupe_held(int32_t x, int32_t y, bool *out_lens_only)
Held-finger step of the cover loupe gesture: pan an open lens, or open one once the press has been he...
sh_main_const_t
Boot + banner formatting constants.
@ k_sh_fnv_prime
FNV-1a 32-bit prime.
@ k_sh_thirds
Reader edge-tap split.
@ k_sh_fnv_offset
FNV-1a 32-bit offset basis.
@ k_sh_hex_digits
Hex digits in the framebuffer hash.
@ k_sh_nib_bits
Bits per hex digit.
@ k_sh_nib_mask
Low-nibble mask.
@ k_sh_demo_period
Input polls between demo steps.
@ k_sh_demo_steps
Idle-demo sequence length.
@ k_sh_idle_dim_ms
No-input time before backlight off.
static int32_t sh_edge_dir(int32_t x)
Reader edge-tap to direction: -1 left third, +1 right third, else 0.
static void sh_input_init(void)
Open touch + the two user buttons (best-effort; input is optional).
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 void sh_loading_overlay(const char *name)
Paint a "Loading from SD card..." panel before a (blocking) SD open.
static void sh_print_banner(const sh_comic_probe_t *cbz, const sh_comic_probe_t *cbr, bool rtl_ok)
Emit the gate banner: book count, SD flag, framebuffer hash, comic digests.
static void sh_setup_or_halt(void)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
static const display_cfg_t k_sh_display_cfg
static void sh_panel_or_halt(void)
SDRAM + GLCDC panel bring-up; bind ra8_gfx to the live framebuffer.
uint16_t * sh_fb_pixels(void)
The live RGB565 framebuffer ra8_gfx scans (defined in main.c).
static bool sh_tap_cover(int32_t x, int32_t y, bool header)
Handle a cover-screen tap; returns whether to repaint.
static uint32_t sh_fb_hash(void)
FNV-1a hash of the whole framebuffer (deterministic render digest).
static tinfl_decompressor s_tinfl
Static DEFLATE decompressor state (~11 KiB) kept off the small stack.
static void sh_present_loupe(void)
Repaint only the fixed lens window during a loupe pan and flush just it.
static bool sh_cover_gesture(bool down, int32_t x, int32_t y, bool was_down, bool *out_lens_only)
Cover-screen press-hold loupe gesture: a hold opens the magnifier, drag pans it, release exits; a sho...
@ k_library_count
Number of entries in k_library.
static const library_book_t k_library[k_library_count]
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_backlight_set(bool on)
Turn the J1 panel backlight (BLEN, P514) on or off.
ra8_err_t ra8_board_sw_read(ra8_board_sw_id_t sw, ra8_board_sw_state_t *out_pressed)
Sample the current state of sw.
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_sw_state_t
Logical "pressed" / "released" state.
@ k_ra8_board_sw_released
RA8 board sw released.
@ k_ra8_board_sw_pressed
RA8 board sw pressed.
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.
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.
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.
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.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
char * strncpy(char *dst, const char *src, size_t n)
Copy bounded string to destination buffer.
size_t strlen(const char *s)
Calculate string length.
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.
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.
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.
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.
uint32_t ra8_time_ms(void)
Get the current 1 kHz tick count.
Multi-touch input driver – GoodIX GT911 backend.
ra8_err_t ra8_touch_read(ra8_touch_point_t *out_points, uint8_t max_count, uint8_t *got_count)
Drain the current touch frame.
@ k_ra8_touch_irq_pin_unset
Sentinel for "no IRQ pin attached".
Software Watchdog Timer (WDT) driver header.
@ k_ra8_wdt_timeout_16384
16384 cycles.
@ k_ra8_wdt_clkdiv_8192
PCLKB / 8192.
ra8_err_t ra8_wdt_refresh_for(ra8_wdt_instance_t which)
Refresh a specific WDT instance.
ra8_err_t ra8_wdt_init(const ra8_wdt_cfg_t *cfg)
Initialise the WDT in register-start mode.
@ k_ra8_wdt_window_start_100
100 % (no upper bound).
@ k_ra8_wdt_on_expiry_reset
RSTIRQS=1 – internal reset.
@ k_ra8_wdt_sleep_keep_count
SLCSTP=0 – counter runs in Sleep.
@ k_ra8_wdt_window_end_0
0 % (no lower bound).
@ k_ra8_wdt0
WDT0 – Cortex-M85 side.
Shared contract for the ereader_shelf multi-screen e-reader.
bool sh_reader_turn(int32_t dir)
Turn the reader page by dir (-1/+1) across chapters; returns changed.
bool sh_comic_tap(int32_t x, bool header)
Handle a comic-screen tap: header returns to the shelf, else page-turn.
void sh_comic_render(void)
Render the current comic page full-screen (title bar + fitted image).
uint32_t sh_reader_first_content(void)
First chapter with substantial prose (skips title/imprint front matter).
void sh_reader_load_chapter(uint32_t chapter)
Load + wrap a chapter into the reader working set.
void sh_shelf_build_thumbs(void)
Copy the baked books' pre-decoded covers into sh_state_t::thumb at boot.
void sh_toc_scroll(int32_t dir)
Scroll the TOC list by dir pages (-1 up / +1 down), clamped.
bool sh_book_open(uint16_t idx)
Open shelf entry idx by its format; sets g_sh.open_fmt + chapter count, and (for SD books on first op...
int32_t sh_shelf_hit(int32_t x, int32_t y)
Hit-test a shelf tap; returns the book index or -1.
void sh_comic_selfcheck(sh_comic_probe_t *cbz, sh_comic_probe_t *cbr, bool *rtl_ok)
Headless boot self-check: decode the baked CBZ + CBR page 0, verify RTL.
bool sh_comic_turn(int32_t dir)
Turn the comic page by dir in reading order, clamped to the ends.
@ k_sh_screen_shelf
Book grid with cover thumbnails.
@ k_sh_screen_comic
Full-page image reader (CBZ / CBR).
@ k_sh_screen_reader
Reading a book.
@ k_sh_screen_cover
One book's cover / title page.
@ k_sh_screen_toc
Chapter list.
void sh_sd_scan(void)
Append every root *.RBK file on the card as an SD shelf entry.
@ k_sh_loupe_w
Lens window width in framebuffer pixels.
@ k_sh_loupe_h
Lens window height in framebuffer pixels.
@ k_sh_loupe_hold_ms
Press-hold duration that opens the lens (ms).
@ k_sh_uart_baud
Console baud.
@ k_sh_line_h
Reader text line height.
@ k_sh_glyph_h
Bitmap font cell height.
@ k_sh_fb_h
Panel height in pixels.
@ k_sh_poll_ms
Input poll period in ms.
@ k_sh_glyph_w
Bitmap font cell width.
@ k_sh_bar_h
Header / title-bar height.
@ k_sh_linebuf
Per-line draw buffer bytes.
@ k_sh_poll_pts
Touch points polled per read.
@ k_sh_fb_w
Panel width in pixels.
@ k_sh_dec_base
Decimal formatting base.
@ k_sh_max_books
Shelf / thumbnail-cache capacity.
void sh_cover_loupe_render(void)
Draw the magnifier loupe over the cover at the current pan centre.
sh_cover_act_t
Result of a tap on the cover screen.
@ k_sh_cover_read
Open the reader at chapter 0.
@ k_sh_cover_toc
Open the table of contents.
void sh_toc_render(void)
Render the open book's chapter list (TOC).
bool sh_cover_loupe_map(int32_t px, int32_t py, int32_t *out_cx, int32_t *out_cy)
Map a cover-screen touch to full-res source coordinates for the loupe.
void sh_reader_render(void)
Render the current reader page.
void sh_comic_append_banner(char *b, size_t *pos, const sh_comic_probe_t *cbz, const sh_comic_probe_t *cbr, bool rtl_ok)
Append " cbz=P:WxH:CRC cbr=P:WxH:CRC rtl=OK" to the boot banner buffer.
void sh_reader_prefetch_adjacent(void)
Read-ahead warm the adjacent chapters into the page cache (#207).
size_t sh_fmt_uint(char *dst, size_t pos, uint32_t v)
Append unsigned v as decimal into dst at pos; returns new pos.
bool sh_sd_mount(void)
Bring up the Pmod2 microSD over ra8_sdmmc_spi and mount its FAT volume.
void sh_shelf_render(void)
Render the shelf grid (cover cards) into the framebuffer.
sh_state_t g_sh
The single whole-app state instance (defined in main.c).
sh_cover_act_t sh_cover_action(int32_t x, int32_t y)
Classify a cover-screen tap into a sh_cover_act_t.
int32_t sh_toc_hit(int32_t x, int32_t y)
Hit-test a TOC tap; returns the chapter index or -1.
@ k_sh_col_bg
App background (dark wood).
@ k_sh_col_card
Card / page fill (paper).
@ k_sh_col_sub
Secondary ink (author / hints).
void sh_cover_render(void)
Render the selected book's cover / title page.
static bool sh_fmt_is_comic(sh_book_fmt_t fmt)
True if fmt is a comic-archive container (CBZ, CBR, or CBT).
Configuration descriptor passed into display_init.
Framebuffer descriptor returned by display_get_framebuffer.
void * pixels
Base of pixel data (RGB565 unless noted).
Rectangle in framebuffer coordinates passed into display_flush.
The two touch settings that are an APPLICATION choice, not a board fact.
One decoded touch contact.
Register-start-mode configuration block.
One container's headless self-check result (page 0 decode digest).
One shelf book, sourced from MRAM (baked) or the SD card, in either the .rabook or ....
bool from_sd
true: read sd_name from SD; false: use blob.
const uint8_t * blob
Baked RBKC bytes (MRAM), or NULL when SD.
uint16_t thumb_w
Pre-baked thumbnail width.
uint16_t thumb_h
Pre-baked thumbnail height.
const uint8_t * thumb
Pre-baked gray8 cover thumbnail, or NULL.
uint32_t blob_len
Baked length, or SD file size in bytes.
char title[k_sh_title_cap]
Display title.
char author[k_sh_author_cap]
Display author.
Whole-app UI + reader state (single instance g_sh).