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

USBHS HOST-mode controller model (self-loop peer of the USBFS device). More...

#include "board_usb_host.h"
#include <stdio.h>
#include <string.h>
#include "board_usb.h"
#include "emu_host_io_internal.h"
#include "ra8_usb_regs.h"
Include dependency graph for board_usb_host.c:

Go to the source code of this file.

Data Structures

struct  usbhs_state_t
 Aggregate USBHS host-controller model state. More...

Enumerations

enum  usbhs_geom_t : uint64_t {
  k_usbhs_base = 0x40351000UL ,
  k_usbhs_span = 0x104UL ,
  k_usbhs_reg_words = 0x104UL / 2U ,
  k_usbhs_stage_cap = 512UL ,
  k_usbhs_mps_fall = 64UL
}
 USBHS register-window geometry and staging sizes. More...
enum  usbhs_dvst_t : uint16_t {
  k_usbhs_dvst_rhst_fs = 0x0002U ,
  k_usbhs_dvst_usbrst = 0x0040U
}
 DVSTCTR0 fields the model owns (HUM Ch 37.2.5). More...
enum  usbhs_pulse_t : uint16_t {
  k_usbhs_dcpctr_sureq = 0x4000U ,
  k_usbhs_dcpctr_sureqclr = 0x0800U ,
  k_usbhs_dcpctr_ccpl = 0x0004U ,
  k_usbhs_ctr_sqset = 0x0080U ,
  k_usbhs_ctr_sqclr = 0x0100U ,
  k_usbhs_ctr_pulse_mask = 0x4980U
}
 DCPCTR / PIPECTR write-pulse bits that never persist in a shadow. More...
enum  usbhs_int1_t : uint16_t {
  k_usbhs_int1_sack = 0x0010U ,
  k_usbhs_int1_sign = 0x0020U
}
 INTSTS1 host-event bits the model latches (HUM Ch 37.2.15). More...
enum  usbhs_bits_t : uint16_t {
  k_usbhs_setup_dir_in = 0x0080U ,
  k_usbhs_dcp_bit = 0x0001U ,
  k_usbhs_lnst_j_state = 0x0001U ,
  k_usbhs_byte_mask = 0x00FFU
}
 SETUP-word decode + status-bit constants for the host model. More...
enum  usbhs_misc_t : uint32_t { k_usbhs_byte_bits = 8U }
 Small integer constants (shifts / offsets) used by the model. More...
enum  usbhs_field_t : uint16_t {
  k_usbhs_dcpmaxp_mxps = 0x007FU ,
  k_usbhs_pipemaxp_mxps = 0x07FFU ,
  k_usbhs_rhst_mask = 0x0007U
}
 Register field masks (HUM Ch 37.2) not exported by ra8_usb_regs.h. More...

Functions

static uint32_t internal_usbhs_word (uint64_t off)
 Word index into the 16-bit register shadow for a window offset.
static uint8_t internal_usbhs_cur_pipe (void)
 Currently-selected CFIFO pipe number (CFIFOSEL.CURPIPE[3:0]).
static bool internal_usbhs_cfifo_isel (void)
 True when CFIFOSEL selects the write (ISEL) side of the DCP port.
static uint8_t internal_usbhs_pipe_ep (uint8_t pipe)
 Device endpoint number a host pipe addresses (PIPECFG.EPNUM).
static bool internal_usbhs_pipe_is_tx (uint8_t pipe)
 True when a host pipe transmits (host-to-device; PIPECFG.DIR set).
static uint16_t internal_usbhs_pipe_mps (uint8_t pipe)
 A pipe's effective max packet size (fallback when unprogrammed).
static uint16_t internal_usbhs_dcp_mps (void)
 The DCP's effective max packet size (fallback when unprogrammed).
static void internal_usbhs_do_setup (uc_engine *uc)
 Run the SETUP transaction the firmware host launched with SUREQ.
static void internal_usbhs_do_ccpl (uc_engine *uc)
 Run the status stage the firmware host launched with CCPL.
