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

USBX device-controller-driver bridge to ra8_usb – per-module cross-translation-unit contract. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_isr.h"
#include "ra8_usb.h"
#include "ux_dcd_ra8_usb.h"
Include dependency graph for ux_dcd_ra8_usb_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_usb_dcd_pipe_slot_t
 Per-pipe class-layer cache so the IRQ handler can re-arm BRDY-driven transfers without crawling the device endpoint list. More...
struct  ra8_usb_dcd_t
 Bridge-singleton state. More...
struct  ra8_usb_dcd_diag_t
 Externally-readable diagnostic counters for OUT-pipe stall debug. More...

Enumerations

enum  ra8_usb_dcd_intsts0_field_shift_t : uint8_t { k_ra8_int0_dvsq_shift = 4U }
 Bit-position shifts used to extract INTSTS0 multi-bit fields. More...
enum  ux_dcd_ra8_usb_orphan_cfg_t : uint16_t { k_ra8_usb_orphan_bytes = 64U }
enum  ra8_usb_dcd_trace_t : uint32_t {
  k_dcd_trace_entries = 64U ,
  k_dcd_trace_kind_out = 1U ,
  k_dcd_trace_kind_in = 2U ,
  k_dcd_trace_kind_setup = 3U ,
  k_dcd_trace_kind_shift = 24U ,
  k_dcd_trace_code_shift = 16U ,
  k_dcd_trace_no_code = 0xFFU ,
  k_dcd_trace_cbw_len = 31U ,
  k_dcd_trace_cbw_op_off = 15U ,
  k_dcd_trace_byte_shift = 8U ,
  k_dcd_trace_op_read10 = 0x28U ,
  k_dcd_trace_op_write10 = 0x2AU ,
  k_dcd_trace_cdb_lba_hi = 4U ,
  k_dcd_trace_cdb_lba_lo = 5U ,
  k_dcd_trace_kind_ocap = 5U ,
  k_dcd_trace_kind_ouse = 6U ,
  k_dcd_trace_kind_ccpl = 7U ,
  k_dcd_trace_kind_dvst = 9U ,
  k_dcd_trace_nibble = 0x0FU ,
  k_dcd_trace_nib_shift = 4U ,
  k_dcd_out_drain_max = 4U
}
 Sizing/packing constants for the JLink-readable event ring. More...
enum  ra8_setup_byte_idx_t : uint8_t {
  k_setup_idx_bmrt = 0U ,
  k_setup_idx_brq = 1U ,
  k_setup_idx_val_lo = 2U ,
  k_setup_idx_val_hi = 3U ,
  k_setup_idx_idx_lo = 4U ,
  k_setup_idx_idx_hi = 5U ,
  k_setup_idx_len_lo = 6U ,
  k_setup_idx_len_hi = 7U
}
 Wire-format byte indices into the USBX SETUP buffer. More...
enum  ra8_setup_byte_pack_t : uint16_t {
  k_setup_byte_shift = 8U ,
  k_setup_byte_mask = 0xFFU
}
 Bit-shift / mask constants for splitting a uint16_t SETUP field into its little-endian byte pair. More...
enum  ra8_usb_ep_addr_field_t : uint8_t {
  k_ra8_usb_ep_addr_dir_in_bit = 0x80U ,
  k_ra8_usb_ep_addr_num_mask = 0x0FU
}
 Bit fields of a USB endpoint address (bEndpointAddress). More...
enum  ra8_usb_dcd_field_mask_t : uint16_t {
  k_ra8_usb_dvsq_field_mask = 0x07U ,
  k_ra8_usb_state_unknown = 0xFFUL
}
 Small field masks and sentinels used across the DCD bridge. More...
enum  ra8_usb_dispatch_skip_bit_t : uint8_t {
  k_ra8_usb_skip_usbreq_unchanged = 0x40U ,
  k_ra8_usb_skip_process_ok = 0x80U
}
 Bits ORed into g_dispatch_skip_reason to record why a SETUP dispatch was skipped or how it completed. More...

Functions

uint8_t priv_ep_to_pipe (uint8_t ep_addr)
 Map a USB EP number (1..9) into the PIPE table index.
unsigned int priv_transfer_request (struct UX_SLAVE_TRANSFER_STRUCT *tr)
 USBX UX_DCD_TRANSFER_REQUEST dispatcher entry point.
void priv_usbfs_irq_mask (void)
 Mask the USB IRQ at the NVIC to break an interrupt storm.
void priv_trace_event (uint8_t kind, uint8_t code, uint16_t length)
 Append one packed event to the JLink-readable trace ring.
ra8_elc_event_t priv_pick_event (ra8_usb_speed_t speed)
 Pick the ELC event number for a controller.
ra8_isr_handler_t priv_pick_isr (ra8_usb_speed_t speed)
 Pick the ISR trampoline for a controller.
void priv_event_cb (void *ctx, ra8_usb_speed_t speed, uint16_t status_mask)
 ra8_usb_attach_handler trampoline into ux_dcd_ra8_usb_irq.
unsigned int priv_dispatch_setup (const ra8_usb_setup_t *setup)
 Push a decoded SETUP packet into the USBX chapter-9 dispatcher.
void priv_handle_ctrt (ra8_usb_speed_t speed, uint16_t intsts0)
 Handle the CTRT (control-transfer-stage) interrupt branch.
void priv_handle_ctrl_out_data (ra8_usb_speed_t speed)
 Drain a deferred control-OUT data stage and run chapter-9.
void priv_dvst_default_state (ra8_usb_speed_t speed)
 Process the DVSQ=Default branch of the DVST handler.
void priv_irq_dvst_prelude (ra8_usb_speed_t speed, uint16_t intsts0)
 Capture DVSTCTR0 / RHST history, mirror speed, dispatch DVST.

Variables

ra8_usb_dcd_t g_dcd
 The single bridge instance, defined in ux_dcd_ra8_usb.c.
ra8_usb_dcd_diag_t g_diag
 Bridge diagnostic counter block, defined in ux_dcd_ra8_usb.c.
volatile uint32_t g_dcd_auto_echo_enable
 Non-zero once ISR-side auto-echo is armed.
uint8_t g_dcd_auto_echo_out_pipe
 Pipe drained by the in-ISR auto-echo path.
