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

USBX device-controller-driver bridge to ra8_usb – SETUP / chapter-9 control path. More...

#include <stdint.h>
#include <string.h>
#include "ra8_check.h"
#include "ra8_elc_regs.h"
#include "ra8_isr.h"
#include "ra8_log.h"
#include "ra8_usb_regs.h"
#include "tx_api.h"
#include "ux_api.h"
#include "ux_dcd_ra8_usb.h"
#include "ux_dcd_ra8_usb_internal.h"
#include "ux_device_stack.h"
#include "ux_system.h"
#include "ux_utility.h"
Include dependency graph for ux_dcd_ra8_usb_setup.c:

Go to the source code of this file.

Macros

#define UX_SOURCE_CODE

Enumerations

enum  ra8_usb_setup_local_t : uint8_t {
  k_ra8_usb_setup_dir_mask = 0x80U ,
  k_ra8_usb_breq_set_address = 0x05U
}
 Local USB SETUP-packet bit-field constants. More...
enum  ra8_usb_dcp_brdy_t : uint16_t { k_ra8_usb_dcp_brdy_bit = 0x0001U }
 BRDYSTS / BRDYENB bit for the Default Control Pipe (pipe 0). More...
enum  ra8_dcd_dwt_t : uintptr_t { k_dcd_dwt_cyccnt_addr = 0xE0001004U }
 Armv8-M Data Watchpoint and Trace unit register addresses. More...
enum  ra8_usb_setup_usbreq_t : uint16_t {
  k_ra8_usb_usbreq_breq_mask = 0xFF00U ,
  k_ra8_usb_usbreq_bmrt_mask = 0x00FFU ,
  k_ra8_usb_usbreq_set_addr = 0x0500U
}
 Byte masks and request encodings applied to the USBREQ mirror. More...
enum  ra8_usb_setup_fp_shift_t : uint8_t { k_ra8_usb_fp_shift_usbleng = 48U }
 Bit offset of each 16-bit SETUP mirror inside the 64-bit SETUP fingerprint word. More...

Functions

void priv_trace_event (uint8_t kind, uint8_t code, uint16_t length)
 Append one packed event to the JLink-readable trace ring.
static void internal_pack_setup_le (volatile uint8_t *buf, const ra8_usb_setup_t *setup)
 Pack a decoded SETUP into the 8-byte USB-wire little-endian layout.
static bool internal_try_defer_ctrl_out (const ra8_usb_setup_t *setup, UX_SLAVE_TRANSFER *tr)
 Arm + defer a control-WRITE data stage; report whether it was deferred.
unsigned int priv_dispatch_setup (const ra8_usb_setup_t *setup)
 Push a decoded SETUP packet into the USBX chapter-9 dispatcher.
static void internal_ctrt_dispatch_fresh_setup (ra8_usb_speed_t speed, uint64_t fingerprint)
 Drain a fresh SETUP and forward to the chapter-9 dispatcher.
static void internal_ctrt_handle_valid (ra8_usb_speed_t speed)
 VALID-observed branch of priv_handle_ctrt.
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.

Variables

volatile uint32_t g_setup_dispatch_count = 0U
 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 = 0U
 Total SETUP packets latched into g_setup_packet_buffer.
volatile uint32_t g_dispatch_skip_reason = 0U
 Last-iteration bitmask of why a SETUP dispatch was skipped or completed.
volatile bool g_ctrl_out_pending = false
 A control-write data stage is armed and awaiting the host's OUT data.
UX_SLAVE_TRANSFER * g_ctrl_out_tr = UX_NULL
 EP0 transfer request whose data buffer the deferred OUT data fills.
volatile uint16_t g_ctrl_out_wlen = 0U
 wLength (cap) of the pending control-write data stage, in bytes.
volatile uint32_t g_ctrl_out_rx = 0U
 Byte count drained by the most recent deferred control-OUT receive.
volatile uint32_t g_ctrl_out_done = 0U
 Count of completed deferred control-OUT data stages.
volatile uint64_t g_last_dispatched_setup_fp = 0U
 64-bit fingerprint of the last dispatched SETUP packet.
volatile uint64_t g_dispatched_fp_ring [4] = {}
 Ring of the last 4 dispatched SETUP fingerprints (oldest at index 0).
