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_keyboard.h"
38#include "ra8_mstp.h"
39#include "ra8_time.h"
40#include "ra8_ui.h"
41
43typedef enum : int32_t {
44 k_kb_uart_baud = 115200,
47 k_kb_frame_w = 1024,
52
55
57static const char k_kb_word[] = "hi";
59static const char k_kb_expected[] = "Hi 9";
60
61static const uint8_t k_msg_boot[] = "keyboard-hil: boot\r\n";
62static const uint8_t k_msg_fail[] = "keyboard-hil: FAIL init\r\n";
63static const uint8_t k_msg_lay[] = "kbd: FAIL layout\r\n";
64static const uint8_t k_msg_miss[] = "kbd: FAIL mismatch\r\n";
65static const uint8_t k_msg_pre[] = "kbd: q=";
66static const uint8_t k_msg_mid[] = " commit=";
67static const uint8_t k_msg_taps[] = " taps=";
68static const uint8_t k_msg_ok[] = " PASS\r\n";
69
71static void kb_print(const uint8_t* msg, uint32_t len)
72{
73 (void)ra8_board_uart_console_write((msg), (size_t)(len));
74}
75
77static void kb_panic_halt(const uint8_t* msg, uint32_t len)
78{
79 kb_print(msg, len);
80 __asm__ volatile("bkpt #0");
81 while (1) {
82 __asm__ volatile("wfi");
83 }
84}
85
87static void kb_print_uint(uint32_t value)
88{
89 uint8_t buf[k_kb_dec_ten];
90 uint32_t n = 0U;
91 if (value == 0U) {
92 buf[n] = '0';
93 n++;
94 }
95 while ((value > 0U) && (n < (uint32_t)k_kb_dec_ten)) {
96 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_kb_dec_ten));
97 n++;
98 value /= (uint32_t)k_kb_dec_ten;
99 }
100 for (uint32_t i = 0U; i < n; i++) {
101 kb_print(&buf[n - 1U - i], 1U);
102 }
103}
104
106static uint8_t kb_key_of(char ch)
107{
108 for (uint8_t i = 0U; i < s_kb.count; i++) {
109 if ((s_kb.keys[i].kind == k_ra8_kbd_key_char) && (s_kb.keys[i].ch_lower == ch)) {
110 return i;
111 }
112 }
113 return (uint8_t)k_ra8_kbd_no_hit;
114}
115
118{
119 for (uint8_t i = 0U; i < s_kb.count; i++) {
120 if (s_kb.keys[i].kind == kind) {
121 return i;
122 }
123 }
124 return (uint8_t)k_ra8_kbd_no_hit;
125}
126
128static void kb_tap(ra8_kbd_text_t* t, uint8_t idx, uint32_t* taps)
129{
130 const ra8_ui_rect_t* r = &s_kb.keys[idx].rect;
131 const int32_t cx = r->x + (r->w / (int32_t)k_kb_half);
132 const int32_t cy = r->y + (r->h / (int32_t)k_kb_half);
133 const uint8_t hit = ra8_kbd_hit(&s_kb, cx, cy);
134 (void)ra8_kbd_apply(t, &s_kb, hit);
135 (*taps)++;
136}
137
139static void kb_setup_or_halt(void)
140{
141 uint32_t cpuclk0_hz = 0U;
142 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
143 kb_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
144 }
146 kb_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
147 }
148 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
149 kb_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
150 }
152 kb_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
153 }
154}
155
157static bool kb_streq(const char* a, const char* b)
158{
159 for (uint32_t i = 0U; i < (uint32_t)k_ra8_kbd_text_max; i++) {
160 if (a[i] != b[i]) {
161 return false;
162 }
163 if (a[i] == '\0') {
164 return true;
165 }
166 }
167 return false;
168}
169
178void main(void)
179{
182 kb_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
183
184 const ra8_ui_rect_t frame = {.x = k_kb_frame_x,
185 .y = k_kb_frame_y,
186 .w = k_kb_frame_w,
187 .h = k_kb_frame_h};
188 if (ra8_kbd_layout_init(&s_kb, &frame) != k_ra8_ok) {
189 kb_panic_halt(k_msg_lay, (uint32_t)sizeof(k_msg_lay) - 1U);
190 }
191
193 if (ra8_kbd_text_init(&t) != k_ra8_ok) {
194 kb_panic_halt(k_msg_lay, (uint32_t)sizeof(k_msg_lay) - 1U);
195 }
196
197 /* Type "Hi 9" -- exercises one-shot SHIFT (caps), SPACE, and the 123 layer
198 * toggle to reach a digit, then commits with RETURN. */
199 uint32_t taps = 0U;
200 kb_tap(&t, kb_key_of_kind(k_ra8_kbd_key_shift), &taps); /* -> capitalise next */
201 for (uint32_t i = 0U; i < (uint32_t)(sizeof(k_kb_word) - 1U); i++) {
202 kb_tap(&t, kb_key_of(k_kb_word[i]), &taps); /* h -> H (one-shot), then i */
203 }
205 kb_tap(&t, kb_key_of_kind(k_ra8_kbd_key_layer), &taps); /* 123 -> numbers layer */
206 kb_tap(&t, kb_key_of('9'), &taps); /* digit, now reachable */
207 kb_tap(&t, kb_key_of_kind(k_ra8_kbd_key_enter), &taps); /* RETURN commits */
208
209 if (!kb_streq(t.buf, k_kb_expected) || !t.committed) {
210 kb_panic_halt(k_msg_miss, (uint32_t)sizeof(k_msg_miss) - 1U);
211 }
212
213 kb_print(k_msg_pre, (uint32_t)sizeof(k_msg_pre) - 1U);
214 kb_print((const uint8_t*)t.buf, (uint32_t)t.len);
215 kb_print(k_msg_mid, (uint32_t)sizeof(k_msg_mid) - 1U);
216 kb_print_uint((uint32_t)(t.committed ? 1U : 0U));
217 kb_print(k_msg_taps, (uint32_t)sizeof(k_msg_taps) - 1U);
218 kb_print_uint(taps);
219 kb_print(k_msg_ok, (uint32_t)sizeof(k_msg_ok) - 1U);
220
221 while (1) {
222 __asm__ volatile("wfi");
223 }
224}
void main(void)
Secure fallback main entry point.
Definition main.c:37
ra8_kbd_layout_t s_kb
On-screen keyboard grid.
Definition main.c:223
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 const uint8_t k_msg_miss[]
Console banner fragment: cache miss counter label.
Definition main.c:288
static const uint8_t k_msg_mid[]
Definition main.c:93
static void kb_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
Definition main.c:71
static void kb_tap(ra8_kbd_text_t *t, uint8_t idx, uint32_t *taps)
Tap key idx's centre through hit-test + apply; count the tap.
Definition main.c:128
static void kb_panic_halt(const uint8_t *msg, uint32_t len)
Print the fail banner and trap (ra8_emulator halts on the BKPT).
Definition main.c:77
static bool kb_streq(const char *a, const char *b)
Compare two NUL-terminated strings for equality.
Definition main.c:157
static uint8_t kb_key_of_kind(ra8_kbd_key_kind_t kind)
Find the first key of a non-char kind, or k_ra8_kbd_no_hit.
Definition main.c:117
static const uint8_t k_msg_taps[]
Definition main.c:67
static const char k_kb_expected[]
Expected query after the SHIFT / SPACE / 123-layer / digit sequence.
Definition main.c:59
static void kb_setup_or_halt(void)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
Definition main.c:139
static const uint8_t k_msg_lay[]
Definition main.c:63
static const char k_kb_word[]
Lowercase letters typed (with SHIFT before the first) -> "Hi".
Definition main.c:57
static uint8_t kb_key_of(char ch)
Find the key index of printable ch, or k_ra8_kbd_no_hit.
Definition main.c:106
static void kb_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
Definition main.c:87
kb_consts_t
Console / frame knobs (no magic numbers).
Definition main.c:43
@ k_kb_frame_w
Keyboard frame: width.
Definition main.c:47
@ k_kb_dec_ten
Decimal radix / small-buf cap.
Definition main.c:50
@ k_kb_half
Centre divisor.
Definition main.c:49
@ k_kb_frame_h
Keyboard frame: height.
Definition main.c:48
@ k_kb_uart_baud
Console baud.
Definition main.c:44
@ k_kb_frame_x
Keyboard frame: left.
Definition main.c:45
@ k_kb_frame_y
Keyboard frame: top (lower panel).
Definition main.c:46
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
On-screen keyboard widget – iOS-style layers, shift, hit-test.
uint8_t ra8_kbd_hit(const ra8_kbd_layout_t *kb, int32_t px, int32_t py)
Map a tap to a key index.
ra8_err_t ra8_kbd_text_init(ra8_kbd_text_t *t)
Reset a text buffer to empty / uncommitted.
ra8_err_t ra8_kbd_apply(ra8_kbd_text_t *t, ra8_kbd_layout_t *kb, uint8_t key_idx)
Apply key key_idx to the text buffer, SHIFT, and active layer.
ra8_kbd_key_kind_t
What a key does when tapped.
@ k_ra8_kbd_key_space
Append a space.
@ k_ra8_kbd_key_layer
Switch to the layer in aux.
@ k_ra8_kbd_key_enter
Commit the query (RETURN).
@ k_ra8_kbd_key_char
Append the shift-correct char.
@ k_ra8_kbd_key_shift
Toggle the one-shot SHIFT.
ra8_err_t ra8_kbd_layout_init(ra8_kbd_layout_t *kb, const ra8_ui_rect_t *frame)
Lay the letters layer into frame; clear SHIFT.
@ k_ra8_kbd_no_hit
ra8_kbd_hit "no key" sentinel.
@ k_ra8_kbd_text_max
Text buffer capacity incl.
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.
The key grid for the active layer, plus SHIFT / layer / frame state.
The typed query buffer + commit state.
char buf[k_ra8_kbd_text_max]
NUL-terminated query.
uint8_t len
Chars before the NUL.
bool committed
RETURN was applied.
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