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
36
37#include <stddef.h>
38#include <stdint.h>
39
40#include "ra8_board_ek_ra8d2.h"
41#include "ra8_boot_entry.h"
42#include "ra8_cgc.h"
43#include "ra8_err.h"
44#include "ra8_gfx.h"
45#include "ra8_isr.h"
46#include "ra8_mstp.h"
47#include "ra8_time.h"
48#include "reflow_svg.h"
49#include "svg_fixture.h"
50
52typedef enum : uint32_t {
53 k_es_uart_baud = 115200U,
54 k_es_fb_w = 160U,
55 k_es_fb_h = 120U,
56 k_es_col_bg = 0x202028U,
57 k_es_fnv_offset = 0x811C9DC5U,
58 k_es_fnv_prime = 0x01000193U,
64
66static uint16_t s_framebuffer[(size_t)k_es_fb_h * (size_t)k_es_fb_w];
67
68static const uint8_t k_msg_boot[] = "ereader-svg-hil: boot\r\n";
69static const uint8_t k_msg_fail[] = "ereader-svg-hil: FAIL init\r\n";
70static const uint8_t k_msg_size[] = "ereader-svg-hil: FAIL size\r\n";
71static const uint8_t k_msg_rerr[] = "ereader-svg-hil: FAIL render\r\n";
72static const uint8_t k_msg_pre[] = "ereader-svg-hil: svg ";
73static const uint8_t k_msg_x[] = "x";
74static const uint8_t k_msg_crc[] = " crc=";
75static const uint8_t k_msg_ok[] = " PASS\r\n";
76
78static void es_print(const uint8_t* msg, uint32_t len)
79{
80 (void)ra8_board_uart_console_write(msg, (size_t)len);
81}
82
84static void es_panic_halt(const uint8_t* msg, uint32_t len)
85{
86 es_print(msg, len);
87 __asm__ volatile("bkpt #0");
88 while (1) {
89 __asm__ volatile("wfi");
90 }
91}
92
94static uint32_t es_framebuffer_hash(void)
95{
96 const uint8_t* p = (const uint8_t*)s_framebuffer;
97 const size_t n = sizeof(s_framebuffer);
98 uint32_t hsh = (uint32_t)k_es_fnv_offset;
99 for (size_t i = 0U; i < n; i++) {
100 hsh = (hsh ^ (uint32_t)p[i]) * (uint32_t)k_es_fnv_prime;
101 }
102 return hsh;
103}
104
106static void es_print_hex(uint32_t value)
107{
108 uint8_t buf[k_es_hex_nibbles];
109 for (uint32_t i = 0U; i < (uint32_t)k_es_hex_nibbles; i++) {
110 const uint32_t shift = ((uint32_t)k_es_hex_nibbles - 1U - i) * (uint32_t)k_es_nibble_bits;
111 const uint32_t nib = (value >> shift) & (uint32_t)k_es_nibble_mask;
112 buf[i] = (uint8_t)((nib < (uint32_t)k_es_dec_ten) ? ('0' + nib) : ('A' + (nib - k_es_dec_ten)));
113 }
114 es_print(buf, (uint32_t)k_es_hex_nibbles);
115}
116
118static void es_print_uint(uint32_t value)
119{
120 uint8_t buf[k_es_dec_ten];
121 uint32_t n = 0U;
122 if (value == 0U) {
123 buf[n] = '0';
124 n++;
125 }
126 while ((value > 0U) && (n < (uint32_t)k_es_dec_ten)) {
127 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_es_dec_ten));
128 n++;
129 value /= (uint32_t)k_es_dec_ten;
130 }
131 for (uint32_t i = 0U; i < n; i++) {
132 es_print(&buf[n - 1U - i], 1U);
133 }
134}
135
137static void es_setup_or_halt(void)
138{
139 uint32_t cpuclk0_hz = 0U;
140 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
141 es_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
142 }
144 es_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
145 }
146 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
147 es_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
148 }
150 es_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
151 }
152}
153
167static void es_render_svg_or_halt(int32_t* out_w, int32_t* out_h)
168{
169 const size_t svg_len = sizeof(k_svg_fixture) - 1U;
170 if (ra8_svg_size((const uint8_t*)k_svg_fixture, svg_len, out_w, out_h) != k_ra8_ok) {
171 es_panic_halt(k_msg_size, (uint32_t)sizeof(k_msg_size) - 1U);
172 }
173 if (ra8_svg_render((const uint8_t*)k_svg_fixture,
174 svg_len,
175 0,
176 0,
177 (int32_t)k_es_fb_w,
178 (int32_t)k_es_fb_h) != k_ra8_ok) {
179 es_panic_halt(k_msg_rerr, (uint32_t)sizeof(k_msg_rerr) - 1U);
180 }
181}
182
191void main(void)
192{
195 es_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
196
198 (uint16_t)k_es_fb_w,
199 (uint16_t)k_es_fb_h,
201 es_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
202 }
203 (void)ra8_gfx_clear((uint32_t)k_es_col_bg);
204
205 int32_t svg_w = 0;
206 int32_t svg_h = 0;
207 es_render_svg_or_halt(&svg_w, &svg_h);
208
209 es_print(k_msg_pre, (uint32_t)sizeof(k_msg_pre) - 1U);
210 es_print_uint((uint32_t)svg_w);
211 es_print(k_msg_x, (uint32_t)sizeof(k_msg_x) - 1U);
212 es_print_uint((uint32_t)svg_h);
213 es_print(k_msg_crc, (uint32_t)sizeof(k_msg_crc) - 1U);
215 es_print(k_msg_ok, (uint32_t)sizeof(k_msg_ok) - 1U);
216
217 while (1) {
218 __asm__ volatile("wfi");
219 }
220}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static const uint8_t k_msg_pre[]
Definition main.c:151
static const uint8_t k_msg_ok[]
Definition main.c:153
static const uint8_t k_msg_crc[]
Definition main.c:152
static const uint8_t k_msg_boot[]
Definition main.c:140
static const uint8_t k_msg_fail[]
Definition main.c:63
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 const uint8_t k_msg_x[]
Definition main.c:85
static const uint8_t k_msg_rerr[]
Definition main.c:71
static void es_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
Definition main.c:118
static void es_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
Definition main.c:78
es_consts_t
Console / render knobs (no magic numbers).
Definition main.c:52
@ k_es_nibble_mask
Low-nibble mask.
Definition main.c:61
@ k_es_dec_ten
Hex digit / decimal split.
Definition main.c:62
@ k_es_fb_w
Framebuffer width, pixels.
Definition main.c:54
@ k_es_fnv_prime
FNV-1a 32-bit prime.
Definition main.c:58
@ k_es_hex_nibbles
Hex digits in a 32-bit value.
Definition main.c:59
@ k_es_fnv_offset
FNV-1a 32-bit offset basis.
Definition main.c:57
@ k_es_fb_h
Framebuffer height, pixels.
Definition main.c:55
@ k_es_col_bg
Framebuffer clear colour.
Definition main.c:56
@ k_es_nibble_bits
Bits per hex nibble.
Definition main.c:60
@ k_es_uart_baud
Console baud.
Definition main.c:53
static void es_print_hex(uint32_t value)
Print a 32-bit value as 8 upper-case hex digits.
Definition main.c:106
static uint32_t es_framebuffer_hash(void)
FNV-1a hash over the rendered framebuffer.
Definition main.c:94
static const uint8_t k_msg_size[]
Definition main.c:70
static void es_render_svg_or_halt(int32_t *out_w, int32_t *out_h)
Read the SVG intrinsic size and render it into the framebuffer.
Definition main.c:167
static void es_panic_halt(const uint8_t *msg, uint32_t len)
Print the fail banner and trap (ra8_emulator halts on the BKPT).
Definition main.c:84
static void es_setup_or_halt(void)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
Definition main.c:137
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
Minimal SVG handling for the reflow ereader (#112).
ra8_err_t ra8_svg_render(const uint8_t *svg, size_t len, int32_t x, int32_t y, int32_t w, int32_t h)
Render an SVG's vector shapes into a box.
ra8_err_t ra8_svg_size(const uint8_t *svg, size_t len, int32_t *out_w, int32_t *out_h)
Report an SVG's intrinsic size (width/height, else viewBox dimensions).
Baked deterministic SVG vector-art fixture for ereader_svg.
static const char k_svg_fixture[]
Baked SVG vector-art document (NUL-terminated ASCII).
Definition svg_fixture.h:17