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
27
28#include <stddef.h>
29#include <stdint.h>
30
31#include "font_fixture.h"
32#include "ra8_attributes.h"
33#include "ra8_board_ek_ra8d2.h"
34#include "ra8_boot_entry.h"
35#include "ra8_cgc.h"
36#include "ra8_err.h"
37#include "ra8_gfx.h"
38#include "ra8_isr.h"
39#include "ra8_mstp.h"
40#include "ra8_time.h"
41#include "reflow.h"
42
44typedef enum : uint32_t {
45 k_rc_fb_w = 160U,
46 k_rc_fb_h = 192U,
49 k_rc_ink = 0xFF101010U,
50 k_rc_link_col = 0xFF2A52BEU,
51 k_rc_bg = 0xF4F0E8U,
52 k_rc_uart_baud = 115200U,
53 k_rc_fnv_offset = 2166136261U,
54 k_rc_fnv_prime = 16777619U,
60
62static uint16_t s_framebuffer[(size_t)k_rc_fb_h * (size_t)k_rc_fb_w];
63
66
75static const char s_rc_chapter[] =
76 "<html><body><h1>The Machine</h1>"
77 "<p>The Time Traveller was expounding a recondite matter to us. His pale grey "
78 "eyes shone and twinkled, and his usually pale face was flushed and animated.</p>"
79 "<p>The fire burnt brightly, and the soft radiance of the incandescent lights "
80 "caught the bubbles that flashed and passed in our glasses.</p>"
81 "<p>Our chairs, being his patents, embraced and caressed us rather than "
82 "submitted to be sat upon, and there was that luxurious after-dinner "
83 "atmosphere when thought runs gracefully free of the trammels of precision.</p>"
84 "<p>And he put it to us in this way, marking the points with a lean forefinger, "
85 "as we sat and lazily admired his earnestness over this new paradox.</p>"
86 "</body></html>";
87
95static const uint8_t s_msg_boot[] = "reflow-content-hil: boot\r\n";
103static const uint8_t s_msg_fail[] = "reflow-content-hil: FAIL init\r\n";
111static const uint8_t s_msg_lerr[] = "reflow-content-hil: FAIL layout\r\n";
119static const uint8_t s_msg_pre[] = "reflow-content-hil: pages=";
127static const uint8_t s_msg_crc[] = " crc=";
135static const uint8_t s_msg_rpages[] = " rpages=";
143static const uint8_t s_msg_eol[] = "\r\n";
144
158RA8_INTERNAL static void internal_rc_print(const uint8_t* msg, uint32_t len)
159{
160 (void)ra8_board_uart_console_write(msg, (size_t)len);
161}
162
176[[noreturn]] RA8_INTERNAL static void internal_rc_panic_halt(const uint8_t* msg, uint32_t len)
177{
178 internal_rc_print(msg, len);
179 __asm__ volatile("bkpt #0");
180 while (1) {
181 __asm__ volatile("wfi");
182 }
183}
184
197RA8_INTERNAL static void internal_rc_print_hex(uint32_t value)
198{
199 uint8_t buf[k_rc_hex_nibbles];
200 for (uint32_t i = 0U; i < (uint32_t)k_rc_hex_nibbles; i++) {
201 const uint32_t shift = ((uint32_t)k_rc_hex_nibbles - 1U - i) * (uint32_t)k_rc_nibble_bits;
202 const uint32_t nib = (value >> shift) & (uint32_t)k_rc_nibble_mask;
203 buf[i] = (uint8_t)((nib < (uint32_t)k_rc_dec_ten) ? ('0' + nib) : ('A' + (nib - k_rc_dec_ten)));
204 }
205 internal_rc_print(buf, (uint32_t)k_rc_hex_nibbles);
206}
207
220RA8_INTERNAL static void internal_rc_print_uint(uint32_t value)
221{
222 uint8_t buf[k_rc_dec_ten];
223 uint32_t n = 0U;
224 if (value == 0U) {
225 buf[n] = '0';
226 n++;
227 }
228 while ((value > 0U) && (n < (uint32_t)k_rc_dec_ten)) {
229 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_rc_dec_ten));
230 n++;
231 value /= (uint32_t)k_rc_dec_ten;
232 }
233 for (uint32_t i = 0U; i < n; i++) {
234 internal_rc_print(&buf[n - 1U - i], 1U);
235 }
236}
237
253RA8_INTERNAL static uint32_t internal_rc_render_all(uint32_t* out_hash)
254{
255 uint32_t pages = 0U;
256 (void)reflow_get_page_count(&s_engine, &pages);
257 uint32_t hsh = (uint32_t)k_rc_fnv_offset;
258 const size_t nbytes = (size_t)k_rc_fb_w * (size_t)k_rc_fb_h * sizeof(uint16_t);
259 for (uint32_t p = 0U; p < pages; p++) {
260 (void)ra8_gfx_clear((uint32_t)k_rc_bg);
262 const uint8_t* fb = (const uint8_t*)s_framebuffer;
263 for (size_t i = 0U; i < nbytes; i++) {
264 hsh = (hsh ^ (uint32_t)fb[i]) * (uint32_t)k_rc_fnv_prime;
265 }
266 }
267 *out_hash = hsh;
268 return pages;
269}
270
283{
284 uint32_t cpuclk0_hz = 0U;
285 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
286 internal_rc_panic_halt(s_msg_fail, (uint32_t)sizeof(s_msg_fail) - 1U);
287 }
289 internal_rc_panic_halt(s_msg_fail, (uint32_t)sizeof(s_msg_fail) - 1U);
290 }
291 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
292 internal_rc_panic_halt(s_msg_fail, (uint32_t)sizeof(s_msg_fail) - 1U);
293 }
295 internal_rc_panic_halt(s_msg_fail, (uint32_t)sizeof(s_msg_fail) - 1U);
296 }
297}
298
307void main(void)
308{
311 internal_rc_print(s_msg_boot, (uint32_t)sizeof(s_msg_boot) - 1U);
312
314 (uint16_t)k_rc_fb_w,
315 (uint16_t)k_rc_fb_h,
317 internal_rc_panic_halt(s_msg_fail, (uint32_t)sizeof(s_msg_fail) - 1U);
318 }
319 if (reflow_init((uint16_t)k_rc_fb_w,
320 (uint16_t)k_rc_fb_h,
322 (size_t)s_ahem_ttf_len,
323 (uint16_t)k_rc_font_px,
324 (uint32_t)k_rc_ink,
325 (uint32_t)k_rc_link_col,
326 &s_engine) != k_ra8_ok) {
327 internal_rc_panic_halt(s_msg_fail, (uint32_t)sizeof(s_msg_fail) - 1U);
328 }
329 uint32_t pages = 0U;
331 (const uint8_t*)s_rc_chapter,
332 (uint32_t)(sizeof(s_rc_chapter) - 1U),
333 &pages) != k_ra8_ok) {
334 internal_rc_panic_halt(s_msg_lerr, (uint32_t)sizeof(s_msg_lerr) - 1U);
335 }
336
337 uint32_t crc1 = 0U;
338 const uint32_t pages1 = internal_rc_render_all(&crc1);
339
340 /* Re-flow at a larger size on the cached chapter; render again. */
342 internal_rc_panic_halt(s_msg_lerr, (uint32_t)sizeof(s_msg_lerr) - 1U);
343 }
344 uint32_t crc2 = 0U;
345 const uint32_t pages2 = internal_rc_render_all(&crc2);
346
347 internal_rc_print(s_msg_pre, (uint32_t)sizeof(s_msg_pre) - 1U);
349 internal_rc_print(s_msg_crc, (uint32_t)sizeof(s_msg_crc) - 1U);
351 internal_rc_print(s_msg_rpages, (uint32_t)sizeof(s_msg_rpages) - 1U);
353 internal_rc_print(s_msg_crc, (uint32_t)sizeof(s_msg_crc) - 1U);
355 internal_rc_print(s_msg_eol, (uint32_t)sizeof(s_msg_eol) - 1U);
356
357 while (1) {
358 __asm__ volatile("wfi");
359 }
360}
void main(void)
Secure fallback main entry point.
Definition main.c:37
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 reflow_t s_engine
Reflow engine (glyph / page / token / text pools live inside).
Definition main.c:199
static const uint8_t s_msg_boot[]
Console marker emitted after core and peripheral setup.
Definition main.c:216
static const uint8_t s_msg_fail[]
Diagnostic emitted when the VFS round-trip fails.
Definition main.c:104
static void internal_rc_print_hex(uint32_t value)
Print a 32-bit value as eight uppercase hexadecimal digits.
Definition main.c:197
static void internal_rc_panic_halt(const uint8_t *msg, uint32_t len)
Emit a failure banner, break into the debugger, and halt.
Definition main.c:176
static const uint8_t s_msg_crc[]
Separator introducing a rendered-framebuffer hash.
Definition main.c:127
static const char s_rc_chapter[]
Fixed multi-paragraph HTML chapter used by both layout passes.
Definition main.c:75
static uint32_t internal_rc_render_all(uint32_t *out_hash)
Render every page of the laid-out chapter; fold an FNV over the output.
Definition main.c:253
static const uint8_t s_msg_pre[]
Prefix for the original page-count diagnostic.
Definition main.c:119
static const uint8_t s_msg_rpages[]
Separator introducing the larger-font page count.
Definition main.c:135
static void internal_rc_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the board UART console.
Definition main.c:158
static void internal_rc_print_uint(uint32_t value)
Print an unsigned 32-bit integer in decimal.
Definition main.c:220
static const uint8_t s_msg_lerr[]
Fatal chapter layout or font-size reflow diagnostic.
Definition main.c:111
static void internal_rc_setup_or_halt(void)
Bring up clocks, module-stop control, timekeeping, and the console.
Definition main.c:282
rc_consts_t
Framebuffer / console / hash / type-size knobs.
Definition main.c:44
@ k_rc_fb_w
Framebuffer width, pixels.
Definition main.c:45
@ k_rc_ink
Body ink colour (ARGB).
Definition main.c:49
@ k_rc_bg
Page background (0x00RRGGBB).
Definition main.c:51
@ k_rc_nibble_bits
Bits per hex nibble.
Definition main.c:56
@ k_rc_fnv_offset
FNV-1a-32 offset basis.
Definition main.c:53
@ k_rc_dec_ten
Hex digit / decimal split.
Definition main.c:58
@ k_rc_reflow_px
Re-flow font size, pixels.
Definition main.c:48
@ k_rc_fnv_prime
FNV-1a-32 prime.
Definition main.c:54
@ k_rc_link_col
Anchor colour (ARGB).
Definition main.c:50
@ k_rc_hex_nibbles
Hex digits in a 32-bit value.
Definition main.c:55
@ k_rc_font_px
Body font size, pixels.
Definition main.c:47
@ k_rc_nibble_mask
Low-nibble mask.
Definition main.c:57
@ k_rc_fb_h
Framebuffer height, pixels.
Definition main.c:46
@ k_rc_uart_baud
Console baud.
Definition main.c:52
static const uint8_t s_msg_eol[]
Console line terminator for the result banner.
Definition main.c:143
static const uint8_t s_ahem_ttf[]
Embedded Ahem TrueType font bytes.
static const uint32_t s_ahem_ttf_len
Exact byte length of s_ahem_ttf.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
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.
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
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
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_init(void *fb, uint16_t width, uint16_t height, ra8_gfx_format_t format)
Bind ra8_gfx to a caller-owned framebuffer.
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
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
HTML / CSS reflow + paginate engine for the ra8d2 ereader.
ra8_err_t reflow_render_page(const reflow_t *engine, uint32_t page_idx, void *framebuffer)
Render one page into the active ra8_gfx framebuffer.
ra8_err_t reflow_layout_chapter(reflow_t *engine, const uint8_t *xhtml_buf, size_t xhtml_len, uint32_t *out_total_pages)
Parse + lay out one chapter of XHTML.
ra8_err_t reflow_set_font_size(reflow_t *engine, uint16_t new_font_px)
Change the body font size and re-flow the cached chapter.
ra8_err_t reflow_init(uint16_t viewport_w, uint16_t viewport_h, const uint8_t *font_data, size_t font_len, uint16_t font_px, uint32_t body_color, uint32_t link_color, reflow_t *out_engine)
Initialise a reflow engine for a given viewport / font.
ra8_err_t reflow_get_page_count(const reflow_t *engine, uint32_t *out_count)
Report the laid-out page count.
Reflow / pagination engine state.