uint8_t g_dcd_auto_echo_in_pipe
 Pipe the auto-echo path re-queues onto.
volatile uint32_t g_isr_spurious_run
 Consecutive event-less ISR entries since the last SysTick re-enable.
uint8_t g_orphan_buf [k_ra8_usb_orphan_bytes]
 One held no-receiver bulk-OUT packet.
uint16_t g_orphan_len
 Held orphan byte count; 0 = empty.
uint8_t g_orphan_pipe
 Pipe the held orphan packet is on.
volatile uint32_t g_setup_dispatch_count
 Count of SETUP packets fed into the chapter-9 dispatcher.
volatile uint8_t g_setup_packet_buffer [8]
 Wire-format bytes of the most recent SETUP packet.
volatile uint32_t g_setup_packet_count
 Total SETUP packets latched into g_setup_packet_buffer.
volatile uint32_t g_dispatch_skip_reason
 Last-iteration bitmask of why a SETUP dispatch was skipped or completed.
volatile uint64_t g_last_dispatched_setup_fp
 64-bit fingerprint of the last dispatched SETUP packet.
volatile uint32_t g_setup_token_observed
 Counter of proven device-side SETUP-token latches.

Detailed Description

USBX device-controller-driver bridge to ra8_usb – per-module cross-translation-unit contract.

Tag
[Ring 5 / PORT] {World: S}

The DCD bridge implementation is split across ux_dcd_ra8_usb.c and its per-aspect siblings (ux_dcd_ra8_usb_{ep,xfer,isr,setup,dvst, dvst_default,irq}.c). This header carries every symbol that more than one of those translation units references: the shared typed-enum and struct definitions, the bridge singleton and diagnostic blocks (extern), and the handful of formerly-static helpers that are called across the split. Single-translation-unit symbols stay private to their owning .c; only genuinely shared symbols live here.

This header is included by every translation unit of the bridge, after the public ux_dcd_ra8_usb.h.

Since
0.1.0

Definition in file ux_dcd_ra8_usb_internal.h.

Enumeration Type Documentation

◆ ra8_setup_byte_idx_t

enum ra8_setup_byte_idx_t : uint8_t

Wire-format byte indices into the USBX SETUP buffer.

Mirrors the USB 2.0 Ch 9.3 layout, identical to USBX's own UX_SETUP_REQUEST_TYPE .. UX_SETUP_LENGTH constants but expressed as a typed enum to satisfy the project's no-magic-numbers rule and to keep the SETUP-pack code readable.

Enumerator
k_setup_idx_bmrt 

bmRequestType (offset 0).

k_setup_idx_brq 

bRequest (offset 1).

k_setup_idx_val_lo 

wValue low byte (offset 2).

k_setup_idx_val_hi 

wValue high byte (offset 3).

k_setup_idx_idx_lo 

wIndex low byte (offset 4).

k_setup_idx_idx_hi 

wIndex high byte (offset 5).

k_setup_idx_len_lo 

wLength low byte (offset 6).

k_setup_idx_len_hi 

wLength high byte (offset 7).

Definition at line 174 of file ux_dcd_ra8_usb_internal.h.

◆ ra8_setup_byte_pack_t

enum ra8_setup_byte_pack_t : uint16_t

Bit-shift / mask constants for splitting a uint16_t SETUP field into its little-endian byte pair.

Enumerator
k_setup_byte_shift 

Bits per byte for the hi-byte extraction.

k_setup_byte_mask 

Low-byte mask after the shift.

Definition at line 190 of file ux_dcd_ra8_usb_internal.h.

◆ ra8_usb_dcd_field_mask_t

enum ra8_usb_dcd_field_mask_t : uint16_t

Small field masks and sentinels used across the DCD bridge.

Enumerator
k_ra8_usb_dvsq_field_mask 

3-bit DVSQ/RHST field after shift.

k_ra8_usb_state_unknown 

Device-state snapshot sentinel.

Definition at line 211 of file ux_dcd_ra8_usb_internal.h.

◆ ra8_usb_dcd_intsts0_field_shift_t

Bit-position shifts used to extract INTSTS0 multi-bit fields.

HUM Ch 36.2.16 INTSTS0 p 1986: DVSQ occupies bits 6:4.

Enumerator
k_ra8_int0_dvsq_shift 

DVSQ[2:0] field starts at bit 4.

Definition at line 50 of file ux_dcd_ra8_usb_internal.h.

◆ ra8_usb_dcd_trace_t

enum ra8_usb_dcd_trace_t : uint32_t

Sizing/packing constants for the JLink-readable event ring.

Each ring entry is one uint32 packed as kind<<24 | code<<16 | length: kind 1 = bulk-OUT transfer completed (code = SCSI opcode when the transfer is a 31-byte CBW), kind 2 = bulk-IN transfer completed (code unused), kind 3 = EP0 SETUP received (code = bRequest, length = wValue). Read s_trace_seq then s_trace[] via JLink to reconstruct the device-side BOT conversation after a host probe.

Enumerator
k_dcd_trace_entries 

Ring slots (power of two).

k_dcd_trace_kind_out 

Bulk-OUT transfer completed.

k_dcd_trace_kind_in 

Bulk-IN transfer completed.

k_dcd_trace_kind_setup 

EP0 SETUP received.

k_dcd_trace_kind_shift 

Kind field bit offset.

k_dcd_trace_code_shift 

Code field bit offset.

k_dcd_trace_no_code 

Code when none applies.

k_dcd_trace_cbw_len 

BOT CBW wire length.

k_dcd_trace_cbw_op_off 

CDB opcode offset inside a CBW.

k_dcd_trace_byte_shift 

CDB byte-pair packing shift.

k_dcd_trace_op_read10 

SCSI READ(10) opcode.

k_dcd_trace_op_write10 

SCSI WRITE(10) opcode.

k_dcd_trace_cdb_lba_hi 

CDB byte: LBA bits 15..8.

k_dcd_trace_cdb_lba_lo 

CDB byte: LBA bits 7..0.

k_dcd_trace_kind_ocap 

Orphan OUT packet captured.

k_dcd_trace_kind_ouse 

Orphan packet fed to a transfer.

k_dcd_trace_kind_ccpl 

EP0 H2D status stage driven.