volatile uint8_t g_dispatched_fp_ring_idx = 0U
volatile uint8_t g_state_at_dispatch = 0U
 Snapshot of ux_slave_device_state at the moment of the most recent SETUP dispatch.
static volatile uint32_t s_trace [k_dcd_trace_entries] = {}
 JLink-readable ring of packed transfer/SETUP events.
static volatile uint32_t s_trace_ts [k_dcd_trace_entries] = {}
 DWT cycle-count timestamp per s_trace slot.
static volatile uint32_t *const s_dcd_dwt_cyccnt = (volatile uint32_t*)k_dcd_dwt_cyccnt_addr
 DWT cycle counter address (Armv8-M DWT_CYCCNT).
static volatile uint32_t s_trace_seq = 0U
 Monotonic count of events written to s_trace.

Detailed Description

USBX device-controller-driver bridge to ra8_usb – SETUP / chapter-9 control path.

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

Control-transfer (CTRT) handling: SETUP packet decode, the chapter-9 dispatch into the USBX device stack, deferred control-OUT data stages, and the JLink-readable trace ring.

Split out of ux_dcd_ra8_usb.c to keep each translation unit under the maintainability line cap; the cross-translation-unit contract lives in ux_dcd_ra8_usb_internal.h.

Since
0.1.0

Definition in file ux_dcd_ra8_usb_setup.c.

Macro Definition Documentation

◆ UX_SOURCE_CODE

#define UX_SOURCE_CODE

Definition at line 22 of file ux_dcd_ra8_usb_setup.c.

Enumeration Type Documentation

◆ ra8_dcd_dwt_t

enum ra8_dcd_dwt_t : uintptr_t

Armv8-M Data Watchpoint and Trace unit register addresses.

Enumerator
k_dcd_dwt_cyccnt_addr 

DWT_CYCCNT free-running cycle counter.

Definition at line 254 of file ux_dcd_ra8_usb_setup.c.

◆ ra8_usb_dcp_brdy_t

enum ra8_usb_dcp_brdy_t : uint16_t

BRDYSTS / BRDYENB bit for the Default Control Pipe (pipe 0).

The DCP is pipe 0, so its buffer-ready status occupies bit 0 of the per-pipe BRDYSTS / BRDYENB registers (HUM Ch 36.2.13 "BRDYSTS" p 1984). Used by priv_handle_ctrl_out_data to detect that the host's control-OUT data stage has landed in the DCP bank.

Enumerator
k_ra8_usb_dcp_brdy_bit 

DCP (pipe 0) BRDYSTS / BRDYENB bit.

Definition at line 230 of file ux_dcd_ra8_usb_setup.c.

◆ ra8_usb_setup_fp_shift_t

enum ra8_usb_setup_fp_shift_t : uint8_t

Bit offset of each 16-bit SETUP mirror inside the 64-bit SETUP fingerprint word.

USBREQ occupies bits 0-15, USBVAL bits 16-31, USBINDX bits 32-47 and USBLENG bits 48-63. Only the USBLENG offset falls outside the ignored small-integer set and needs a name here.

Enumerator
k_ra8_usb_fp_shift_usbleng 

USBLENG packs into fingerprint bits 48-63.

Definition at line 321 of file ux_dcd_ra8_usb_setup.c.

◆ ra8_usb_setup_local_t

enum ra8_usb_setup_local_t : uint8_t

Local USB SETUP-packet bit-field constants.

bmRequestType direction bit (bit 7) per USB 2.0 sec 9.3.

Enumerator
k_ra8_usb_setup_dir_mask 

RA8 USB setup dir mask.

k_ra8_usb_breq_set_address 

RA8 USB breq set address.

Definition at line 210 of file ux_dcd_ra8_usb_setup.c.

◆ ra8_usb_setup_usbreq_t

enum ra8_usb_setup_usbreq_t : uint16_t

Byte masks and request encodings applied to the USBREQ mirror.

The USBREQ register packs bRequest in its high byte and bmRequestType in its low byte (HUM Ch 37.2.21 p 2087). The SET_ADDRESS standard request is bRequest = 5 (0x05) with bmRequestType = 0, i.e. USBREQ high byte == 0x05 (0x0500 packed).

Enumerator
k_ra8_usb_usbreq_breq_mask 

bRequest (high) byte of USBREQ.

k_ra8_usb_usbreq_bmrt_mask 

bmRequestType (low) byte of USBREQ.

