46 return "CDC-ACM active";
48 return "Printer active";
50 return "Vendor active";
75 while (((uint32_t)i + 2U) <= (uint32_t)len) {
76 const uint8_t blen = d[i];
77 const uint8_t btype = d[i + 1U];
104 i = (uint16_t)((uint32_t)i + (uint32_t)blen);
133 (void)
priv_emu_io_errf(
" [usb] HID mouse report: btn=0x%02X dx=%+d dy=%+d -> cursor (%d,%d)\n",
161 "GET_DESCRIPTOR(device,8)"},
167 "GET_DESCRIPTOR(device,full)"},
179 "GET_DESCRIPTOR(device,full)"},
185 "GET_DESCRIPTOR(config,9)"},
191 "GET_DESCRIPTOR(config,full)"},
197 "GET_DESCRIPTOR(string,0)"},
203 "SET_CONFIGURATION(1)"},
215 "SET_CONTROL_LINE_STATE"},
269 s_usb.dcp_in.len = 0U;
270 s_usb.dcp_in.valid =
false;
271 s_usb.dcp_out.len = 0U;
272 s_usb.dcp_out.rd = 0U;
273 s_usb.dcp_out.ready =
false;
283 s_usb.dcp_out.len = n;
284 s_usb.dcp_out.rd = 0U;
285 s_usb.dcp_out.ready =
true;
289 s_usb.setup_valid =
true;
293 (void)snprintf(line,
sizeof(line),
"SETUP[%u] %s -> CTRT raised", (
unsigned)
s_host_step, s->
name);
310 s_usb.dcp_in.len = 0U;
311 s_usb.dcp_in.valid =
false;
326 const bool seen = (
s_usb.reg[w] & ccpl) != 0U;
328 s_usb.reg[w] = (uint16_t)(
s_usb.reg[w] & (uint16_t)~ccpl);
345 snprintf(line,
sizeof(line),
"SET_ADDRESS: DVSQ -> Address (addr=%u)", (
unsigned)s->
w_value);
411 s_usb.setup_valid =
false;
566 b->len = (uint16_t)chunk;
592 if (b->valid && (b->len > 0U)) {
606 }
else if (b->valid) {
618typedef enum : uint8_t {
626typedef enum : uint8_t {
633typedef enum : uint32_t {
668 for (uint32_t i = 0U; i < 16U; i++) {
705 uint8_t cdb_len = 0U;
706 uint32_t data_len = 0U;
713 uint8_t* d = b->data;
732 for (uint32_t i = 0U; i < 16U; i++) {
763 const uint16_t n = (b->len < cap) ? b->len : cap;
764 for (uint16_t i = 0U; i < n; i++) {
792 const uint32_t last_lba =
Module-private state + interfaces shared by the board_usb TUs.
uint32_t s_msc_blocks
MSC capacity in blocks (vhost).
@ k_usb_dir_host_to_device
OUT: host -> device (control write).
@ k_usb_dir_device_to_host
IN: device -> host (control read).
void priv_usb_raise_irq(uc_engine *uc)
Pend the device's ICU interrupt via the registered raiser (dev).
@ k_le_lane_b2
Bits 23:16.
@ k_le_lane_b3
Most-significant byte (bits 31:24).
@ k_le_lane_b0
Least-significant byte (bits 7:0).
usb_host_sub_t
Per-SETUP-step sub-states.
@ k_sub_status
Deliver the status stage + raise CTRT.
@ k_sub_wait_in
Wait for the device's IN data (control read).
@ k_sub_deliver
Latch the SETUP + raise CTRT.
@ k_sub_next
Advance to the next script step.
@ k_sub_wait_ack
Wait for the device's CCPL (transfer end).
bool s_external_host
Bridge host owns the bus (core).
@ k_phase_reset
Holding bus reset; device re-arms its DCP.
@ k_phase_done
Terminal idle.
@ k_phase_configured
Device configured; optional bulk echo.
@ k_phase_setup
Walking the enumeration script.
@ k_cdc_req_set_control_line_state
SET_CONTROL_LINE_STATE.
@ k_cdc_req_set_line_coding
SET_LINE_CODING (OUT data).
usb_state_t s_usb
Controller + FIFO state (core).
uint8_t s_host_substate
Per-step sub-state (core).
int32_t s_hid_cy
Accumulated HID mouse Y (vhost).
uint32_t s_echo_in_got
Echoed bytes read back (core).
@ k_usb_dt_interface
INTERFACE descriptor type.
@ k_usb_iclass_vendor
Vendor specific (issue #265).
@ k_usb_iclass_cdc_comm
Communications (CDC control).
@ k_usb_iclass_hid
Human Interface Device.
@ k_usb_iclass_cdc_data
CDC data.
@ k_usb_iclass_msc
Mass Storage.
@ k_usb_iclass_printer
Printer (issue #265).
uint8_t s_host_step
Enumeration-script index (core).
uint32_t s_host_wait
Sub-state wait ticks (core).
uint32_t s_msc_block_len
MSC block size (vhost).
uint8_t s_dev_class
Detected device class (vhost).
uint8_t s_echo_out[k_usb_echo_cap]
Host bulk-OUT payload (core).
uint8_t s_host_phase
Virtual-host phase (core).
@ k_usb_req_set_config
SET_CONFIGURATION.
@ k_usb_req_get_descriptor
GET_DESCRIPTOR.
@ k_usb_req_set_address
SET_ADDRESS.
void priv_usb_intsts0_set(uint8_t bit)
Set one INTSTS0 event bit in the register shadow (dev).
@ k_usb_in_cap
DCP/bulk IN staging cap (multi-MPS).
@ k_usb_dcp_mps
EP0 default control-pipe max packet.
@ k_usb_pipe_mps
Bulk-FS data pipe max packet.
@ k_usb_dt_string
STRING descriptor.
@ k_usb_dt_device
DEVICE descriptor.
@ k_usb_dt_config
CONFIGURATION descriptor.
@ k_be_lane_b3
Most-significant byte (bits 31:24).
@ k_be_lane_b2
Bits 23:16.
@ k_be_lane_b0
Least-significant byte (bits 7:0).
uint32_t s_msc_read_ok
MSC read data bytes (vhost).
void priv_usb_log_line(const char *msg)
Append one already-formatted line to the enumeration-step log (core).
int32_t s_hid_cx
Accumulated HID mouse X (vhost).
usb_dev_class_t
USB device class the host detected from the interface descriptor.
@ k_usb_class_printer
Printer (7/1/x), issue #265.
@ k_usb_class_cdc
CDC-ACM (virtual serial).
@ k_usb_class_hid
HID (boot mouse / keyboard).
@ k_usb_class_msc
Mass storage (BOT/SCSI).
@ k_usb_class_unknown
Not yet detected.
@ k_usb_class_vendor
Vendor specific (0xFF).
@ k_cdc_line_coding_len
SET_LINE_CODING wLength.
@ k_cbw_cdblen_off
CBW bCBWCBLength offset.
@ k_usb_shift24
Byte-3 position in a 32-bit word.
@ k_sector_bytes
Logical block size.
@ k_usb_req_class_iface
bmRequestType: class, interface, host->device.
@ k_cbw_tag_off
CBW dCBWTag offset (LE u32).
@ k_scsi_inquiry
SCSI INQUIRY opcode.
@ k_iface_class_off
bInterfaceClass offset in the iface descriptor.
@ k_scsi_read_capacity
SCSI READ CAPACITY(10) opcode.
@ k_cbw_flags_off
CBW bmCBWFlags offset.
@ k_cbw_cdb_off
CBW CBWCB (command block) offset.
@ k_cbw_dtl_off
CBW dCBWDataTransferLength offset (LE u32).
@ k_inquiry_len
INQUIRY allocation length.
@ k_cdb10_len
10-byte CDB length.
@ k_cbw_lun_off
CBW bCBWLUN offset.
@ k_scsi_read10
SCSI READ(10) opcode.
bool s_msc_inquiry_ok
MSC INQUIRY completed (vhost).
@ k_cap10_last_lba_off
Returned logical block address (BE u32).
@ k_cap10_blocklen_off
Block length in bytes (BE u32).
@ k_usb_desc_dev_len
Full device-descriptor length.
@ k_usb_str_len
String-descriptor request length.
@ k_usb_step_timeout
Host per-step wait budget (ticks).
@ k_usb_reset_settle
Ticks held in bus reset before SETUP.
@ k_usb_cfg_full_cap
Config-descriptor full request cap.
@ k_usb_bulk_in_pipe
CDC bulk IN pipe (EP1 IN -> pipe 1).
@ k_usb_bulk_out_pipe
CDC bulk OUT pipe (EP2 OUT -> pipe 2).
@ k_usb_desc8_len
First GET_DESCRIPTOR(device) length.
@ k_usb_byte_mask
One-byte mask.
@ k_usb_log_width
Bytes per enumeration-step log line.
@ k_usb_post_cfg_idle
Settle ticks after CONFIGURED.
@ k_usb_cfg_probe_len
Config-descriptor header probe len.
@ k_usb_addr_assigned
Address the host assigns the device.
@ k_usb_config_value
bConfigurationValue the host sets.
@ k_usb_byte_bits
Bits per byte.
static uint32_t internal_usb_word(uint64_t off)
Word index into the 16-bit register shadow for a window offset.
void priv_usb_log_count(const char *label, unsigned n)
Log a labelled count once (label + n) into the step log (core).
uint32_t s_hid_reports
HID reports read (vhost).
uint32_t s_echo_out_len
Bytes queued by –usb-in (core).
bool priv_host_dcp_pid_buf(void)
True when the device armed its DCP to BUF (ready for OUT) (vhost).
uint8_t s_hid_buttons
Last HID button bitmap (vhost).
uint32_t s_echo_out_sent
Bytes delivered to device (core).
static void internal_host_msc_phase_csw(uc_engine *uc)
Phase k_msc_csw: take the CSW, then advance to the next command.
static uint32_t s_msc_tag
Running dCBWTag.
static void internal_host_msc_drive(uc_engine *uc)
Drive the MSC BOT state machine one tick while CONFIGURED.
static void internal_host_msc_phase_data(uc_engine *uc)
Phase k_msc_data: drain the data phase until it is done or stalls.
void priv_host_mark_configured(uc_engine *uc)
Mark the device CONFIGURED: advance DVSQ and raise DVST.
static void internal_host_step_next(uc_engine *uc, const usb_setup_step_t *s)
Sub-state k_sub_next: record any post-step effect, advance the step.
static void internal_host_msc_parse_capacity(const uint8_t *d, uint16_t n)
Parse a READ CAPACITY (10) response into block count + size.
static uint32_t s_msc_data_len
Expected data-phase length.
static void internal_host_step_wait_in(void)
Sub-state k_sub_wait_in: await the device's control-IN response.
void priv_host_run_configured_phase(uc_engine *uc)
Phase k_phase_configured: optionally drive the CDC bulk echo.
void priv_host_run_setup_phase(uc_engine *uc)
Run one micro-step of the active enumeration script entry.
bool priv_host_take_ccpl(void)
Observe (and clear) DCPCTR.CCPL: the device ended a control transfer.
void priv_host_apply_no_data(uc_engine *uc, const usb_setup_step_t *s)
Apply the SIE-owned side effects of a no-data control request.
static void internal_host_step_status(uc_engine *uc)
Sub-state k_sub_status: deliver the control-read status stage.
static void internal_host_msc_phase_send(uc_engine *uc)
Phase k_msc_send: push the next CBW, or finish the script.
static const usb_setup_step_t s_k_enum_script[]
The chapter-9 + CDC SETUP sequence the virtual host drives.
static uint16_t internal_host_setup_ctsq(const usb_setup_step_t *s)
CTSQ control-stage value the host advertises for a SETUP.
static void internal_host_msc_record_data(const uint8_t *d, uint16_t n)
Record one data-phase burst against the command that is in flight.
static void internal_host_msc_build_cdb(uint8_t cmd, uint8_t *cdb, uint8_t *cdb_len, uint32_t *data_len)
Build the SCSI CDB for the scripted command cmd.
static uint32_t s_msc_wait
Phase pacing.
bool priv_host_device_attached(void)
True when SYSCFG.DPRPU is set: the device has attached its pull-up.
msc_script_cmd_t
Index of each command in the scripted SCSI sequence.
@ k_msc_cmd_read10
READ (10): LBA 0, one block.
@ k_msc_cmd_inquiry
INQUIRY: standard data, 36-byte allocation.
@ k_msc_cmd_read_capacity
READ CAPACITY (10): last LBA + block size.
static uint32_t internal_host_script_len(void)
Number of steps in the enumeration script.
msc_const_t
BOT / SCSI sizing the host uses (USB Mass Storage BBB 1.0).
@ k_msc_cmd_count
Scripted commands (below).
@ k_msc_csw_len
Command Status Wrapper length.
@ k_msc_settle
Ticks to wait for a phase.
@ k_msc_flag_in
bmCBWFlags: device-to-host.
@ k_msc_cbw_len
Command Block Wrapper length.
const char * priv_usb_class_active_str(void)
Human-readable active-class suffix once the device is configured.
static void internal_host_step_deliver(uc_engine *uc, const usb_setup_step_t *s)
Sub-state k_sub_deliver: latch + raise CTRT, then pick the next sub.
void priv_host_echo_read_in(uc_engine *uc)
Drain bytes the device queued on the IN pipe; ack the IN transfer.
static void internal_host_msc_send_cbw(uc_engine *uc)
Push the current command's CBW onto the bulk-OUT pipe (raise BRDY).
static uint16_t internal_host_msc_take_in(uc_engine *uc, uint8_t *out, uint16_t cap)
Consume one IN buffer (data or CSW) and acknowledge it with BEMP.
void priv_host_run_idle_phase(uc_engine *uc)
Phase k_phase_idle: wait for the device pull-up, then bus-reset.
static uint8_t s_msc_cmd
Index into the SCSI command script.
static void internal_host_echo_send_out(uc_engine *uc)
Deliver one bulk-OUT packet to the CDC data OUT pipe and signal BRDY.
static void internal_usb_hid_decode_report(const uint8_t *d, uint16_t len)
Decode one HID boot-protocol mouse input report from the device.
static uint32_t s_msc_data_got
Data-phase bytes read so far.
static uint8_t s_msc_phase
msc_phase_t for the active command.
void priv_usb_detect_class(const uint8_t *d, uint16_t len)
Detect the device class from a returned descriptor, if it is config.
bool priv_host_dcp_pid_buf(void)
DCPCTR.PID == BUF: the device has armed an IN response.
static void internal_host_latch_setup(const usb_setup_step_t *s)
Latch a SETUP packet into USBREQ..USBLENG (host -> device).
msc_phase_t
MSC BOT per-command phase.
@ k_msc_csw
Read the 13-byte CSW.
@ k_msc_send
Push the next command's CBW.
@ k_msc_done
All scripted commands finished.
@ k_msc_data
Read the data-phase bytes.
void priv_host_run_reset_phase(uc_engine *uc)
Phase k_phase_reset: hold reset a few ticks so the DCP re-arms.
static void internal_host_drain_in(void)
Drain the device's queued control-IN data as the host's read.
static void internal_host_step_wait_ack(void)
Sub-state k_sub_wait_ack: await the device's CCPL (transfer end).
void priv_host_deliver_setup(uc_engine *uc, const usb_setup_step_t *s)
Deliver the current script step's SETUP and raise the CTRT IRQ.
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.
static volatile bool s_configured
Latched true once the host drives the device to CONFIGURED.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Event Link Controller (ELC) register layout for the Renesas RA8D2.
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
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_syscfg_bit_dprpu
D+ pull-up enable (device).
@ k_ra8_usb_off_usbleng
USBLENG : USB request wLength.
@ k_ra8_usb_off_usbindx
USBINDX : USB request wIndex.
@ k_ra8_usb_off_usbaddr
USBADDR : USB address.
@ k_ra8_usb_off_usbval
USBVAL : USB request wValue.
@ k_ra8_usb_off_bempsts
BEMPSTS : BEMP Status.
@ k_ra8_usb_off_dcpctr
DCPCTR : DCP control.
@ k_ra8_usb_off_usbreq
USBREQ : USB request type.
@ k_ra8_usb_off_brdysts
BRDYSTS : BRDY Status.
@ k_ra8_usb_off_syscfg
SYSCFG : System config.
@ k_ra8_dcpctr_bit_ccpl
Control transfer end enable.
@ k_ra8_usbaddr_addr_mask
7-bit USB address [6:0].
@ k_ra8_ctsq_rdss
Control read status stage.
@ k_ra8_ctsq_rdds
Control read data stage.
@ k_ra8_ctsq_wrds
Control write data stage.
@ k_ra8_ctsq_wrnd
Control write nodata status.
@ 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_address
Address assigned.
@ k_ra8_dvsq_default
Default (post bus reset).
@ k_ra8_dvsq_configured
Configured.
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).
uint16_t w_length
wLength (host's expected data size).
uint8_t b_request
bRequest.
uint8_t bm_request_type
Direction + type + recipient.
const char * name
Human label for the step log.
static volatile uint32_t s_trace[k_dcd_trace_entries]
JLink-readable ring of packed transfer/SETUP events.