|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
On-silicon HIL: open + parse a real .epub from SD via ra8_fs (#114). More...
#include <stddef.h>#include <stdint.h>#include "epub.h"#include "epub_fixture.h"#include "epub_fs.h"#include "ra8_board_ek_ra8d2.h"#include "ra8_boot_entry.h"#include "ra8_cgc.h"#include "ra8_err.h"#include "ra8_isr.h"#include "ra8_log.h"#include "ra8_port_constants.h"#include "ra8_port_utils.h"#include "ra8_sci_spi.h"#include "ra8_sdmmc_spi.h"#include "ra8_spi.h"#include "ra8_time.h"Go to the source code of this file.
Enumerations | |
| enum | eoh_consts_t : uint32_t { k_eoh_uart_baud = 115200U , k_eoh_spi_chan = 0U , k_eoh_expect_chap = 2U , k_eoh_expect_crc = 0xCF23AEEEU , k_eoh_chap_cap = 4096U , k_eoh_crc_init = 0xFFFFFFFFU , k_eoh_crc_poly = 0xEDB88320U , k_eoh_crc_bits = 8U , k_eoh_hex_nibbles = 8U , k_eoh_nibble_bits = 4U , k_eoh_nibble_mask = 0x0FU , k_eoh_dec_ten = 10U } |
| Console / SPI / parse knobs (no magic numbers). More... | |
| enum | eoh_err_t : uint32_t { k_eoh_err_none = 0U , k_eoh_err_init = 1U , k_eoh_err_card = 2U , k_eoh_err_mount = 3U , k_eoh_err_prov = 4U , k_eoh_err_open = 5U , k_eoh_err_chap = 6U , k_eoh_err_load = 7U , k_eoh_err_crc = 8U , k_eoh_err_meta = 9U } |
| Failure-stage codes stamped to g_eoh_err for SWD / --dump-sym. More... | |
| enum | eoh_pace_t : uint32_t { k_eoh_frame_ms = 100U } |
| Idle-loop pacing for the success heartbeat. More... | |
Functions | |
| static void | eoh_print (const uint8_t *msg, uint32_t len) |
| Emit a byte run on the SCI8 console. | |
| static void | eoh_fail (uint32_t err, const uint8_t *msg, uint32_t len) |
| Stamp the failure stage, print the FAIL banner, and park the CPU. | |
| static uint32_t | eoh_crc32 (const uint8_t *data, size_t len) |
CRC-32 (reflected, poly 0xEDB88320) over data. | |
| static void | eoh_print_hex (uint32_t value) |
| Print a 32-bit value as 8 upper-case hex digits. | |
| static void | eoh_print_uint (uint32_t value) |
| Print a small unsigned integer in decimal. | |
| static ra8_err_t | eoh_spi_set_clock (void *ctx, uint32_t hz) |
| static ra8_err_t | eoh_spi_cs (void *ctx, bool asserted) |
| ra8_sdmmc_spi_transport_t::cs over ra8_gpio (CS active-low). | |
| static ra8_err_t | eoh_spi_xfer (void *ctx, const uint8_t *tx, uint8_t *rx, uint32_t len) |
| ra8_sdmmc_spi_transport_t::xfer over ra8_sci_spi_xfer. | |
| static ra8_err_t | eoh_spi_pins_init (void) |
| Route Pmod2 SPI pins and claim CS as a GPIO output (idle high). | |
| static void | eoh_setup_or_halt (uint32_t *out_pclka_hz) |
| Bring up CGC + SysTick + console SCI + SPI + CS GPIO; halt on fail. | |
| static void | eoh_init_card_or_halt (uint32_t *pclka_hz) |
| Init the SD card over SPI; halt with a diagnostic on failure. | |
| static ra8_fs_mount_t * | eoh_mount_or_halt (void) |
| Mount the card, formatting FAT32 first if it is blank/unmountable. | |
| static void | eoh_provision_or_halt (ra8_fs_mount_t *mount) |
| Write the baked .epub onto the volume if k_eoh_book_path absent. | |
| static uint16_t | eoh_parse_or_halt (ra8_fs_mount_t *mount, uint32_t *out_crc) |
| Open the provisioned .epub off SD, verify the spine, CRC chapter 0. | |
| void | main (void) |
| App entry: SD bring-up -> provision -> open/parse -> heartbeat idle. | |
Variables | |
| static const ra8_port_pin_t | k_eoh_pin_sck = (ra8_port_pin_t)k_ra8_board_pmod2_spi_sck |
| Pmod2 SPI pins (J25) – SCI0 Simple-SPI; CS held by GPIO. | |
| static const ra8_port_pin_t | k_eoh_pin_cipo = (ra8_port_pin_t)k_ra8_board_pmod2_spi_cipo |
| static const ra8_port_pin_t | k_eoh_pin_copi = (ra8_port_pin_t)k_ra8_board_pmod2_spi_copi |
| static const ra8_port_pin_t | k_eoh_pin_cs = (ra8_port_pin_t)k_ra8_board_pmod2_spi_cs |
| static const char | k_eoh_book_path [] = "BOOK.EPB" |
| Book path on the SD volume (8.3 short name; ra8_fs is root-only). | |
| volatile uint32_t | g_eoh_err = (uint32_t)k_eoh_err_none |
| First failing stage (eoh_err_t), 0 on success. | |
| volatile uint32_t | g_eoh_chapters = 0U |
| Parsed chapter (spine) count on success; 0 otherwise. | |
| volatile uint32_t | g_eoh_crc = 0U |
| Chapter-0 decompressed-XHTML CRC-32 on success; 0 otherwise. | |
| volatile uint32_t | g_eoh_heartbeat = 0U |
| Idle heartbeat; advances ONLY after a clean parse (the HIL gate). | |
| static epub_book_t | s_book |
| Opened book (large – file-scope, not on the stack). | |
| static epub_stream_fs_ctx_t | s_epub_io |
| Streamed-open source-file context; must outlive s_book (#230). | |
| static uint8_t | s_chapter [k_eoh_chap_cap] |
| Chapter-0 XHTML scratch (file-scope to keep the stack small). | |
| static ra8_fs_backend_t | s_backend |
| SD backend; file-scope so the mount handle may reference it. | |
| static const uint8_t | k_msg_boot [] = "epub-open-hil: boot\r\n" |
| static const uint8_t | k_msg_cardok [] = "epub-open-hil: card ready\r\n" |
| static const uint8_t | k_msg_finit [] = "epub-hil: FAIL init\r\n" |
| static const uint8_t | k_msg_fcard [] = "epub-hil: FAIL card\r\n" |
| static const uint8_t | k_msg_fmount [] = "epub-hil: FAIL mount\r\n" |
| static const uint8_t | k_msg_fprov [] = "epub-hil: FAIL provision\r\n" |
| static const uint8_t | k_msg_fopen [] = "epub-hil: FAIL open\r\n" |
| static const uint8_t | k_msg_fchap [] = "epub-hil: FAIL chapters\r\n" |
| static const uint8_t | k_msg_fload [] = "epub-hil: FAIL load\r\n" |
| static const uint8_t | k_msg_fcrc [] = "epub-hil: FAIL crc\r\n" |
| static const uint8_t | k_msg_fmeta [] = "epub-hil: FAIL meta\r\n" |
| static const uint8_t | k_msg_pre [] = "epub-hil: chapters=" |
| static const uint8_t | k_msg_crc [] = " ch0_crc=" |
| static const uint8_t | k_msg_ok [] = " PASS\r\n" |
On-silicon HIL: open + parse a real .epub from SD via ra8_fs (#114).
epub_parse proved the epub parse stack runs on the M85 from a baked in-memory blob (#139). This app closes the storage gap: it reads the .epub off a real microSD card through ra8_fs – the exact path the e-reader uses – so the byte-twiddling parse layer is exercised against real SD timing + the FAT read path, not just a .rodata array.
Flow: bring up the Pmod2 microSD over the ra8_sdmmc_spi SPI-mode driver, mount an ra8_fs volume (formatting FAT32 first if the card is blank), self-provision a known 2-chapter .epub onto it if absent (the same seed_two_chapters seed as epub_parse), then epub_open_streamed_fs() it – the production open path (#230): no whole-file buffer, every ZIP read seeks the card on demand – and assert:
epub-hil: chapters=2 ch0_crc=CF23AEEE PASS
The HIL gate is memprobe (J-Link / ra8_emulator --dump-sym), not the console: an SD app drives the SCI0 Simple-SPI bus, and ra8_emulator folds every SCI channel into one console line, so the SCI8 banner is interleaved with SPI traffic there (the same reason the sibling SD HIL apps – sd_font_render, fs_format_mount – gate on SWD globals). The success path advances g_eoh_heartbeat once per frame and only after every assertion passes (chapter count, byte-exact CRC, metadata); any failure stamps g_eoh_err and parks without bumping the heartbeat. So a steadily-advancing heartbeat with a zero g_eoh_err proves the whole SD -> ra8_fs -> epub pipeline ran. The console banner remains for a real-bench scope and human triage.
Required external hardware (on-bench): Digilent PMOD MicroSD (410-380) in Pmod2 (J25) with a microSD inserted. THIS APP MAY FORMAT THE CARD. Under ra8_emulator attach a blank card with --sd-new 64:fat32.
Definition in file main.c.
| enum eoh_consts_t : uint32_t |
Console / SPI / parse knobs (no magic numbers).
| enum eoh_err_t : uint32_t |
Failure-stage codes stamped to g_eoh_err for SWD / --dump-sym.
Zero means "no failure yet". Each value identifies the first step that failed, so a memprobe gate can triage without the console.
| enum eoh_pace_t : uint32_t |
|
static |
CRC-32 (reflected, poly 0xEDB88320) over data.
Definition at line 183 of file main.c.
References k_eoh_crc_bits, k_eoh_crc_init, and k_eoh_crc_poly.
Referenced by eoh_parse_or_halt().
|
static |
Stamp the failure stage, print the FAIL banner, and park the CPU.
Records err in g_eoh_err (for the --dump-sym / J-Link memprobe gate), emits msg on the console (for a real-bench scope), then spins in WFI. The success heartbeat (g_eoh_heartbeat) is never bumped from here, so a memprobe gate sees a frozen heartbeat plus a non-zero g_eoh_err.
| [in] | err | Failure-stage code (eoh_err_t). |
| [in] | msg | Console diagnostic bytes. |
| [in] | len | Length of msg. |
Definition at line 173 of file main.c.
References eoh_print(), and g_eoh_err.
Referenced by eoh_init_card_or_halt(), eoh_mount_or_halt(), eoh_parse_or_halt(), eoh_provision_or_halt(), and eoh_setup_or_halt().
|
static |
Init the SD card over SPI; halt with a diagnostic on failure.
Definition at line 295 of file main.c.
References eoh_fail(), eoh_print(), eoh_spi_cs(), eoh_spi_set_clock(), eoh_spi_xfer(), k_eoh_err_card, k_msg_cardok, k_msg_fcard, k_ra8_ok, and ra8_sdmmc_spi_init().
Referenced by main().
|
static |
Mount the card, formatting FAT32 first if it is blank/unmountable.
Binds the SD backend, tries to mount; a blank card (e.g. ra8_emulator's --sd-new before any format, or a fresh bench card) fails to mount, so it is formatted FAT32 and mounted. Halts on a hard failure.
Definition at line 316 of file main.c.
References eoh_fail(), k_eoh_err_mount, k_msg_fmount, k_ra8_fs_type_fat32, k_ra8_ok, ra8_fs_format_opts_t::label, ra8_fs_format(), ra8_fs_mount(), ra8_sdmmc_spi_bind_fs_backend(), s_backend, and ra8_fs_format_opts_t::type.
Referenced by main().
|
static |
Open the provisioned .epub off SD, verify the spine, CRC chapter 0.
| [in] | mount | Mounted SD volume holding k_eoh_book_path. |
| [out] | out_crc | Receives the CRC-32 of chapter 0's decompressed XHTML. |
Definition at line 355 of file main.c.
References eoh_crc32(), eoh_fail(), epub_get_chapter_count(), epub_get_metadata(), epub_load_chapter(), epub_open_streamed_fs(), k_eoh_book_path, k_eoh_chap_cap, k_eoh_err_chap, k_eoh_err_crc, k_eoh_err_load, k_eoh_err_meta, k_eoh_err_open, k_eoh_expect_chap, k_eoh_expect_crc, k_msg_fchap, k_msg_fcrc, k_msg_fload, k_msg_fmeta, k_msg_fopen, k_ra8_ok, s_book, s_chapter, s_epub_io, and epub_metadata_t::title.
Referenced by main().
|
static |
Emit a byte run on the SCI8 console.
Definition at line 156 of file main.c.
References ra8_board_uart_console_write().
Referenced by eoh_fail(), eoh_init_card_or_halt(), eoh_print_hex(), eoh_print_uint(), and main().
|
static |
Print a 32-bit value as 8 upper-case hex digits.
Definition at line 197 of file main.c.
References eoh_print(), k_eoh_dec_ten, k_eoh_hex_nibbles, k_eoh_nibble_bits, and k_eoh_nibble_mask.
Referenced by main().
|
static |
Print a small unsigned integer in decimal.
Definition at line 210 of file main.c.
References eoh_print(), and k_eoh_dec_ten.
Referenced by main().
|
static |
Write the baked .epub onto the volume if k_eoh_book_path absent.
Definition at line 335 of file main.c.
References eoh_fail(), k_eoh_book_path, k_eoh_err_prov, k_epub_fixture, k_epub_fixture_len, k_msg_fprov, k_ra8_fs_mode_read, k_ra8_ok, ra8_fs_close(), ra8_fs_open(), and ra8_fs_write_file().
Referenced by main().
|
static |
Bring up CGC + SysTick + console SCI + SPI + CS GPIO; halt on fail.
Definition at line 270 of file main.c.
References eoh_fail(), eoh_spi_pins_init(), k_eoh_err_init, k_eoh_spi_chan, k_eoh_uart_baud, k_msg_finit, k_ra8_clock_id_cpuclk0, k_ra8_clock_id_pclka, k_ra8_ok, k_ra8_sdmmc_spi_clock_init_hz, k_ra8_spi_mode_0, ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_sci_spi_init(), and ra8_time_init().
Referenced by main().
|
static |
ra8_sdmmc_spi_transport_t::cs over ra8_gpio (CS active-low).
Definition at line 238 of file main.c.
References k_eoh_pin_cs, k_ra8_level_high, k_ra8_level_low, and ra8_gpio_write().
Referenced by eoh_init_card_or_halt().
|
staticnodiscard |
Route Pmod2 SPI pins and claim CS as a GPIO output (idle high).
Definition at line 252 of file main.c.
References k_eoh_pin_cipo, k_eoh_pin_copi, k_eoh_pin_cs, k_eoh_pin_sck, k_ra8_level_high, k_ra8_ok, k_ra8_psel_sci_async, ra8_gpio_output_init(), and ra8_pfs_route_peripheral().
Referenced by eoh_setup_or_halt().
|
static |
Definition at line 231 of file main.c.
References k_eoh_spi_chan, and ra8_sci_spi_set_clock().
Referenced by eoh_init_card_or_halt().
|
static |
ra8_sdmmc_spi_transport_t::xfer over ra8_sci_spi_xfer.
Definition at line 245 of file main.c.
References k_eoh_spi_chan, and ra8_sci_spi_xfer().
Referenced by eoh_init_card_or_halt().
| void main | ( | void | ) |
App entry: SD bring-up -> provision -> open/parse -> heartbeat idle.
The application entry point Reset_Handler hands control to.
Definition at line 393 of file main.c.
References eoh_init_card_or_halt(), eoh_mount_or_halt(), eoh_parse_or_halt(), eoh_print(), eoh_print_hex(), eoh_print_uint(), eoh_provision_or_halt(), eoh_setup_or_halt(), g_eoh_chapters, g_eoh_crc, g_eoh_heartbeat, k_eoh_frame_ms, k_msg_boot, k_msg_crc, k_msg_ok, k_msg_pre, ra8_delay_ms(), ra8_isr_globals_enable(), and ra8_log_init().
| volatile uint32_t g_eoh_chapters = 0U |
| volatile uint32_t g_eoh_crc = 0U |
| volatile uint32_t g_eoh_err = (uint32_t)k_eoh_err_none |
First failing stage (eoh_err_t), 0 on success.
SWD / --dump-sym.
Definition at line 123 of file main.c.
Referenced by eoh_fail().
| volatile uint32_t g_eoh_heartbeat = 0U |
|
static |
Book path on the SD volume (8.3 short name; ra8_fs is root-only).
Definition at line 91 of file main.c.
Referenced by eoh_parse_or_halt(), and eoh_provision_or_halt().
|
static |
Definition at line 86 of file main.c.
Referenced by eoh_spi_pins_init().
|
static |
Definition at line 87 of file main.c.
Referenced by eoh_spi_pins_init().
|
static |
Definition at line 88 of file main.c.
Referenced by eoh_spi_cs(), and eoh_spi_pins_init().
|
static |
Pmod2 SPI pins (J25) – SCI0 Simple-SPI; CS held by GPIO.
Definition at line 85 of file main.c.
Referenced by eoh_spi_pins_init().
|
static |
|
static |
Definition at line 141 of file main.c.
Referenced by eoh_init_card_or_halt(), and etoc_init_card_or_halt().
|
static |
Definition at line 152 of file main.c.
Referenced by erb_render_chapter(), ls_emit_banner(), and main().
|
static |
Definition at line 143 of file main.c.
Referenced by eoh_init_card_or_halt(), and etoc_init_card_or_halt().
|
static |
Definition at line 147 of file main.c.
Referenced by eoh_parse_or_halt().
|
static |
Definition at line 149 of file main.c.
Referenced by eoh_parse_or_halt(), and wa_verify_or_halt().
|
static |
Definition at line 142 of file main.c.
Referenced by eoh_setup_or_halt(), and etoc_setup_or_halt().
|
static |
Definition at line 148 of file main.c.
Referenced by eoh_parse_or_halt().
|
static |
Definition at line 150 of file main.c.
Referenced by eoh_parse_or_halt().
|
static |
Definition at line 144 of file main.c.
Referenced by eoh_mount_or_halt(), and etoc_mount_or_halt().
|
static |
Definition at line 146 of file main.c.
Referenced by eoh_parse_or_halt().
|
static |
Definition at line 145 of file main.c.
Referenced by eoh_provision_or_halt(), and etoc_provision_one().
|
static |
Definition at line 153 of file main.c.
Referenced by ez_print_banner(), main(), and mg_print_banner().
|
static |
Definition at line 151 of file main.c.
Referenced by ez_print_banner(), ls_emit_banner(), main(), and mg_print_banner().
|
static |
SD backend; file-scope so the mount handle may reference it.
Definition at line 138 of file main.c.
Referenced by eoh_mount_or_halt(), etoc_mount_or_halt(), internal_pc_mount_or_halt(), and sh_sd_mount().
|
static |
Opened book (large – file-scope, not on the stack).
Definition at line 132 of file main.c.
Referenced by compile_fixture(), ec_render_cover_or_halt(), eoh_parse_or_halt(), ep_parse_or_halt(), est_open_or_halt(), etoc_check_bad(), etoc_read_toc(), sh_sd_book_close(), sh_sd_book_open(), sh_sd_book_read(), and sh_sd_comic_read().
|
static |
Chapter-0 XHTML scratch (file-scope to keep the stack small).
Definition at line 136 of file main.c.
Referenced by eoh_parse_or_halt(), and ep_parse_or_halt().
|
static |
Streamed-open source-file context; must outlive s_book (#230).
Definition at line 134 of file main.c.
Referenced by eoh_parse_or_halt(), etoc_check_bad(), etoc_read_toc(), sh_sd_close_epub(), and sh_sd_open_epub().