k_dcd_trace_kind_dvst 

DVST event (code = dvsq|state).

k_dcd_trace_nibble 

Low-nibble mask for packed bytes.

k_dcd_trace_nib_shift 

High-nibble shift.

k_dcd_out_drain_max 

Max OUT banks drained per ISR pass.

Definition at line 140 of file ux_dcd_ra8_usb_internal.h.

◆ ra8_usb_dispatch_skip_bit_t

Bits ORed into g_dispatch_skip_reason to record why a SETUP dispatch was skipped or how it completed.

Enumerator
k_ra8_usb_skip_usbreq_unchanged 

USBREQ unchanged since last dispatch.

k_ra8_usb_skip_process_ok 

control_request_process returned OK.

Definition at line 221 of file ux_dcd_ra8_usb_internal.h.

◆ ra8_usb_ep_addr_field_t

enum ra8_usb_ep_addr_field_t : uint8_t

Bit fields of a USB endpoint address (bEndpointAddress).

USB 2.0 sec 9.6.6: bit 7 is the direction bit (1 = IN), and bits 3:0 carry the endpoint number; bits 6:4 are reserved.

Enumerator
k_ra8_usb_ep_addr_dir_in_bit 

Direction bit set => IN endpoint.

k_ra8_usb_ep_addr_num_mask 

Endpoint-number field (bits 3:0).

Definition at line 202 of file ux_dcd_ra8_usb_internal.h.

◆ ux_dcd_ra8_usb_orphan_cfg_t

enum ux_dcd_ra8_usb_orphan_cfg_t : uint16_t
Enumerator
k_ra8_usb_orphan_bytes 

One full-speed bulk MPS packet.

Definition at line 90 of file ux_dcd_ra8_usb_internal.h.

Function Documentation

◆ priv_dispatch_setup()

unsigned int priv_dispatch_setup ( const ra8_usb_setup_t * setup)

Push a decoded SETUP packet into the USBX chapter-9 dispatcher.

Defined in ux_dcd_ra8_usb_setup.c.

Parameters
[in]setupDecoded SETUP packet snapshot (non-null).
Returns
USBX result code.
Return values
UX_SUCCESSChapter-9 dispatcher consumed the SETUP.
UX_ERRORsetup null, USBX not bound, or EP0 unavailable.
Precondition
setup is non-null.
_ux_system_slave is bound by _ux_device_stack_initialize.
Postcondition
EP0 transfer-request setup buffer holds the wire-format SETUP.
Chapter-9 dispatcher has been invoked synchronously.
Note
Runs in IRQ-callback context; must not block.
Since
0.1.0

Mirrors the SETUP into the JLink-readable probe buffer (g_setup_packet_buffer) so the bench can confirm the bridge drained USBREQ/USBVAL/USBINDX/USBLENG correctly even before USBX is fully bound, then forwards the packet through _ux_system_slave's EP0 transfer-request buffer into _ux_device_stack_control_request_process.

Parameters
[in]setupDecoded SETUP packet snapshot (non-null).
Returns
USBX result code.
Return values
UX_SUCCESSChapter-9 dispatcher consumed the SETUP.
UX_ERRORsetup was null, or USBX is not yet bound, or EP0 endpoint is not available.
Precondition
setup is non-null.
_ux_system_slave is bound by _ux_device_stack_initialize.
Postcondition
EP0 transfer-request setup buffer holds the wire-format SETUP.
Chapter-9 dispatcher has been invoked synchronously.
Note
Runs in IRQ-callback context (called from ra8_usb_dispatch via priv_event_cb); must not block.
Since
0.1.0

Definition at line 430 of file ux_dcd_ra8_usb_setup.c.

References ra8_usb_setup_t::b_request, g_dispatch_skip_reason, g_setup_packet_buffer, g_setup_packet_count, internal_pack_setup_le(), internal_try_defer_ctrl_out(), k_dcd_trace_kind_setup, k_ra8_usb_skip_process_ok, priv_trace_event(), and ra8_usb_setup_t::w_value.

Referenced by internal_ctrt_dispatch_fresh_setup(), and internal_dvst_dispatch_if_new().

◆ priv_dvst_default_state()

void priv_dvst_default_state ( ra8_usb_speed_t speed)

Process the DVSQ=Default branch of the DVST handler.

Defined in ux_dcd_ra8_usb_dvst_default.c; drains the persistent SETUP mirrors, dispatches a fresh SETUP if USBREQ changed, then re-arms the DCP via ra8_usb_device_busreset_rearm.

Parameters
[in]speedWhich controller fired.
Precondition
Caller confirmed dvsq == k_ra8_dvsq_default.
g_dcd is past ux_dcd_ra8_usb_initialize.
Postcondition
DCP re-armed via ra8_usb_device_busreset_rearm.
g_busreset_rearm_count incremented.
Note
ISR-callback context; must not block.
Since
0.1.0

Process the DVSQ=Default branch of the DVST handler.

Captures DCPCTR / INTSTS0 probes, drains the persistent SETUP mirrors, dispatches a fresh SETUP if USBREQ changed, then re-arms DCP via ra8_usb_device_busreset_rearm so the IP can latch the host's next SETUP token (FSP usb_pstd_busreset parity). HUM Ch 36.2.7 / 36.2.10 / 36.2.21 (FS) and Ch 37 mirrors.

Parameters
[in]speedWhich controller fired.
Precondition
Caller confirmed dvsq == k_ra8_dvsq_default.
Bridge is past ux_dcd_ra8_usb_initialize.
Postcondition
DCP re-armed via ra8_usb_device_busreset_rearm.
g_busreset_rearm_count incremented.
Note
ISR-callback context; must not block.
Since
0.1.0

Definition at line 453 of file ux_dcd_ra8_usb_dvst_default.c.