k_ra8_usb_usbreq_set_addr 

USBREQ high byte == SET_ADDRESS (5).

Definition at line 306 of file ux_dcd_ra8_usb_setup.c.

Function Documentation

◆ internal_ctrt_dispatch_fresh_setup()

void internal_ctrt_dispatch_fresh_setup ( ra8_usb_speed_t speed,
uint64_t fingerprint )
static

Drain a fresh SETUP and forward to the chapter-9 dispatcher.

Called by internal_ctrt_handle_valid for every observed non-SET_ADDRESS SETUP. Reads the SETUP via ra8_usb_read_setup_unconditional, records the fingerprint in the diagnostic ring, promotes USBX device state to ATTACHED if it dropped below the chapter-9 gate, dispatches via priv_dispatch_setup, and on no-data H2D control transfers (e.g. SET_CONFIGURATION, SET_INTERFACE, SET_FEATURE) pulses CCPL via ra8_usb_control_response so the host observes the status-stage IN-ZLP. HUM Ch 37.3 p 2147.

Parameters
[in]speedWhich controller fired.
[in]fingerprintPacked USBREQ/USBVAL/USBINDX/USBLENG snapshot used as the dedup key.
Precondition
Caller has verified VALID is observed and the fingerprint is new.
Controller register block matches speed.
Postcondition
g_last_dispatched_setup_fp updated.
CCPL pulsed for no-data H2D control transfers.
Note
ISR-callback context; must not block.
Since
0.1.0

Definition at line 512 of file ux_dcd_ra8_usb_setup.c.

References ra8_usb_setup_t::b_request, ra8_usb_setup_t::bm_request_type, g_dispatched_fp_ring, g_dispatched_fp_ring_idx, g_last_dispatched_setup_fp, g_setup_dispatch_count, g_state_at_dispatch, k_dcd_trace_kind_ccpl, k_ra8_ok, k_ra8_usb_setup_dir_mask, k_ra8_usb_state_unknown, priv_dispatch_setup(), priv_trace_event(), RA8_INTERNAL, ra8_usb_control_response(), ra8_usb_read_setup_unconditional(), and ra8_usb_setup_t::w_length.

Referenced by internal_ctrt_handle_valid().

◆ internal_ctrt_handle_valid()

void internal_ctrt_handle_valid ( ra8_usb_speed_t speed)
static

VALID-observed branch of priv_handle_ctrt.

Reads USBREQ/USBVAL/USBINDX/USBLENG (HUM Ch 37.2.21..24 p 2087..2090, persistent mirrors), computes a 64-bit fingerprint for dedup, short-circuits SET_ADDRESS (HUM Ch 37.3 p 2147 – SIE owns the USBADDR latch and the IN-ZLP status stage), and otherwise forwards a fresh SETUP via internal_ctrt_dispatch_fresh_setup.

Parameters
[in]speedWhich controller fired.
Precondition
Caller has verified the VALID bit in INTSTS0.
Bridge is past ux_dcd_ra8_usb_initialize.
Postcondition
INTSTS0.VALID is W0C-cleared for every observed SETUP.
For non-SET_ADDRESS SETUPs the chapter-9 dispatcher has run.
Note
ISR-callback context; must not block.
Since
0.1.0

Definition at line 579 of file ux_dcd_ra8_usb_setup.c.

References internal_ctrt_dispatch_fresh_setup(), r_usb_regs_t::INTSTS0, k_ra8_intsts0_mask_valid, k_ra8_usb_fp_shift_usbleng, k_ra8_usb_speed_hs, k_ra8_usb_usbreq_bmrt_mask, k_ra8_usb_usbreq_breq_mask, k_ra8_usb_usbreq_set_addr, RA8_INTERNAL, ra8_usb_fs(), ra8_usb_hs(), r_usb_regs_t::USBINDX, r_usb_regs_t::USBLENG, r_usb_regs_t::USBREQ, and r_usb_regs_t::USBVAL.

Referenced by priv_handle_ctrt().

◆ internal_pack_setup_le()

void internal_pack_setup_le ( volatile uint8_t * buf,
const ra8_usb_setup_t * setup )
static

Pack a decoded SETUP into the 8-byte USB-wire little-endian layout.

