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

Self-loop (loop-cable) transport (see board_usb_internal.h). More...

#include <stdio.h>
#include <string.h>
#include "board_usb_internal.h"
#include "ra8_elc_regs.h"
#include "ra8_usb_regs.h"
Include dependency graph for board_usb_loop.c:

Go to the source code of this file.

Enumerations

enum  loop_req_mask_t : uint16_t {
  k_loop_req_bm_mask = 0x00FFU ,
  k_ra8_usb_dcp_brdy_bit = 0x0001U
}
 SETUP-word decode helpers + the DCP status bit for the loop path. More...

Functions

static void internal_loop_reset_pipe (uint8_t pipe)
 Reset one pipe's IN/OUT staging plus the host-side read cursor.
static void internal_loop_reset_dcp (void)
 Reset the DCP staging (both directions) plus the host read cursor.
void board_usb_loop_latch (void)
 Latch the self-loop: the firmware brought a controller up as HOST.
bool board_usb_loop_attached (void)
 Whether the modelled USBFS device presents its D+ pull-up.
void board_usb_loop_bus_reset (uc_engine *uc)
 Deliver a bus reset to the modelled USBFS device (host released RST).
bool board_usb_loop_setup (uc_engine *uc, uint16_t req, uint16_t val, uint16_t indx, uint16_t leng)
 Deliver one SETUP packet from the firmware host to the device.
bool board_usb_loop_take_ccpl (uc_engine *uc)
 Poll the device's control-transfer completion (DCPCTR.CCPL).
uint16_t board_usb_loop_ctrl_in_avail (void)
 Control-IN bytes the device has queued and the host not yet drained.
uint16_t board_usb_loop_ctrl_in_read (uint8_t *dst, uint16_t cap)
 Drain up to cap control-IN bytes from the device's DCP staging.
void board_usb_loop_ctrl_in_flush (void)
 Drop whatever remains of the device's control-IN staging.
void board_usb_loop_ctrl_out (uc_engine *uc, const uint8_t *data, uint16_t len)
 Deliver a control-OUT data-stage packet to the device's DCP.
void board_usb_loop_status_out_zlp (uc_engine *uc)
 Run the control-read status stage against the device (host OUT ZLP).
void board_usb_loop_bulk_out (uc_engine *uc, uint8_t ep, const uint8_t *data, uint16_t len)
 Deliver one bulk-OUT packet from the firmware host to a device pipe.
uint16_t board_usb_loop_bulk_in_avail (uint8_t ep)
 Bulk-IN bytes a device pipe has queued and the host not yet drained.
uint16_t board_usb_loop_bulk_in_read (uc_engine *uc, uint8_t ep, uint8_t *dst, uint16_t cap)
 Drain up to cap bulk-IN bytes from a device pipe's staging.
void board_usb_loop_bulk_in_flush (uint8_t ep)
 Drop whatever remains of a device pipe's bulk-IN staging.

Variables

bool s_loop_latched
 Firmware host owns the bus.
static bool s_loop_pending_cfg
 SET_CONFIGURATION in flight.
static uint16_t s_loop_dcp_rd
 Host cursor into dcp_in.
static uint16_t s_loop_pipe_rd [k_usb_pipe_count]
 Host cursors into pipe_in.
uint32_t s_loop_setups
 SETUPs the fw host delivered.
uint32_t s_loop_bulk_out_pkts
 Bulk-OUT packets delivered.
uint32_t s_loop_bulk_in_pkts
 Bulk-IN packets drained.

Detailed Description

Self-loop (loop-cable) transport (see board_usb_internal.h).

The board_usb_loop_* family the register-level USBHS host model drives when the firmware itself is the bus host (self-loop bench), plus the latch/reset state – moved verbatim out of board_usb.c.

Since
0.1.0

Definition in file board_usb_loop.c.

Enumeration Type Documentation

◆ loop_req_mask_t

enum loop_req_mask_t : uint16_t

SETUP-word decode helpers + the DCP status bit for the loop path.