References r_usb_regs_t::CFIFOSEL, r_usb_regs_t::DCPCTR, g_busreset_rearm_count, g_cfifosel_after_rearm, g_dcpctr_after_rearm, g_dcpctr_bit_map_observed, g_dcpctr_pre_rearm, g_dispatch_attempts, g_intenb0_after_rearm, g_intsts0_at_sqmon_edge, g_intsts0_observed_or_recent, r_usb_regs_t::INTENB0, internal_dvst_capture_setup_mirror(), internal_dvst_dispatch_if_new(), r_usb_regs_t::INTSTS0, k_ra8_dcpctr_mask_sqmon, k_ra8_usb_speed_hs, ra8_usb_device_busreset_rearm(), ra8_usb_fs(), ra8_usb_hs(), s_prev_dcpctr_sqmon, r_usb_regs_t::USBINDX, r_usb_regs_t::USBLENG, r_usb_regs_t::USBREQ, and r_usb_regs_t::USBVAL.

Referenced by internal_handle_dvst().

◆ priv_ep_to_pipe()

uint8_t priv_ep_to_pipe ( uint8_t ep_addr)

Map a USB EP number (1..9) into the PIPE table index.

Defined in ux_dcd_ra8_usb_xfer.c.

Parameters
[in]ep_addrEndpoint address (with dir bit in 0x80).
Returns
Pipe index 0..9, or k_ux_dcd_ra8_usb_max_pipes on overflow.
Return values
0The masked endpoint number is 0 (control endpoint EP0).
1..9The masked endpoint number, used directly as the pipe index.
k_ux_dcd_ra8_usb_max_pipesThe masked endpoint number is >= the pipe count (out-of-range overflow sentinel).
Precondition
g_dcd is past ux_dcd_ra8_usb_initialize.
Caller has validated arguments.
Postcondition
Side effects bounded to documented state.
State reflects operation result.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Map a USB EP number (1..9) into the PIPE table index.

Parameters
[in]ep_addrEndpoint address (with dir bit in 0x80).
Returns
Pipe index 0..9, or k_ux_dcd_ra8_usb_max_pipes on overflow.

See implementation for details.

Return values
0Success or default value.
Precondition
Module has been initialized.
Caller has validated arguments.
Postcondition
Side effects bounded to documented state.
State reflects operation result.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 66 of file ux_dcd_ra8_usb_xfer.c.

References k_ra8_usb_ep_addr_num_mask, and k_ux_dcd_ra8_usb_max_pipes.

Referenced by internal_endpoint_create(), internal_endpoint_destroy(), internal_endpoint_stall(), and priv_transfer_request().

◆ priv_event_cb()

void priv_event_cb ( void * ctx,
ra8_usb_speed_t speed,
uint16_t status_mask )

ra8_usb_attach_handler trampoline into ux_dcd_ra8_usb_irq.

Defined in ux_dcd_ra8_usb_isr.c.

Parameters
[in,out]ctxUnused ra8_usb callback context.
[in]speedWhich controller fired.
[in]status_maskINTSTS0 snapshot forwarded from ra8_usb_dispatch.
Precondition
g_dcd is past ux_dcd_ra8_usb_initialize.
Caller is ra8_usb_dispatch.
Postcondition
ux_dcd_ra8_usb_irq has run for the snapshot.
No other state changes here.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

ra8_usb_attach_handler trampoline into ux_dcd_ra8_usb_irq.

See implementation for details.

Parameters
[in,out]ctxSee function signature.
[in,out]speedSee function signature.
[in,out]status_maskSee function signature.
Precondition
Module has been initialized.
Caller has validated arguments.
Postcondition
Side effects bounded to documented state.
State reflects operation result.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 500 of file ux_dcd_ra8_usb_isr.c.

References ux_dcd_ra8_usb_irq().

Referenced by ux_dcd_ra8_usb_initialize().

◆ priv_handle_ctrl_out_data()

void priv_handle_ctrl_out_data ( ra8_usb_speed_t speed)

Drain a deferred control-OUT data stage and run chapter-9.

Defined in ux_dcd_ra8_usb_setup.c.

Parameters
[in]speedWhich controller fired (FS or HS).
Precondition
g_dcd is past ux_dcd_ra8_usb_initialize.
Runs ahead of the CTRT status handling within the same IRQ.
Postcondition
On a drained packet, the pending flag is cleared and chapter-9 ran.
On a not-yet-landed bank, state is unchanged (retried next IRQ).
Note
ISR-callback context; must not block past the bounded CFIFO wait.
Since
0.1.0

Back half of the host->device control-write data path; the front half (priv_dispatch_setup) armed the DCP and set g_ctrl_out_pending on the SETUP IRQ. Invoked from ux_dcd_ra8_usb_irq on every IRQ, AHEAD of the CTRT status handling, this acts only when a control-write data stage is pending and the host's OUT packet has landed in the DCP bank (DCP BRDY asserted). It drains the bytes into the captured EP0 transfer buffer via ra8_usb_dcp_out_read and then runs ::_ux_device_stack_control_request_process so the class control_request (e.g. DFU_DNLOAD) sees its payload. The control-write status stage (IN-ZLP) is driven separately by the CTSQ=wrss edge in priv_handle_ctrt.

Deferring to this BRDY IRQ – rather than receiving synchronously in the SETUP IRQ – is mandatory on the USB self-loop: the FS device ISR and the lower-priority HS host worker thread share one CPU, so a blocking receive in the SETUP path would spin out the very thread that must SEND the data.

Parameters
[in]speedWhich controller fired (FS or HS).
Precondition
Bridge is past ux_dcd_ra8_usb_initialize.
Runs ahead of the CTRT status handling within the same IRQ.
Postcondition
On a drained packet, g_ctrl_out_pending is cleared and chapter-9 ran.
On a not-yet-landed bank, state is unchanged (retried next IRQ).
Note
ISR-callback context; must not block past the bounded CFIFO wait.
See also
priv_dispatch_setup
ra8_usb_dcp_out_read
Since
0.1.0

Definition at line 712 of file ux_dcd_ra8_usb_setup.c.

References r_usb_regs_t::BRDYSTS, g_ctrl_out_done, g_ctrl_out_pending, g_ctrl_out_rx, g_ctrl_out_tr, g_ctrl_out_wlen, k_ra8_ok, k_ra8_usb_dcp_brdy_bit, k_ra8_usb_speed_hs, ra8_usb_control_response(), ra8_usb_dcp_out_read(), ra8_usb_fs(), and ra8_usb_hs().

Referenced by ux_dcd_ra8_usb_irq().

◆ priv_handle_ctrt()

void priv_handle_ctrt ( ra8_usb_speed_t speed,
uint16_t intsts0 )

