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
34
35#include <stddef.h>
36#include <stdint.h>
37
38#include "imgfmt_fixtures.h"
39#include "ra8_board_ek_ra8d2.h"
40#include "ra8_boot_entry.h"
41#include "ra8_cgc.h"
42#include "ra8_err.h"
43#include "ra8_gfx.h"
44#include "ra8_isr.h"
45#include "ra8_mstp.h"
46#include "ra8_time.h"
47#include "reflow_image.h"
48
50typedef enum : uint32_t {
51 k_ef_uart_baud = 115200U,
52 k_ef_fb_w = 160U,
53 k_ef_fb_h = 120U,
54 k_ef_arena_bytes = 128U * 1024U,
55 k_ef_col_bg = 0x202028U,
56 k_ef_fnv_offset = 0x811C9DC5U,
57 k_ef_fnv_prime = 0x01000193U,
63
65static uint16_t s_framebuffer[(size_t)k_ef_fb_h * (size_t)k_ef_fb_w];
68
69static const uint8_t k_msg_boot[] = "ereader-imgfmt-hil: boot\r\n";
70static const uint8_t k_msg_fail[] = "ereader-imgfmt-hil: FAIL init\r\n";
71static const uint8_t k_msg_dbmp[] = "ereader-imgfmt-hil: FAIL bmp\r\n";
72static const uint8_t k_msg_dgif[] = "ereader-imgfmt-hil: FAIL gif\r\n";
73static const uint8_t k_msg_pre[] = "ereader-imgfmt-hil: bmp=";
74static const uint8_t k_msg_gif[] = " gif=";
75static const uint8_t k_msg_ok[] = " PASS\r\n";
76
78static void ef_print(const uint8_t* msg, uint32_t len)
79{
80 (void)ra8_board_uart_console_write(msg, (size_t)len);
81}
82
84static void ef_panic_halt(const uint8_t* msg, uint32_t len)
85{
86 ef_print(msg, len);
87 __asm__ volatile("bkpt #0");
88 while (1) {
89 __asm__ volatile("wfi");
90 }
91}
92
94static uint32_t ef_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_ef_fnv_offset;
99 for (size_t i = 0U; i < n; i++) {
100 hsh = (hsh ^ (uint32_t)p[i]) * (uint32_t)k_ef_fnv_prime;
101 }
102 return hsh;
103}
104
106static void ef_print_hex(uint32_t value)
107{
108 uint8_t buf[k_ef_hex_nibbles];
109 for (uint32_t i = 0U; i < (uint32_t)k_ef_hex_nibbles; i++) {
110 const uint32_t shift = ((uint32_t)k_ef_hex_nibbles - 1U - i) * (uint32_t)k_ef_nibble_bits;
111 const uint32_t nib = (value >> shift) & (uint32_t)k_ef_nibble_mask;
112 buf[i] = (uint8_t)((nib < (uint32_t)k_ef_dec_ten) ? ('0' + nib) : ('A' + (nib - k_ef_dec_ten)));
113 }
114 ef_print(buf, (uint32_t)k_ef_hex_nibbles);
115}
116
118static void ef_setup_or_halt(void)
119{
120 uint32_t cpuclk0_hz = 0U;
121 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
122 ef_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
123 }
125 ef_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
126 }
127 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
128 ef_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
129 }
131 ef_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
132 }
133}
134
150static uint32_t
151ef_decode_and_hash(const uint8_t* bytes, size_t len, const uint8_t* fail_msg, uint32_t fail_len)
152{
153 (void)ra8_gfx_clear((uint32_t)k_ef_col_bg);
154 ra8_img_arena_t arena = {.base = s_img_arena,
155 .cap = (size_t)k_ef_arena_bytes,
156 .offset = 0U,
157 .live = 0U};
158 int32_t out_w = 0;
159 int32_t out_h = 0;
160 if (ra8_img_decode_blit(&arena,
161 bytes,
162 len,
163 0,
164 0,
165 (int32_t)k_ef_fb_w,
166 (int32_t)k_ef_fb_h,
167 &out_w,
168 &out_h) != k_ra8_ok) {
169 ef_panic_halt(fail_msg, fail_len);
170 }
171 return ef_framebuffer_hash();
172}
173
182void main(void)
183{
186 ef_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
187
189 (uint16_t)k_ef_fb_w,
190 (uint16_t)k_ef_fb_h,
192 ef_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
193 }
194
195 const uint32_t bmp_crc =
196 ef_decode_and_hash(k_bmp, (size_t)k_bmp_len, k_msg_dbmp, (uint32_t)sizeof(k_msg_dbmp) - 1U);
197 const uint32_t gif_crc =
198 ef_decode_and_hash(k_gif, (size_t)k_gif_len, k_msg_dgif, (uint32_t)sizeof(k_msg_dgif) - 1U);
199
200 ef_print(k_msg_pre, (uint32_t)sizeof(k_msg_pre) - 1U);
201 ef_print_hex(bmp_crc);
202 ef_print(k_msg_gif, (uint32_t)sizeof(k_msg_gif) - 1U);
203 ef_print_hex(gif_crc);
204 ef_print(k_msg_ok, (uint32_t)sizeof(k_msg_ok) - 1U);
205
206 while (1) {
207 __asm__ volatile("wfi");
208 }
209}
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_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 void ef_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
Definition main.c:78
static const uint8_t k_msg_dgif[]
Definition main.c:72
static const uint8_t k_msg_dbmp[]
Definition main.c:71
static const uint8_t k_msg_gif[]
Definition main.c:74
static uint32_t ef_framebuffer_hash(void)
FNV-1a hash over the rendered framebuffer.
Definition main.c:94
static void ef_print_hex(uint32_t value)
Print a 32-bit value as 8 upper-case hex digits.
Definition main.c:106
static void ef_setup_or_halt(void)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
Definition main.c:118
ef_consts_t
Console / render knobs (no magic numbers).
Definition main.c:50
@ k_ef_fnv_prime
FNV-1a 32-bit prime.
Definition main.c:57
@ k_ef_nibble_bits
Bits per hex nibble.
Definition main.c:59
@ k_ef_arena_bytes
Image decode scratch, bytes.
Definition main.c:54
@ k_ef_dec_ten
Hex digit / decimal split.
Definition main.c:61
@ k_ef_nibble_mask
Low-nibble mask.
Definition main.c:60
@ k_ef_hex_nibbles
Hex digits in a 32-bit value.
Definition main.c:58
@ k_ef_fb_h
Framebuffer height, pixels.
Definition main.c:53
@ k_ef_col_bg
Framebuffer clear colour.
Definition main.c:55
@ k_ef_fb_w
Framebuffer width, pixels.
Definition main.c:52
@ k_ef_uart_baud
Console baud.
Definition main.c:51
@ k_ef_fnv_offset
FNV-1a 32-bit offset basis.
Definition main.c:56
static uint32_t ef_decode_and_hash(const uint8_t *bytes, size_t len, const uint8_t *fail_msg, uint32_t fail_len)
Clear the framebuffer, decode+scale+blit one image, hash the result.
Definition main.c:151
static void ef_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
Baked BMP + GIF test images for the ereader_imgfmt gate.
@ k_gif_len
Gif length.
@ k_bmp_len
Bmp length.
static const uint8_t k_gif[k_gif_len]
Baked 40x30 four-quadrant GIF image.
static const uint8_t k_bmp[k_bmp_len]
Baked 40x30 four-quadrant BMP image.
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
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.