ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph.h File Reference

Register-accurate peripheral-model framework for the board emulator. More...

#include <stdint.h>
#include <unicorn/unicorn.h>
Include dependency graph for board_periph.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  board_glcdc_fb_t
 Active GLCDC graphics-layer framebuffer descriptor. More...

Enumerations

enum  board_led_id_t : uint8_t {
  k_board_led1 = 0U ,
  k_board_led2 = 1U ,
  k_board_led3 = 2U ,
  k_board_led_count = 3U
}
 Board user-LED identity, mirrored from the EK-RA8D2 BSP. More...
enum  board_device_t : uint8_t {
  k_board_device_ra8d2 = 0U ,
  k_board_device_ra8p1 = 1U
}
 The RA8 device the emulator models for this run. More...

Functions

void board_periph_set_device (board_device_t device)
 Select which RA8 device the peripheral model emulates.
board_device_t board_periph_device (void)
 Report which RA8 device the peripheral model is emulating.
void board_periph_set_usbhs_loop (bool on)
 Enable the chip-internal USBHS-host self-loop model (–usbhs-loop).
bool board_periph_usbhs_loop (void)
 Report whether the USBHS-host self-loop model is enabled.
void board_periph_init (bool trace)
 One-time reset of all peripheral-model state.
void board_periph_reset_set_cause (bool power_on, bool software, bool watchdog, bool iwdt)
 Record the cause of a warm reboot in the sticky RSTSRn flags.
void board_periph_reset_request_reboot (bool watchdog, bool iwdt)
 Request a warm reboot from a peripheral model (e.g.
bool board_periph_reset_take_request (bool *out_watchdog, bool *out_iwdt)
 Consume a pending peripheral reboot request, if any (run-loop side).
void board_periph_sci_set_tx_sink (void(*sink)(uint8_t channel, uint8_t byte))
 Wire a host sink that receives every byte the firmware transmits.
void board_periph_sci_feed_rx (uint8_t channel, const uint8_t *data, uint32_t len)
 Queue host->firmware bytes for a channel's receive path.
void board_periph_touch_inject (uint16_t x, uint16_t y)
 Arm a pending touch contact for the modelled GT911 device.
uint32_t board_periph_touch_reported (void)
 Count of touch contacts the firmware has drained from the GT911 model.
void board_periph_touch_seq_reset (void)
 Clear the modelled GT911 injected-touch sequence FIFO.
bool board_periph_touch_seq_push (uint16_t x, uint16_t y)
 Queue one raw touch point onto the modelled GT911 injection FIFO.
uint32_t board_periph_led_level (board_led_id_t led)
 Read the last driven output level of a board LED.
void board_periph_gpio_set_input (uint8_t port, uint8_t pin, bool level)
 Drive a GPIO pin's input level from outside the firmware.
bool board_periph_gpio_get_input (uint8_t port, uint8_t pin)
 Read the externally-injected input level of a GPIO pin.
uint16_t board_periph_led_color_rgb565 (board_led_id_t led)
 The on-colour of a board LED as a packed RGB565 value.
const char * board_periph_uart_last_line (void)
 The most recent complete line the firmware transmitted over any SCI.
uint32_t board_periph_uart_tx_total (void)
 Total bytes the firmware has transmitted over all SCI channels.
uint32_t board_periph_irq_count (uint32_t irq)
 Number of times a given NVIC line was taken in this run.
uint32_t board_periph_irq_total (void)
 Total NVIC interrupts the ICU has delivered in this run.
bool board_periph_touch_last (uint16_t *x, uint16_t *y)
 Report the coordinates of the most recently drained touch contact.
void board_periph_battery_set (uint8_t soc_pct, bool charging)
 Set the emulated battery state surfaced by the MAX17048 fuel gauge.
void board_periph_battery_get (uint8_t *out_soc, bool *out_charging)
 Read back the emulated battery state (for the status overlay).
uint8_t board_periph_sci_console_channel (void)
 The SCI channel the EK-RA8D2 console (J-Link OB VCOM) uses.
uint64_t board_periph_read (uc_engine *uc, uint64_t addr, unsigned size, bool *handled)
 Dispatch an MMIO read to the owning block, if any.
void board_periph_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value, bool *handled)
 Dispatch an MMIO write to the owning block, if any.
void board_periph_tick (uc_engine *uc)
 Advance every modelled timer by one emulation chunk and raise events.
void board_periph_nvic_set_enable (uint32_t irq, bool enable)
 Set or clear a NVIC line's enable in the model's set-enable shadow.
bool board_periph_next_irq (uint32_t *out_irq)
 Pop the next pending, enabled NVIC IRQ number the ICU has queued.
void board_periph_note_irq_taken (uint32_t irq)
 Record that NVIC IRQ irq was actually taken (for the summary).
bool board_periph_glcdc_get_framebuffer (board_glcdc_fb_t *out)
 Report the active GLCDC graphics-layer framebuffer, if one is programmed.
void board_periph_report (uc_engine *uc)
 Print the peripheral-model section of the end-of-run summary.