Handle the CTRT (control-transfer-stage) interrupt branch.

Defined in ux_dcd_ra8_usb_setup.c.

Parameters
[in]speedWhich controller fired.
[in]intsts0INTSTS0 snapshot captured at the top of the ISR.
Precondition
Caller has masked intsts0 against the event mask.
g_dcd is past ux_dcd_ra8_usb_initialize.
Postcondition
For SET_ADDRESS, INTSTS0.VALID is W0C-cleared.
For other fresh SETUPs the chapter-9 dispatcher has run.
Note
ISR-callback context; must not block.
Since
0.1.0

Decodes the CTSQ status field from intsts0, drains any latched VALID SETUP via internal_ctrt_handle_valid, and threads the per-stage handlers (SETUP / IN data / OUT data / status). Pulled out of the outer ISR so each helper stays under the NASA P10 Rule 4 size cap. Per HUM Ch 37.2.18 p 2081, USBREQ/USBVAL/USBINDX/USBLENG persist after the SIE auto-clears VALID, so VALID is drained unconditionally and the dispatcher dedups via a 64-bit fingerprint.

Parameters
[in]speedWhich controller fired (k_ra8_usb_speed_fs or k_ra8_usb_speed_hs).
[in]intsts0INTSTS0 snapshot captured at the top of the ISR.
Precondition
Caller has masked intsts0 against the event mask.
Bridge is past ux_dcd_ra8_usb_initialize.
Postcondition
For SET_ADDRESS, INTSTS0.VALID is W0C-cleared.
For other fresh SETUPs the chapter-9 dispatcher has run.
Note
ISR-callback context; must not block.
Since
0.1.0

Definition at line 652 of file ux_dcd_ra8_usb_setup.c.

References internal_ctrt_handle_valid(), k_ra8_ctsq_rdss, k_ra8_ctsq_sqer, k_ra8_ctsq_wrnd, k_ra8_ctsq_wrss, k_ra8_intsts0_mask_ctsq, k_ra8_intsts0_mask_valid, and ra8_usb_control_response().

Referenced by ux_dcd_ra8_usb_irq().

◆ priv_irq_dvst_prelude()

void priv_irq_dvst_prelude ( ra8_usb_speed_t speed,
uint16_t intsts0 )

Capture DVSTCTR0 / RHST history, mirror speed, dispatch DVST.

Defined in ux_dcd_ra8_usb_dvst.c.

Parameters
[in]speedWhich controller fired (FS or HS).
[in]intsts0INTSTS0 snapshot (forwarded to internal_handle_dvst).
Precondition
Caller has already verified the DVST bit is set in intsts0.
g_dcd is past ux_dcd_ra8_usb_initialize.
Postcondition
g_dvst_irq_count and the RHST history are updated.
Speed mirror updated and the DVST state-machine update has run.
Note
ISR-only; must not block.
Since
0.1.0

Pulled out of ux_dcd_ra8_usb_irq so the outer ISR fits in one page. Reads DVSTCTR0 (HUM Ch 36.2.5 p 1971) for RHST history, latches the first-observed value into g_dvstctr0_at_first_dvst, mirrors the settled link speed via internal_dvst_track_speed, then calls internal_handle_dvst for the state-machine update.

Parameters
[in]speedWhich controller fired (FS or HS).
[in]intsts0INTSTS0 snapshot (forwarded to internal_handle_dvst).
Precondition
Caller has already verified the DVST bit is set in intsts0.
Bridge is past ux_dcd_ra8_usb_initialize.
Postcondition
g_dvst_irq_count and g_rhst_history_count incremented.
Speed mirror updated and internal_handle_dvst has run.
Note
ISR-only; must not block.
Since
0.1.0

Definition at line 472 of file ux_dcd_ra8_usb_dvst.c.

References r_usb_regs_t::DVSTCTR0, g_dvst_irq_count, g_dvstctr0_at_first_dvst, g_rhst_history, g_rhst_history_count, internal_dvst_track_speed(), internal_handle_dvst(), k_ra8_usb_dcd_rhst_hist_n, k_ra8_usb_dvsq_field_mask, k_ra8_usb_speed_hs, k_ra8_usb_u16_unset, ra8_usb_fs(), and ra8_usb_hs().

Referenced by ux_dcd_ra8_usb_irq().

◆ priv_pick_event()

ra8_elc_event_t priv_pick_event ( ra8_usb_speed_t speed)

Pick the ELC event number for a controller.

Defined in ux_dcd_ra8_usb_isr.c.

Parameters
[in]speedWhich controller (FS or HS).
Returns
ra8_elc_event_t event number for that controller.
Return values
k_ra8_elc_event_usbhs_int_resumespeed is k_ra8_usb_speed_hs.
k_ra8_elc_event_usbfs_intspeed is k_ra8_usb_speed_fs (any non-HS value).
Precondition
speed is k_ra8_usb_speed_fs or k_ra8_usb_speed_hs.
g_dcd is past ux_dcd_ra8_usb_initialize.
Postcondition
No state mutated.
Pure function.
Note
Pure function.
Since
0.1.0
Parameters
[in]speedWhich controller (FS or HS).
Returns
ra8_elc_event_t event number for that controller.
Precondition
speed is k_ra8_usb_speed_fs or k_ra8_usb_speed_hs.
Postcondition
No state mutated.
Note
Pure function.
Since
0.1.0

See implementation for details.

Return values
0Success or default value.
Precondition
Module has been initialized.
Postcondition
Side effects bounded to documented state.

Definition at line 457 of file ux_dcd_ra8_usb_isr.c.

References k_ra8_elc_event_usbfs_int, k_ra8_elc_event_usbhs_int_resume, and k_ra8_usb_speed_hs.

Referenced by internal_init_bind_owner(), and internal_usbfs_storm_guard_init().

◆ priv_pick_isr()

ra8_isr_handler_t priv_pick_isr ( ra8_usb_speed_t speed)

Pick the ISR trampoline for a controller.

Defined in ux_dcd_ra8_usb_isr.c.