Enumerator
k_loop_req_bm_mask 

bmRequestType byte of USBREQ.

k_ra8_usb_dcp_brdy_bit 

BRDYSTS bit 0: the DCP (pipe 0).

Definition at line 41 of file board_usb_loop.c.

Function Documentation

◆ board_usb_loop_attached()

bool board_usb_loop_attached ( void )

Whether the modelled USBFS device presents its D+ pull-up.

Returns
true when the device firmware set SYSCFG.DPRPU (attach), else false.
Since
0.1.0

Whether the modelled usbfs device presents its d+ pull-up; this step is contained within the board USB model and uses bounded caller or module-owned storage.

Return values
trueThe board USB loop attached condition holds or completed successfully; false otherwise.
Precondition
Arguments satisfy the ranges documented for board USB loop attached.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 92 of file board_usb_loop.c.

References priv_host_device_attached().

Referenced by internal_usbhs_do_setup(), internal_usbhs_dvstctr_write(), and internal_usbhs_reg_read().

◆ board_usb_loop_bulk_in_avail()

uint16_t board_usb_loop_bulk_in_avail ( uint8_t ep)

Bulk-IN bytes a device pipe has queued and the host not yet drained.

Parameters
[in]epDevice endpoint number (1..9).
Returns
Byte count remaining in that pipe's IN staging (0 when none).
Since
0.1.0

Bulk-in bytes a device pipe has queued and the host not yet drained; this step is contained within the board USB model and uses bounded caller or module-owned storage.

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

References k_usb_pipe_count, s_loop_pipe_rd, and s_usb.

Referenced by board_usb_loop_bulk_in_read(), internal_usbhs_brdysts_value(), and internal_usbhs_cfifoctr_value().

◆ board_usb_loop_bulk_in_flush()

void board_usb_loop_bulk_in_flush ( uint8_t ep)

Drop whatever remains of a device pipe's bulk-IN staging.

Parameters
[in]epDevice endpoint number (1..9).
Returns
Nothing.
Since
0.1.0

Drop whatever remains of a device pipe's bulk-in staging; this step is contained within the board USB model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for board USB loop bulk in flush.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 282 of file board_usb_loop.c.

References k_usb_pipe_count, s_loop_pipe_rd, and s_usb.

Referenced by internal_usbhs_cfifoctr_write().

◆ board_usb_loop_bulk_in_read()

uint16_t board_usb_loop_bulk_in_read ( uc_engine * uc,
uint8_t ep,
uint8_t * dst,
uint16_t cap )

Drain up to cap bulk-IN bytes from a device pipe's staging.

Once the staging is fully drained the device's BEMP for that pipe is raised (transmit buffer empty) so the device firmware can queue the next packet – exactly what the built-in host's echo reader does.

