61 priv_usb_log_line(
"role swap: FS window = host model, HS window = device model (Config B)");
91 if (setup ==
nullptr) {
95 .bm_request_type = setup[0],
96 .b_request = setup[1],
97 .w_value = (uint16_t)((uint16_t)setup[2] | (uint16_t)((uint16_t)setup[3] << 8)),
98 .w_index = (uint16_t)((uint16_t)setup[4] | (uint16_t)((uint16_t)setup[5] << 8)),
99 .w_length = (uint16_t)((uint16_t)setup[6] | (uint16_t)((uint16_t)setup[7] << 8)),
100 .name =
"bridge SETUP",
115 if (buf ==
nullptr) {
118 uint16_t n =
s_usb.dcp_in.len;
129 const uint16_t limit =
131 for (uint16_t i = 0U; (i < limit) && (w >= 0) && ((size_t)w <
sizeof(line)); i++) {
132 w += snprintf(&line[w],
sizeof(line) - (
size_t)w,
"%02X ", (
unsigned)
s_usb.dcp_in.data[i]);
136 s_usb.dcp_in.len = 0U;
137 s_usb.dcp_in.valid =
false;
144 s_usb.setup_valid =
false;
161 if (data ==
nullptr) {
166 if (n > (uint16_t)
sizeof(b->data)) {
167 n = (uint16_t)
sizeof(b->data);
169 (void)
memcpy(b->data, data, n);
174 s_usb.reg[w] = (uint16_t)(
s_usb.reg[w] | (uint16_t)(1U << dev_pipe));
186 return b->ready && (b->rd >= b->len);
192 return b->valid && (b->len > 0U);
197 if (buf ==
nullptr) {
205 (void)
memcpy(buf, b->data, n);
209 s_usb.reg[w] = (uint16_t)(
s_usb.reg[w] | (uint16_t)(1U << dev_pipe));
218 if (data ==
nullptr) {
275 s_usb.dcp_out.rd = 0U;
276 s_usb.dcp_out.ready =
true;
uint32_t board_usbhs_host_shadow_handoff(uint16_t *dst_words, uint32_t word_capacity)
Hand the host model's register shadow off and reset the host model.
void board_usb_bridge_mark_configured(uc_engine *uc)
Mark the device configured after a host SET_CONFIGURATION.
bool board_usb_bridge_bulk_out_consumed(uint8_t dev_pipe)
Whether the device has drained the last host bulk-OUT packet.
bool board_usb_bridge_dcp_out_consumed(void)
Whether the device has drained the last host DCP control-OUT packet.
void board_usb_bridge_ctrl_status(uc_engine *uc)
Drive the read-status stage of a host control-read (raise CTRT).
bool board_usb_roles_swapped(void)
Whether the self-loop window roles are swapped (Config B).
bool board_usb_bridge_dcp_in_ready(void)
Whether the device has queued a control-IN response on the DCP.
void board_usb_bridge_deliver_setup(uc_engine *uc, const uint8_t *setup)
Deliver an 8-byte host SETUP packet to the device (raise its CTRT).
uint16_t board_usb_bridge_bulk_in_take(uc_engine *uc, uint8_t dev_pipe, uint8_t *buf, uint16_t cap)
Consume a device bulk-IN packet from dev_pipe into buf.
void board_usb_dev_reg_write(uc_engine *uc, uint64_t off, unsigned size, uint64_t value)
Device-model register write by window byte offset (role routing).
void priv_bridge_pump_device(uc_engine *uc)
Re-assert a device level-triggered condition the polled host awaits.
void board_usb_roles_swap(uc_engine *uc)
Swap the self-loop window<->model bindings (enter Config B).
void board_usb_set_external_host(bool present)
Declare (or withdraw) a real-firmware USB host driving the device.
uint64_t board_usb_dev_reg_read(uc_engine *uc, uint64_t off, unsigned size)
Device-model register read by window byte offset (role routing).
void board_usb_bridge_bus_reset(uc_engine *uc)
Bridge a host bus reset onto the device (advance DVSQ to Default).
bool board_usb_dev_attached(void)
Whether the modelled USBFS device has asserted its D+ pull-up (DPRPU).
bool board_usb_bridge_bulk_in_ready(uint8_t dev_pipe)
Whether the device has queued a bulk-IN packet on dev_pipe.
void board_usb_bridge_dcp_out(uc_engine *uc, const uint8_t *data, uint16_t len)
Deliver a host control-write data-stage packet to the device DCP.
uint16_t board_usb_bridge_dcp_in_take(uint8_t *buf, uint16_t cap)
Consume the device's queued control-IN response into buf.
void board_usb_bridge_bulk_out(uc_engine *uc, uint8_t dev_pipe, const uint8_t *data, uint16_t len)
Deliver a host bulk-OUT packet to a device endpoint pipe.
bool board_usb_bridge_dev_took_ccpl(void)
Take (consume) the device's control-transfer completion (DCPCTR.CCPL).
Module-private state + interfaces shared by the board_usb TUs.
void priv_usb_reg_write(uint64_t off, uint32_t value, unsigned size)
USBFS window register write dispatch (dev).
void priv_usb_raise_irq(uc_engine *uc)
Pend the device's ICU interrupt via the registered raiser (dev).
uint8_t s_dcp_hold[k_usb_in_cap]
Held control-OUT bytes (core).
bool s_external_host
Bridge host owns the bus (core).
usb_state_t s_usb
Controller + FIFO state (core).
void priv_host_mark_configured(uc_engine *uc)
Advance the device state to CONFIGURED (vhost).
void priv_usb_intsts0_set(uint8_t bit)
Set one INTSTS0 event bit in the register shadow (dev).
bool priv_host_take_ccpl(void)
Consume the device's CCPL (control transfer complete) (vhost).
@ k_usb_pipe_count
DCP (0) + PIPE1..PIPE9.
@ k_usb_reg_words
16-bit register shadow word count.
void priv_host_apply_no_data(uc_engine *uc, const usb_setup_step_t *s)
Apply a no-data control write's device-state side effects (vhost).
bool priv_host_device_attached(void)
True when SYSCFG.DPRPU is set: the device attached its pull-up (vhost).
void priv_usb_log_line(const char *msg)
Append one already-formatted line to the enumeration-step log (core).
bool s_dcp_hold_pending
Held bytes await the arm (core).
@ k_usb_log_width
Bytes per enumeration-step log line.
@ k_usb_trace_dump_max
Control-IN payload bytes shown in –trace.
@ k_usb_dcp_pipe_bit
DCP (pipe 0) BRDYSTS/BRDYENB bit mask.
static uint32_t internal_usb_word(uint64_t off)
Word index into the 16-bit register shadow for a window offset.
uint16_t s_dcp_hold_len
Held byte count (core).
void priv_usb_log_count(const char *label, unsigned n)
Log a labelled count once (label + n) into the step log (core).
void priv_usb_detect_class(const uint8_t *d, uint16_t len)
Detect the device class from the enumerated config descriptor (vhost).
bool priv_host_dcp_pid_buf(void)
True when the device armed its DCP to BUF (ready for OUT) (vhost).
bool s_roles_swapped
Self-loop role polarity (core).
uint32_t priv_usb_reg_read(uint64_t off, unsigned size)
USBFS window register read dispatch (dev).
uint16_t g_dev_irq_event
Device ICU event number (core).
void priv_host_deliver_setup(uc_engine *uc, const usb_setup_step_t *s)
Latch a SETUP packet into USBREQ..USBLENG + raise CTRT (vhost).
Bounded raw-descriptor I/O seam for the RA8 emulator.
emu_io_result_t priv_emu_io_errf(const char *format,...)
Format bounded text and write it to the injected error descriptor.
Event Link Controller (ELC) register layout for the Renesas RA8D2.
@ k_ra8_elc_event_usbhs_int_resume
USBHS combined int + resume.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
USB Full-Speed + High-Speed controller layout for the Renesas RA8D2.
@ k_ra8_pid_buf
BUF response (transmit/receive).
@ k_ra8_pid_mask
PID[1:0] field mask.
@ k_ra8_usb_off_brdyenb
BRDYENB : BRDY Enable.
@ k_ra8_usb_off_bempsts
BEMPSTS : BEMP Status.
@ k_ra8_usb_off_dcpctr
DCPCTR : DCP control.
@ k_ra8_usb_off_brdysts
BRDYSTS : BRDY Status.
@ k_ra8_ctsq_rdss
Control read status stage.
@ k_ra8_int0_bit_bemp
Buffer-empty interrupt.
@ k_ra8_int0_bit_dvst
Device-state transition.
@ k_ra8_int0_bit_brdy
Buffer-ready interrupt.
@ k_ra8_int0_bit_ctrt
Control-transfer-stage transition.
@ k_ra8_dvsq_default
Default (post bus reset).
One pipe's device-visible IN staging buffer (device -> host payload).
One pipe's host-visible OUT staging buffer (host -> device payload).
One SETUP step in the host enumeration script (USB 2.0 sec 9.4).
static volatile uint32_t s_trace[k_dcd_trace_entries]
JLink-readable ring of packed transfer/SETUP events.