Detailed Description

Register-accurate peripheral-model framework for the board emulator.

A registry that maps RA8D2 peripheral-register address ranges to per-block read/write handlers backed by real state, dispatched from ra8_emulator's MMIO callbacks. It SUPERSEDES the sparse reflect-then-settle fallback for the blocks modelled here (the fallback still answers every UNmodelled address), so a non-display example produces real peripheral data instead of faked ready-bit handshakes.

The first blocks modelled are GPIO/PORT (the board LEDs become observable), the AGT and GPT timers (counters that advance on their configured clock and raise compare-match / overflow / underflow events), the ICU/NVIC (a peripheral event linked through IELSR pends the matching NVIC IRQ, taken as a real Cortex-M exception by the engine's exception layer), and the SCI_B UART (TDR writes are captured to a host console sink, RDR reads return a host-supplied byte stream, and TXI / TEI / RXI route through the same ICU event path so interrupt-driven serial works as well as polled). The block table is the extension point: I2C / SPI / USB slot in as new entries later.

Design: this module owns no Unicorn engine of its own and takes no AppKit dependency. main.c passes the engine in where the model must read or write emulated memory / pend an NVIC line, so board_periph stays plain C and the exception delivery stays in the one place that already models it.

Since
0.1.0

Definition in file board_periph.h.

Enumeration Type Documentation

◆ board_device_t

enum board_device_t : uint8_t

The RA8 device the emulator models for this run.

ra8_emulator's peripheral models were written for the RA8D2; the RA8P1 (R7KA8P1KFLCAC) shares the RA8D2's entire register map and memory map, so the same models serve both parts. Only one RA8P1-only block differs – the Arm Ethos-U55 NPU (0x40140000) – and it is gated with k_board_block_dev_ra8p1 so it is dispatched only when the active device is the RA8P1. The default is the RA8D2, so a run with no --device flag behaves exactly as before this device knob existed.

Invariant
Exactly one value is active per run; set once before the run loop.
See also
board_periph_set_device
board_block_device_t
Since
0.1.0
Enumerator
k_board_device_ra8d2 

Renesas RA8D2 (default): no NPU.

k_board_device_ra8p1 

Renesas RA8P1: adds the Ethos-U55 NPU.

Definition at line 75 of file board_periph.h.

◆ board_led_id_t

enum board_led_id_t : uint8_t

Board user-LED identity, mirrored from the EK-RA8D2 BSP.

Pin assignments per libs/ra8_board_ek_ra8d2 (EK-RA8D2 v1 UM Table 24, p 31): LED1 BLUE = P600, LED2 GREEN = P303, LED3 RED = PA07. All three are active-high. board_periph traces these specific port/pin output latches so the run summary / –trace can report each LED transition.

Enumerator
k_board_led1 

LED1, BLUE, P600 (port 6, pin 0).

k_board_led2 

LED2, GREEN, P303 (port 3, pin 3).

k_board_led3 

LED3, RED, PA07 (port 10, pin 7).

k_board_led_count 

Board led count.

Definition at line 51 of file board_periph.h.

Function Documentation

◆ board_periph_battery_get()

void board_periph_battery_get ( uint8_t * out_soc,
bool * out_charging )

Read back the emulated battery state (for the status overlay).

Parameters
[out]out_socReceives the state-of-charge percent (NULL ok).
[out]out_chargingReceives the charging flag (NULL ok).
Since
0.1.0

Read back the emulated battery state (for the status overlay); this step is contained within the board periph model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for board periph battery get.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 334 of file board_periph_i2c_devices.c.

References s_battery.

Referenced by apply_battery_click(), internal_fill_status_hw(), and internal_main_apply_button_battery().

◆ board_periph_battery_set()

void board_periph_battery_set ( uint8_t soc_pct,
bool charging )

Set the emulated battery state surfaced by the MAX17048 fuel gauge.

The firmware reads state-of-charge + charge direction from a MAX17048-class fuel gauge at I2C 0x36; this drives that device's register file. Set from the CLI (--battery <pct> / --charge) before the run. soc_pct is clamped to 0..100.

Parameters
[in]soc_pctState-of-charge percent (clamped to [0, 100]).
[in]chargingtrue marks the charger attached (CRATE reads positive).
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph battery set.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 327 of file board_periph_i2c_devices.c.

References internal_fuelgauge_seed(), k_battery_soc_max, s_battery, and s_fuelgauge.

Referenced by apply_battery_click(), and internal_main_apply_button_battery().

◆ board_periph_device()

board_device_t board_periph_device ( void )

Report which RA8 device the peripheral model is emulating.

Read-only accessor over the active-device selection last set by board_periph_set_device (defaults to k_board_device_ra8d2).

Returns
The active device (k_board_device_ra8d2 / k_board_device_ra8p1).
Return values
k_board_device_ra8d2Default, or the last RA8D2 selection.
k_board_device_ra8p1Last selected via board_periph_set_device.
Precondition
None; safe at any time – the selection is statically initialized to RA8D2.
Postcondition
No model state is modified (read-only accessor).
The returned value is a valid board_device_t enumerator.
Note
Not thread-safe; single-threaded run-loop / setup use.
See also
board_periph_set_device
Since
0.1.0
Precondition
The call executes on the emulator's single owning thread.

Definition at line 204 of file board_periph.c.

References s_device.

Referenced by internal_main_load_primary().

◆ board_periph_glcdc_get_framebuffer()

bool board_periph_glcdc_get_framebuffer ( board_glcdc_fb_t * out)

Report the active GLCDC graphics-layer framebuffer, if one is programmed.

Reads the descriptor the GLCDC model snooped from the firmware's graphics-layer register writes (GR1 preferred; GR2 if only it is enabled). Lets a ra8_emulator harness locate and checksum the rendered framebuffer in emulated memory without re-deriving the layout from raw registers. The pixels themselves are read with uc_mem_read at base; this only returns the layout.

Parameters
[out]outReceives the active framebuffer descriptor on success; left unchanged when no layer is programmed. Ignored if NULL.
Returns
true when a graphics layer has a framebuffer programmed (and out was written), false otherwise.
Postcondition
On true, out->base points into a modelled RAM window.
On false, out is untouched.
Note
Not thread-safe; single-threaded run-loop / report use.
Since
0.1.0
Return values
trueThe board periph glcdc get framebuffer condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for board periph glcdc get framebuffer.
The call executes on the emulator's single owning thread.

Definition at line 253 of file board_periph_glcdc.c.

References internal_glcdc_layer_decode(), and s_glcdc.

Referenced by internal_glcdc_report().

◆ board_periph_gpio_get_input()

bool board_periph_gpio_get_input ( uint8_t port,
uint8_t pin )

Read the externally-injected input level of a GPIO pin.

Returns the level last set by board_periph_gpio_set_input for pin (the board's switches idle high). Lets an interactive caller toggle a push-button by reading the current state and writing its inverse – e.g. an on-screen SW1 click flips P009 between released (high) and pressed (low).

Parameters
[in]portPORT index (0-based; PORT0 == 0).
[in]pinPin number within the port (0..15).
Returns
The injected level (true = high, false = low); false if out of range.
Precondition
The peripheral model has been initialised.
Note
Not thread-safe; single-threaded harness use.
Since
0.1.0
Return values
trueThe board periph GPIO get input condition holds or completed successfully; false otherwise.
Precondition
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.

Definition at line 276 of file board_periph_gpio.c.

References k_pins_per_port, k_port_count, pin, and s_port.

Referenced by internal_fill_status_hw().

◆ board_periph_gpio_set_input()

void board_periph_gpio_set_input ( uint8_t port,
uint8_t pin,
bool level )

Drive a GPIO pin's input level from outside the firmware.

Lets the harness inject a pin level that the firmware reads back through PIDR (PCNTR2) – the model for a physical input such as a user push-button. The board's active-low switches SW1 (P009) / SW2 (P008) idle high (released) and are pulled low to model a press, so --button (and a live-view key) can exercise button-driven firmware paths (e.g. gpio_input_demo: SW1 -> LED1). Only the named pin's input is affected; output pins still read their latch.

Parameters
[in]portPORT index (0-based; PORT0 == 0).
[in]pinPin number within the port (0..15).
[in]levelInjected level: true = high, false = low.
Returns
Nothing.
Precondition
The peripheral model has been initialised.
port / pin are within range (out-of-range is ignored).
Postcondition
Subsequent PIDR reads of pin (when configured as input) see level.
Output pins are unaffected (they read their driven latch).
Note
Not thread-safe; single-threaded harness use.
Since
0.1.0

Definition at line 262 of file board_periph_gpio.c.

References k_pins_per_port, k_port_count, pin, and s_port.

Referenced by board_eink_apply_gpio_defaults(), internal_main_apply_button_battery(), and set_switch().

◆ board_periph_init()

void board_periph_init ( bool trace)

One-time reset of all peripheral-model state.

Clears every modelled block (PORT latches/direction, AGT/GPT counters and status, ICU event-link table and NVIC pend records) and the observability counters. Call once after the memory map is created and before the run loop.

Parameters
[in]traceWhen true, each LED / GPIO transition and each taken IRQ is logged to injected error sink as it happens (the –trace flag).
Returns
Nothing.
Postcondition
All counters read zero and every block is in its reset state.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph init.
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 531 of file board_periph.c.

References board_usb_host_init(), board_usb_init(), board_usb_set_irq_raiser(), internal_board_periph_build_order(), internal_usb_irq_raiser(), k_icu_ielsr_cnt, k_irq_track_max, k_nvic_enable_words, s_block_count, s_block_order, s_blocks, s_ielsr, s_irq_head, s_irq_tail, s_irq_taken, s_irq_total, s_last_block, s_nvic_iser_shadow, s_order_built, and s_trace.

Referenced by internal_main_bringup_peripherals(), and warm_reboot().

◆ board_periph_irq_count()

uint32_t board_periph_irq_count ( uint32_t irq)

Number of times a given NVIC line was taken in this run.

Parameters
[in]irqNVIC line number (0-based).
Returns
Times the engine vectored in irq (0 if never, or out of range).
Since
0.1.0

Number of times a given nvic line was taken in this run; this step is contained within the board periph model and uses bounded caller or module-owned storage.

Return values
valueThe operation-specific board periph interrupt count value.
Precondition
Arguments satisfy the ranges documented for board periph interrupt count.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 685 of file board_periph.c.

References k_irq_track_max, and s_irq_taken.

Referenced by internal_fill_status_hw().

◆ board_periph_irq_total()

uint32_t board_periph_irq_total ( void )

Total NVIC interrupts the ICU has delivered in this run.

Returns
Sum of every taken IRQ (the board view's "IRQ" activity total).
Since
0.1.0

Total nvic interrupts the icu has delivered in this run; this step is contained within the board periph model and uses bounded caller or module-owned storage.

Return values
valueThe operation-specific board periph interrupt total value.
Precondition
Arguments satisfy the ranges documented for board periph interrupt total.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 693 of file board_periph.c.

References s_irq_total.

Referenced by internal_fill_status_hw(), and internal_run_stop_idle().

◆ board_periph_led_color_rgb565()

uint16_t board_periph_led_color_rgb565 ( board_led_id_t led)

The on-colour of a board LED as a packed RGB565 value.

Returns the real EK-RA8D2 indicator colour the LED emits when driven high – LED1 blue (P600), LED2 green (P303), LED3 red (PA07) per the BSP – encoded as RGB565 so the board view can fill the indicator in the genuine colour (and the --ppm composite, also RGB565, captures it for verification). The value is the lit colour regardless of the live level; pair it with board_periph_led_level to decide lit vs dark.

Parameters
[in]ledBoard LED identity (board_led_id_t).
Returns
RGB565 on-colour (0 for an out-of-range led).
Since
0.1.0
Return values
valueThe operation-specific board periph led color rgb565 value.
Precondition
Arguments satisfy the ranges documented for board periph led color rgb565.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 293 of file board_periph_gpio.c.

References k_board_led_count, and s_k_led_map.

Referenced by internal_fill_status_hw().

◆ board_periph_led_level()

uint32_t board_periph_led_level ( board_led_id_t led)

Read the last driven output level of a board LED.

Read-only accessor over the GPIO/PORT model's per-LED latch shadow, so the graphical board view can light each indicator without reaching into module internals. The level is the active-high pin drive recorded by the PORT write path: 1 once the firmware drives the LED's pin high, 0 once it drives it low.

Parameters
[in]ledBoard LED identity (board_led_id_t).
Returns
1 if the LED's pin is currently driven high, else 0 (0 for an out-of-range led).
Since
0.1.0
Return values
valueThe operation-specific board periph led level value.
Precondition
Arguments satisfy the ranges documented for board periph led level.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 285 of file board_periph_gpio.c.

References k_board_led_count, and s_led_level.

Referenced by internal_fill_status_hw().

◆ board_periph_next_irq()

bool board_periph_next_irq ( uint32_t * out_irq)

Pop the next pending, enabled NVIC IRQ number the ICU has queued.

The software half of "the ICU asserts a line and the NVIC latches it". The run loop calls this at an instruction boundary; the returned IRQ number is vectored in by the engine's exception layer as a real Cortex-M exception (vector 16 + IRQn from VTOR). Priority and PRIMASK are handled by that layer, so this only reports a line that is event-linked and NVIC-enabled.

Parameters
[out]out_irqReceives the IRQ number (0-based, NVIC line) on success.
Returns
true if a pending IRQ was popped into out_irq.
Since
0.1.0
Return values
trueThe board periph next interrupt condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for board periph next interrupt.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 664 of file board_periph.c.

References k_irq_queue_len, s_irq_head, s_irq_ring, and s_irq_tail.

Referenced by internal_exc_take_periph_irq().

◆ board_periph_note_irq_taken()

void board_periph_note_irq_taken ( uint32_t irq)

Record that NVIC IRQ irq was actually taken (for the summary).

Parameters
[in]irqIRQ number that the engine just vectored in.
Returns
Nothing.
Since
0.1.0

Record that nvic irq irq was actually taken (for the summary); this step is contained within the board periph model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for board periph note interrupt taken.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 674 of file board_periph.c.

References k_irq_track_max, priv_emu_io_errf(), s_irq_taken, s_irq_total, and s_trace.

Referenced by internal_exc_take_periph_irq().

◆ board_periph_nvic_set_enable()

void board_periph_nvic_set_enable ( uint32_t irq,
bool enable )

Set or clear a NVIC line's enable in the model's set-enable shadow.

The Cortex-M NVIC ISER / ICER registers are set-enable / clear-enable: a written 1 sets (ISER) or clears (ICER) that interrupt line and a written 0 is ignored, so several independent stores accumulate. ra8_emulator maps the PPB as plain RAM, where a raw "1 << bit" store to ISER would instead overwrite the whole word and drop every other enabled line. main.c decodes ISER / ICER writes and calls this so the ICU model sees the correct accumulated enable state – essential once firmware enables more than one line at once (SCI RXI + TXI + TEI, and the USB controller lines in Phase 3).

Parameters
[in]irqNVIC line number (0-based).
[in]enabletrue to set the line's enable, false to clear it.
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph NVIC set enable.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 357 of file board_periph.c.

References k_nvic_enable_words, and s_nvic_iser_shadow.

Referenced by internal_on_nvic_en_write().

◆ board_periph_read()

uint64_t board_periph_read ( uc_engine * uc,
uint64_t addr,
unsigned size,
bool * handled )

Dispatch an MMIO read to the owning block, if any.

Looks up addr in the block table; on a hit the block's read handler returns the register value and *handled is set true. On a miss *handled is false and the caller falls back to the sparse model.

Parameters
[in,out]ucUnicorn engine (handlers may read emulated memory).
[in]addrAbsolute peripheral address being read.
[in]sizeAccess width in bytes (1/2/4).
[out]handledTrue iff a modelled block answered the read.
Returns
The register value when *handled is true, else 0.
Since
0.1.0
Return values
valueThe operation-specific board periph read value.
Precondition
Arguments satisfy the ranges documented for board periph read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 572 of file board_periph.c.

References board_usb_host_read(), board_usb_read(), internal_block_for_addr(), internal_icu_ielsr_slot(), internal_icu_read(), k_icu_ielsr_cnt, board_periph_block_t::observe, priv_board_mstp_addr_stopped(), priv_board_mstp_note_gated_access(), and board_periph_block_t::read.

Referenced by mmio_read().

◆ board_periph_report()

void board_periph_report ( uc_engine * uc)

Print the peripheral-model section of the end-of-run summary.

Reports the final driven level of each board LED and its transition count, each modelled timer's final counter / event totals, the per-IRQ taken count, and each active SCI channel's transmitted / received byte totals – the observability the epic asks for (GPIO/LED transitions + per-IRQ interrupt counts + captured serial), beyond the generic MMIO table main.c already prints.

Parameters
[in,out]ucUnicorn engine (read for any final register state).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph report.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 729 of file board_periph.c.

References board_usb_host_report(), board_usb_report(), internal_report_irqs(), k_core_irq_report_order, s_block_count, s_block_order, and s_blocks.

Referenced by internal_run_print_stop_summary().

◆ board_periph_reset_request_reboot()

void board_periph_reset_request_reboot ( bool watchdog,
bool iwdt )

Request a warm reboot from a peripheral model (e.g.

the watchdog).

A peripheral block cannot perform the reboot itself (the run loop in main.c owns that), so it records a request here and the run loop polls board_periph_reset_take_request once per chunk. Used by the WDT model when its down-counter underflows in reset mode. Exactly one of the flags should be true.

Parameters
[in]watchdogtrue for a watchdog-0 reset (RSTSR1.WDTRF).
[in]iwdttrue for an independent-watchdog reset (RSTSR1.IWDTRF).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph reset request reboot.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 96 of file board_periph_reset.c.

References k_reboot_cause_iwdt, k_reboot_cause_wdt, and s_reboot_req_cause.

Referenced by internal_wdt_tick().

◆ board_periph_reset_set_cause()

void board_periph_reset_set_cause ( bool power_on,
bool software,
bool watchdog,
bool iwdt )

Record the cause of a warm reboot in the sticky RSTSRn flags.

Called by the ra8_emulator reboot path (main.c) just before it re-enters the firmware from the reset vector, so the next boot reads the reset cause it expects. For a power-on reboot, leaves RSTSR0.PORF set and asserts nothing else. For any other reset, clears PORF and latches the specific cause in RSTSR1: SWRF (software reset / AIRCR.SYSRESETREQ), WDTRF (watchdog-0 reset), or IWDTRF (independent-watchdog reset). The reset block's reset hook preserves these flags across the warm reboot. Exactly one of the four booleans should be true for a well-formed reset cause.

Parameters
[in]power_ontrue for a power-on / cold reboot (RSTSR0.PORF).
[in]softwaretrue to latch RSTSR1.SWRF (software reset).
[in]watchdogtrue to latch RSTSR1.WDTRF (watchdog-0 reset).
[in]iwdttrue to latch RSTSR1.IWDTRF (independent-watchdog reset).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph reset set cause.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 119 of file board_periph_reset.c.

References k_rstsr0_porf, k_rstsr1_iwdtrf, k_rstsr1_swrf, k_rstsr1_wdtrf, s_rstsr0, and s_rstsr1.

Referenced by internal_run_loop_prologue(), and internal_run_loop_run_chunk().

◆ board_periph_reset_take_request()

bool board_periph_reset_take_request ( bool * out_watchdog,
bool * out_iwdt )

Consume a pending peripheral reboot request, if any (run-loop side).

Polled by the run loop each chunk. If a peripheral requested a warm reboot (board_periph_reset_request_reboot), reports which cause and clears the request so it fires once.

Parameters
[out]out_watchdogSet true if the request was a watchdog-0 reset.
[out]out_iwdtSet true if the request was an independent-WDT reset.
Returns
true if a request was pending (and consumed); false otherwise.
Since
0.1.0
Return values
trueThe board periph reset take request condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for board periph reset take request.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 105 of file board_periph_reset.c.

References k_reboot_cause_iwdt, k_reboot_cause_none, k_reboot_cause_wdt, and s_reboot_req_cause.

Referenced by internal_run_loop_prologue().

◆ board_periph_sci_console_channel()

uint8_t board_periph_sci_console_channel ( void )

The SCI channel the EK-RA8D2 console (J-Link OB VCOM) uses.

PD02 TXD / PD03 RXD route to SCI8 on the EK-RA8D2 v1, surfaced as the board's debug-console UART (mirrored from libs/ra8_board_ek_ra8d2). main.c feeds --input and --keys to this channel by default.

Returns
The console SCI channel index (8 on the EK-RA8D2).
Since
0.1.0
Return values
valueThe operation-specific board periph SCI console channel value.
Precondition
Arguments satisfy the ranges documented for board periph SCI console channel.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 156 of file board_periph_sci.c.

References k_sci_console_ch.

Referenced by internal_main_feed_inputs(), internal_run_loop_tick_inputs(), and internal_run_print_stop_summary().

◆ board_periph_sci_feed_rx()

void board_periph_sci_feed_rx ( uint8_t channel,
const uint8_t * data,
uint32_t len )

Queue host->firmware bytes for a channel's receive path.

Appends len bytes to the channel's RX queue. The SCI_B model asserts CSR.RDRF (and the FIFO RX data flags) while the queue is non-empty, returns queued bytes from reads of RDR oldest-first, and – if the firmware armed RXI (CCR0.RIE) and routed the channel's RXI event through the ICU – pends the RXI interrupt so interrupt-driven receive also runs. main.c feeds this from --input and --keys so a console example sees real input. Bytes beyond the per-channel queue capacity are dropped (reported on --trace).

Parameters
[in]channelSCI channel index (0..9). Out-of-range is ignored.
[in]dataSource bytes (copied into the queue); ignored if NULL.
[in]lenNumber of bytes to queue.
Returns
Nothing.
Postcondition
Up to the queue's free space of data is readable via RDR and RDRF reflects availability.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph SCI feed rx.
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 161 of file board_periph_sci.c.

References board_periph_trace(), k_sci_count, k_sci_rx_queue_len, priv_emu_io_errf(), sci_state_t::rx, sci_state_t::rx_dropped, sci_state_t::rx_head, sci_state_t::rx_tail, and s_sci.

Referenced by internal_main_feed_inputs(), internal_run_loop_tick_inputs(), and internal_sci_reg_write().

◆ board_periph_sci_set_tx_sink()

void board_periph_sci_set_tx_sink ( void(* sink )(uint8_t channel, uint8_t byte))

Wire a host sink that receives every byte the firmware transmits.

The SCI_B model calls sink once per byte written to a channel's TDR (the transmit-data register, used by both the polled and interrupt TX paths and by FIFO mode, which also writes TDR). main.c installs a sink that prints each byte to injected output sink with a clear [uart] prefix so a console example's output is captured and greppable. When no callback is installed, transmitted bytes are still counted for the end-of-run summary but not echoed.

Parameters
[in]sinkCallback invoked as sink(channel, byte) per TX byte, or NULL to detach. The model owns no copy of byte.
Returns
Nothing.
Postcondition
Subsequent TDR writes are delivered to sink.
Since
0.1.0

Definition at line 151 of file board_periph_sci.c.

References s_sci_tx_sink.

Referenced by internal_main_bringup_peripherals().

◆ board_periph_set_device()

void board_periph_set_device ( board_device_t device)

Select which RA8 device the peripheral model emulates.

Sets the active device used to gate the RA8P1-only NPU block. Called once by main.c after parsing --device and before the run loop; the selection persists across warm reboots (the emulated silicon does not change part between resets). An out-of-range value is clamped to k_board_device_ra8d2 so a malformed flag can never leave the model in an undefined device state.

Parameters
[in]deviceDevice to emulate (k_board_device_ra8d2 / k_board_device_ra8p1); out-of-range clamps to RA8D2.
Returns
Nothing.
Precondition
The peripheral registry constructors have run (they always do, pre-main).
Called once during single-threaded setup, before the run loop (not re-entrant).
Postcondition
board_periph_device reports the clamped selection.
RA8P1-only blocks are dispatched iff device is k_board_device_ra8p1.
Note
Not thread-safe; call once from the single-threaded setup path.
See also
board_periph_device
Since
0.1.0

Definition at line 198 of file board_periph.c.

References k_board_device_ra8d2, k_board_device_ra8p1, s_device, and s_last_block.

Referenced by internal_main_bringup_peripherals().

◆ board_periph_set_usbhs_loop()

void board_periph_set_usbhs_loop ( bool on)

Enable the chip-internal USBHS-host self-loop model (–usbhs-loop).

Gates every board_periph_block_t whose loop_only flag is set: a loop-only block (the USBHS host controller model, board_periph_usbhs_host.c) owns its register window ONLY when this is enabled. Off (the default), such a block is skipped and its window falls through to the sparse fallback, exactly as an unmodelled reserved region does – so a run WITHOUT the flag is byte-for-behaviour unchanged (the USBHS host apps that rely on the function seam are untouched). main.c sets this once, after argument parsing, for an app declared as a chip-internal self-loop.

Parameters
[in]ontrue to activate loop-only blocks for this run.
Returns
Nothing.
Postcondition
Loop-only blocks own their windows iff on; the dispatch cache is invalidated so the change takes effect immediately.
Note
Not thread-safe; single-threaded setup use.
See also
board_periph_usbhs_loop
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph set usbhs loop.
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 209 of file board_periph.c.

References s_last_block, and s_usbhs_loop.

Referenced by internal_main_bringup_peripherals().

◆ board_periph_tick()

void board_periph_tick ( uc_engine * uc)

Advance every modelled timer by one emulation chunk and raise events.

Called once per run-loop chunk (the same cadence as one SysTick period). Each running AGT / GPT counter steps by its per-chunk increment; a wrap past the period sets the block's status flag (overflow / underflow / compare-match) and, if that event is linked through the ICU with its NVIC line enabled, records a pending IRQ for the engine to take. Stopped timers do not advance. The SCI_B model is also serviced here: with TX always drained in the model, an enabled TXI / TEI re-pends each tick so an interrupt-driven transmitter keeps streaming, and an enabled RXI pends while queued RX bytes remain.

Parameters
[in,out]ucUnicorn engine (the ICU reads IELSR / NVIC ISER from PPB).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph tick.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 651 of file board_periph.c.

References board_usb_tick(), s_block_count, s_block_order, and s_blocks.

Referenced by internal_run_loop_tick_inputs().

◆ board_periph_touch_inject()

void board_periph_touch_inject ( uint16_t x,
uint16_t y )

Arm a pending touch contact for the modelled GT911 device.

ra8_emulator turns a --click argument or a live board_view mouse-down into a single pending contact here. The contact is answered through the REAL firmware path: ra8_touch_read issues a GT911 status read over ra8_i3c_transfer (the I3C peripheral in legacy I2C mode), and the modelled GT911 device – registered on the modelled I3C/I2C bus at its 7-bit address – reports a status byte with one point plus a point0 record carrying x / y. The contact is one-shot: once the firmware reads the point record it is cleared and board_periph_touch_reported is incremented, so the next frame reads "no frame ready" exactly as the real controller would after a tap is drained. There is no function-level touch hook; the firmware's ra8_touch -> I3C -> GT911 code runs unchanged.

Parameters
[in]xPanel X coordinate of the contact (GT911-native units).
[in]yPanel Y coordinate of the contact.
Returns
Nothing.
Postcondition
The next GT911 status read reports a buffer-ready frame with one point.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph touch inject.
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 304 of file board_periph_i2c.c.

References s_gt911.

Referenced by internal_run_loop_tick_inputs(), and route_click().

◆ board_periph_touch_last()

bool board_periph_touch_last ( uint16_t * x,
uint16_t * y )

Report the coordinates of the most recently drained touch contact.

Read-only accessor over the GT911 model's last-reported point, so the board view can show "touch x,y" for the last tap the firmware drained through the real ra8_touch -> I3C -> GT911 path. Writes nothing when no contact has been reported yet.

Parameters
[out]xReceives the last contact's X coordinate (unchanged if none).
[out]yReceives the last contact's Y coordinate (unchanged if none).
Returns
true if at least one contact has been drained (and x / y were written), false otherwise.
Since
0.1.0
Return values
trueThe board periph touch last condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for board periph touch last.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 353 of file board_periph_i2c.c.

References s_gt911.

Referenced by internal_fill_status_hw().

◆ board_periph_touch_reported()

uint32_t board_periph_touch_reported ( void )

Count of touch contacts the firmware has drained from the GT911 model.

Incremented each time the firmware reads the GT911 point0 record for an armed contact (i.e. a real ra8_touch_read -> I3C -> GT911 point fetch completed). The run loop uses this – instead of a stub-side counter – to know a headless --click has flowed all the way through the real touch path before it drains the post-click settle window.

Returns
Number of contacts reported through the modelled GT911.
Since
0.1.0
Return values
valueThe operation-specific board periph touch reported value.
Precondition
Arguments satisfy the ranges documented for board periph touch reported.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 348 of file board_periph_i2c.c.

References s_gt911.

Referenced by internal_run_loop_click_tail(), internal_run_loop_tick_inputs(), and internal_run_print_stop_summary().

◆ board_periph_touch_seq_push()

bool board_periph_touch_seq_push ( uint16_t x,
uint16_t y )

Queue one raw touch point onto the modelled GT911 injection FIFO.

Appends (x, y) to the sequence the GT911 model serves one point per drained frame (see board_periph_touch_seq_reset). While the FIFO is non-empty every GT911 status read reports a buffer-ready frame with one contact, and the matching point0 read returns the head point and advances the queue – exactly as a real GT911 latches the next physical touch after the controller drains and acks the current one. Points are consumed in push order, so callers push them in the same order the firmware presents targets.

Parameters
[in]xPanel X coordinate of the queued contact (GT911-native units).
[in]yPanel Y coordinate of the queued contact.
Returns
true if the point was queued; false if the FIFO is full.
Postcondition
On true the queued depth grows by one.
Since
0.1.0
Return values
trueThe board periph touch seq push condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for board periph touch seq push.
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 318 of file board_periph_i2c.c.

References k_gt911_seq_max, and s_gt911.

Referenced by internal_main_arm_touch_seq().

◆ board_periph_touch_seq_reset()

void board_periph_touch_seq_reset ( void )

Clear the modelled GT911 injected-touch sequence FIFO.

The FIFO is the multi-tap analogue of board_periph_touch_inject: instead of one re-armed contact it queues a SEQUENCE of distinct raw points, delivering the next queued point on each ra8_touch_read frame the firmware drains. It exists so an interactive N-point flow – e.g. the touch-calibration example (touch_cal, #262), which must collect one raw sample per on-screen target – can run headless in ra8_emulator: on silicon a human taps N cross-hairs; in EIL the CLI (--touch-seq, board_periph_touch_seq_push) supplies N synthetic raw taps that return through the genuine ra8_touch_read decode. Resetting empties the queue and drops any point armed from it.

Returns
Nothing.
Postcondition
The sequence FIFO is empty; the next status read reports "no frame".
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board periph touch seq reset.
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 311 of file board_periph_i2c.c.

References s_gt911.

Referenced by internal_main_arm_touch_seq().

◆ board_periph_uart_last_line()

const char * board_periph_uart_last_line ( void )

The most recent complete line the firmware transmitted over any SCI.

The SCI_B TX path captures each transmitted byte into a line buffer that is latched on newline (CR is dropped), so the board view can show the last console line a non-display example printed – e.g. "hello, ra8d2!" from uart_hello -- on its "UART:" status line. Returns a pointer to static storage holding the last completed line (empty string before the first newline); the pointer must not be freed and is valid until the next TX byte.

Returns
NUL-terminated last UART line (never NULL; empty until one is sent).
Since
0.1.0

Definition at line 183 of file board_periph_sci.c.

References s_uart_last.

Referenced by internal_fill_status_hw(), and internal_run_stop_banner().

◆ board_periph_uart_tx_total()

uint32_t board_periph_uart_tx_total ( void )

Total bytes the firmware has transmitted over all SCI channels.

Sum of every modelled SCI channel's TX byte counter – a coarse "how chatty is this firmware" figure the board view shows beside the console panel. Counts raw TDR-write bytes (including CR/LF), not completed lines.

Returns
Total SCI TX byte count since reset.
Since
0.1.0
Return values
valueThe operation-specific board periph uart tx total value.
Precondition
Arguments satisfy the ranges documented for board periph uart tx total.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 188 of file board_periph_sci.c.

References k_sci_count, and s_sci.

Referenced by internal_fill_status_console().

◆ board_periph_usbhs_loop()

bool board_periph_usbhs_loop ( void )

Report whether the USBHS-host self-loop model is enabled.

Returns
true when board_periph_set_usbhs_loop last enabled it, else false.
Precondition
None; safe at any time (defaults to false).
Postcondition
No model state is modified (read-only accessor).
Note
Not thread-safe; single-threaded run-loop / setup use.
See also
board_periph_set_usbhs_loop
Since
0.1.0

Report whether the usbhs-host self-loop model is enabled; this step is contained within the board periph model and uses bounded caller or module-owned storage.

Return values
trueThe board periph usbhs loop condition holds or completed successfully; false otherwise.
Precondition
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 215 of file board_periph.c.

References s_usbhs_loop.

◆ board_periph_write()

void board_periph_write ( uc_engine * uc,
uint64_t addr,
unsigned size,
uint64_t value,
bool * handled )

Dispatch an MMIO write to the owning block, if any.

Parameters
[in,out]ucUnicorn engine (handlers may read emulated memory).
[in]addrAbsolute peripheral address being written.
[in]sizeAccess width in bytes (1/2/4).
[in]valueValue being written.
[out]handledTrue iff a modelled block consumed the write.
Returns
Nothing.
Since
0.1.0

Dispatch an mmio write to the owning block, if any; this step is contained within the board periph model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for board periph write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 611 of file board_periph.c.

References board_usb_host_write(), board_usb_write(), internal_block_for_addr(), internal_icu_ielsr_slot(), internal_icu_write(), k_icu_ielsr_cnt, board_periph_block_t::observe, priv_board_mstp_addr_stopped(), priv_board_mstp_note_gated_access(), and board_periph_block_t::write.

Referenced by mmio_write().