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
50
51#include <stddef.h>
52#include <stdint.h>
53#include <string.h>
54
55#include "ra8_attributes.h"
56#include "ra8_boot_entry.h"
57#include "ra8_cgc.h"
58#include "ra8_check.h"
59#include "ra8_err.h"
60#include "ra8_io.h"
61#include "ra8_log.h"
62#include "ra8_port_constants.h"
63#include "ra8_port_utils.h"
64#include "ra8_sci.h"
65#include "ra8_time.h"
66#include "ra8_xspi.h"
67
92
103typedef enum : uint32_t {
108
124typedef struct {
126 const char* name;
127 const char* label;
128 const char* file;
130
139 (ra8_port_pin_t)(((uint16_t)k_ra8_port_13 << (uint16_t)k_swap_pin_shift) | (uint16_t)k_ra8_pin_2);
148 (ra8_port_pin_t)(((uint16_t)k_ra8_port_13 << (uint16_t)k_swap_pin_shift) | (uint16_t)k_ra8_pin_3);
149
160
168
170static uint8_t s_payload[k_swap_payload];
172
174static const char* const s_tag = "ra8_io_swap_demo";
175
195RA8_INTERNAL static void internal_swap_uart_print(const char* msg)
196{
197 (void)ra8_io_stream_puts(&s_uart, msg);
198}
199
219RA8_INTERNAL static void internal_swap_fill(uint32_t len)
220{
221 for (uint32_t i = 0U; i < len; ++i) {
222 s_payload[i] = (uint8_t)(((i * (uint32_t)k_swap_pat_mul) + (uint32_t)k_swap_pat_add) ^
223 (uint32_t)k_swap_pat_xor);
224 }
225}
226
250RA8_INTERNAL static ra8_err_t internal_swap_vfs_write(const char* path, uint32_t len)
251{
252 RA8_CHECK_NULL_PTR(path, s_tag, "path");
254
255 ra8_fs_file_t* wf = nullptr;
257 const ra8_err_t werr = ra8_fs_write(wf, s_payload, len);
258 RA8_RETURN_ON_ERROR(ra8_fs_close(wf), s_tag, "close w");
259 return werr;
260}
261
287RA8_INTERNAL static ra8_err_t internal_swap_vfs_read_verify(const char* path, uint32_t len)
288{
289 RA8_CHECK_NULL_PTR(path, s_tag, "path");
291
292 ra8_fs_file_t* rf = nullptr;
294 (void)memset(s_readback, 0, sizeof(s_readback));
295 uint32_t got = 0U;
296 const ra8_err_t rerr = ra8_fs_read(rf, s_readback, len, &got);
297 RA8_RETURN_ON_ERROR(ra8_fs_close(rf), s_tag, "close r");
298 RA8_RETURN_ON_ERROR(rerr, s_tag, "read");
299 if ((got != len) || (memcmp(s_payload, s_readback, (size_t)len) != 0)) {
301 }
302 return k_ra8_ok;
303}
304
335{
336 RA8_CHECK_NULL_PTR(b, s_tag, "backend");
337 RA8_CHECK_NULL_PTR(log, s_tag, "log");
338
339 (void)ra8_io_stream_puts(log, "swap[");
340 (void)ra8_io_stream_puts(log, b->name);
341 (void)ra8_io_stream_puts(log, "]: mount ");
342 (void)ra8_io_stream_puts(log, b->label);
344 ra8_fs_format_opts_t opts = {};
346 opts.label = b->label;
347 RA8_RETURN_ON_ERROR(ra8_fs_format(&s_be, &opts), s_tag, "format");
348 ra8_fs_mount_t* mnt = nullptr;
349 RA8_RETURN_ON_ERROR(ra8_fs_mount(&s_be, &mnt), s_tag, "mount");
350 RA8_RETURN_ON_ERROR(ra8_io_vfs_mount(b->name, mnt), s_tag, "vfs mount");
351
353 RA8_RETURN_ON_ERROR(internal_swap_vfs_write(b->file, len), s_tag, "write");
355
356 RA8_RETURN_ON_ERROR(ra8_io_vfs_unmount(b->name), s_tag, "vfs unmount");
357 RA8_RETURN_ON_ERROR(ra8_fs_unmount(mnt), s_tag, "unmount");
358 (void)ra8_io_stream_puts(log, " -> ");
359 (void)ra8_io_stream_put_u32(log, len);
360 (void)ra8_io_stream_puts(log, " bytes ok\r\n");
361 return k_ra8_ok;
362}
363
388{
389 RA8_CHECK_NULL_PTR(out_used, s_tag, "out_used");
390 RA8_VALIDATE_INIT(s_ram_log_state.buf != nullptr, s_tag, "ram log");
391
392 uint32_t used = 0U;
394 internal_swap_uart_print("ra8_io_swap_demo: --- ram-captured stdio ---\r\n");
396 internal_swap_uart_print("ra8_io_swap_demo: --- end capture ---\r\n");
397 *out_used = used;
398 return k_ra8_ok;
399}
400
424RA8_INTERNAL static ra8_err_t internal_swap_run_all(const char** out_failed)
425{
426 RA8_CHECK_NULL_PTR(out_failed, s_tag, "out_failed");
427 *out_failed = nullptr;
428
432 (uint32_t)k_swap_ram_blocks,
433 false),
434 s_tag,
435 "ram bind");
437 s_tag,
438 "xspi init");
441 (uint8_t)k_swap_xspi_inst,
442 (uint32_t)k_swap_xspi_base,
443 (uint32_t)k_swap_xspi_blocks,
444 false),
445 s_tag,
446 "xspi bind");
447
448 const swap_backend_t table[k_swap_backends] = {
449 {.bd = &s_ram_bd, .name = "ram", .label = "RAIORAM", .file = "ram:/DATA.BIN"},
450 {.bd = &s_xspi_bd, .name = "xs", .label = "RAIOXS", .file = "xs:/DATA.BIN"},
451 };
452
453 for (uint32_t i = 0U; i < (uint32_t)k_swap_backends; ++i) {
454 const ra8_err_t e = internal_swap_run_one(&table[i], (uint32_t)k_swap_payload, &s_ram_log);
455 if (e != k_ra8_ok) {
456 *out_failed = table[i].name;
457 return e;
458 }
459 }
460 return k_ra8_ok;
461}
462
482{
483 uint32_t cpuclk0_hz = 0U;
484 uint32_t pclka_hz = 0U;
485 if ((ra8_cgc_init() != k_ra8_ok) ||
488 (ra8_time_init(cpuclk0_hz) != k_ra8_ok) ||
491 while (true) {
492 }
493 }
494 const ra8_sci_cfg_t sci_cfg = {.baud = (uint32_t)k_swap_uart_baud,
495 .data_bits = k_ra8_sci_data_8,
496 .parity = k_ra8_sci_parity_none,
497 .stop_bits = k_ra8_sci_stop_1,
498 .pclk_hz = pclka_hz};
499 if (ra8_sci_init((uint8_t)k_swap_uart_chan, &sci_cfg) != k_ra8_ok) {
500 while (true) {
501 }
502 }
503}
504
521void main(void)
522{
523 ra8_log_init();
526 (void)ra8_io_log_attach(&s_uart); /* route ra8_log errors onto the UART too */
527 internal_swap_uart_print("ra8_io_swap_demo: boot\r\n");
528
529 /* Retarget the engine's stdio into the in-RAM capture sink. */
530 (void)
532
533 const char* failed = nullptr;
534 const ra8_err_t swap_e = internal_swap_run_all(&failed);
535
536 uint32_t captured = 0U;
537 const ra8_err_t rep_e = internal_swap_replay_capture(&captured);
538
539 if (swap_e == k_ra8_ok) {
540 internal_swap_uart_print("ra8_io_swap_demo: two-backend swap (ram + xs) PASS\r\n");
541 } else if (failed != nullptr) {
542 internal_swap_uart_print("ra8_io_swap_demo: backend ");
544 internal_swap_uart_print(" FAIL\r\n");
545 } else {
546 internal_swap_uart_print("ra8_io_swap_demo: swap FAIL\r\n");
547 }
548
549 if ((rep_e == k_ra8_ok) && (captured > 0U)) {
550 internal_swap_uart_print("ra8_io_swap_demo: ram-stream capture ");
551 (void)ra8_io_stream_put_u32(&s_uart, captured);
552 internal_swap_uart_print(" bytes PASS\r\n");
553 } else {
554 internal_swap_uart_print("ra8_io_swap_demo: ram-stream capture FAIL\r\n");
555 }
556
557 (void)ra8_sci_flush((uint8_t)k_swap_uart_chan);
558 while (true) {
559 }
560}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static void internal_demo_setup_or_halt(void)
Bring CGC + the J-Link OB VCOM console + on-board Ethernet + RSIP up.
Definition main.c:285
static uint8_t s_payload[(size_t) k_demo_payload]
Original payload, compressed-blob staging, and the inflated copy.
Definition main.c:92
static ra8_io_stream_t s_uart
UART output stream + its sink state.
Definition main.c:88
static ra8_fs_backend_t s_be
ra8_fs backend bridged onto the cached block device.
Definition main.c:71
static ra8_io_blockdev_ram_state_t s_ram_state
Definition main.c:154
static ra8_err_t internal_swap_vfs_write(const char *path, uint32_t len)
Open a VFS path for writing, write len bytes, and close it.
Definition main.c:250
static ra8_io_stream_ram_state_t s_ram_log_state
Definition main.c:166
static const ra8_port_pin_t s_swap_rxd
SCI8 console receive pin, PD03.
Definition main.c:147
static ra8_err_t internal_swap_vfs_read_verify(const char *path, uint32_t len)
Re-open a VFS path for reading and byte-compare against s_payload.
Definition main.c:287
static ra8_io_stream_t s_ram_log
In-RAM stdio capture stream + its sink state and backing buffer.
Definition main.c:165
static uint8_t s_ram_disk[(size_t) k_swap_ram_blocks *(size_t) k_ra8_io_block_size_bytes]
128 KiB RAM-disk backing buffer (in SRAM .bss).
Definition main.c:151
static ra8_io_blockdev_t s_xspi_bd
xSPI (OSPI NOR) block-device handle + its backend state.
Definition main.c:156
static void internal_swap_uart_print(const char *msg)
Print a NUL-terminated string on the UART console stream.
Definition main.c:195
static uint8_t s_ram_log_buf[k_swap_log_cap]
Definition main.c:167
swap_pattern_t
Deterministic payload-pattern coefficients (no magic numbers).
Definition main.c:103
@ k_swap_pat_xor
Linear pattern XOR mask.
Definition main.c:106
@ k_swap_pat_add
Linear pattern additive bias.
Definition main.c:105
@ k_swap_pat_mul
Linear pattern multiplier.
Definition main.c:104
swap_const_t
Console, volume, and payload knobs (no magic numbers).
Definition main.c:80
@ k_swap_log_cap
RAM stdio-capture buffer capacity.
Definition main.c:89
@ k_swap_backends
Number of block-device backends swapped.
Definition main.c:90
@ k_swap_xspi_inst
xSPI controller instance index.
Definition main.c:85
@ k_swap_payload
Bytes written + read back per backend.
Definition main.c:88
@ k_swap_uart_chan
SCI8 J-Link OB console.
Definition main.c:81
@ k_swap_xspi_blocks
256 KiB OSPI NOR window (FAT12).
Definition main.c:87
@ k_swap_uart_baud
Console baud.
Definition main.c:82
@ k_swap_pin_shift
Port byte position in ra8_port_pin_t.
Definition main.c:83
@ k_swap_ram_blocks
128 KiB in-SRAM RAM disk (FAT12).
Definition main.c:84
@ k_swap_xspi_base
Flash byte offset of logical block 0.
Definition main.c:86
static ra8_err_t internal_swap_run_all(const char **out_failed)
Bind both block-device backends and run the swap over the table.
Definition main.c:424
static ra8_err_t internal_swap_replay_capture(uint32_t *out_used)
Replay the RAM-captured stdio out of the UART console.
Definition main.c:387
static ra8_io_stream_uart_state_t s_uart_state
Definition main.c:163
static void internal_swap_fill(uint32_t len)
Fill s_payload with the deterministic linear byte pattern.
Definition main.c:219
static const ra8_port_pin_t s_swap_txd
SCI8 console transmit pin, PD02.
Definition main.c:138
static ra8_err_t internal_swap_run_one(const swap_backend_t *b, uint32_t len, ra8_io_stream_t *log)
Run the identical FAT/VFS round-trip over one pre-bound block device.
Definition main.c:334
static ra8_io_blockdev_t s_ram_bd
RAM block-device handle + its backend state.
Definition main.c:153
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
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
@ k_ra8_clock_id_pclka
PCLKA.
Definition ra8_cgc.h:73
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_VALIDATE_INIT(initialized, tag, message)
Precondition: module must be initialized.
Definition ra8_check.h:334
#define RA8_CHECK_RANGE_TAG(value, min, max, errcode, tag)
Tagged range check (adds a component tag to the log line).
Definition ra8_check.h:311
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_checksum_mismatch
Stored / transmitted checksum does not match computed value.
Definition ra8_err.h:465
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
int memcmp(const void *a, const void *b, size_t n)
Compare bytes in two memory areas.
ra8_err_t ra8_fs_format(const ra8_fs_backend_t *backend, const ra8_fs_format_opts_t *opts)
Format a block device as a fresh, empty FAT12/FAT16/FAT32/exFAT volume.
ra8_err_t ra8_fs_write(ra8_fs_file_t *file, const uint8_t *buf, uint32_t len)
Write len bytes; allocate new clusters from FAT free-space scan as needed.
ra8_err_t ra8_fs_mount(const ra8_fs_backend_t *backend, ra8_fs_mount_t **out_handle)
Mount a FAT volume from a block-device backend, auto-selecting the first partition.
ra8_err_t ra8_fs_read(ra8_fs_file_t *file, uint8_t *buf, uint32_t max_len, uint32_t *got_len)
Read up to max_len bytes; advance the cluster chain on cluster crossings.
ra8_err_t ra8_fs_unmount(ra8_fs_mount_t *handle)
Unmount a previously mounted volume and release its slot.
ra8_err_t ra8_fs_close(ra8_fs_file_t *file)
Close an open file, stamping its final modification time.
@ k_ra8_fs_type_fat12
count_of_clusters < 4085.
@ k_ra8_fs_mode_read
Read-only, must exist.
@ k_ra8_fs_mode_write
Truncate (or create) for writing.
@ k_ra8_psel_sci_async
00100b: SCI async serial (UART).
ra8_io – unified peripheral-agnostic I/O fabric (umbrella header).
@ k_ra8_io_block_size_bytes
Bytes per logical block (the only size).
ra8_err_t ra8_io_blockdev_as_fs_backend(const ra8_io_blockdev_t *bd, ra8_fs_backend_t *out)
Expose a bound block device as an ra8_fs_backend_t for ra8_fs.
ra8_err_t ra8_io_blockdev_ram_init(ra8_io_blockdev_t *bd, ra8_io_blockdev_ram_state_t *state, uint8_t *storage, uint32_t block_count, bool read_only)
Bind a RAM block-device backend into a caller-owned handle.
ra8_err_t ra8_io_blockdev_xspi_init(ra8_io_blockdev_t *bd, ra8_io_blockdev_xspi_state_t *state, uint8_t instance, uint32_t base_off, uint32_t block_count, bool read_only)
Bind an OSPI NOR block-device backend into a caller-owned handle.
static uint8_t s_readback[k_ra8_io_roundtrip_max_payload]
ra8_err_t ra8_io_log_attach(ra8_io_stream_t *s)
Route ra8_log output to a bound ra8_io stream.
Definition ra8_io_log.c:61
ra8_err_t ra8_io_stream_write(ra8_io_stream_t *s, const uint8_t *buf, uint32_t len, uint32_t *out_written)
Write len bytes to the bound sink.
ra8_err_t ra8_io_stream_puts(ra8_io_stream_t *s, const char *str)
Write a NUL-terminated string (without the NUL) to the bound sink.
ra8_err_t ra8_io_stream_put_u32(ra8_io_stream_t *s, uint32_t value)
Write value as unsigned decimal ASCII (no leading zeros).
ra8_err_t ra8_io_stream_ram_used(const ra8_io_stream_ram_state_t *state, uint32_t *out_used)
Report how many bytes have been captured into the RAM sink.
ra8_err_t ra8_io_stream_ram_init(ra8_io_stream_t *s, ra8_io_stream_ram_state_t *state, uint8_t *buf, uint32_t cap)
Bind a RAM stream sink into a caller-owned stream handle.
ra8_err_t ra8_io_stream_uart_init(ra8_io_stream_t *s, ra8_io_stream_uart_state_t *state, uint8_t channel)
Bind a UART stream sink into a caller-owned stream handle.
ra8_err_t ra8_io_vfs_mount(const char *name, ra8_fs_mount_t *mount)
Register a mounted volume under a name.
Definition ra8_io_vfs.c:418
ra8_err_t ra8_io_vfs_open(const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file)
Open a file by "name:/path".
Definition ra8_io_vfs.c:547
ra8_err_t ra8_io_vfs_unmount(const char *name)
Remove a named mount from the table.
Definition ra8_io_vfs.c:490
Lightweight Logging Interface for ra8-firmware.
void ra8_log_init(void)
Initialise the logging backend.
Definition ra8_log.c:379
@ k_ra8_xspi_lio_1s1s1s
1S-1S-1S extended SPI.
Typed Port / Pin Constants for the RA8D2 IOPORT Module.
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
@ k_ra8_port_13
RA8 port 13.
@ k_ra8_pin_2
RA8 pin 2.
@ k_ra8_pin_3
RA8 pin 3.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_pfs_route_peripheral(ra8_port_pin_t pin, ra8_psel_t psel, const char *owner)
Route a pin to a non-IRQ peripheral function via PFS.PSEL.
Definition gpio.c:238
Full-featured Serial Communications Interface driver.
@ k_ra8_sci_stop_1
RA8 SCI stop 1.
Definition ra8_sci.h:81
@ k_ra8_sci_parity_none
RA8 SCI parity none.
Definition ra8_sci.h:71
ra8_err_t ra8_sci_init(uint8_t channel, const ra8_sci_cfg_t *cfg)
Initialise an SCI channel using the descriptor.
Definition ra8_sci.c:410
@ k_ra8_sci_data_8
RA8 SCI data 8.
Definition ra8_sci.h:91
ra8_err_t ra8_sci_flush(uint8_t channel)
Block until the channel's transmit shift register is empty.
Definition ra8_sci.c:543
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
static ra8_xspi_state_t s_xspi_state[k_ra8_xspi_instance_count]
Per-instance callback state (s_ prefix for file-static).
Definition ra8_xspi.c:447
xSPI / Octo-SPI driver (flash read/program/erase + ID/status)
ra8_err_t ra8_xspi_init(uint8_t instance, ra8_xspi_lio_mode_t mode)
Initialise an xSPI instance in the chosen link-layer IO mode.
Definition ra8_xspi.c:372
Block-device interface that ra8_fs runs on top of.
Open-file state.
Tunables for ra8_fs_format() (the on-disk geometry of a fresh volume).
ra8_fs_type_t type
FAT variant to lay down (12/16/32).
const char * label
0..11 char volume label, or NULL.
Cached parse of one mounted FAT volume.
Caller-owned private state for a RAM block device.
Caller-allocated block-device handle binding a backend to its context.
Caller-owned private state for an OSPI NOR block device.
Caller-owned private state for a RAM stream sink.
Caller-allocated byte-stream handle binding a sink to its context.
Caller-owned private state for a UART stream sink.
Configuration descriptor for ra8_sci_init.
Definition ra8_sci.h:103
One row of the drop-in block-device swap table.
Definition main.c:124
ra8_io_blockdev_t * bd
Pre-bound block-device handle (RAM or xSPI).
Definition main.c:125
const char * label
11-char-max FAT volume label literal.
Definition main.c:127
const char * name
VFS volume name, e.g.
Definition main.c:126
const char * file
Full "<name>:/DATA.BIN" VFS path.
Definition main.c:128