Parameters
[in]speedWhich controller (FS or HS).
Returns
Function pointer to the trampoline.
Return values
internal_usbhs_isrspeed is k_ra8_usb_speed_hs.
internal_usbfs_isrspeed is k_ra8_usb_speed_fs (any non-HS value).
Precondition
speed is k_ra8_usb_speed_fs or k_ra8_usb_speed_hs.
g_dcd is past ux_dcd_ra8_usb_initialize.
Postcondition
No state mutated.
Pure function.
Note
Pure function.
Since
0.1.0
Parameters
[in]speedWhich controller (FS or HS).
Returns
Function pointer to the trampoline.
Precondition
speed is k_ra8_usb_speed_fs or k_ra8_usb_speed_hs.
Postcondition
No state mutated.
Note
Pure function.
Since
0.1.0

See implementation for details.

Return values
0Success or default value.
Precondition
Module has been initialized.
Postcondition
Side effects bounded to documented state.

Definition at line 481 of file ux_dcd_ra8_usb_isr.c.

References internal_usbfs_isr(), internal_usbhs_isr(), and k_ra8_usb_speed_hs.

Referenced by internal_init_bind_owner().

◆ priv_trace_event()

void priv_trace_event ( uint8_t kind,
uint8_t code,
uint16_t length )

Append one packed event to the JLink-readable trace ring.

Defined in ux_dcd_ra8_usb_setup.c; packs kind<<24 | code<<16 | length into the next ring slot.

Parameters
[in]kindEvent kind (ra8_usb_dcd_trace_t kinds).
[in]codePer-kind code byte (opcode / bRequest / none).
[in]lengthPer-kind 16-bit payload (length or wValue).
Precondition
Any context; single concurrent writer (IRQ-callback path).
g_dcd is past ux_dcd_ra8_usb_initialize.
Postcondition
One ring slot holds the packed event; sequence incremented.
No other state changes.
Note
Diagnostic only; never read by production code.
Since
0.1.0

Packs kind<<24 | code<<16 | length into the next ring slot and bumps the sequence counter. Overwrites the oldest entry once the ring wraps.

Parameters
[in]kindEvent kind (ra8_usb_dcd_trace_t kinds).
[in]codePer-kind code byte (opcode / bRequest / none).
[in]lengthPer-kind 16-bit payload (length or wValue).
Precondition
Any context; single concurrent writer (IRQ-callback path).
s_trace_seq monotonicity is maintained by that single writer.
Postcondition
One ring slot holds the packed event; sequence incremented.
No other state changes.
Note
Diagnostic only; never read by production code.
Since
0.1.0

Definition at line 288 of file ux_dcd_ra8_usb_setup.c.

References k_dcd_trace_code_shift, k_dcd_trace_entries, k_dcd_trace_kind_shift, s_dcd_dwt_cyccnt, s_trace, s_trace_seq, and s_trace_ts.

Referenced by internal_ctrt_dispatch_fresh_setup(), internal_dvst_record_history(), internal_irq_complete_in(), internal_irq_drain_orphan_out(), internal_irq_finish_out(), internal_submit_consume_orphan(), and priv_dispatch_setup().

◆ priv_transfer_request()

unsigned int priv_transfer_request ( struct UX_SLAVE_TRANSFER_STRUCT * tr)

USBX UX_DCD_TRANSFER_REQUEST dispatcher entry point.

Defined in ux_dcd_ra8_usb_xfer.c; validates the incoming transfer request, maps the endpoint to a pipe, and dispatches to the EP0 control path or the IN/OUT data-transfer path.

Parameters
[in,out]trUSBX transfer request to submit.
Returns
USBX result code.
Return values
UX_SUCCESSTransfer submitted (and completed by the IRQ path).
UX_TRANSFER_ERRORValidation or bridge-layer rejection.
Precondition
g_dcd is past ux_dcd_ra8_usb_initialize.
Caller is the USBX device-stack dispatcher (task context).
Postcondition
For non-EP0 IN transfers, g_dcd.pipes[pipe] holds the stash.
g_diag counters reflect the dispatch.
Note
Not ISR-safe; runs on the USBX device task context.
Since
0.1.0

Validates the incoming transfer request, maps the endpoint address to a pipe index, and dispatches to either internal_ep0_transfer (EP0 control) or stashes the request and submits an IN/OUT data transfer via internal_submit_pipe through the ra8_usb_* register layer. Under non-standalone builds the request is then awaited via internal_wait_completion so USBX class drivers see synchronous completion with non-zero actual_length.

Parameters
[in,out]trUSBX transfer request to submit. ux_slave_transfer_request_endpoint must point at a configured endpoint; data pointer and requested length describe the buffer.
Returns
USBX result code.
Return values
UX_SUCCESSTransfer submitted (and, in non-standalone builds, completed by the IRQ path).
UX_TRANSFER_ERRORtr was null, endpoint was null, pipe was out of range, or the bridge layer rejected the submission.
Precondition
Bridge is past ux_dcd_ra8_usb_initialize.
Caller is the USBX device-stack dispatcher (task context).
Postcondition
For non-EP0 IN transfers, g_dcd.pipes[pipe] holds the active stash.
g_diag counters reflect the dispatch.
Note
Not ISR-safe; runs on the USBX device task context.
Since
0.1.0

Definition at line 465 of file ux_dcd_ra8_usb_xfer.c.

References g_dcd, g_diag, internal_ep0_transfer(), internal_submit_pipe(), internal_wait_completion(), k_ra8_usb_ep_addr_dir_in_bit, k_ux_dcd_ra8_usb_max_pipes, and priv_ep_to_pipe().

Referenced by _ux_dcd_ra8_usb_function().

◆ priv_usbfs_irq_mask()

void priv_usbfs_irq_mask ( void )

Mask the USB IRQ at the NVIC to break an interrupt storm.

Defined in ux_dcd_ra8_usb.c; called from the ISR trampolines once a sustained run of event-less entries proves a storm.

Precondition
Called from the active controller's ISR context.
s_usb_irq_slot has been resolved at init.
Postcondition
USB IRQ line disabled at the NVIC until the next SysTick re-enable.
Pending USB events stay latched in INTSTS0 / BRDYSTS (level state).
Note
ISR-safe.
Since
0.1.0

Called from internal_usbfs_isr or internal_usbhs_isr once a sustained run of event-less entries proves a storm is in progress. With the line masked the storming controller cannot tail-chain the CPU, so RTOS thread mode runs; the per-app 1 ms SysTick_Handler re-enables the line via ux_dcd_ra8_usb_irq_reenable. The line masked is s_usb_irq_slot – whichever controller this DCD instance drives.