Serialises bmRequestType, bRequest, wValue, wIndex, wLength in the byte order USB 2.0 Ch 9.3 mandates for the SETUP packet – the same order USBX's ux_slave_transfer_request_setup buffer expects. The RA8 USB controller delivers the multi-byte fields already in host endian via USBREQ/USBVAL/USBINDX/USBLENG (HUM Ch 36.2.17..20), so the helper just re-serialises them little-endian.

Parameters
[out]buf8-byte destination buffer (any aligned uint8_t[8]).
[in]setupDecoded SETUP source.
Precondition
buf and setup are non-null.
buf has space for 8 bytes.
Postcondition
buf[0..7] holds the wire-format SETUP packet.
Source setup is unmodified.
Note
Pure data-shuffling; safe in IRQ context.
Since
0.1.0

Definition at line 346 of file ux_dcd_ra8_usb_setup.c.

References ra8_usb_setup_t::b_request, ra8_usb_setup_t::bm_request_type, k_setup_byte_mask, k_setup_byte_shift, k_setup_idx_bmrt, k_setup_idx_brq, k_setup_idx_idx_hi, k_setup_idx_idx_lo, k_setup_idx_len_hi, k_setup_idx_len_lo, k_setup_idx_val_hi, k_setup_idx_val_lo, RA8_INTERNAL, ra8_usb_setup_t::w_index, ra8_usb_setup_t::w_length, and ra8_usb_setup_t::w_value.

Referenced by priv_dispatch_setup().

◆ internal_try_defer_ctrl_out()

bool internal_try_defer_ctrl_out ( const ra8_usb_setup_t * setup,
UX_SLAVE_TRANSFER * tr )
static

Arm + defer a control-WRITE data stage; report whether it was deferred.

A host->device control transfer with a non-empty data stage (e.g. DFU_DNLOAD) cannot be dispatched from the SETUP IRQ: the chapter-9 class control_request reads its payload from the control buffer, but the host's OUT data has not arrived yet, and receiving it synchronously here would spin the FS device ISR while the lower-priority HS host worker – the thread that must SEND the data – is preempted (a same-CPU deadlock). So arm the DCP and record the pending transfer; priv_handle_ctrl_out_data drains the data on the subsequent DCP BRDY IRQ and only THEN runs the dispatcher. A fresh SETUP always clears any stale pending state first.

Parameters
[in]setupDecoded SETUP packet (non-null).
[in]trEP0 transfer request whose buffer receives the OUT data.
Returns
true when the data stage was deferred (caller must NOT dispatch now); false for IN / no-data requests (caller dispatches immediately).
Return values
trueControl-write data stage armed; dispatch deferred to the BRDY ISR.
falseIN or no-data request; caller dispatches chapter-9 immediately.
Precondition
The DCP PID write gate is open (INTSTS0.VALID cleared).
tr is the bound EP0 transfer request.
Postcondition
On defer: DCP armed, g_ctrl_out_pending set, g_ctrl_out_tr captured.
On no-defer: g_ctrl_out_pending cleared.
Note
ISR-callback context. Nested ifs (not a compound &&) keep this out of the MC/DC compound-decision inventory.
See also
priv_handle_ctrl_out_data
Since
0.1.0

Definition at line 389 of file ux_dcd_ra8_usb_setup.c.

References ra8_usb_setup_t::bm_request_type, g_ctrl_out_pending, g_ctrl_out_tr, g_ctrl_out_wlen, g_dcd, k_ra8_usb_setup_dir_mask, RA8_INTERNAL, ra8_usb_dcp_out_arm(), and ra8_usb_setup_t::w_length.

Referenced by priv_dispatch_setup().

◆ 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.

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_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.

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.

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_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.

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().

Variable Documentation

◆ g_ctrl_out_done

volatile uint32_t g_ctrl_out_done = 0U

Count of completed deferred control-OUT data stages.

Note
Diagnostic; JLink-readable. Single-writer (priv_handle_ctrl_out_data).
Since
0.1.0

Definition at line 159 of file ux_dcd_ra8_usb_setup.c.

Referenced by priv_handle_ctrl_out_data().

◆ g_ctrl_out_pending

volatile bool g_ctrl_out_pending = false

A control-write data stage is armed and awaiting the host's OUT data.