Parameters
[in,out]ucUnicorn engine (to pend the device's USB interrupt).
[in]epDevice endpoint number (1..9).
[out]dstDestination buffer.
[in]capCapacity of dst in bytes.
Returns
Number of bytes copied (0 when nothing is staged).
Since
0.1.0
Return values
valueThe operation-specific board USB loop bulk in read value.
Precondition
Arguments satisfy the ranges documented for board USB loop bulk in read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 257 of file board_usb_loop.c.

References board_usb_loop_bulk_in_avail(), internal_usb_word(), k_ra8_int0_bit_bemp, k_ra8_usb_off_bempsts, k_usb_pipe_count, priv_usb_intsts0_set(), priv_usb_raise_irq(), s_loop_bulk_in_pkts, s_loop_pipe_rd, and s_usb.

Referenced by internal_usbhs_cfifo_read().

◆ board_usb_loop_bulk_out()

void board_usb_loop_bulk_out ( uc_engine * uc,
uint8_t ep,
const uint8_t * data,
uint16_t len )

Deliver one bulk-OUT packet from the firmware host to a device pipe.

Stages the packet in the device pipe's OUT buffer and raises the pipe's BRDY, mirroring the built-in host's echo path. The device pipe is addressed by ENDPOINT number: the ux_dcd_ra8_usb bridge maps device endpoint n onto controller pipe n, the same fixed mapping the built-in virtual host encodes.

Parameters
[in,out]ucUnicorn engine (to pend the device's USB interrupt).
[in]epDevice endpoint number (1..9).
[in]dataPacket bytes.
[in]lenPacket length (clamped to the pipe staging size).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB loop bulk out.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 230 of file board_usb_loop.c.

References internal_usb_word(), k_ra8_int0_bit_brdy, k_ra8_usb_off_brdysts, k_usb_pipe_count, memcpy(), priv_usb_intsts0_set(), priv_usb_raise_irq(), s_loop_bulk_out_pkts, and s_usb.

Referenced by internal_usbhs_cfifoctr_write().

◆ board_usb_loop_bus_reset()

void board_usb_loop_bus_reset ( uc_engine * uc)

Deliver a bus reset to the modelled USBFS device (host released RST).

Drops any staged control / bulk data (a bus reset empties the FIFOs), forces the device state to Default, and raises the DVST interrupt so the device firmware re-arms its DCP – the same sequence the built-in virtual host performs at the start of its enumeration.

Parameters
[in,out]ucUnicorn engine (to pend the device's USB interrupt).
Returns
Nothing.
Postcondition
Device DVSQ = Default; stale staging buffers are cleared.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB loop bus 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 97 of file board_usb_loop.c.

References internal_loop_reset_dcp(), internal_loop_reset_pipe(), k_ra8_ctsq_idle, k_ra8_dvsq_default, k_ra8_int0_bit_dvst, k_usb_pipe_count, priv_usb_intsts0_set(), priv_usb_log_line(), priv_usb_raise_irq(), and s_usb.

Referenced by internal_usbhs_dvstctr_write().

◆ board_usb_loop_ctrl_in_avail()

uint16_t board_usb_loop_ctrl_in_avail ( void )

Control-IN bytes the device has queued and the host not yet drained.

Returns
Byte count remaining in the device's DCP IN staging (0 when none is committed).
Since
0.1.0

Control-in bytes the device has queued and the host not yet drained; this step is contained within the board USB model and uses bounded caller or module-owned storage.

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

References s_loop_dcp_rd, and s_usb.

Referenced by board_usb_loop_ctrl_in_read(), internal_usbhs_brdysts_value(), and internal_usbhs_cfifoctr_value().

◆ board_usb_loop_ctrl_in_flush()

void board_usb_loop_ctrl_in_flush ( void )

Drop whatever remains of the device's control-IN staging.

The host-side equivalent of a DCP read-window BCLR: any undrained response bytes are discarded and the staging is released.

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

References s_loop_dcp_rd, and s_usb.

Referenced by internal_usbhs_cfifoctr_write().

◆ board_usb_loop_ctrl_in_read()

uint16_t board_usb_loop_ctrl_in_read ( uint8_t * dst,
uint16_t cap )

Drain up to cap control-IN bytes from the device's DCP staging.

The host-side read cursor advances; once the staging is fully drained it is released so the device can queue the next response.

Parameters
[out]dstDestination buffer.
[in]capCapacity of dst in bytes.
Returns
Number of bytes copied (0 when nothing is staged).
Since
0.1.0
Return values
valueThe operation-specific board USB loop ctrl in read value.
Precondition
Arguments satisfy the ranges documented for board USB loop ctrl in read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 182 of file board_usb_loop.c.

References board_usb_loop_ctrl_in_avail(), priv_usb_detect_class(), s_loop_dcp_rd, and s_usb.

Referenced by internal_usbhs_cfifo_read().

◆ board_usb_loop_ctrl_out()

void board_usb_loop_ctrl_out ( uc_engine * uc,
const uint8_t * data,
uint16_t len )

Deliver a control-OUT data-stage packet to the device's DCP.

Stages the bytes in the device's DCP OUT buffer and raises the device's DCP BRDY – the packet a device-side ra8_usb_dcp_out_read then drains.

Parameters
[in,out]ucUnicorn engine (to pend the device's USB interrupt).
[in]dataPayload bytes (host to device).
[in]lenPayload length in bytes (clamped to the staging size).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB loop ctrl out.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 206 of file board_usb_loop.c.

References internal_usb_word(), k_ra8_int0_bit_brdy, k_ra8_usb_dcp_brdy_bit, k_ra8_usb_off_brdysts, memcpy(), priv_usb_intsts0_set(), priv_usb_raise_irq(), and s_usb.

Referenced by internal_usbhs_cfifoctr_write().

◆ board_usb_loop_latch()

void board_usb_loop_latch ( void )

Latch the self-loop: the firmware brought a controller up as HOST.

Called by the USBHS host model when the firmware selects host mode (SYSCFG.DCFM on the HS instance). From then on the bench topology is the loop cable – the firmware host owns the bus – so the built-in virtual host parks for the remainder of the run (its tick returns immediately) instead of competing for the device's control pipe and stealing bulk-IN data. One-way for the run; a later host deinit leaves the cable in place, exactly like the physical bench.

Returns
Nothing.
Postcondition
board_usb_tick is inert; the loop calls below drive the device.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB loop latch.
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 83 of file board_usb_loop.c.

References priv_usb_log_line(), and s_loop_latched.

Referenced by board_usb_host_write().

◆ board_usb_loop_setup()

bool board_usb_loop_setup ( uc_engine * uc,
uint16_t req,
uint16_t val,
uint16_t indx,
uint16_t leng )

Deliver one SETUP packet from the firmware host to the device.

Latches the four SETUP half-words into USBREQ..USBLENG, marks the SETUP valid with the matching control-stage code (CTSQ), and raises the device's CTRT interrupt. SET_ADDRESS is applied SIE-style (USBADDR latch + DVSQ Address + DVST) exactly as the built-in host does; SET_CONFIGURATION arms the configured-state transition for the device's CCPL.

Parameters
[in,out]ucUnicorn engine (to pend the device's USB interrupt).
[in]reqUSBREQ word (bmRequestType | bRequest << 8).
[in]valwValue.
[in]indxwIndex.
[in]lengwLength.
Returns
true when the device SIE completes the whole transfer itself (SET_ADDRESS): the host's status stage needs no device CCPL.
Return values
trueSIE-handled request; treat the status stage as already done.
falseNormal request; the device firmware will end it with CCPL.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB loop setup.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 111 of file board_usb_loop.c.

References internal_loop_reset_dcp(), internal_usb_word(), k_loop_req_bm_mask, k_ra8_ctsq_rdds, k_ra8_ctsq_wrds, k_ra8_ctsq_wrnd, k_ra8_dvsq_address, k_ra8_int0_bit_ctrt, k_ra8_int0_bit_dvst, k_ra8_usb_off_usbaddr, k_ra8_usb_off_usbindx, k_ra8_usb_off_usbleng, k_ra8_usb_off_usbreq, k_ra8_usb_off_usbval, k_ra8_usbaddr_addr_mask, k_usb_byte_bits, k_usb_dir_device_to_host, k_usb_dir_host_to_device, k_usb_log_width, k_usb_req_set_address, k_usb_req_set_config, priv_host_take_ccpl(), priv_usb_intsts0_set(), priv_usb_log_line(), priv_usb_raise_irq(), s_loop_pending_cfg, s_loop_setups, and s_usb.

Referenced by internal_usbhs_do_setup().

◆ board_usb_loop_status_out_zlp()

void board_usb_loop_status_out_zlp ( uc_engine * uc)

Run the control-read status stage against the device (host OUT ZLP).

Advances the device's control stage to "read status" and raises CTRT so the device firmware completes the transfer with CCPL – what the host's zero-length status OUT causes on hardware.

Parameters
[in,out]ucUnicorn engine (to pend the device's USB interrupt).
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB loop status out zlp.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 222 of file board_usb_loop.c.

References k_ra8_ctsq_rdss, k_ra8_int0_bit_ctrt, priv_usb_intsts0_set(), priv_usb_raise_irq(), and s_usb.

Referenced by internal_usbhs_do_ccpl().

◆ board_usb_loop_take_ccpl()

bool board_usb_loop_take_ccpl ( uc_engine * uc)

Poll the device's control-transfer completion (DCPCTR.CCPL).

Observes – and consumes – the device firmware's CCPL write, which on hardware makes the device SIE hand the host its status-stage ZLP. When the completed request was SET_CONFIGURATION the device state advances to Configured (DVST raised), mirroring the built-in host's flow.

Parameters
[in,out]ucUnicorn engine (to pend the device's USB interrupt).
Returns
true when the device had asserted CCPL since the last poll.
Return values
trueTransfer complete; the host's status ZLP is available.
falseNo completion yet (device firmware still processing).
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for board USB loop take ccpl.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB 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 162 of file board_usb_loop.c.

References priv_host_mark_configured(), priv_host_take_ccpl(), and s_loop_pending_cfg.

Referenced by internal_usbhs_brdysts_value().

◆ internal_loop_reset_dcp()

void internal_loop_reset_dcp ( void )
static

Reset the DCP staging (both directions) plus the host read cursor.

Reset the dcp staging (both directions) plus the host read cursor; this step is contained within the board USB loop model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for loop reset default control pipe.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB loop 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 73 of file board_usb_loop.c.

References RA8_INTERNAL, s_loop_dcp_rd, and s_usb.

Referenced by board_usb_loop_bus_reset(), and board_usb_loop_setup().

◆ internal_loop_reset_pipe()

void internal_loop_reset_pipe ( uint8_t pipe)
static

Reset one pipe's IN/OUT staging plus the host-side read cursor.

Reset one pipe's in/out staging plus the host-side read cursor; this step is contained within the board USB loop model and uses bounded caller or module-owned storage.

Parameters
[in]pipeUSB pipe index selected by the transfer.
Precondition
Arguments satisfy the ranges documented for loop reset pipe.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board USB loop 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 55 of file board_usb_loop.c.

References RA8_INTERNAL, s_loop_pipe_rd, and s_usb.

Referenced by board_usb_loop_bus_reset().

Variable Documentation

◆ s_loop_bulk_in_pkts

uint32_t s_loop_bulk_in_pkts

Bulk-IN packets drained.

Bulk-IN packets (loop).

Definition at line 29 of file board_usb_loop.c.

Referenced by board_usb_loop_bulk_in_read(), and board_usb_report().

◆ s_loop_bulk_out_pkts

uint32_t s_loop_bulk_out_pkts

Bulk-OUT packets delivered.

Bulk-OUT packets (loop).

Definition at line 28 of file board_usb_loop.c.

Referenced by board_usb_loop_bulk_out(), and board_usb_report().

◆ s_loop_dcp_rd

uint16_t s_loop_dcp_rd
static

◆ s_loop_latched

bool s_loop_latched

Firmware host owns the bus.

Firmware host owns the bus (loop).

Definition at line 23 of file board_usb_loop.c.

Referenced by board_usb_loop_latch(), board_usb_report(), and board_usb_tick().

◆ s_loop_pending_cfg

bool s_loop_pending_cfg
static

SET_CONFIGURATION in flight.

Definition at line 24 of file board_usb_loop.c.

Referenced by board_usb_loop_setup(), and board_usb_loop_take_ccpl().

◆ s_loop_pipe_rd

uint16_t s_loop_pipe_rd[k_usb_pipe_count]
static

◆ s_loop_setups

uint32_t s_loop_setups

SETUPs the fw host delivered.

SETUPs from the fw host (loop).

Definition at line 27 of file board_usb_loop.c.

Referenced by board_usb_loop_setup(), and board_usb_report().