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
29
30#include <stddef.h>
31#include <stdint.h>
32
33#include "epub.h"
34#include "epub_fixture.h"
35#include "ra8_board_ek_ra8d2.h"
36#include "ra8_boot_entry.h"
37#include "ra8_cgc.h"
38#include "ra8_err.h"
39#include "ra8_isr.h"
40#include "ra8_mstp.h"
41#include "ra8_time.h"
42
44typedef enum : uint32_t {
45 k_ep_uart_baud = 115200U,
47 k_ep_chap_cap = 4096U,
48 k_ep_crc_init = 0xFFFFFFFFU,
49 k_ep_crc_poly = 0xEDB88320U,
56
60static uint8_t s_chapter[k_ep_chap_cap];
61
62static const uint8_t k_msg_boot[] = "epub-parse-hil: boot\r\n";
63static const uint8_t k_msg_fail[] = "epub-parse-hil: FAIL init\r\n";
64static const uint8_t k_msg_open[] = "epub: FAIL open\r\n";
65static const uint8_t k_msg_chap[] = "epub: FAIL chapters\r\n";
66static const uint8_t k_msg_load[] = "epub: FAIL load\r\n";
67static const uint8_t k_msg_meta[] = "epub: FAIL meta\r\n";
68static const uint8_t k_msg_pre[] = "epub: chapters=";
69static const uint8_t k_msg_crc[] = " ch0_crc=";
70static const uint8_t k_msg_ok[] = " PASS\r\n";
71
73static void ep_print(const uint8_t* msg, uint32_t len)
74{
75 (void)ra8_board_uart_console_write(msg, (size_t)len);
76}
77
79static void ep_panic_halt(const uint8_t* msg, uint32_t len)
80{
81 ep_print(msg, len);
82 __asm__ volatile("bkpt #0");
83 while (1) {
84 __asm__ volatile("wfi");
85 }
86}
87
89static uint32_t ep_crc32(const uint8_t* data, size_t len)
90{
91 uint32_t crc = (uint32_t)k_ep_crc_init;
92 for (size_t i = 0U; i < len; i++) {
93 crc ^= (uint32_t)data[i];
94 for (uint32_t bit = 0U; bit < (uint32_t)k_ep_crc_bits; bit++) {
95 const uint32_t mask = (uint32_t)(-(int32_t)(crc & 1U));
96 crc = (crc >> 1U) ^ ((uint32_t)k_ep_crc_poly & mask);
97 }
98 }
99 return ~crc;
100}
101
103static void ep_print_hex(uint32_t value)
104{
105 uint8_t buf[k_ep_hex_nibbles];
106 for (uint32_t i = 0U; i < (uint32_t)k_ep_hex_nibbles; i++) {
107 const uint32_t shift = ((uint32_t)k_ep_hex_nibbles - 1U - i) * (uint32_t)k_ep_nibble_bits;
108 const uint32_t nib = (value >> shift) & (uint32_t)k_ep_nibble_mask;
109 buf[i] = (uint8_t)((nib < (uint32_t)k_ep_dec_ten) ? ('0' + nib) : ('A' + (nib - k_ep_dec_ten)));
110 }
111 ep_print(buf, (uint32_t)k_ep_hex_nibbles);
112}
113
115static void ep_print_uint(uint32_t value)
116{
117 uint8_t buf[k_ep_dec_ten];
118 uint32_t n = 0U;
119 if (value == 0U) {
120 buf[n] = '0';
121 n++;
122 }
123 while ((value > 0U) && (n < (uint32_t)k_ep_dec_ten)) {
124 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_ep_dec_ten));
125 n++;
126 value /= (uint32_t)k_ep_dec_ten;
127 }
128 for (uint32_t i = 0U; i < n; i++) {
129 ep_print(&buf[n - 1U - i], 1U);
130 }
131}
132
134static void ep_setup_or_halt(void)
135{
136 uint32_t cpuclk0_hz = 0U;
137 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
138 ep_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
139 }
141 ep_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
142 }
143 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
144 ep_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
145 }
147 ep_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
148 }
149}
150
162static uint16_t ep_parse_or_halt(uint32_t* out_crc)
163{
164 const epub_mem_media_t media = {.data = k_epub_fixture, .size = (size_t)k_epub_fixture_len};
165 if (epub_open(&media, "book.epub", &s_book) != k_ra8_ok) {
166 ep_panic_halt(k_msg_open, (uint32_t)sizeof(k_msg_open) - 1U);
167 }
168 uint16_t chapters = 0U;
169 if ((epub_get_chapter_count(&s_book, &chapters) != k_ra8_ok) ||
170 (chapters != (uint16_t)k_ep_expect_chap)) {
171 ep_panic_halt(k_msg_chap, (uint32_t)sizeof(k_msg_chap) - 1U);
172 }
173 size_t got = 0U;
174 if ((epub_load_chapter(&s_book, 0U, s_chapter, (size_t)k_ep_chap_cap, &got) != k_ra8_ok) ||
175 (got == 0U)) {
176 ep_panic_halt(k_msg_load, (uint32_t)sizeof(k_msg_load) - 1U);
177 }
178 epub_metadata_t meta = {};
179 if (epub_get_metadata(&s_book, &meta) != k_ra8_ok) {
180 ep_panic_halt(k_msg_meta, (uint32_t)sizeof(k_msg_meta) - 1U);
181 }
182 *out_crc = ep_crc32(s_chapter, got);
183 return chapters;
184}
185
194void main(void)
195{
198 ep_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
199
200 uint32_t ch0_crc = 0U;
201 const uint16_t chapters = ep_parse_or_halt(&ch0_crc);
202
203 ep_print(k_msg_pre, (uint32_t)sizeof(k_msg_pre) - 1U);
204 ep_print_uint((uint32_t)chapters);
205 ep_print(k_msg_crc, (uint32_t)sizeof(k_msg_crc) - 1U);
206 ep_print_hex(ch0_crc);
207 ep_print(k_msg_ok, (uint32_t)sizeof(k_msg_ok) - 1U);
208
209 while (1) {
210 __asm__ volatile("wfi");
211 }
212}
void main(void)
Secure fallback main entry point.
Definition main.c:37
EPUB (.epub) reader and chapter iterator for ra8-firmware.
ra8_err_t epub_get_metadata(const epub_book_t *book, epub_metadata_t *out_meta)
Return Dublin Core metadata strings.
ra8_err_t epub_load_chapter(epub_book_t *book, uint16_t idx, uint8_t *out_xhtml, size_t max_len, size_t *got_len)
Extract the raw XHTML bytes of one chapter into the caller's buffer.
ra8_err_t epub_open(const void *media, const char *path, epub_book_t *out_book)
Open an EPUB book from an opaque media handle.
Definition epub_open.c:405
ra8_err_t epub_get_chapter_count(const epub_book_t *book, uint16_t *out_count)
Report how many chapters the spine contains.
static const uint8_t k_epub_fixture[k_epub_fixture_len]
Baked seed_two_chapters.epub byte stream.
@ k_epub_fixture_len
EPUB fixture length.
static epub_book_t s_book
Opened book (large – file-scope, not on the stack).
Definition main.c:132
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 uint8_t s_chapter[k_eoh_chap_cap]
Chapter-0 XHTML scratch (file-scope to keep the stack small).
Definition main.c:136
static uint32_t ep_crc32(const uint8_t *data, size_t len)
CRC-32 (reflected, poly 0xEDB88320) over data.
Definition main.c:89
ep_consts_t
Console / parse knobs (no magic numbers).
Definition main.c:44
@ k_ep_hex_nibbles
Hex digits in a 32-bit value.
Definition main.c:51
@ k_ep_expect_chap
Spine length of the baked seed.
Definition main.c:46
@ k_ep_crc_init
CRC-32 initial value.
Definition main.c:48
@ k_ep_crc_poly
CRC-32 reflected polynomial.
Definition main.c:49
@ k_ep_uart_baud
Console baud.
Definition main.c:45
@ k_ep_nibble_bits
Bits per hex nibble.
Definition main.c:52
@ k_ep_crc_bits
Bits folded per byte.
Definition main.c:50
@ k_ep_nibble_mask
Low-nibble mask.
Definition main.c:53
@ k_ep_dec_ten
Hex digit / decimal split.
Definition main.c:54
@ k_ep_chap_cap
Chapter XHTML scratch capacity.
Definition main.c:47
static const uint8_t k_msg_load[]
Definition main.c:66
static void ep_print_hex(uint32_t value)
Print a 32-bit value as 8 upper-case hex digits.
Definition main.c:103
static const uint8_t k_msg_chap[]
Definition main.c:65
static void ep_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
Definition main.c:73
static const uint8_t k_msg_meta[]
Definition main.c:67
static void ep_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
Definition main.c:115
static const uint8_t k_msg_open[]
Definition main.c:64
static void ep_setup_or_halt(void)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
Definition main.c:134
static uint16_t ep_parse_or_halt(uint32_t *out_crc)
Open the baked EPUB, verify the spine, load + CRC chapter 0.
Definition main.c:162
static const uint8_t k_msg_fail[]
Definition main.c:63
static void ep_panic_halt(void)
Halt forever with the red board LED on.
Definition main.c:389
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
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
Opened EPUB book.
Definition epub.h:286
In-memory EPUB media descriptor.
Definition epub.h:179
Dublin Core metadata bundle returned by epub_get_metadata().
Definition epub.h:370