static uint16_t internal_usbhs_brdysts_value (uc_engine *uc)
 Compose the live BRDYSTS value (and poll the device's CCPL).
static uint16_t internal_usbhs_cfifoctr_value (void)
 CFIFOCTR read value: FRDY plus the receive-side DTLN.
static uint64_t internal_usbhs_cfifo_read (uc_engine *uc, unsigned size)
 Service a CFIFO data-port read: drain receive bytes, packed LE.
static void internal_usbhs_cfifo_write (uint64_t value, unsigned size)
 Append CFIFO data-port write bytes to the OUT staging buffer.
static void internal_usbhs_cfifoctr_write (uc_engine *uc, uint16_t value)
 Apply a CFIFOCTR write: BCLR discards, BVAL commits over the loop.
static void internal_usbhs_dvstctr_write (uc_engine *uc, uint16_t value)
 Apply a DVSTCTR0 write: bus-reset delivery + RHST latch.
static void internal_usbhs_dcpctr_write (uc_engine *uc, uint16_t value)
 Apply a DCPCTR write: PID persists, SUREQ / CCPL pulses execute.
static uint64_t internal_usbhs_reg_read (uc_engine *uc, uint64_t off, unsigned size)
 Read one USBHS register (engaged path).
static void internal_usbhs_reg_write (uc_engine *uc, uint64_t off, unsigned size, uint64_t value64)
 Write one USBHS register (engaged path).
void board_usb_host_init (bool trace)
 Reset the USBHS host-mode model to its power-on state.
void board_usb_host_set_allowed (bool allowed)
 Grant (or deny) the register-level loop for this firmware.
uint64_t board_usb_host_read (uc_engine *uc, uint64_t addr, unsigned size, bool *handled)
 Dispatch an MMIO read inside the USBHS register window.
void board_usb_host_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value, bool *handled)
 Dispatch an MMIO write inside the USBHS register window.
void board_usb_host_report (void)
 Print the USBHS host-model section of the end-of-run summary.

Variables

static usbhs_state_t s_hs
 Single USBHS host-model instance.
static bool s_hs_trace
 When true, each loop-cable transaction is logged to injected error sink.

Detailed Description

USBHS HOST-mode controller model (self-loop peer of the USBFS device).

