ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1
53
54#include <stddef.h>
55#include <stdint.h>
56
57#include "ra8_board_ek_ra8d2.h"
58#include "ra8_boot_entry.h"
59#include "ra8_box.h"
60#include "ra8_cgc.h"
61#include "ra8_display_pal.h"
62#include "ra8_display_pal_lcd.h"
63#include "ra8_err.h"
64#include "ra8_gfx.h"
65#include "ra8_gfx_font.h"
66#include "ra8_glcdc.h"
67#include "ra8_isr.h"
68#include "ra8_mstp.h"
69#include "ra8_panel.h"
70#include "ra8_panel_timing.h"
71#include "ra8_time.h"
72#include "ra8_ui.h"
73#include "ra8_widget.h"
74
80typedef enum : uint16_t {
81 k_wc_fb_w = 512U,
82 k_wc_fb_h = 512U,
85 k_wc_pad = 8U,
88} wc_geom_t;
89
95typedef enum : uint32_t {
96 k_wc_col_clear = 0x000008U,
97 k_wc_col_status_bg = 0x1E2A40U,
98 k_wc_col_footer_bg = 0x14141AU,
99 k_wc_col_left_bg = 0x102038U,
100 k_wc_col_right_bg = 0x382414U,
101 k_wc_col_text = 0xFFFFFFU,
102 k_wc_col_dim = 0xA0A0B0U,
103} wc_color_t;
104
121
127typedef enum : uint32_t {
128 k_wc_uart_baud = 115200U,
130 k_wc_fnv_offset = 2166136261U,
131 k_wc_fnv_prime = 16777619U,
138
143[[gnu::aligned(k_ra8_board_fb_align_bytes)]] static uint16_t
144 s_framebuffer[(uint32_t)k_wc_fb_w * (uint32_t)k_wc_fb_h];
145
151typedef struct {
152 uint32_t frame;
153 uint32_t renders;
155
161typedef struct {
162 const char* label;
163 uint32_t bg;
164 uint32_t renders;
166
167static wc_status_ctx_t s_status = {.frame = 0U, .renders = 0U};
168static wc_tile_ctx_t s_left = {.label = "Left widget", .bg = (uint32_t)k_wc_col_left_bg};
169static wc_tile_ctx_t s_right = {.label = "Right widget", .bg = (uint32_t)k_wc_col_right_bg};
170
175
178 .box_scratch = s_body_scratch,
179 .count = (uint16_t)k_wc_body_n,
180 .box_cap = (uint16_t)k_wc_body_cap,
181 .gap = (int16_t)k_wc_tile_gap,
182 .pad = 0,
183 .axis = k_ra8_widget_axis_row,
184 .reserved = 0U};
185
188 .box_scratch = s_root_scratch,
189 .count = (uint16_t)k_wc_root_n,
190 .box_cap = (uint16_t)k_wc_root_cap,
191 .gap = 0,
192 .pad = 0,
193 .axis = k_ra8_widget_axis_col,
194 .reserved = 0U};
195
199static display_handle_t* s_display = nullptr;
200
201static const uint8_t k_wc_msg_boot[] = "widget-compose-demo: boot\r\n";
202static const uint8_t k_wc_msg_finit[] = "widget-compose-demo: FAIL init\r\n";
203static const uint8_t k_wc_msg_fpanl[] = "widget-compose-demo: FAIL panel\r\n";
204static const uint8_t k_wc_msg_ftree[] = "widget-compose-demo: FAIL tree\r\n";
205static const uint8_t k_wc_msg_fchk[] = "widget-compose-demo: FAIL selfcheck\r\n";
206static const uint8_t k_wc_msg_pre[] = "widget-compose-demo: dirty0=";
207static const uint8_t k_wc_msg_crc0[] = " crc0=";
208static const uint8_t k_wc_msg_d1[] = " dirty1=";
209static const uint8_t k_wc_msg_crc1[] = " crc1=";
210static const uint8_t k_wc_msg_tail[] = " flush=512x44 hint=fast";
211static const uint8_t k_wc_msg_pass[] = " PASS\r\n";
212
213/* ===========================================================================
214 * Console
215 * ===========================================================================
216 */
217
219static void wc_print(const uint8_t* msg, uint32_t len)
220{
221 (void)ra8_board_uart_console_write(msg, (size_t)len);
222}
223
225static void wc_fail_halt(const uint8_t* msg, uint32_t len)
226{
227 wc_print(msg, len);
228 while (1) {
229 __asm__ volatile("wfi");
230 }
231}
232
234static void wc_print_hex(uint32_t value)
235{
236 uint8_t buf[k_wc_hex_nibbles];
237 for (uint32_t i = 0U; i < (uint32_t)k_wc_hex_nibbles; i++) {
238 const uint32_t shift = ((uint32_t)k_wc_hex_nibbles - 1U - i) * (uint32_t)k_wc_nibble_bits;
239 const uint32_t nib = (value >> shift) & (uint32_t)k_wc_nibble_mask;
240 buf[i] = (uint8_t)((nib < (uint32_t)k_wc_dec_ten) ? ('0' + nib) : ('A' + (nib - k_wc_dec_ten)));
241 }
242 wc_print(buf, (uint32_t)k_wc_hex_nibbles);
243}
244
246static void wc_print_uint(uint32_t value)
247{
248 uint8_t buf[k_wc_dec_ten];
249 uint32_t n = 0U;
250 if (value == 0U) {
251 buf[n] = '0';
252 n++;
253 }
254 while ((value > 0U) && (n < (uint32_t)k_wc_dec_ten)) {
255 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_wc_dec_ten));
256 n++;
257 value /= (uint32_t)k_wc_dec_ten;
258 }
259 for (uint32_t i = 0U; i < n; i++) {
260 wc_print(&buf[n - 1U - i], 1U);
261 }
262}
263
265static uint32_t wc_framebuffer_hash(void)
266{
267 const uint8_t* p = (const uint8_t*)s_framebuffer;
268 const size_t n = sizeof(s_framebuffer);
269 uint32_t hsh = (uint32_t)k_wc_fnv_offset;
270 for (size_t i = 0U; i < n; i++) {
271 hsh = (hsh ^ (uint32_t)p[i]) * (uint32_t)k_wc_fnv_prime;
272 }
273 return hsh;
274}
275
276/* ===========================================================================
277 * Widget renderers
278 * ===========================================================================
279 */
280
282static void wc_fmt_frame(char* buf, uint32_t frame)
283{
284 static const char prefix[] = "frame=";
285 uint32_t pos = 0U;
286 for (uint32_t i = 0U; i < (uint32_t)(sizeof(prefix) - 1U); i++) {
287 buf[pos] = prefix[i];
288 pos++;
289 }
290 char digits[k_wc_dec_ten];
291 uint32_t n = 0U;
292 if (frame == 0U) {
293 digits[n] = '0';
294 n++;
295 }
296 while ((frame > 0U) && (n < (uint32_t)k_wc_dec_ten)) {
297 digits[n] = (char)('0' + (frame % (uint32_t)k_wc_dec_ten));
298 n++;
299 frame /= (uint32_t)k_wc_dec_ten;
300 }
301 for (uint32_t i = 0U; i < n; i++) {
302 buf[pos] = digits[n - 1U - i];
303 pos++;
304 }
305 buf[pos] = '\0';
306}
307
310{
311 wc_status_ctx_t* st = (wc_status_ctx_t*)w->ctx;
312 st->renders++;
313 char frame_str[k_wc_frame_buf];
314 wc_fmt_frame(frame_str, st->frame);
315 (void)
316 ra8_gfx_rect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, (uint32_t)k_wc_col_status_bg, true);
317 const int32_t tx = w->rect.x + (int32_t)k_wc_pad;
318 (void)ra8_gfx_text_out(tx,
319 w->rect.y + (int32_t)k_wc_pad,
320 "widget-compose-demo status bar",
322 (uint32_t)k_wc_col_text,
323 (uint32_t)k_wc_col_status_bg);
324 (void)ra8_gfx_text_out(tx,
325 w->rect.y + (int32_t)k_wc_pad + (int32_t)k_wc_line_h,
326 frame_str,
328 (uint32_t)k_wc_col_dim,
329 (uint32_t)k_wc_col_status_bg);
330}
331
334{
335 wc_tile_ctx_t* t = (wc_tile_ctx_t*)w->ctx;
336 t->renders++;
337 (void)ra8_gfx_rect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, t->bg, true);
338 const int32_t tx = w->rect.x + (int32_t)k_wc_pad;
339 (void)ra8_gfx_text_out(tx,
340 w->rect.y + (int32_t)k_wc_pad,
341 t->label,
343 (uint32_t)k_wc_col_text,
344 t->bg);
345 (void)ra8_gfx_text_out(tx,
346 w->rect.y + (int32_t)k_wc_pad + (int32_t)k_wc_line_h +
347 (int32_t)k_wc_line_h,
348 "nested in the body panel",
350 (uint32_t)k_wc_col_dim,
351 t->bg);
352}
353
356{
357 (void)w->ctx;
358 (void)
359 ra8_gfx_rect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, (uint32_t)k_wc_col_footer_bg, true);
360 (void)ra8_gfx_text_out(w->rect.x + (int32_t)k_wc_pad,
361 w->rect.y + ((int32_t)k_wc_footer_h / 4),
362 "ra8_widget_panel: nested tree, damage-tracked flush",
364 (uint32_t)k_wc_col_dim,
365 (uint32_t)k_wc_col_footer_bg);
366}
367
369static const ra8_widget_vtable_t k_wc_status_vt = {.measure = nullptr,
370 .render = wc_status_render,
371 .on_input = nullptr};
372static const ra8_widget_vtable_t k_wc_tile_vt = {.measure = nullptr,
373 .render = wc_tile_render,
374 .on_input = nullptr};
375static const ra8_widget_vtable_t k_wc_footer_vt = {.measure = nullptr,
376 .render = wc_footer_render,
377 .on_input = nullptr};
378
379/* ===========================================================================
380 * Tree assembly + compose
381 * ===========================================================================
382 */
383
386 const ra8_widget_vtable_t* vt,
387 void* ctx,
388 int16_t fixed,
389 uint16_t flex)
390{
391 *w = (ra8_widget_t){};
392 w->vt = vt;
393 w->ctx = ctx;
394 w->fixed = fixed;
395 w->flex = flex;
396 w->visible = true;
397}
398
400static bool wc_build_tree(void)
401{
406
407 /* The body child is itself a panel -- the nesting the new primitive adds. */
409 return false;
410 }
411 s_root_kids[k_wc_w_body].flex = 1U;
413}
414
417{
418 for (uint16_t i = 0U; i < (uint16_t)k_wc_root_n; i++) {
419 (void)ra8_widget_invalidate(&s_root_kids[i], refresh);
420 }
421}
422
424static ra8_err_t wc_compose(ra8_ui_rect_t* dmg, ra8_widget_refresh_t* hint, uint16_t* dirty)
425{
426 const ra8_ui_rect_t frame = {.x = 0, .y = 0, .w = (int32_t)k_wc_fb_w, .h = (int32_t)k_wc_fb_h};
427 return ra8_widget_panel_compose(&s_root, &frame, dmg, hint, dirty);
428}
429
430/* ===========================================================================
431 * GLCDC panel bring-up + flush
432 * ===========================================================================
433 */
434
438 .framebuffer = s_framebuffer,
439 .framebuffer_bytes = sizeof(s_framebuffer),
440 .width_px = (uint16_t)k_wc_fb_w,
441 .height_px = (uint16_t)k_wc_fb_h,
442 .pixfmt = k_display_pixfmt_rgb565,
443 .panel_timing = &s_ra8_panel_ek_ra8d2_timing,
444};
445
447static bool wc_panel_up(void)
448{
450 return false;
451 }
452 if (s_display == nullptr) {
453 return false;
454 }
455 display_fb_t fb = {};
457 return false;
458 }
459 if (fb.pixels != (void*)s_framebuffer) {
460 return false;
461 }
463 (uint16_t)k_wc_fb_w,
464 (uint16_t)k_wc_fb_h,
466}
467
476
479{
480 if (s_display == nullptr) {
481 return;
482 }
483 if ((dmg->w <= 0) || (dmg->h <= 0)) {
484 return;
485 }
486 const display_rect_t r = {.x = (uint16_t)dmg->x,
487 .y = (uint16_t)dmg->y,
488 .w = (uint16_t)dmg->w,
489 .h = (uint16_t)dmg->h};
490 (void)display_flush(s_display, r, wc_map_hint(hint));
491}
492
493/* ===========================================================================
494 * Deterministic self-check
495 * ===========================================================================
496 */
497
499static bool wc_check_full(uint32_t* out_crc, uint16_t* out_dirty)
500{
501 s_left.renders = 0U;
502 s_right.renders = 0U;
504 ra8_ui_rect_t dmg = {};
506 uint16_t nd = 0U;
507 if (wc_compose(&dmg, &hint, &nd) != k_ra8_ok) {
508 return false;
509 }
510 if (nd != (uint16_t)k_wc_root_n) {
511 return false;
512 }
513 if ((dmg.w != (int32_t)k_wc_fb_w) || (dmg.h != (int32_t)k_wc_fb_h)) {
514 return false;
515 }
516 if (hint != k_ra8_widget_refresh_quality) {
517 return false;
518 }
519 if ((s_left.renders != 1U) || (s_right.renders != 1U)) {
520 return false; /* nested body panel must have composited both tiles */
521 }
522 *out_crc = wc_framebuffer_hash();
523 *out_dirty = nd;
524 return true;
525}
526
528static bool wc_check_partial(uint32_t* out_crc, uint16_t* out_dirty)
529{
530 s_left.renders = 0U;
531 s_right.renders = 0U;
532 s_status.frame++;
534 ra8_ui_rect_t dmg = {};
536 uint16_t nd = 0U;
537 if (wc_compose(&dmg, &hint, &nd) != k_ra8_ok) {
538 return false;
539 }
540 if (nd != 1U) {
541 return false;
542 }
543 if ((dmg.x != 0) || (dmg.y != 0) || (dmg.w != (int32_t)k_wc_fb_w)) {
544 return false;
545 }
546 if (dmg.h != (int32_t)k_wc_status_h) {
547 return false;
548 }
549 if (hint != k_ra8_widget_refresh_fast) {
550 return false;
551 }
552 if ((s_left.renders != 0U) || (s_right.renders != 0U)) {
553 return false; /* partial flush must NOT re-render the body */
554 }
555 *out_crc = wc_framebuffer_hash();
556 *out_dirty = nd;
557 return true;
558}
559
561static bool wc_selfcheck(uint32_t* crc0, uint16_t* d0, uint32_t* crc1, uint16_t* d1)
562{
563 if (!wc_check_full(crc0, d0)) {
564 return false;
565 }
566 if (!wc_check_partial(crc1, d1)) {
567 return false;
568 }
569 return (*crc0 != *crc1); /* the advanced frame counter changes the composite */
570}
571
572/* ===========================================================================
573 * Boot
574 * ===========================================================================
575 */
576
578static void wc_setup_or_halt(void)
579{
580 uint32_t cpuclk0_hz = 0U;
581 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
582 wc_fail_halt(k_wc_msg_finit, (uint32_t)sizeof(k_wc_msg_finit) - 1U);
583 }
585 wc_fail_halt(k_wc_msg_finit, (uint32_t)sizeof(k_wc_msg_finit) - 1U);
586 }
587 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
588 wc_fail_halt(k_wc_msg_finit, (uint32_t)sizeof(k_wc_msg_finit) - 1U);
589 }
591 wc_fail_halt(k_wc_msg_finit, (uint32_t)sizeof(k_wc_msg_finit) - 1U);
592 }
593}
594
596static void wc_print_banner(uint16_t d0, uint32_t crc0, uint16_t d1, uint32_t crc1)
597{
598 wc_print(k_wc_msg_pre, (uint32_t)sizeof(k_wc_msg_pre) - 1U);
599 wc_print_uint((uint32_t)d0);
600 wc_print(k_wc_msg_crc0, (uint32_t)sizeof(k_wc_msg_crc0) - 1U);
601 wc_print_hex(crc0);
602 wc_print(k_wc_msg_d1, (uint32_t)sizeof(k_wc_msg_d1) - 1U);
603 wc_print_uint((uint32_t)d1);
604 wc_print(k_wc_msg_crc1, (uint32_t)sizeof(k_wc_msg_crc1) - 1U);
605 wc_print_hex(crc1);
606 wc_print(k_wc_msg_tail, (uint32_t)sizeof(k_wc_msg_tail) - 1U);
607 wc_print(k_wc_msg_pass, (uint32_t)sizeof(k_wc_msg_pass) - 1U);
608}
609
611static void wc_tick_live(void)
612{
613 s_status.frame++;
615 ra8_ui_rect_t dmg = {};
617 uint16_t nd = 0U;
618 if (wc_compose(&dmg, &hint, &nd) == k_ra8_ok) {
619 wc_flush_rect(&dmg, hint);
620 }
621}
622
633void main(void)
634{
637 wc_print(k_wc_msg_boot, (uint32_t)sizeof(k_wc_msg_boot) - 1U);
638
639 if (!wc_panel_up()) {
640 wc_fail_halt(k_wc_msg_fpanl, (uint32_t)sizeof(k_wc_msg_fpanl) - 1U);
641 }
642 if (!wc_build_tree()) {
643 wc_fail_halt(k_wc_msg_ftree, (uint32_t)sizeof(k_wc_msg_ftree) - 1U);
644 }
645
646 uint32_t crc0 = 0U;
647 uint32_t crc1 = 0U;
648 uint16_t d0 = 0U;
649 uint16_t d1 = 0U;
650 if (!wc_selfcheck(&crc0, &d0, &crc1, &d1)) {
651 wc_fail_halt(k_wc_msg_fchk, (uint32_t)sizeof(k_wc_msg_fchk) - 1U);
652 }
653 wc_print_banner(d0, crc0, d1, crc1);
654
655 /* Land on a full composite and show it live on the panel. */
656 (void)ra8_gfx_clear((uint32_t)k_wc_col_clear);
658 ra8_ui_rect_t dmg = {};
660 uint16_t nd = 0U;
661 if (wc_compose(&dmg, &hint, &nd) == k_ra8_ok) {
662 wc_flush_rect(&dmg, hint);
663 }
664
665 while (1) {
666 wc_tick_live();
667 ra8_delay_ms((uint32_t)k_wc_frame_ms);
668 }
669}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static display_handle_t * s_display
Definition main.c:78
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).
Definition main.c:67
static ra8_widget_status_bar_t s_status
Definition main.c:292
static ra8_widget_panel_t s_root_panel
Root column-panel descriptor tiling the five chrome bands.
Definition main.c:349
static ra8_widget_t s_root_kids[k_wd_root_n]
The five chrome bands.
Definition main.c:345
static ra8_box_t s_root_scratch[k_wd_root_cap]
Root layout scratch.
Definition main.c:346
static ra8_widget_t s_root
The root panel widget (composed each frame).
Definition main.c:359
static bool wc_build_tree(void)
Assemble the nested widget tree; return false on a bind error.
Definition main.c:400
static void wc_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the board console.
Definition main.c:219
wc_color_t
0xRRGGBB palette (ra8_gfx packs to RGB565).
Definition main.c:95
@ k_wc_col_clear
Whole-frame clear (near black).
Definition main.c:96
@ k_wc_col_footer_bg
Footer fill (dark).
Definition main.c:98
@ k_wc_col_right_bg
Right tile (warm brown).
Definition main.c:100
@ k_wc_col_dim
Secondary text (gray).
Definition main.c:102
@ k_wc_col_left_bg
Left tile (deep blue).
Definition main.c:99
@ k_wc_col_text
Primary text (white).
Definition main.c:101
@ k_wc_col_status_bg
Status-bar fill (slate).
Definition main.c:97
static const uint8_t k_wc_msg_pre[]
Definition main.c:206
static ra8_box_t s_body_scratch[k_wc_body_cap]
Body layout scratch.
Definition main.c:173
static const uint8_t k_wc_msg_fpanl[]
Definition main.c:203
wc_widget_idx_t
Index of each widget within its parent array.
Definition main.c:110
@ k_wc_w_body
Root child 1: nested body panel.
Definition main.c:112
@ k_wc_w_right
Body child 1: right tile (flex).
Definition main.c:117
@ k_wc_w_left
Body child 0: left tile (flex).
Definition main.c:116
@ k_wc_w_footer
Root child 2: footer (fixed).
Definition main.c:113
@ k_wc_body_n
Body child count.
Definition main.c:118
@ k_wc_root_cap
Root ra8_box scratch (count + 1).
Definition main.c:115
@ k_wc_body_cap
Body ra8_box scratch (count + 1).
Definition main.c:119
@ k_wc_w_status
Root child 0: status bar (fixed).
Definition main.c:111
@ k_wc_root_n
Root child count.
Definition main.c:114
static bool wc_check_partial(uint32_t *out_crc, uint16_t *out_dirty)
Assert the partial compose: status-only damage, tiles untouched.
Definition main.c:528
static void wc_footer_render(ra8_widget_t *w)
Footer render: fill + a one-line hint.
Definition main.c:355
static const uint8_t k_wc_msg_finit[]
Definition main.c:202
static void wc_invalidate_all(ra8_widget_refresh_t refresh)
Mark every root child dirty so the next compose repaints the tree.
Definition main.c:416
static void wc_tile_render(ra8_widget_t *w)
Body-tile render: fill + label + a per-tile render counter.
Definition main.c:333
static const uint8_t k_wc_msg_d1[]
Definition main.c:208
static const uint8_t k_wc_msg_ftree[]
Definition main.c:204
static const uint8_t k_wc_msg_crc1[]
Definition main.c:209
static const ra8_widget_vtable_t k_wc_tile_vt
Definition main.c:372
wc_console_t
Console baud + text-format constants.
Definition main.c:127
@ k_wc_nibble_mask
Low-nibble mask.
Definition main.c:134
@ k_wc_frame_buf
"frame=N" string buffer.
Definition main.c:136
@ k_wc_uart_baud
Console baud.
Definition main.c:128
@ k_wc_fnv_offset
FNV-1a-32 offset basis.
Definition main.c:130
@ k_wc_dec_ten
Hex/decimal split + buf.
Definition main.c:135
@ k_wc_frame_ms
Live status repaint (ms).
Definition main.c:129
@ k_wc_nibble_bits
Bits per hex nibble.
Definition main.c:133
@ k_wc_fnv_prime
FNV-1a-32 prime.
Definition main.c:131
@ k_wc_hex_nibbles
Hex digits per 32-bit.
Definition main.c:132
static const uint8_t k_wc_msg_fchk[]
Definition main.c:205
static void wc_flush_rect(const ra8_ui_rect_t *dmg, ra8_widget_refresh_t hint)
Flush only dmg to the panel with the mapped refresh hint.
Definition main.c:478
static const uint8_t k_wc_msg_tail[]
Definition main.c:210
static ra8_widget_panel_t s_body_panel
Body row-panel descriptor (the nested panel).
Definition main.c:177
static bool wc_check_full(uint32_t *out_crc, uint16_t *out_dirty)
Assert the full compose: 3 dirty, full-frame quality, tiles drawn.
Definition main.c:499
static void wc_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
Definition main.c:246
static const ra8_widget_vtable_t k_wc_status_vt
Status / footer / tiles are display-only (NULL on_input).
Definition main.c:369
static void wc_tick_live(void)
Advance the frame counter and partial-flush only the status band.
Definition main.c:611
static void wc_print_banner(uint16_t d0, uint32_t crc0, uint16_t d1, uint32_t crc1)
Emit the PASS banner once every self-check assertion holds.
Definition main.c:596
static const uint8_t k_wc_msg_pass[]
Definition main.c:211
static ra8_err_t wc_compose(ra8_ui_rect_t *dmg, ra8_widget_refresh_t *hint, uint16_t *dirty)
Compose the tree into the framebuffer; report the flush rect.
Definition main.c:424
static wc_tile_ctx_t s_left
Definition main.c:168
static const display_cfg_t k_wc_display_cfg
Display PAL config: GLCDC LCD backend bound to the SRAM framebuffer.
Definition main.c:436
static const uint8_t k_wc_msg_boot[]
Definition main.c:201
static void wc_leaf_init(ra8_widget_t *w, const ra8_widget_vtable_t *vt, void *ctx, int16_t fixed, uint16_t flex)
Build a leaf widget bound to a vtable + context.
Definition main.c:385
static const uint8_t k_wc_msg_crc0[]
Definition main.c:207
static void wc_setup_or_halt(void)
Bring up clocks/MSTP/time and the console.
Definition main.c:578
static bool wc_panel_up(void)
Bring up the GLCDC panel and bind ra8_gfx to its framebuffer.
Definition main.c:447
static void wc_fmt_frame(char *buf, uint32_t frame)
Format "frame=<n>" into buf (>= k_wc_frame_buf bytes, NUL-term).
Definition main.c:282
static void wc_print_hex(uint32_t value)
Print value as 8 uppercase hex digits.
Definition main.c:234
static wc_tile_ctx_t s_right
Definition main.c:169
static void wc_status_render(ra8_widget_t *w)
Status-bar render: fill + title over the live frame counter.
Definition main.c:309
static const ra8_widget_vtable_t k_wc_footer_vt
Definition main.c:375
static uint32_t wc_framebuffer_hash(void)
FNV-1a-32 over the composited framebuffer bytes.
Definition main.c:265
static ra8_widget_t s_body_kids[k_wc_body_n]
[left tile, right tile].
Definition main.c:172
wc_geom_t
Framebuffer + band geometry (no magic numbers).
Definition main.c:80
@ k_wc_line_h
Text line pitch (16px glyph + 2).
Definition main.c:86
@ k_wc_footer_h
Footer band height, pixels.
Definition main.c:84
@ k_wc_fb_h
Framebuffer height, pixels.
Definition main.c:82
@ k_wc_tile_gap
Gap between the two body tiles.
Definition main.c:87
@ k_wc_pad
Inner text padding, pixels.
Definition main.c:85
@ k_wc_fb_w
Framebuffer width, pixels.
Definition main.c:81
@ k_wc_status_h
Status-bar band height, pixels.
Definition main.c:83
static bool wc_selfcheck(uint32_t *crc0, uint16_t *d0, uint32_t *crc1, uint16_t *d1)
Run the whole deterministic surface; return both composites' CRCs.
Definition main.c:561
static display_refresh_hint_t wc_map_hint(ra8_widget_refresh_t hint)
Map a widget refresh hint to the display PAL refresh hint.
Definition main.c:469
static void wc_fail_halt(const uint8_t *msg, uint32_t len)
Print a fail banner and park forever in WFI.
Definition main.c:225
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
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.
Definition ra8_cgc.c:132
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
Definition ra8_cgc.h:70
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
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.
display_refresh_hint_t
Intent passed into display_flush; backends map this onto whatever waveform/mode their controller offe...
@ k_display_refresh_fast
Prioritise latency.
@ 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.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
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.
Definition ra8_gfx.h:40
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).
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
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.
Definition ra8_mstp.c:291
Active display-panel descriptor for the EK-RA8D2 (ER-TFT070-6).
@ k_ra8_board_fb_align_bytes
GLCDC AXI burst alignment, in bytes.
Definition ra8_panel.h:108
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.
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.
Definition ra8_time.c:59
void ra8_delay_ms(uint32_t ms)
Busy-wait for at least ms milliseconds.
Definition ra8_time.c:129
Bounded UI interaction core: hit-testing, screen stack, paging.
Zero-heap composable widget layer (dwm-style) over ra8_box + ra8_ui.
@ k_ra8_widget_axis_row
Horizontal stack (left -> right).
Definition ra8_widget.h:177
@ k_ra8_widget_axis_col
Vertical stack (top -> bottom).
Definition ra8_widget.h:176
ra8_err_t ra8_widget_panel_init(ra8_widget_t *w, ra8_widget_panel_t *panel)
Bind a widget instance to a container panel.
ra8_err_t ra8_widget_panel_compose(ra8_widget_t *panel_w, const ra8_ui_rect_t *frame, ra8_ui_rect_t *out_damage, ra8_widget_refresh_t *out_hint, uint16_t *out_dirty)
Run one top-level compose cycle over a panel and report the flush.
ra8_err_t ra8_widget_invalidate(ra8_widget_t *w, ra8_widget_refresh_t refresh)
Mark a widget dirty with a refresh hint (folds upward in strength).
Definition ra8_widget.c:286
ra8_widget_refresh_t
E-ink-style refresh hint carried by a dirty widget.
Definition ra8_widget.h:98
@ k_ra8_widget_refresh_fast
Partial / A2 (text-only change).
Definition ra8_widget.h:100
@ k_ra8_widget_refresh_none
Clean – not dirty.
Definition ra8_widget.h:99
@ k_ra8_widget_refresh_quality
Full / GC16 (whole-area redraw).
Definition ra8_widget.h:101
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.
One node in a box tree (caller-owned).
Definition ra8_box.h:90
Axis-aligned rectangle in framebuffer pixel coordinates.
Definition ra8_ui.h:72
int32_t w
Width (pixels, >= 0).
Definition ra8_ui.h:75
int32_t h
Height (pixels, >= 0).
Definition ra8_ui.h:76
int32_t x
Left edge (pixels).
Definition ra8_ui.h:73
int32_t y
Top edge (pixels).
Definition ra8_ui.h:74
A container widget's child array + stack-layout parameters (#145).
One widget instance (caller-owned, no allocation).
Behaviour table shared by all widgets of one kind.
Definition ra8_widget.h:121
Status-bar state: the live frame counter it renders.
Definition main.c:151
uint32_t renders
Times the status render ran.
Definition main.c:153
uint32_t frame
Frame counter shown in the status bar.
Definition main.c:152
One body tile: a label over a coloured fill + a render counter.
Definition main.c:161
uint32_t bg
Tile background colour.
Definition main.c:163
uint32_t renders
Times this tile rendered.
Definition main.c:164
const char * label
Tile heading.
Definition main.c:162