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
55
56#include <stddef.h>
57#include <stdint.h>
58
59#include "ra8_board_ek_ra8d2.h"
60#include "ra8_boot_entry.h"
61#include "ra8_cgc.h"
62#include "ra8_err.h"
63#include "ra8_eth.h"
64#include "ra8_isr.h"
65#include "ra8_log.h"
66#include "ra8_mstp.h"
67#include "ra8_time.h"
68
70typedef enum : uint32_t {
71 k_eop_uart_baud = 115200U,
79
107typedef enum : uint32_t {
108 k_eop_pad_bytes = RA8_ETH_PROBE_PAD_BYTES,
109} eop_pad_t;
110
111static_assert((k_eop_pad_bytes % 16U) == 0U, "pad must be a multiple of 16");
112static_assert(k_eop_pad_bytes >= 16U, "pad must be non-empty");
113
130[[gnu::section(".bss")]] static volatile uint8_t s_eop_bss_pad[k_eop_pad_bytes];
131
133typedef enum : uint8_t {
134 k_eop_mac_0 = 0x02U,
135 k_eop_mac_1 = 0x00U,
136 k_eop_mac_2 = 0x00U,
137 k_eop_mac_3 = 0x00U,
138 k_eop_mac_4 = 0x00U,
139 k_eop_mac_5 = 0x01U,
140} eop_mac_t;
141
142static const uint8_t k_eop_msg_boot[] = "eth-open-probe: boot\r\n";
143static const uint8_t k_eop_msg_clock[] = "eth-open-probe: cpuclk0=";
144static const uint8_t k_eop_msg_pad[] = " bss_pad=";
145static const uint8_t k_eop_msg_padlen[] = " pad_bytes=";
146static const uint8_t k_eop_msg_board[] = "eth-open-probe: board_eth rc=";
147static const uint8_t k_eop_msg_opening[] = "eth-open-probe: calling ra8_eth_open ch=1\r\n";
148static const uint8_t k_eop_msg_open_rc[] = "eth-open-probe: eth_open rc=";
149static const uint8_t k_eop_msg_pass[] = "eth-open-probe: PASS\r\n";
150static const uint8_t k_eop_msg_fail[] = "eth-open-probe: FAIL\r\n";
151static const uint8_t k_eop_msg_hw_fail[] = "eth-open-probe: hw_init_failed\r\n";
152static const uint8_t k_eop_msg_newline[] = "\r\n";
153static const uint8_t k_eop_hex_digits[] = "0123456789ABCDEF";
154static const uint8_t k_eop_msg_hex_lead[] = "0x";
155
173static void eop_print(const uint8_t* msg, uint32_t len)
174{
175 (void)ra8_board_uart_console_write(msg, (size_t)len);
176}
177
199static void eop_log_sink(void* ctx, uint8_t byte)
200{
201 (void)ctx;
202 (void)ra8_board_uart_console_write(&byte, 1U);
203}
204
221static void eop_print_hex(uint32_t value)
222{
223 eop_print(k_eop_msg_hex_lead, (uint32_t)sizeof(k_eop_msg_hex_lead) - 1U);
224 for (uint32_t i = 0U; i < (uint32_t)k_eop_hex_chars; i++) {
225 const uint32_t shift = ((uint32_t)k_eop_hex_chars - 1U - i) * (uint32_t)k_eop_hex_shift;
226 const uint32_t digit = (value >> shift) & (uint32_t)k_eop_hex_mask;
227 eop_print(&k_eop_hex_digits[digit], 1U);
228 }
229}
230
247static void eop_print_uint(uint32_t value)
248{
249 uint8_t buf[k_eop_dec_max];
250 uint32_t n = 0U;
251 if (value == 0U) {
252 buf[n] = (uint8_t)'0';
253 n++;
254 }
255 while ((value > 0U) && (n < (uint32_t)k_eop_dec_max)) {
256 buf[n] = (uint8_t)((uint32_t)'0' + (value % (uint32_t)k_eop_dec_base));
257 n++;
258 value /= (uint32_t)k_eop_dec_base;
259 }
260 for (uint32_t i = 0U; i < n; i++) {
261 eop_print(&buf[n - 1U - i], 1U);
262 }
263}
264
287static uint32_t eop_bss_pad_anchor(void)
288{
289 enum : uint8_t {
290 k_eop_pad_probe_idx = 0U,
291 k_eop_pad_probe_byte = 0xA5U,
292 };
293 s_eop_bss_pad[k_eop_pad_probe_idx] = (uint8_t)k_eop_pad_probe_byte;
294 return (uint32_t)(uintptr_t)&s_eop_bss_pad[k_eop_pad_probe_idx];
295}
296
311[[noreturn]] static void eop_panic_halt(void)
312{
313 eop_print(k_eop_msg_hw_fail, (uint32_t)sizeof(k_eop_msg_hw_fail) - 1U);
314 __asm__ volatile("bkpt #0");
315 while (1) {
316 __asm__ volatile("wfi");
317 }
318}
319
338static void eop_setup_or_halt(uint32_t* out_cpuclk_hz)
339{
340 uint32_t cpuclk0_hz = 0U;
341 if (ra8_cgc_init() != k_ra8_ok) {
343 }
346 }
347 if (ra8_mstp_init() != k_ra8_ok) {
349 }
350 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
352 }
355 }
356 *out_cpuclk_hz = cpuclk0_hz;
357}
358
391[[nodiscard]] static ra8_err_t eop_run_once(void)
392{
393 const ra8_err_t board_rc = ra8_board_ethernet_init();
394 eop_print(k_eop_msg_board, (uint32_t)sizeof(k_eop_msg_board) - 1U);
395 eop_print_uint((uint32_t)board_rc);
396 eop_print(k_eop_msg_newline, (uint32_t)sizeof(k_eop_msg_newline) - 1U);
397 if (board_rc != k_ra8_ok) {
398 return board_rc;
399 }
400
401 const ra8_eth_cfg_t cfg = {
402 .mac_address = {(uint8_t)k_eop_mac_0,
403 (uint8_t)k_eop_mac_1,
404 (uint8_t)k_eop_mac_2,
405 (uint8_t)k_eop_mac_3,
406 (uint8_t)k_eop_mac_4,
407 (uint8_t)k_eop_mac_5},
408 .channel = (uint8_t)k_eop_channel,
409 .num_tx_descriptors = 0U,
410 .num_rx_descriptors = 0U,
411 .buffer_size = 0U,
412 };
413
414 eop_print(k_eop_msg_opening, (uint32_t)sizeof(k_eop_msg_opening) - 1U);
415 const ra8_err_t open_rc = ra8_eth_open(&cfg);
416 eop_print(k_eop_msg_open_rc, (uint32_t)sizeof(k_eop_msg_open_rc) - 1U);
417 eop_print_uint((uint32_t)open_rc);
418 eop_print(k_eop_msg_newline, (uint32_t)sizeof(k_eop_msg_newline) - 1U);
419 return open_rc;
420}
421
422void main(void)
423{
424 uint32_t cpuclk0_hz = 0U;
425 eop_setup_or_halt(&cpuclk0_hz);
427
428 /* Route the shared fault decoder's ra8_log dump onto the bench
429 * console before anything that can fault runs. */
431
432 eop_print(k_eop_msg_boot, (uint32_t)sizeof(k_eop_msg_boot) - 1U);
433 eop_print(k_eop_msg_clock, (uint32_t)sizeof(k_eop_msg_clock) - 1U);
434 eop_print_hex(cpuclk0_hz);
435 eop_print(k_eop_msg_pad, (uint32_t)sizeof(k_eop_msg_pad) - 1U);
437 eop_print(k_eop_msg_padlen, (uint32_t)sizeof(k_eop_msg_padlen) - 1U);
439 eop_print(k_eop_msg_newline, (uint32_t)sizeof(k_eop_msg_newline) - 1U);
440
441 if (eop_run_once() != k_ra8_ok) {
442 eop_print(k_eop_msg_fail, (uint32_t)sizeof(k_eop_msg_fail) - 1U);
443 } else {
444 eop_print(k_eop_msg_pass, (uint32_t)sizeof(k_eop_msg_pass) - 1U);
445 }
446
447 while (1) {
448 __asm__ volatile("wfi");
449 }
450}
void main(void)
Secure fallback main entry point.
Definition main.c:37
eop_mac_t
Locally-administered MAC the probe opens with.
Definition main.c:133
@ k_eop_mac_2
Octet 2.
Definition main.c:136
@ k_eop_mac_5
Octet 5.
Definition main.c:139
@ k_eop_mac_3
Octet 3.
Definition main.c:137
@ k_eop_mac_0
Octet 0 – locally administered, unicast.
Definition main.c:134
@ k_eop_mac_1
Octet 1.
Definition main.c:135
@ k_eop_mac_4
Octet 4.
Definition main.c:138
eop_pad_t
Size of the leading .bss pad that steers where the HAL's Ethernet statics land in SRAM.
Definition main.c:107
@ k_eop_pad_bytes
Leading .bss pad, bytes.
Definition main.c:108
static void eop_print(const uint8_t *msg, uint32_t len)
Push bytes at the SCI8 console, discarding the write status.
Definition main.c:173
static const uint8_t k_eop_msg_open_rc[]
Definition main.c:148
static void eop_print_hex(uint32_t value)
Print a 32-bit value as 0x + eight upper-case hex digits.
Definition main.c:221
static void eop_setup_or_halt(uint32_t *out_cpuclk_hz)
Bring up clocks, MSTP, SysTick and the SCI8 console; halt on failure.
Definition main.c:338
static void eop_print_uint(uint32_t value)
Print an unsigned 32-bit value in decimal.
Definition main.c:247
static void eop_log_sink(void *ctx, uint8_t byte)
ra8_log byte sink forwarding every log byte to the console.
Definition main.c:199
static ra8_err_t eop_run_once(void)
Run the board Ethernet bring-up and the one ra8_eth_open call.
Definition main.c:391
static const uint8_t k_eop_msg_padlen[]
Definition main.c:145
static uint32_t eop_bss_pad_anchor(void)
Touch s_eop_bss_pad and report where it starts.
Definition main.c:287
static const uint8_t k_eop_msg_board[]
Definition main.c:146
static const uint8_t k_eop_msg_hw_fail[]
Definition main.c:151
static const uint8_t k_eop_msg_hex_lead[]
Definition main.c:154
static const uint8_t k_eop_msg_fail[]
Definition main.c:150
static const uint8_t k_eop_msg_pass[]
Definition main.c:149
static const uint8_t k_eop_msg_newline[]
Definition main.c:152
static const uint8_t k_eop_msg_opening[]
Definition main.c:147
eop_consts_t
Console + probe knobs (no magic numbers).
Definition main.c:70
@ k_eop_hex_mask
Nibble mask for one hex digit.
Definition main.c:75
@ k_eop_hex_shift
Bits consumed per emitted hex digit.
Definition main.c:74
@ k_eop_dec_max
Digits in the widest uint32 (4294967295).
Definition main.c:77
@ k_eop_hex_chars
Hex digits printed per 32-bit value.
Definition main.c:73
@ k_eop_uart_baud
SCI8 J-Link VCOM console baud.
Definition main.c:71
@ k_eop_channel
EK-RA8D2 RJ45 is ETHA1 / RMAC1.
Definition main.c:72
@ k_eop_dec_base
Decimal base for the status-code printer.
Definition main.c:76
static const uint8_t k_eop_hex_digits[]
Definition main.c:153
static const uint8_t k_eop_msg_boot[]
Definition main.c:142
static volatile uint8_t s_eop_bss_pad[k_eop_pad_bytes]
Leading .bss filler that positions every library static behind it.
Definition main.c:130
static void eop_panic_halt(void)
Print the negative banner and park the CPU.
Definition main.c:311
static const uint8_t k_eop_msg_clock[]
Definition main.c:143
static const uint8_t k_eop_msg_pad[]
Definition main.c:144
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_ethernet_init(void)
Bring up the on-board RGMII Ethernet PHY and RMAC1/ETHA1.
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
Ethernet Switch Module (ESWM) + frame TX/RX driver.
ra8_err_t ra8_eth_open(const ra8_eth_cfg_t *cfg)
Open the NIC: bring up the controller stack and the descriptor rings.
Definition ra8_eth.c:756
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
Lightweight Logging Interface for ra8-firmware.
void ra8_log_set_byte_sink(ra8_log_byte_sink_fn_t fn, void *ctx)
Install (or clear) an optional byte sink for log output.
Definition ra8_log.c:56
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
Per-channel NIC configuration.
Definition ra8_eth.h:228