Implements the model declared in board_usb_host.h. The register window is the shared "USB2_B" layout (ra8_usb_regs.h; HUM Ch 37 for the USBHS instance) plus the HS-only PHY registers (PLLSTA / PHYSET / LPSTS) and the DEVADDn slots. The polled first-party host engine drives this window with plain MMIO – no interrupts – so the model services each access synchronously and forwards the resulting bus transactions to the modelled USBFS device over the loop-cable transport (board_usb.h):

  • DCPCTR.SUREQ runs the SETUP transaction: the USBREQ..USBLENG mirrors are delivered to the device (its CTRT path) and SACK latches in INTSTS1 – a device SIE always ACKs a SETUP (USB 2.0 sec 8.5.3), so no wait is modelled. With nothing attached SIGN latches instead.
  • BRDYSTS composes live: the DCP bit reflects control-IN bytes the device committed (or its status-stage ZLP after the device's CCPL), and each receive pipe's bit reflects that endpoint's committed bulk-IN staging.
  • The CFIFO port drains those stagings on reads (32-bit accesses, the HS MBW) and accumulates OUT payloads on writes; CFIFOCTR.BVAL commits an OUT packet over the loop (control-OUT to the DCP, bulk-OUT to the addressed endpoint) and raises the matching BEMP "transmitted" status.
  • DCPCTR.CCPL runs the status stage: an OUT ZLP after a control read (advancing the device to its read-status stage), or – after a control write / no-data request – arming the wait for the device firmware's CCPL, whose observation becomes the host's status-ZLP BRDY.
  • DVSTCTR0.USBRST release delivers a bus reset to the device and latches RHST = full-speed (the looped USBFS device); SYSSTS0.LNST reflects the device's D+ pull-up.
Since
0.1.0

Definition in file board_usb_host.c.

Enumeration Type Documentation

◆ usbhs_bits_t

enum usbhs_bits_t : uint16_t

SETUP-word decode + status-bit constants for the host model.

Enumerator
k_usbhs_setup_dir_in 

bmRequestType bit 7: device-to-host.

k_usbhs_dcp_bit 

BRDYSTS / BEMPSTS bit 0 (the DCP).

k_usbhs_lnst_j_state 

SYSSTS0.LNST: J-state (FS idle).

k_usbhs_byte_mask 

One-byte mask.

Definition at line 84 of file board_usb_host.c.

◆ usbhs_dvst_t

enum usbhs_dvst_t : uint16_t

DVSTCTR0 fields the model owns (HUM Ch 37.2.5).

Enumerator
k_usbhs_dvst_rhst_fs 

RHST = 10b: full-speed link.

k_usbhs_dvst_usbrst 

USBRST: bus-reset signalling.

Definition at line 62 of file board_usb_host.c.

◆ usbhs_field_t

enum usbhs_field_t : uint16_t

Register field masks (HUM Ch 37.2) not exported by ra8_usb_regs.h.

Enumerator
k_usbhs_dcpmaxp_mxps 

DCPMAXP.MXPS: DCP max packet field.

k_usbhs_pipemaxp_mxps 

PIPEMAXP.MXPS: pipe max packet field.

k_usbhs_rhst_mask 

DVSTCTR0.RHST: connected-speed (RO).

Definition at line 97 of file board_usb_host.c.

◆ usbhs_geom_t

enum usbhs_geom_t : uint64_t

USBHS register-window geometry and staging sizes.

Enumerator
k_usbhs_base 

USBHS base (HUM Ch 37, p 2059).

k_usbhs_span 

Window: through LPSTS at +0x102.

k_usbhs_reg_words 

16-bit register shadow word count.

k_usbhs_stage_cap 

OUT staging (one HS bulk packet).

k_usbhs_mps_fall 

DTLN clamp when no MPS is programmed.

Definition at line 53 of file board_usb_host.c.

◆ usbhs_int1_t

enum usbhs_int1_t : uint16_t

INTSTS1 host-event bits the model latches (HUM Ch 37.2.15).

Enumerator
k_usbhs_int1_sack 

SACK: the device ACKed the SETUP.

k_usbhs_int1_sign 

SIGN: three SETUP attempts failed.

Definition at line 78 of file board_usb_host.c.

◆ usbhs_misc_t

enum usbhs_misc_t : uint32_t

Small integer constants (shifts / offsets) used by the model.

Enumerator
k_usbhs_byte_bits 

Bits per byte (LE packing shifts).

Definition at line 92 of file board_usb_host.c.

◆ usbhs_pulse_t

enum usbhs_pulse_t : uint16_t

DCPCTR / PIPECTR write-pulse bits that never persist in a shadow.

Enumerator
k_usbhs_dcpctr_sureq 

SUREQ: launch the SETUP (pulse).

k_usbhs_dcpctr_sureqclr 

SUREQCLR: abort a SETUP (pulse).

k_usbhs_dcpctr_ccpl 

CCPL: run the status stage.

k_usbhs_ctr_sqset 

SQSET: force DATA1 (pulse).

k_usbhs_ctr_sqclr 

SQCLR: force DATA0 (pulse).

k_usbhs_ctr_pulse_mask 

SUREQ | SQCLR | SQSET (never stored).

Definition at line 68 of file board_usb_host.c.

Function Documentation

◆ board_usb_host_init()

void board_usb_host_init ( bool trace)

Reset the USBHS host-mode model to its power-on state.

Clears the register shadows, the per-pipe configuration window, the FIFO staging and the engagement latch. Call once from board_periph_init before the run loop, next to board_usb_init.

Parameters
[in]traceWhen true, each loop-cable transaction is logged to injected error sink.
Returns
Nothing.
Postcondition
The model is dormant; every window access falls through until the firmware engages host mode (and the loop is allowed).
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB host 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 789 of file board_usb_host.c.

References s_hs, and s_hs_trace.

Referenced by board_periph_init().

◆ board_usb_host_read()

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

Dispatch an MMIO read inside the USBHS register window.

Parameters
[in,out]ucUnicorn engine (loop-cable calls pend device IRQs).
[in]addrAbsolute peripheral address being read.
[in]sizeAccess width in bytes (1 / 2 / 4).
[out]handledTrue iff the model is engaged and addr is inside the USBHS window.
Returns
The register value when *handled is true, else 0.
Since
0.1.0

Dispatch an mmio read inside the usbhs register window; this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Return values
valueThe operation-specific board USB host read value.
Precondition
Arguments satisfy the ranges documented for board USB host read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host 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 800 of file board_usb_host.c.

References internal_usbhs_reg_read(), k_usbhs_base, k_usbhs_span, and s_hs.

Referenced by board_periph_read().

◆ board_usb_host_report()

void board_usb_host_report ( void )

Print the USBHS host-model section of the end-of-run summary.

Silent unless the model engaged; then reports the SETUP / bulk transaction totals the firmware host drove over the loop.

Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB host report.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host 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 843 of file board_usb_host.c.

References priv_emu_io_errf(), and s_hs.

Referenced by board_periph_report().

◆ board_usb_host_set_allowed()

void board_usb_host_set_allowed ( bool allowed)

Grant (or deny) the register-level loop for this firmware.

main.c calls this after its usb-host seam installer ran: when a C-level seam (virtual keyboard / virtual MSC disk) was installed for the firmware's host API, the register path is shadowed by those seams and this model must stay dormant so seamed apps keep their exact current behaviour. Only an unseamed firmware (e.g. the TrustZone NS image, whose symbols the seam installer never scans) gets the register-level loop.

Parameters
[in]allowedtrue to allow engagement on a host-mode SYSCFG write.
Returns
Nothing.
Postcondition
With allowed false the model never claims the window this run.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB host set allowed.
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 795 of file board_usb_host.c.

References s_hs.

Referenced by internal_main_install_run_seams().

◆ board_usb_host_write()

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

Dispatch an MMIO write inside the USBHS register window.

Pre-engagement, only the SYSCFG word is watched (for the DCFM host-role select that engages the model); the write still reports unhandled so the sparse fallback keeps recording it, preserving the behaviour of every USBHS app that never engages.

Parameters
[in,out]ucUnicorn engine (loop-cable calls pend device IRQs).
[in]addrAbsolute peripheral address being written.
[in]sizeAccess width in bytes (1 / 2 / 4).
[in]valueValue being written.
[out]handledTrue iff the model is engaged and consumed the write.
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB host write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host 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 811 of file board_usb_host.c.

References board_usb_loop_latch(), internal_usbhs_reg_write(), internal_usbhs_word(), k_ra8_syscfg_bit_dcfm, k_ra8_usb_off_syscfg, k_usbhs_base, k_usbhs_span, priv_emu_io_errf(), and s_hs.

Referenced by board_periph_write().

◆ internal_usbhs_brdysts_value()

uint16_t internal_usbhs_brdysts_value ( uc_engine * uc)
static

Compose the live BRDYSTS value (and poll the device's CCPL).

The DCP bit reflects control-IN bytes the device committed or a ready status ZLP; while the CCPL watch is armed each read polls the looped device's completion so the spin inside internal_host_dcp_in_wait observes the status ZLP the moment the device firmware finishes the request. Each configured receive pipe's bit reflects its endpoint's committed bulk-IN staging.

Parameters
[in,out]ucUnicorn engine (the CCPL poll may pend the device IRQ).
Returns
The BRDYSTS read value.
Return values
0No packet is ready on the DCP or any receive pipe.
Precondition
The model is engaged.
The loop transport is initialised (board_usb model live).
Postcondition
A consumed device CCPL is folded into the status-ZLP flag.
No other model state changes (compose-only otherwise).
Note
Called from the MMIO read hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 387 of file board_usb_host.c.

References board_usb_loop_bulk_in_avail(), board_usb_loop_ctrl_in_avail(), board_usb_loop_take_ccpl(), internal_usbhs_pipe_ep(), internal_usbhs_pipe_is_tx(), k_ra8_usb_pipe_count, k_usbhs_dcp_bit, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_reg_read().

◆ internal_usbhs_cfifo_isel()

bool internal_usbhs_cfifo_isel ( void )
static

True when CFIFOSEL selects the write (ISEL) side of the DCP port.

True when cfifosel selects the write (isel) side of the dcp port; this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Returns
The usbhs cfifo isel result produced by the board USB host model.
Return values
trueThe usbhs cfifo isel condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for usbhs cfifo isel.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 206 of file board_usb_host.c.

References internal_usbhs_word(), k_ra8_fifosel_isel, k_ra8_usb_off_cfifosel, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_cfifoctr_value(), and internal_usbhs_cfifoctr_write().

◆ internal_usbhs_cfifo_read()

uint64_t internal_usbhs_cfifo_read ( uc_engine * uc,
unsigned size )
static

Service a CFIFO data-port read: drain receive bytes, packed LE.

Pops up to size bytes from the selected receive source (DCP control-IN or a receive pipe's bulk-IN) and packs them little-endian – the 32-bit MBW drain the HS engine performs, including its final partial-word read where only the low DTLN-remainder bytes are meaningful.

Parameters
[in,out]ucUnicorn engine (a drained pipe raises the device BEMP).
[in]sizeAccess width in bytes (1 / 2 / 4).
Returns
The packed read value.
Return values
0Nothing staged for the selected source.
Precondition
The model is engaged and CFIFOSEL selects the transfer's pipe.
The caller observed FRDY (always ready here).
Postcondition
Up to size receive bytes are consumed from the staging.
A fully-drained bulk staging raises the device's BEMP for the pipe.
Note
Called from the MMIO read hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 469 of file board_usb_host.c.

References board_usb_loop_bulk_in_read(), board_usb_loop_ctrl_in_read(), internal_usbhs_cur_pipe(), internal_usbhs_pipe_ep(), internal_usbhs_pipe_is_tx(), k_usbhs_byte_bits, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_reg_read().

◆ internal_usbhs_cfifo_write()

void internal_usbhs_cfifo_write ( uint64_t value,
unsigned size )
static

Append CFIFO data-port write bytes to the OUT staging buffer.

Accumulates the little-endian bytes of each port write (32-bit head words at CFIFO+0, the 16-bit CFIFOH / 8-bit CFIFOHH residual aliases at +2 / +3) until BVAL commits the packet over the loop.

Parameters
[in]valueThe written value (little-endian byte order).
[in]sizeAccess width in bytes (1 / 2 / 4).
Returns
Nothing.
Precondition
The model is engaged.
The staging has room (bounded by k_usbhs_stage_cap).
Postcondition
Up to size bytes are appended to the staging.
Overflow bytes beyond the staging capacity are dropped.
Note
Called from the MMIO write hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 510 of file board_usb_host.c.

References k_usbhs_byte_bits, k_usbhs_byte_mask, k_usbhs_stage_cap, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_reg_write().

◆ internal_usbhs_cfifoctr_value()

uint16_t internal_usbhs_cfifoctr_value ( void )
static

CFIFOCTR read value: FRDY plus the receive-side DTLN.

FRDY is always ready (the port never stalls in the model). DTLN presents the next packet's length for the selected receive source: the device's control-IN staging on the DCP read window, or the addressed endpoint's bulk-IN staging on a receive pipe – clamped to the max packet size so a long response drains as MPS-sized packets ending in a short one, exactly the framing the polled engine's short-packet logic expects.

Returns
The composed CFIFOCTR value.
Return values
k_ra8_fifoctr_frdyNo receive bytes pending (DTLN = 0).
Precondition
The model is engaged.
CFIFOSEL selects the pipe the caller is transferring on.
Postcondition
No model state changes (compose-only).
DTLN <= the selected pipe's max packet size.
Note
Called from the MMIO read hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 430 of file board_usb_host.c.

References board_usb_loop_bulk_in_avail(), board_usb_loop_ctrl_in_avail(), internal_usbhs_cfifo_isel(), internal_usbhs_cur_pipe(), internal_usbhs_dcp_mps(), internal_usbhs_pipe_ep(), internal_usbhs_pipe_is_tx(), internal_usbhs_pipe_mps(), k_ra8_fifoctr_dtln, k_ra8_fifoctr_frdy, k_usbhs_mps_fall, and RA8_INTERNAL.

Referenced by internal_usbhs_reg_read().

◆ internal_usbhs_cfifoctr_write()

void internal_usbhs_cfifoctr_write ( uc_engine * uc,
uint16_t value )
static

Apply a CFIFOCTR write: BCLR discards, BVAL commits over the loop.

BCLR on a write window drops the staged OUT bytes; on a receive window it releases the pending source (control-IN remainder plus the status-ZLP flag on the DCP, the endpoint's bulk-IN staging on a pipe). BVAL commits the staged bytes: a control-OUT data packet to the device's DCP, or a bulk-OUT packet to the addressed endpoint – each latching the matching BEMP "transmitted" status the engine's post-commit wait polls. A zero-length DCP BVAL (the read-status OUT ZLP) is inert here: the CCPL pulse that follows runs that stage.

Parameters
[in,out]ucUnicorn engine (loop delivery pends the device IRQ).
[in]valueThe written CFIFOCTR value.
Returns
Nothing.
Precondition
The model is engaged and CFIFOSEL selects the transfer's pipe.
Staged bytes (for BVAL) were pushed via the CFIFO port.
Postcondition
BCLR: the selected side's staging is empty.
BVAL: the packet is delivered and the staging reset.
Note
Called from the MMIO write hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 541 of file board_usb_host.c.

References board_usb_loop_bulk_in_flush(), board_usb_loop_bulk_out(), board_usb_loop_ctrl_in_flush(), board_usb_loop_ctrl_out(), internal_usbhs_cfifo_isel(), internal_usbhs_cur_pipe(), internal_usbhs_pipe_ep(), internal_usbhs_pipe_is_tx(), internal_usbhs_word(), k_ra8_fifoctr_bclr, k_ra8_fifoctr_bval, k_ra8_usb_off_bempsts, k_usbhs_dcp_bit, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_reg_write().

◆ internal_usbhs_cur_pipe()

uint8_t internal_usbhs_cur_pipe ( void )
static

Currently-selected CFIFO pipe number (CFIFOSEL.CURPIPE[3:0]).

Currently-selected cfifo pipe number (cfifosel.curpipe[3:0]); this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Returns
The usbhs cur pipe result produced by the board USB host model.
Return values
valueThe operation-specific usbhs cur pipe value.
Precondition
Arguments satisfy the ranges documented for usbhs cur pipe.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 190 of file board_usb_host.c.

References internal_usbhs_word(), k_ra8_fifosel_curpipe, k_ra8_usb_off_cfifosel, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_cfifo_read(), internal_usbhs_cfifoctr_value(), and internal_usbhs_cfifoctr_write().

◆ internal_usbhs_dcp_mps()

uint16_t internal_usbhs_dcp_mps ( void )
static

The DCP's effective max packet size (fallback when unprogrammed).

The dcp's effective max packet size (fallback when unprogrammed); this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Returns
The usbhs default control pipe mps result produced by the board USB host model.
Return values
valueThe operation-specific usbhs default control pipe mps value.
Precondition
Arguments satisfy the ranges documented for usbhs default control pipe mps.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 274 of file board_usb_host.c.

References internal_usbhs_word(), k_ra8_usb_off_dcpmaxp, k_usbhs_dcpmaxp_mxps, k_usbhs_mps_fall, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_cfifoctr_value().

◆ internal_usbhs_dcpctr_write()

void internal_usbhs_dcpctr_write ( uc_engine * uc,
uint16_t value )
static

Apply a DCPCTR write: PID persists, SUREQ / CCPL pulses execute.

The write-pulse bits (SUREQ / SUREQCLR / SQSET / SQCLR) never persist – SUREQ launches the SETUP transaction and self-clears (a read never observes it mid-flight; the model runs it synchronously). A CCPL rising edge runs the status stage for the active transfer direction.

Parameters
[in,out]ucUnicorn engine (transactions pend the device IRQ).
[in]valueThe written DCPCTR value.
Returns
Nothing.
Precondition
The model is engaged.
For SUREQ, the USBREQ..USBLENG mirrors hold the request.
Postcondition
The shadow holds the persistent bits (PID / CCPL) of value.
Any launched transaction's side effects are applied.
Note
Called from the MMIO write hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 626 of file board_usb_host.c.

References internal_usbhs_do_ccpl(), internal_usbhs_do_setup(), internal_usbhs_word(), k_ra8_usb_off_dcpctr, k_usbhs_ctr_pulse_mask, k_usbhs_dcpctr_ccpl, k_usbhs_dcpctr_sureq, k_usbhs_dcpctr_sureqclr, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_reg_write().

◆ internal_usbhs_do_ccpl()

void internal_usbhs_do_ccpl ( uc_engine * uc)
static

Run the status stage the firmware host launched with CCPL.

After a control READ the host drives an OUT ZLP: advance the device to its read-status stage (its firmware then completes with CCPL) and latch the host's DCP BEMP – the ZLP "transmitted" indication its best-effort wait polls. After a control WRITE / no-data request the host collects the DEVICE's status ZLP: when the SIE already ran it (SET_ADDRESS) the ZLP is ready now, otherwise arm the CCPL watch that internal_usbhs_brdysts_value polls.

Parameters
[in,out]ucUnicorn engine (loop delivery pends the device IRQ).
Returns
Nothing.
Precondition
A SETUP for the active transfer completed (SACK observed).
The model is engaged.
Postcondition
Read status: device advanced to read-status; host DCP BEMP latched.
Write / no-data status: the status-ZLP source is armed or ready.
Note
Called from the MMIO write hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 352 of file board_usb_host.c.

References board_usb_loop_status_out_zlp(), internal_usbhs_word(), k_ra8_usb_off_bempsts, k_usbhs_dcp_bit, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_dcpctr_write().

◆ internal_usbhs_do_setup()

void internal_usbhs_do_setup ( uc_engine * uc)
static

Run the SETUP transaction the firmware host launched with SUREQ.

Reads the USBREQ..USBLENG mirrors from the shadow and delivers the packet to the looped device. A device SIE always ACKs a SETUP token, so SACK latches synchronously; with no device attached (D+ pull-up absent) SIGN latches instead, exactly the three-strikes failure the engine expects. SET_ADDRESS reports SIE-handled: the status stage needs no device CCPL.

Parameters
[in,out]ucUnicorn engine (loop delivery pends the device IRQ).
Returns
Nothing.
Precondition
The model is engaged (host mode + loop granted).
The USBREQ..USBLENG shadows hold the request to deliver.
Postcondition
SACK or SIGN is latched in the INTSTS1 shadow.
The per-transfer stage flags are re-armed for the new transfer.
Note
Called from the MMIO write hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 304 of file board_usb_host.c.

References board_usb_loop_attached(), board_usb_loop_setup(), internal_usbhs_word(), k_ra8_usb_off_intsts1, k_ra8_usb_off_usbindx, k_ra8_usb_off_usbleng, k_ra8_usb_off_usbreq, k_ra8_usb_off_usbval, k_usbhs_int1_sack, k_usbhs_int1_sign, k_usbhs_setup_dir_in, priv_emu_io_errf(), RA8_INTERNAL, s_hs, and s_hs_trace.

Referenced by internal_usbhs_dcpctr_write().

◆ internal_usbhs_dvstctr_write()

void internal_usbhs_dvstctr_write ( uc_engine * uc,
uint16_t value )
static

Apply a DVSTCTR0 write: bus-reset delivery + RHST latch.

The read-only RHST field is masked out of the stored value. On the USBRST falling edge (reset released) with a device attached, the bus reset is delivered to the looped device and RHST latches full-speed – the looped peer is the USBFS controller, so the link trains to FS.

Parameters
[in,out]ucUnicorn engine (loop delivery pends the device IRQ).
[in]valueThe written DVSTCTR0 value.
Returns
Nothing.
Precondition
The model is engaged.
The stored shadow holds the previous DVSTCTR0 control bits.
Postcondition
The shadow holds value minus RHST; RHST reflects the reset result.
On the reset release with a device attached the device re-defaults.
Note
Called from the MMIO write hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 591 of file board_usb_host.c.

References board_usb_loop_attached(), board_usb_loop_bus_reset(), internal_usbhs_word(), k_ra8_usb_off_dvstctr0, k_usbhs_dvst_rhst_fs, k_usbhs_dvst_usbrst, k_usbhs_rhst_mask, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_reg_write().

◆ internal_usbhs_pipe_ep()

uint8_t internal_usbhs_pipe_ep ( uint8_t pipe)
static

Device endpoint number a host pipe addresses (PIPECFG.EPNUM).

Device endpoint number a host pipe addresses (pipecfg.epnum); this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Parameters
[in]pipeUSB pipe index selected by the transfer.
Returns
The usbhs pipe ep result produced by the board USB host model.
Return values
valueThe operation-specific usbhs pipe ep value.
Precondition
Arguments satisfy the ranges documented for usbhs pipe ep.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 223 of file board_usb_host.c.

References k_ra8_pipecfg_epnum_mask, k_ra8_usb_pipe_count, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_brdysts_value(), internal_usbhs_cfifo_read(), internal_usbhs_cfifoctr_value(), and internal_usbhs_cfifoctr_write().

◆ internal_usbhs_pipe_is_tx()

bool internal_usbhs_pipe_is_tx ( uint8_t pipe)
static

True when a host pipe transmits (host-to-device; PIPECFG.DIR set).

True when a host pipe transmits (host-to-device; pipecfg.dir set); this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Parameters
[in]pipeUSB pipe index selected by the transfer.
Returns
The usbhs pipe is tx result produced by the board USB host model.
Return values
trueThe usbhs pipe is tx condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for usbhs pipe is tx.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 241 of file board_usb_host.c.

References k_ra8_pipecfg_dir_in, k_ra8_usb_pipe_count, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_brdysts_value(), internal_usbhs_cfifo_read(), internal_usbhs_cfifoctr_value(), and internal_usbhs_cfifoctr_write().

◆ internal_usbhs_pipe_mps()

uint16_t internal_usbhs_pipe_mps ( uint8_t pipe)
static

A pipe's effective max packet size (fallback when unprogrammed).

A pipe's effective max packet size (fallback when unprogrammed); this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Parameters
[in]pipeUSB pipe index selected by the transfer.
Returns
The usbhs pipe mps result produced by the board USB host model.
Return values
valueThe operation-specific usbhs pipe mps value.
Precondition
Arguments satisfy the ranges documented for usbhs pipe mps.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 257 of file board_usb_host.c.

References k_ra8_usb_pipe_count, k_usbhs_mps_fall, k_usbhs_pipemaxp_mxps, RA8_INTERNAL, and s_hs.

Referenced by internal_usbhs_cfifoctr_value().

◆ internal_usbhs_reg_read()

uint64_t internal_usbhs_reg_read ( uc_engine * uc,
uint64_t off,
unsigned size )
static

Read one USBHS register (engaged path).

Registers with live semantics are composed (SYSSTS0 line state, PLLSTA lock, DVSTCTR0 RHST, CFIFO / CFIFOCTR receive state, BRDYSTS); everything else answers from the plain shadow – including the PIPESEL-windowed configuration, which reads from the selected pipe's slot.

Parameters
[in,out]ucUnicorn engine (receive paths pend the device IRQ).
[in]offByte offset into the USBHS window.
[in]sizeAccess width in bytes.
Returns
The register value – 64-bit wide so the CFIFO port's 32-bit MBW drains are returned untruncated (every other register is 16-bit).
Return values
0Unwritten plain registers (power-on shadow).
Precondition
The model is engaged.
off < k_usbhs_span.
Postcondition
Receive-side reads consume staged bytes (CFIFO only).
All other reads leave the model unchanged.
Note
Called from the MMIO read hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 668 of file board_usb_host.c.

References board_usb_loop_attached(), internal_usbhs_brdysts_value(), internal_usbhs_cfifo_read(), internal_usbhs_cfifoctr_value(), internal_usbhs_word(), k_ra8_fifosel_curpipe, k_ra8_pllsta_plllock, k_ra8_usb_off_brdysts, k_ra8_usb_off_cfifo, k_ra8_usb_off_cfifoctr, k_ra8_usb_off_dvstctr0, k_ra8_usb_off_nrdysts, k_ra8_usb_off_pipebuf, k_ra8_usb_off_pipecfg, k_ra8_usb_off_pipemaxp, k_ra8_usb_off_pipeperi, k_ra8_usb_off_pipesel, k_ra8_usb_off_syssts0, k_ra8_usb_pipe_count, k_ra8_usbhs_off_pllsta, k_usbhs_lnst_j_state, RA8_INTERNAL, and s_hs.

Referenced by board_usb_host_read().

◆ internal_usbhs_reg_write()

void internal_usbhs_reg_write ( uc_engine * uc,
uint64_t off,
unsigned size,
uint64_t value64 )
static

Write one USBHS register (engaged path).

Dispatches the registers with live semantics (CFIFO staging, CFIFOCTR commits, DCPCTR pulses, DVSTCTR0 reset edges, W0C statuses, the PIPESEL-windowed configuration and the PIPECTR pulse bits); everything else stores to the plain shadow.

Parameters
[in,out]ucUnicorn engine (transactions pend the device IRQ).
[in]offByte offset into the USBHS window.
[in]sizeAccess width in bytes.
[in]value64The written value – 64-bit wide so the CFIFO port's 32-bit MBW fills arrive untruncated (every other register consumes its low 16 bits).
Returns
Nothing.
Precondition
The model is engaged.
off < k_usbhs_span.
Postcondition
The write's semantics are applied (shadow / staging / transaction).
Pulse bits never persist in the stored shadows.
Note
Called from the MMIO write hook; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 723 of file board_usb_host.c.

References internal_usbhs_cfifo_write(), internal_usbhs_cfifoctr_write(), internal_usbhs_dcpctr_write(), internal_usbhs_dvstctr_write(), internal_usbhs_word(), k_ra8_fifosel_curpipe, k_ra8_usb_off_bempsts, k_ra8_usb_off_brdysts, k_ra8_usb_off_cfifo, k_ra8_usb_off_cfifoctr, k_ra8_usb_off_dcpctr, k_ra8_usb_off_dvstctr0, k_ra8_usb_off_intsts1, k_ra8_usb_off_nrdysts, k_ra8_usb_off_pipebuf, k_ra8_usb_off_pipecfg, k_ra8_usb_off_pipectr, k_ra8_usb_off_pipemaxp, k_ra8_usb_off_pipeperi, k_ra8_usb_off_pipesel, k_ra8_usb_pipe_count, k_ra8_usb_pipectr_count, k_usbhs_ctr_pulse_mask, k_usbhs_dcp_bit, and s_hs.

Referenced by board_usb_host_write().

◆ internal_usbhs_word()

uint32_t internal_usbhs_word ( uint64_t off)
static

Word index into the 16-bit register shadow for a window offset.

Word index into the 16-bit register shadow for a window offset; this step is contained within the board USB host model and uses bounded caller or module-owned storage.

Parameters
[in]offRegister or byte offset addressed by the operation.
Returns
The usbhs word result produced by the board USB host model.
Return values
valueThe operation-specific usbhs word value.
Precondition
Arguments satisfy the ranges documented for usbhs word.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB host model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 175 of file board_usb_host.c.

References RA8_INTERNAL.

Referenced by board_usb_host_write(), internal_usbhs_cfifo_isel(), internal_usbhs_cfifoctr_write(), internal_usbhs_cur_pipe(), internal_usbhs_dcp_mps(), internal_usbhs_dcpctr_write(), internal_usbhs_do_ccpl(), internal_usbhs_do_setup(), internal_usbhs_dvstctr_write(), internal_usbhs_reg_read(), and internal_usbhs_reg_write().

Variable Documentation

◆ s_hs

usbhs_state_t s_hs
static

Single USBHS host-model instance.

One controller instance exists on the RA8D2, so one model instance suffices; both engines dispatch into it through the shared MMIO hooks.

Note
Mutated only from the ra8_emulator MMIO hooks; not for direct use.
Warning
Reset via board_usb_host_init only.
Since
0.1.0

Definition at line 147 of file board_usb_host.c.

◆ s_hs_trace

bool s_hs_trace
static

When true, each loop-cable transaction is logged to injected error sink.

Latched from the –trace flag by board_usb_host_init.

Note
Read-only outside init.
Warning
Set via board_usb_host_init only.
Since
0.1.0

Definition at line 157 of file board_usb_host.c.

Referenced by board_usb_host_init(), and internal_usbhs_do_setup().