Precondition
Called from the active controller's ISR context.
s_usb_irq_slot has been resolved at init.
Postcondition
USB IRQ line disabled at the NVIC until the next SysTick re-enable.
Pending USB events stay latched in INTSTS0 / BRDYSTS (level state).
Note
ISR-safe.
Since
0.1.0

Definition at line 231 of file ux_dcd_ra8_usb.c.

References internal_usbfs_irq_set_enabled().

Referenced by internal_usbfs_isr(), and internal_usbhs_isr().

Variable Documentation

◆ g_dcd

ra8_usb_dcd_t g_dcd
extern

The single bridge instance, defined in ux_dcd_ra8_usb.c.

The single bridge instance.

RA8 has two USB controllers but the device stack only ever drives one at a time, so a single instance is sufficient. Updated from the ISR and the dispatch trampoline; concurrency is arbitrated at the call-site.

Note
Not thread-safe.
Since
0.1.0

RA8 has two USB controllers but the device stack only ever drives one at a time, so a single static is sufficient.

Note
Not thread-safe – updated from the ISR and the dispatch trampoline; concurrency must be arbitrated at the call-site.

Definition at line 103 of file ux_dcd_ra8_usb.c.

Referenced by _ux_dcd_ra8_usb_function(), internal_endpoint_arm_out_pid(), internal_endpoint_create(), internal_endpoint_destroy(), internal_endpoint_stall(), internal_ep0_transfer(), internal_init_bind_owner(), internal_irq_auto_echo(), internal_irq_complete_in(), internal_irq_complete_out(), internal_irq_drain_orphan_out(), internal_irq_finish_out(), internal_irq_recover_in_nak(), internal_irq_stage_next_in(), internal_irq_walk_pipe(), internal_submit_consume_orphan(), internal_submit_in_pipe(), internal_submit_pipe(), internal_try_defer_ctrl_out(), internal_wait_completion(), priv_transfer_request(), ux_dcd_ra8_usb_initialize(), ux_dcd_ra8_usb_irq(), ux_dcd_ra8_usb_irq_reenable(), ux_dcd_ra8_usb_state(), and ux_dcd_ra8_usb_uninitialize().

◆ g_dcd_auto_echo_enable

volatile uint32_t g_dcd_auto_echo_enable
extern

Non-zero once ISR-side auto-echo is armed.

Defined in ux_dcd_ra8_usb.c.

Since
0.1.0

Definition at line 110 of file ux_dcd_ra8_usb.c.

Referenced by internal_endpoint_arm_out_pid(), internal_irq_auto_echo(), internal_irq_drain_orphan_out(), and ux_dcd_ra8_usb_auto_echo_enable().

◆ g_dcd_auto_echo_in_pipe

uint8_t g_dcd_auto_echo_in_pipe
extern

Pipe the auto-echo path re-queues onto.

Defined in ux_dcd_ra8_usb.c.

Since
0.1.0

Definition at line 114 of file ux_dcd_ra8_usb.c.

Referenced by internal_irq_auto_echo(), and ux_dcd_ra8_usb_auto_echo_enable().

◆ g_dcd_auto_echo_out_pipe

uint8_t g_dcd_auto_echo_out_pipe
extern

Pipe drained by the in-ISR auto-echo path.

Defined in ux_dcd_ra8_usb.c.

Since
0.1.0

Definition at line 112 of file ux_dcd_ra8_usb.c.

Referenced by internal_endpoint_arm_out_pid(), internal_irq_auto_echo(), internal_irq_drain_orphan_out(), and ux_dcd_ra8_usb_auto_echo_enable().

◆ g_diag

ra8_usb_dcd_diag_t g_diag
extern

Bridge diagnostic counter block, defined in ux_dcd_ra8_usb.c.

Bridge diagnostic counter block.

Note
Single-writer per counter; JLink-readable.
Since
0.1.0

Read via JLink memory.

Note
Single-writer per counter; safe under the bridge's single- worker-thread + single-class-thread model.
Since
0.1.0

Definition at line 291 of file ux_dcd_ra8_usb.c.

Referenced by internal_count_change_state(), internal_endpoint_create(), internal_irq_complete_out(), internal_irq_recover_in_nak(), internal_irq_stage_next_in(), internal_irq_walk_pipe(), internal_wait_completion(), and priv_transfer_request().

◆ g_dispatch_skip_reason

volatile uint32_t g_dispatch_skip_reason
extern

Last-iteration bitmask of why a SETUP dispatch was skipped or completed.

Last-iteration bitmask of why the SQMON dispatch path skipped.

Defined in ux_dcd_ra8_usb_setup.c.

Since
0.1.0

Bits:

  • 0x01 prev_sqmon_already_set (legacy probe, no longer gates)
  • 0x02 ra8_usb_read_setup_if_valid_returned_no_data (legacy CTRT only)
  • 0x04 ra8_usb_read_setup_unconditional_returned_err
  • 0x08 priv_dispatch_setup returned non-zero (USBX rejected)
  • 0x10 _ux_system_slave was UX_NULL when dispatch ran
  • 0x20 ux_slave_endpoint_transfer_request unreachable
  • 0x40 sqmon was zero on this DVST entry
  • 0x80 dispatch path actually ran to completion (success marker)
Note
Single-writer (internal_handle_dvst, priv_dispatch_setup).
Since
0.1.0

Definition at line 100 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_dvst_dispatch_if_new(), and priv_dispatch_setup().

◆ g_isr_spurious_run

volatile uint32_t g_isr_spurious_run
extern

Consecutive event-less ISR entries since the last SysTick re-enable.

Consecutive event-less FS ISR entries since the last SysTick re-enable.

Defined in ux_dcd_ra8_usb.c.

Since
0.1.0

Incremented by internal_usbfs_isr on an entry with no real event bit, reset by it on a real event, and zeroed every 1 ms by ux_dcd_ra8_usb_irq_reenable. JLink-readable storm probe.

Since
0.1.0

Definition at line 185 of file ux_dcd_ra8_usb.c.

