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
32
33#include <stddef.h>
34#include <stdint.h>
35
36#include "cover_fixture.h"
37#include "ra8_board_ek_ra8d2.h"
38#include "ra8_boot_entry.h"
39#include "ra8_cgc.h"
40#include "ra8_err.h"
41#include "ra8_gfx.h"
42#include "ra8_isr.h"
43#include "ra8_mstp.h"
44#include "ra8_time.h"
45#include "reflow_image.h"
46
47/* ===========================================================================
48 * Sizing + protocol constants (no magic numbers)
49 * ===========================================================================
50 */
51
53typedef enum : uint32_t {
54 k_iv_fb_w = 160U,
55 k_iv_fb_h = 120U,
56 k_iv_uart_baud = 115200U,
57 k_iv_arena_bytes = 128U * 1024U,
58 k_iv_fnv_offset = 2166136261U,
59 k_iv_fnv_prime = 16777619U,
65
67typedef enum : uint32_t {
68 k_iv_col_bg = 0x202028U,
70
72static uint16_t s_framebuffer[(size_t)k_iv_fb_h * (size_t)k_iv_fb_w];
73
76
77static const uint8_t k_msg_boot[] = "ereader-img-hil: boot\r\n";
78static const uint8_t k_msg_fail[] = "ereader-img-hil: FAIL init\r\n";
79static const uint8_t k_msg_derr[] = "ereader-img-hil: FAIL decode\r\n";
80static const uint8_t k_msg_pre[] = "ereader-img-hil: img ";
81static const uint8_t k_msg_x[] = "x";
82static const uint8_t k_msg_crc[] = " crc=";
83static const uint8_t k_msg_eol[] = "\r\n";
84
85/* ===========================================================================
86 * Console helpers
87 * ===========================================================================
88 */
89
91static void iv_print(const uint8_t* msg, uint32_t len)
92{
93 (void)ra8_board_uart_console_write((msg), (size_t)(len));
94}
95
97static void iv_panic_halt(void)
98{
99 iv_print(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
100 __asm__ volatile("bkpt #0");
101 while (1) {
102 __asm__ volatile("wfi");
103 }
104}
105
107static void iv_print_hex(uint32_t value)
108{
109 uint8_t buf[k_iv_hex_nibbles];
110 for (uint32_t i = 0U; i < (uint32_t)k_iv_hex_nibbles; i++) {
111 const uint32_t shift = ((uint32_t)k_iv_hex_nibbles - 1U - i) * (uint32_t)k_iv_nibble_bits;
112 const uint32_t nib = (value >> shift) & (uint32_t)k_iv_nibble_mask;
113 buf[i] = (uint8_t)((nib < (uint32_t)k_iv_dec_ten) ? ('0' + nib) : ('A' + (nib - k_iv_dec_ten)));
114 }
115 iv_print(buf, (uint32_t)k_iv_hex_nibbles);
116}
117
119static void iv_print_uint(uint32_t value)
120{
121 uint8_t buf[k_iv_dec_ten];
122 uint32_t n = 0U;
123 if (value == 0U) {
124 buf[n] = '0';
125 n++;
126 }
127 while ((value > 0U) && (n < (uint32_t)k_iv_dec_ten)) {
128 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_iv_dec_ten));
129 n++;
130 value /= (uint32_t)k_iv_dec_ten;
131 }
132 for (uint32_t i = 0U; i < n; i++) {
133 iv_print(&buf[n - 1U - i], 1U);
134 }
135}
136
137/* ===========================================================================
138 * Render + hash
139 * ===========================================================================
140 */
141
143static uint32_t iv_framebuffer_hash(void)
144{
145 const uint8_t* p = (const uint8_t*)s_framebuffer;
146 const size_t n = sizeof(s_framebuffer);
147 uint32_t hsh = (uint32_t)k_iv_fnv_offset;
148 for (size_t i = 0U; i < n; i++) {
149 hsh = (hsh ^ (uint32_t)p[i]) * (uint32_t)k_iv_fnv_prime;
150 }
151 return hsh;
152}
153
154/* ===========================================================================
155 * Boot + main
156 * ===========================================================================
157 */
158
160static void iv_setup_or_halt(void)
161{
162 uint32_t cpuclk0_hz = 0U;
163 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
165 }
168 }
169 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
171 }
174 }
175}
176
185void main(void)
186{
189 iv_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
190
192 (uint16_t)k_iv_fb_w,
193 (uint16_t)k_iv_fb_h,
196 }
197 (void)ra8_gfx_clear((uint32_t)k_iv_col_bg);
198
199 ra8_img_arena_t arena = {.base = s_img_arena,
200 .cap = (size_t)k_iv_arena_bytes,
201 .offset = 0U,
202 .live = 0U};
203 int32_t out_w = 0;
204 int32_t out_h = 0;
205 const ra8_err_t err = ra8_img_decode_blit(&arena,
207 (size_t)k_cover_png_len,
208 0,
209 0,
210 (int32_t)k_iv_fb_w,
211 (int32_t)k_iv_fb_h,
212 &out_w,
213 &out_h);
214 if (err != k_ra8_ok) {
215 iv_print(k_msg_derr, (uint32_t)sizeof(k_msg_derr) - 1U);
217 }
218
219 iv_print(k_msg_pre, (uint32_t)sizeof(k_msg_pre) - 1U);
220 iv_print_uint((uint32_t)out_w);
221 iv_print(k_msg_x, (uint32_t)sizeof(k_msg_x) - 1U);
222 iv_print_uint((uint32_t)out_h);
223 iv_print(k_msg_crc, (uint32_t)sizeof(k_msg_crc) - 1U);
225 iv_print(k_msg_eol, (uint32_t)sizeof(k_msg_eol) - 1U);
226
227 while (1) {
228 __asm__ volatile("wfi");
229 }
230}
void main(void)
Secure fallback main entry point.
Definition main.c:37
Baked 120x90 RGB PNG test cover for the ereader_image gate.
static const uint32_t k_cover_png_len
Length of k_cover_png in bytes.
static const uint8_t k_cover_png[]
Encoded 120x90 RGB PNG cover image.
static const uint8_t k_msg_pre[]
Definition main.c:151
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 uint8_t s_img_arena[k_cm_arena_bytes]
Zero-heap bump arena in SDRAM backing the PNG page decode.
Definition main.c:180
static const uint8_t k_msg_derr[]
Definition main.c:83
static const uint8_t k_msg_x[]
Definition main.c:85
static const uint8_t k_msg_eol[]
Definition main.c:328
static void iv_print_hex(uint32_t value)
Print a 32-bit value as 8 upper-case hex digits.
Definition main.c:107
iv_colors_t
0x00RRGGBB palette.
Definition main.c:67
@ k_iv_col_bg
Framebuffer clear colour (dark slate).
Definition main.c:68
static void iv_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
Definition main.c:91
iv_consts_t
Framebuffer / console / hash knobs.
Definition main.c:53
@ k_iv_fnv_prime
FNV-1a-32 prime.
Definition main.c:59
@ k_iv_hex_nibbles
Hex digits in a 32-bit value.
Definition main.c:60
@ k_iv_dec_ten
Hex digit / decimal split.
Definition main.c:63
@ k_iv_arena_bytes
PNG decode scratch, bytes.
Definition main.c:57
@ k_iv_fnv_offset
FNV-1a-32 offset basis.
Definition main.c:58
@ k_iv_uart_baud
Console baud.
Definition main.c:56
@ k_iv_fb_h
Framebuffer height, pixels.
Definition main.c:55
@ k_iv_nibble_mask
Low-nibble mask.
Definition main.c:62
@ k_iv_nibble_bits
Bits per hex nibble.
Definition main.c:61
@ k_iv_fb_w
Framebuffer width, pixels.
Definition main.c:54
static void iv_setup_or_halt(void)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
Definition main.c:160
static void iv_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
Definition main.c:119
static void iv_panic_halt(void)
Print the init-fail banner and spin (ra8_emulator halts on the BKPT).
Definition main.c:97
static uint32_t iv_framebuffer_hash(void)
FNV-1a-32 over the rendered framebuffer bytes.
Definition main.c:143
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
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_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
Zero-heap raster image decode + scale + blit for reflow (#106).
ra8_err_t ra8_img_decode_blit(ra8_img_arena_t *arena, const uint8_t *bytes, size_t len, int32_t dst_x, int32_t dst_y, int32_t box_w, int32_t box_h, int32_t *out_w, int32_t *out_h)
Decode bytes and blit it, scaled to fit, into the bound framebuffer.
Caller-owned bump arena backing a single image decode.