Set true by priv_dispatch_setup when a host->device control transfer with a non-empty data stage (e.g. DFU_DNLOAD) is decoded: the DCP is armed via ra8_usb_dcp_out_arm and the chapter-9 dispatch is DEFERRED. Cleared by priv_handle_ctrl_out_data once the OUT data has landed (DCP BRDY) and been drained, or by a fresh SETUP that abandons the prior transfer. Deferring is mandatory: receiving synchronously in the FS device ISR would spin out the lower-priority HS host worker – the thread that must SEND the data – a same-CPU deadlock.

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

Definition at line 118 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_try_defer_ctrl_out(), and priv_handle_ctrl_out_data().

◆ g_ctrl_out_rx

volatile uint32_t g_ctrl_out_rx = 0U

Byte count drained by the most recent deferred control-OUT receive.

Note
Diagnostic; JLink-readable. Single-writer (priv_handle_ctrl_out_data).
Since
0.1.0

Definition at line 150 of file ux_dcd_ra8_usb_setup.c.

Referenced by priv_handle_ctrl_out_data().

◆ g_ctrl_out_tr

UX_SLAVE_TRANSFER* g_ctrl_out_tr = UX_NULL

EP0 transfer request whose data buffer the deferred OUT data fills.

Snapshot of the device control-endpoint transfer request captured when the control-write SETUP was decoded. priv_handle_ctrl_out_data drains the host's OUT data into ux_slave_transfer_request_data_pointer and then runs the chapter-9 dispatcher on it.

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

Definition at line 132 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_try_defer_ctrl_out(), and priv_handle_ctrl_out_data().

◆ g_ctrl_out_wlen

volatile uint16_t g_ctrl_out_wlen = 0U

wLength (cap) of the pending control-write data stage, in bytes.

Note
Single-writer (priv_dispatch_setup).
Since
0.1.0

Definition at line 141 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_try_defer_ctrl_out(), and priv_handle_ctrl_out_data().

◆ g_dispatch_skip_reason

volatile uint32_t g_dispatch_skip_reason = 0U

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_dispatched_fp_ring

volatile uint64_t g_dispatched_fp_ring[4] = {}

Ring of the last 4 dispatched SETUP fingerprints (oldest at index 0).

Used to disambiguate which 2 SETUPs the chip processed when xfer_req_total < setup_dispatch_count.

Note
Written only by priv_handle_ctrt.
Since
0.1.0

Definition at line 190 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_ctrt_dispatch_fresh_setup().

◆ g_dispatched_fp_ring_idx

volatile uint8_t g_dispatched_fp_ring_idx = 0U

Definition at line 192 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_ctrt_dispatch_fresh_setup().

◆ g_last_dispatched_setup_fp

volatile uint64_t g_last_dispatched_setup_fp = 0U

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_setup_dispatch_count

volatile uint32_t g_setup_dispatch_count = 0U

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] = {}

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 = 0U

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_state_at_dispatch

volatile uint8_t g_state_at_dispatch = 0U

Snapshot of ux_slave_device_state at the moment of the most recent SETUP dispatch.

Used to verify the state-mirror gate was satisfied (must be in {ATTACHED, ADDRESSED, CONFIGURED}).

Note
Single-writer (priv_handle_ctrt).
Since
0.1.0

Definition at line 203 of file ux_dcd_ra8_usb_setup.c.

Referenced by internal_ctrt_dispatch_fresh_setup().

◆ s_dcd_dwt_cyccnt

volatile uint32_t* const s_dcd_dwt_cyccnt = (volatile uint32_t*)k_dcd_dwt_cyccnt_addr
static

DWT cycle counter address (Armv8-M DWT_CYCCNT).

Definition at line 259 of file ux_dcd_ra8_usb_setup.c.

Referenced by priv_trace_event().

◆ s_trace

volatile uint32_t s_trace[k_dcd_trace_entries] = {}
static

◆ s_trace_seq

volatile uint32_t s_trace_seq = 0U
static

Monotonic count of events written to s_trace.

Note
s_trace_seq % k_dcd_trace_entries is the next write slot.
Since
0.1.0

Definition at line 267 of file ux_dcd_ra8_usb_setup.c.

Referenced by priv_trace_event().

◆ s_trace_ts

volatile uint32_t s_trace_ts[k_dcd_trace_entries] = {}
static

DWT cycle-count timestamp per s_trace slot.

Note
Same indexing as s_trace; read via JLink for gap analysis.
Since
0.1.0

Definition at line 248 of file ux_dcd_ra8_usb_setup.c.

Referenced by priv_trace_event().