Referenced by internal_usbfs_isr(), internal_usbhs_isr(), and ux_dcd_ra8_usb_irq_reenable().

◆ g_last_dispatched_setup_fp

volatile uint64_t g_last_dispatched_setup_fp
extern

64-bit fingerprint of the last dispatched SETUP packet.

64-bit fingerprint of the last SETUP packet dispatched from the ISR-driven SETUP drain in priv_handle_ctrt.

Defined in ux_dcd_ra8_usb_setup.c.

Since
0.1.0

Layout (little-endian-style bit packing):

  • bits 0..15: USBREQ (bmRequestType + bRequest)
  • bits 16..31: USBVAL (wValue)
  • bits 32..47: USBINDX (wIndex)
  • bits 48..63: USBLENG (wLength)

Used to de-dup VALID-driven SETUP drains so a single SETUP that fires multiple ISR snapshots is not re-dispatched. A fresh fingerprint (different from this latch) is treated as a new SETUP.

Note
Single-writer (priv_handle_ctrt).
Since
0.1.0

Definition at line 179 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_ctrt_dispatch_fresh_setup(), and internal_handle_dvst().

◆ g_orphan_buf

uint8_t g_orphan_buf[k_ra8_usb_orphan_bytes]
extern

One held no-receiver bulk-OUT packet.

Defined in ux_dcd_ra8_usb_xfer.c.

Since
0.1.0

One held no-receiver bulk-OUT packet.

Definition at line 40 of file ux_dcd_ra8_usb_xfer.c.

Referenced by internal_irq_drain_orphan_out(), and internal_submit_consume_orphan().

◆ g_orphan_len

uint16_t g_orphan_len
extern

Held orphan byte count; 0 = empty.

Defined in ux_dcd_ra8_usb_xfer.c.

Since
0.1.0

Held orphan byte count; 0 = empty.

Definition at line 42 of file ux_dcd_ra8_usb_xfer.c.

Referenced by internal_endpoint_arm_out_pid(), internal_irq_drain_orphan_out(), internal_submit_consume_orphan(), and internal_submit_pipe().

◆ g_orphan_pipe

uint8_t g_orphan_pipe
extern

Pipe the held orphan packet is on.

Defined in ux_dcd_ra8_usb_xfer.c.

Since
0.1.0

Pipe the held orphan packet is on.

Definition at line 44 of file ux_dcd_ra8_usb_xfer.c.

Referenced by internal_irq_drain_orphan_out(), and internal_submit_pipe().

◆ g_setup_dispatch_count

volatile uint32_t g_setup_dispatch_count
extern

Count of SETUP packets fed into the chapter-9 dispatcher.

Counter of SETUP packets fed into the chapter-9 dispatcher.

Defined in ux_dcd_ra8_usb_setup.c.

Since
0.1.0

Bisect probe. Non-zero confirms a SETUP-drain entry point (ra8_usb_read_setup_if_valid or _unconditional) emptied USBREQ/USBVAL/USBINDX/USBLENG and priv_dispatch_setup fired. Stays zero if VALID never asserts (no SETUP token reached the IP). HUM Ch 36.2.16..36.2.19 p 1623..1626.

Note
Written only by priv_handle_ctrt and the VALID fallback in ux_dcd_ra8_usb_irq.
Since
0.1.0

Definition at line 54 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_ctrt_dispatch_fresh_setup(), and internal_dvst_dispatch_if_new().

◆ g_setup_packet_buffer

volatile uint8_t g_setup_packet_buffer[8]
extern

Wire-format bytes of the most recent SETUP packet.

Wire-format bytes of the most recent SETUP packet drained from the controller, ready for JLink inspection.

Defined in ux_dcd_ra8_usb_setup.c.

Since
0.1.0

Layout matches USB 2.0 Ch 9.3: [0]=bmRequestType, [1]=bRequest, [2..3]=wValue (LE), [4..5]=wIndex (LE), [6..7]=wLength (LE). A standard GET_DESCRIPTOR(DEVICE) shows as 80 06 00 01 00 00 40 00. Stays all-zero until the first VALID/CTRT edge drains a SETUP. HUM Ch 36.2.17..36.2.20 (USBREQ/USBVAL/USBINDX/USBLENG).

Note
Single-writer (priv_dispatch_setup).
Since
0.1.0

Definition at line 72 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_dvst_capture_setup_mirror(), and priv_dispatch_setup().

◆ g_setup_packet_count

volatile uint32_t g_setup_packet_count
extern

Total SETUP packets latched into g_setup_packet_buffer.

Defined in ux_dcd_ra8_usb_setup.c.

Since
0.1.0
Note
Single-writer (priv_dispatch_setup).
Since
0.1.0

Definition at line 81 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_dvst_capture_setup_mirror(), and priv_dispatch_setup().

◆ g_setup_token_observed

volatile uint32_t g_setup_token_observed
extern

Counter of proven device-side SETUP-token latches.

Counter incremented every time the IRQ snapshot proves the device-side controller latched a SETUP token from the host.

Defined in ux_dcd_ra8_usb_dvst_default.c.

Since
0.1.0

Two independent evidence paths fold into this counter:

  1. INTSTS0.VALID (bit 3, HUM Ch 36.2.14 / 37.2.18 p 1985 / 2081) was set in the snapshot. This is the canonical SETUP-arrived signal in device mode.
  2. DCPCTR.SQMON (bit 6, HUM Ch 37.2.31 p 2095) was set after a Default-state DVST. Per the HUM, SQMON transitions 0->1 only "on successful reception of the setup packet" in device mode, so a non-zero SQMON observed in g_dcpctr_pre_rearm is hard proof that a SETUP was latched even if the IRQ never saw the VALID edge (race between the polled-dispatch tick and the SIE's SETUP-latch state machine).

Note: INTSTS1.SACK is HOST-mode only (HUM Ch 37.2.19 SACK flag p 2084: "Values read from the SACK flag in device controller mode are invalid."), so SACK cannot serve as a SETUP-receipt probe.

Note
Single-writer (ux_dcd_ra8_usb_irq + internal_handle_dvst).
Since
0.1.0

Definition at line 162 of file ux_dcd_ra8_usb_dvst_default.c.

Referenced by internal_dvst_dispatch_if_new(), and internal_irq_record_snapshot().