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
28
29#include <stddef.h>
30#include <stdint.h>
31
32#include "ra8_board_ek_ra8d2.h"
33#include "ra8_boot_entry.h"
34#include "ra8_cgc.h"
35#include "ra8_err.h"
36#include "ra8_isr.h"
37#include "ra8_mstp.h"
38#include "ra8_time.h"
39#include "ra8_ui.h"
40
42typedef enum : uint32_t {
43 k_iu_uart_baud = 115200U,
46
48typedef enum : uint16_t {
55
57typedef enum : uint16_t {
61
71
84
86static const ra8_ui_target_t k_iu_targets[] = {
87 {.rect = {.x = k_iu_grid_col0_x, .y = k_iu_grid_row0_y, .w = k_iu_cell_w, .h = k_iu_cell_h},
88 .action_id = (uint16_t)k_iu_act_book0},
89 {.rect = {.x = k_iu_grid_col1_x, .y = k_iu_grid_row0_y, .w = k_iu_cell_w, .h = k_iu_cell_h},
90 .action_id = (uint16_t)k_iu_act_book1},
91 {.rect = {.x = k_iu_grid_col0_x, .y = k_iu_grid_row1_y, .w = k_iu_cell_w, .h = k_iu_cell_h},
92 .action_id = (uint16_t)k_iu_act_book2},
93 {.rect = {.x = k_iu_grid_col1_x, .y = k_iu_grid_row1_y, .w = k_iu_cell_w, .h = k_iu_cell_h},
94 .action_id = (uint16_t)k_iu_act_book3},
95 {.rect = {.x = k_iu_grid_col0_x, .y = k_iu_toolbar_y, .w = k_iu_toolbar_w, .h = k_iu_toolbar_h},
96 .action_id = (uint16_t)k_iu_act_toolbar},
97};
98
99static const uint8_t k_msg_boot[] = "ui-hil: boot\r\n";
100static const uint8_t k_msg_fail[] = "ui-hil: FAIL init\r\n";
101static const uint8_t k_msg_pre[] = "ui-hil: taps=";
102static const uint8_t k_msg_hits[] = " hits=";
103static const uint8_t k_msg_nav[] = " nav_ok=";
104static const uint8_t k_msg_pass[] = " PASS\r\n";
105static const uint8_t k_msg_failr[] = " FAIL\r\n";
106
108static void iu_print(const uint8_t* msg, uint32_t len)
109{
110 (void)ra8_board_uart_console_write(msg, (size_t)len);
111}
112
114static void iu_panic_halt(void)
115{
116 iu_print(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
117 __asm__ volatile("bkpt #0");
118 while (1) {
119 __asm__ volatile("wfi");
120 }
121}
122
124static void iu_print_uint(uint32_t value)
125{
126 uint8_t buf[k_iu_dec_ten];
127 uint32_t n = 0U;
128 if (value == 0U) {
129 buf[n] = '0';
130 n++;
131 }
132 while ((value > 0U) && (n < (uint32_t)k_iu_dec_ten)) {
133 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_iu_dec_ten));
134 n++;
135 value /= (uint32_t)k_iu_dec_ten;
136 }
137 for (uint32_t i = 0U; i < n; i++) {
138 iu_print(&buf[n - 1U - i], 1U);
139 }
140}
141
152static bool iu_tap(int32_t px, int32_t py, bool want_hit, uint16_t want_act, uint32_t* hits)
153{
154 const uint16_t count = (uint16_t)(sizeof(k_iu_targets) / sizeof(k_iu_targets[0]));
155 uint16_t action = 0U;
156 bool hit = false;
157 if (ra8_ui_hit_test(k_iu_targets, count, px, py, &action, &hit) != k_ra8_ok) {
158 return false;
159 }
160 if (hit) {
161 (*hits)++;
162 }
163 if (hit != want_hit) {
164 return false;
165 }
166 return want_hit ? (action == want_act) : true;
167}
168
174static bool iu_nav_check(void)
175{
176 ra8_ui_nav_t nav = {};
177 uint16_t top = 0U;
178 if (ra8_ui_nav_init(&nav, (uint16_t)k_iu_screen_library) != k_ra8_ok) {
179 return false;
180 }
181 if ((ra8_ui_nav_top(&nav, &top) != k_ra8_ok) || (top != (uint16_t)k_iu_screen_library)) {
182 return false;
183 }
184 /* Open a book: push the reading screen. */
185 if (ra8_ui_nav_push(&nav, (uint16_t)k_iu_screen_reading) != k_ra8_ok) {
186 return false;
187 }
188 if ((ra8_ui_nav_top(&nav, &top) != k_ra8_ok) || (top != (uint16_t)k_iu_screen_reading)) {
189 return false;
190 }
191 /* Back: pop reveals (and returns) the library beneath. */
192 uint16_t new_top = 0U;
193 if ((ra8_ui_nav_pop(&nav, &new_top) != k_ra8_ok) || (new_top != (uint16_t)k_iu_screen_library)) {
194 return false;
195 }
196 /* The root is never popped: a pop at depth 1 must fail and leave the root. */
197 if (ra8_ui_nav_pop(&nav, &new_top) == k_ra8_ok) {
198 return false;
199 }
200 return (ra8_ui_nav_top(&nav, &top) == k_ra8_ok) && (top == (uint16_t)k_iu_screen_library);
201}
202
204static void iu_setup_or_halt(void)
205{
206 uint32_t cpuclk0_hz = 0U;
207 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
209 }
212 }
213 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
215 }
218 }
219}
220
229void main(void)
230{
233 iu_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
234
235 uint32_t taps = 0U;
236 uint32_t hits = 0U;
237 bool ok = true;
238
239 /* Tap each target's centre -> a hit on its action id. */
240 const uint16_t ntargets = (uint16_t)(sizeof(k_iu_targets) / sizeof(k_iu_targets[0]));
241 for (uint16_t t = 0U; t < ntargets; ++t) {
242 const ra8_ui_rect_t* r = &k_iu_targets[t].rect;
243 const int32_t cx = r->x + (r->w / (int32_t)k_iu_tap_half);
244 const int32_t cy = r->y + (r->h / (int32_t)k_iu_tap_half);
245 ok = iu_tap(cx, cy, true, k_iu_targets[t].action_id, &hits) && ok;
246 taps++;
247 }
248 /* Off-target taps -> misses (the column gutter, and far off-screen). */
249 ok = iu_tap((int32_t)k_iu_miss_gutter_x, (int32_t)k_iu_miss_gutter_y, false, 0U, &hits) && ok;
250 taps++;
251 ok = iu_tap((int32_t)k_iu_miss_off_x, (int32_t)k_iu_miss_off_y, false, 0U, &hits) && ok;
252 taps++;
253
254 const bool nav_ok = iu_nav_check();
255 ok = ok && nav_ok && (hits == (uint32_t)ntargets) &&
256 (taps == (uint32_t)(ntargets + (uint16_t)k_iu_miss_count));
257
258 iu_print(k_msg_pre, (uint32_t)sizeof(k_msg_pre) - 1U);
259 iu_print_uint(taps);
260 iu_print(k_msg_hits, (uint32_t)sizeof(k_msg_hits) - 1U);
261 iu_print_uint(hits);
262 iu_print(k_msg_nav, (uint32_t)sizeof(k_msg_nav) - 1U);
263 iu_print_uint(nav_ok ? 1U : 0U);
264 if (ok) {
265 iu_print(k_msg_pass, (uint32_t)sizeof(k_msg_pass) - 1U);
266 } else {
267 iu_print(k_msg_failr, (uint32_t)sizeof(k_msg_failr) - 1U);
268 }
269
270 while (1) {
271 __asm__ volatile("wfi");
272 }
273}
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_boot[]
Definition main.c:140
static const uint8_t k_msg_fail[]
Definition main.c:63
static const uint8_t k_msg_pass[]
Definition main.c:200
static bool iu_nav_check(void)
Drive the screen stack: open book -> reading, back -> library.
Definition main.c:174
static const ra8_ui_target_t k_iu_targets[]
Representative chrome targets: a 2x2 book grid + a toolbar button.
Definition main.c:86
iu_consts_t
Console knobs (no magic numbers).
Definition main.c:42
@ k_iu_uart_baud
Console baud.
Definition main.c:43
@ k_iu_dec_ten
Decimal base.
Definition main.c:44
iu_screen_t
Screen ids for the nav stack.
Definition main.c:57
@ k_iu_screen_reading
Reading view.
Definition main.c:59
@ k_iu_screen_library
Library / home grid.
Definition main.c:58
iu_action_t
Chrome tap-target action ids.
Definition main.c:48
@ k_iu_act_book3
Library book cell 3.
Definition main.c:52
@ k_iu_act_book2
Library book cell 2.
Definition main.c:51
@ k_iu_act_book0
Library book cell 0.
Definition main.c:49
@ k_iu_act_book1
Library book cell 1.
Definition main.c:50
@ k_iu_act_toolbar
Status-bar toolbar button.
Definition main.c:53
static void iu_panic_halt(void)
Print the fail banner and trap (ra8_emulator halts on the BKPT).
Definition main.c:114
static void iu_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
Definition main.c:124
static const uint8_t k_msg_hits[]
Definition main.c:102
iu_rect_t
Pixel geometry of the chrome tap-target rects.
Definition main.c:73
@ k_iu_toolbar_y
Toolbar-button y.
Definition main.c:80
@ k_iu_toolbar_h
Toolbar-button height.
Definition main.c:82
@ k_iu_grid_row0_y
Top row y of the 2x2 book grid.
Definition main.c:76
@ k_iu_toolbar_w
Toolbar-button width.
Definition main.c:81
@ k_iu_cell_w
Book-cell width.
Definition main.c:78
@ k_iu_grid_row1_y
Bottom row y of the 2x2 book grid.
Definition main.c:77
@ k_iu_cell_h
Book-cell height.
Definition main.c:79
@ k_iu_grid_col0_x
Left column x of the 2x2 book grid.
Definition main.c:74
@ k_iu_grid_col1_x
Right column x of the 2x2 book grid.
Definition main.c:75
static bool iu_tap(int32_t px, int32_t py, bool want_hit, uint16_t want_act, uint32_t *hits)
Hit-test a synthetic tap; verify hit-ness + the resolved action.
Definition main.c:152
static const uint8_t k_msg_nav[]
Definition main.c:103
static void iu_setup_or_halt(void)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
Definition main.c:204
static const uint8_t k_msg_failr[]
Definition main.c:105
iu_miss_pt_t
Off-target tap coordinates that must miss.
Definition main.c:63
@ k_iu_tap_half
Divisor for a rect's centre point.
Definition main.c:68
@ k_iu_miss_gutter_y
Mid-height of the first cell row.
Definition main.c:65
@ k_iu_miss_off_y
Far off-screen y.
Definition main.c:67
@ k_iu_miss_gutter_x
Column gutter (between cells 0 and 1).
Definition main.c:64
@ k_iu_miss_count
Number of off-target (miss) taps.
Definition main.c:69
@ k_iu_miss_off_x
Far off-screen x.
Definition main.c:66
static void iu_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
Definition main.c:108
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
Bounded UI interaction core: hit-testing, screen stack, paging.
ra8_err_t ra8_ui_nav_init(ra8_ui_nav_t *nav, uint16_t root_screen)
Initialise a navigation stack with a root screen.
Definition ra8_ui.c:71
ra8_err_t ra8_ui_nav_push(ra8_ui_nav_t *nav, uint16_t screen)
Push a new screen onto the stack.
Definition ra8_ui.c:79
ra8_err_t ra8_ui_nav_pop(ra8_ui_nav_t *nav, uint16_t *out_screen)
Pop the top screen, revealing the one beneath.
Definition ra8_ui.c:93
ra8_err_t ra8_ui_nav_top(const ra8_ui_nav_t *nav, uint16_t *out_screen)
Read the current (top) screen id.
Definition ra8_ui.c:115
ra8_err_t ra8_ui_hit_test(const ra8_ui_target_t *targets, uint16_t count, int32_t px, int32_t py, uint16_t *out_action, bool *out_hit)
Find the first tap target containing a point.
Definition ra8_ui.c:42
Fixed-depth screen-id stack (caller-owned).
Definition ra8_ui.h:163
Axis-aligned rectangle in framebuffer pixel coordinates.
Definition ra8_ui.h:72
int32_t w
Width (pixels, >= 0).
Definition ra8_ui.h:75
int32_t h
Height (pixels, >= 0).
Definition ra8_ui.h:76
int32_t x
Left edge (pixels).
Definition ra8_ui.h:73
int32_t y
Top edge (pixels).
Definition ra8_ui.h:74
One tap target: a rectangle bound to an opaque action id.
Definition ra8_ui.h:83