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
Go to the documentation of this file.
1
26
27#pragma once
28
29#include <stdint.h>
30
31#include "ra8_attributes.h"
32#include "ra8_isr.h"
33#include "ra8_usb.h"
34#include "ux_dcd_ra8_usb.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40/* -------------------------------------------------------------------------- */
41/* Shared typed enums and structs */
42/* -------------------------------------------------------------------------- */
43
53
60typedef struct {
61 struct UX_SLAVE_TRANSFER_STRUCT* xfer;
62 uint8_t ep_addr;
63 uint8_t dir_in;
64 uint16_t max_pkt;
66
77
78/* Orphan bulk-OUT holding buffer. A host OUT packet can land in the
79 * controller bank during the brief PID=BUF window between one transfer
80 * completing and the next being armed -- the host pipelines a CBW's
81 * data phase straight after the CBW. With no USBX waiter stashed the
82 * IRQ walk cannot drain it, BRDYSTS stays latched, and the USBFS IRQ
83 * storms at the full bus rate: BRDY is a real event so the event-less
84 * storm guard never masks it and RTOS thread mode starves (GitHub
85 * issue #6). internal_irq_drain_orphan_out pulls that packet into
86 * g_orphan_buf -- which W0C-clears BRDYSTS and parks the pipe -- and
87 * internal_submit_pipe hands it to the next bulk-OUT transfer. The
88 * bulk-OUT wire is strictly serial, so a held packet always belongs to
89 * the next OUT transfer USBX submits. */
90typedef enum : uint16_t {
93
103typedef struct {
104 volatile uint32_t xfer_req_total;
105 volatile uint32_t xfer_req_null_arg;
106 volatile uint32_t xfer_req_bad_pipe;
107 volatile uint32_t xfer_req_pipe2_in;
108 volatile uint32_t xfer_req_pipe2_out_dir;
109 volatile uint32_t xfer_req_pipe2_stashed;
110 volatile uint32_t xfer_req_pipe2_block;
111 volatile uint32_t xfer_req_pipe2_woken;
112 volatile uint32_t irq_walk_total;
113 volatile uint32_t irq_walk_pipe2_seen;
114 volatile uint32_t irq_walk_pipe2_complete;
115 volatile uint32_t irq_walk_pipe2_no_data;
116 volatile uint32_t in_rearm_nak;
118 volatile uint32_t in_restage_nak;
120 volatile uint32_t in_stage_fail;
122 volatile uint32_t ep_create_calls;
123 volatile uint32_t ep_create_fail;
124 volatile uint32_t chg_state_attached;
125 volatile uint32_t chg_state_configured;
127
163
184
190typedef enum : uint16_t {
194
206
215
225
226/* -------------------------------------------------------------------------- */
227/* Shared mutable state (defined once; externed here) */
228/* -------------------------------------------------------------------------- */
229
240extern ra8_usb_dcd_t g_dcd;
241
249
256extern volatile uint32_t g_dcd_auto_echo_enable;
257
264extern uint8_t g_dcd_auto_echo_out_pipe;
265
272extern uint8_t g_dcd_auto_echo_in_pipe;
273
280extern volatile uint32_t g_isr_spurious_run;
281
289
296extern uint16_t g_orphan_len;
297
304extern uint8_t g_orphan_pipe;
305
312extern volatile uint32_t g_setup_dispatch_count;
313
320extern volatile uint8_t g_setup_packet_buffer[8];
321
328extern volatile uint32_t g_setup_packet_count;
329
336extern volatile uint32_t g_dispatch_skip_reason;
337
344extern volatile uint64_t g_last_dispatched_setup_fp;
345
352extern volatile uint32_t g_setup_token_observed;
353
354/* -------------------------------------------------------------------------- */
355/* Shared helpers (formerly static; called across translation units) */
356/* -------------------------------------------------------------------------- */
357
374RA8_PRIV uint8_t priv_ep_to_pipe(uint8_t ep_addr);
375
392RA8_PRIV unsigned int priv_transfer_request(struct UX_SLAVE_TRANSFER_STRUCT* tr);
393
406
421RA8_PRIV void priv_trace_event(uint8_t kind, uint8_t code, uint16_t length);
422
438
454
468RA8_PRIV void priv_event_cb(void* ctx, ra8_usb_speed_t speed, uint16_t status_mask);
469
484RA8_PRIV unsigned int priv_dispatch_setup(const ra8_usb_setup_t* setup);
485
498RA8_PRIV void priv_handle_ctrt(ra8_usb_speed_t speed, uint16_t intsts0);
499
512
527
540RA8_PRIV void priv_irq_dvst_prelude(ra8_usb_speed_t speed, uint16_t intsts0);
541
542#ifdef __cplusplus
543}
544#endif
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
ra8_elc_event_t
Partial list of ELC events (populate as drivers need them).
NVIC + ICU IELSR allocator.
void(* ra8_isr_handler_t)(void *ctx)
Driver-supplied callback invoked on interrupt entry.
Definition ra8_isr.h:128
Native USB controller driver public API (device + host modes).
ra8_usb_speed_t
Selects which controller instance the call targets.
Externally-readable diagnostic counters for OUT-pipe stall debug.
volatile uint32_t chg_state_configured
+0x48 CHANGE_STATE(CONFIGURED) calls.
volatile uint32_t xfer_req_pipe2_in
+0x0C pipe == 2.
volatile uint32_t xfer_req_pipe2_woken
+0x1C tx_semaphore_get returned.
volatile uint32_t xfer_req_pipe2_block
+0x18 about to tx_semaphore_get.
volatile uint32_t irq_walk_total
+0x20 IRQ pipe-walk loop iterations.
volatile uint32_t xfer_req_null_arg
+0x04 tr or ep was NULL.
volatile uint32_t xfer_req_bad_pipe
+0x08 pipe index >= max.
volatile uint32_t ep_create_fail
+0x40 endpoint-create failures.
volatile uint32_t irq_walk_pipe2_complete
+0x28 queue_out drained pipe2.
volatile uint32_t xfer_req_total
+0x00 priv_transfer_request entered.
volatile uint32_t in_restage_nak
+0x34 stashed IN at PID=NAK, empty bank, no BEMP; current chunk re-staged.
volatile uint32_t xfer_req_pipe2_stashed
+0x14 pipe2 OUT slot populated.
volatile uint32_t ep_create_calls
+0x3C endpoint-create invocations.
volatile uint32_t in_stage_fail
+0x38 queue_in failed while staging an IN chunk from the IRQ walk.
volatile uint32_t xfer_req_pipe2_out_dir
+0x10 pipe == 2 + OUT direction.
volatile uint32_t irq_walk_pipe2_seen
+0x24 pipe2 walked with non-NULL xfer.
volatile uint32_t chg_state_attached
+0x44 CHANGE_STATE(ATTACHED) calls.
volatile uint32_t in_rearm_nak
+0x30 stashed IN at PID=NAK with a loaded bank; PID forced back to BUF.
volatile uint32_t irq_walk_pipe2_no_data
+0x2C queue_out returned no_data.
Per-pipe class-layer cache so the IRQ handler can re-arm BRDY-driven transfers without crawling the d...
uint16_t max_pkt
Endpoint wMaxPacketSize.
uint8_t ep_addr
USB EP number (with dir bit).
struct UX_SLAVE_TRANSFER_STRUCT * xfer
Active transfer or NULL.
uint8_t dir_in
1 if IN pipe, 0 if OUT.
Bridge-singleton state.
ra8_usb_dcd_pipe_slot_t pipes[k_ux_dcd_ra8_usb_max_pipes]
DCP + PIPE1..9.
struct UX_SLAVE_DCD_STRUCT * owner
Back-pointer into USBX.
ra8_usb_dcd_state_t state
Bridge run-state.
ra8_usb_speed_t speed
Controller this drives.
Decoded 8-byte USB SETUP packet.
USBX device-controller-driver (DCD) bridge to ra8_usb.
@ k_ux_dcd_ra8_usb_max_pipes
DCP + 9 PIPE entries (HUM 36.1).
ra8_usb_dcd_state_t
Run-state of the DCD bridge.
volatile uint64_t g_last_dispatched_setup_fp
64-bit fingerprint of the last dispatched SETUP packet.
uint8_t priv_ep_to_pipe(uint8_t ep_addr)
Map a USB EP number (1..9) into the PIPE table index.
volatile uint32_t g_dcd_auto_echo_enable
Non-zero once ISR-side auto-echo is armed.
volatile uint32_t g_setup_packet_count
Total SETUP packets latched into g_setup_packet_buffer.
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.
@ k_ra8_usb_skip_process_ok
control_request_process returned OK.
@ k_ra8_usb_skip_usbreq_unchanged
USBREQ unchanged since last dispatch.
volatile uint8_t g_setup_packet_buffer[8]
Wire-format bytes of the most recent SETUP packet.
void priv_trace_event(uint8_t kind, uint8_t code, uint16_t length)
Append one packed event to the JLink-readable trace ring.
ra8_usb_dcd_intsts0_field_shift_t
Bit-position shifts used to extract INTSTS0 multi-bit fields.
@ k_ra8_int0_dvsq_shift
DVSQ[2:0] field starts at bit 4.
uint8_t g_dcd_auto_echo_out_pipe
Pipe drained by the in-ISR auto-echo path.
uint16_t g_orphan_len
Held orphan byte count; 0 = empty.
uint8_t g_dcd_auto_echo_in_pipe
Pipe the auto-echo path re-queues onto.
ra8_usb_dcd_t g_dcd
The single bridge instance, defined in ux_dcd_ra8_usb.c.
ra8_setup_byte_pack_t
Bit-shift / mask constants for splitting a uint16_t SETUP field into its little-endian byte pair.
@ k_setup_byte_shift
Bits per byte for the hi-byte extraction.
@ k_setup_byte_mask
Low-byte mask after the shift.
ra8_elc_event_t priv_pick_event(ra8_usb_speed_t speed)
Pick the ELC event number for a controller.
ra8_usb_dcd_trace_t
Sizing/packing constants for the JLink-readable event ring.
@ k_dcd_trace_no_code
Code when none applies.
@ k_dcd_trace_cdb_lba_lo
CDB byte: LBA bits 7..0.
@ k_dcd_trace_nib_shift
High-nibble shift.
@ k_dcd_trace_cbw_op_off
CDB opcode offset inside a CBW.
@ k_dcd_trace_kind_out
Bulk-OUT transfer completed.
@ k_dcd_trace_nibble
Low-nibble mask for packed bytes.
@ k_dcd_trace_cbw_len
BOT CBW wire length.
@ k_dcd_out_drain_max
Max OUT banks drained per ISR pass.
@ k_dcd_trace_cdb_lba_hi
CDB byte: LBA bits 15..8.
@ k_dcd_trace_op_read10
SCSI READ(10) opcode.
@ k_dcd_trace_kind_ouse
Orphan packet fed to a transfer.
@ k_dcd_trace_kind_dvst
DVST event (code = dvsq|state).
@ k_dcd_trace_kind_ccpl
EP0 H2D status stage driven.
@ k_dcd_trace_kind_shift
Kind field bit offset.
@ k_dcd_trace_entries
Ring slots (power of two).
@ k_dcd_trace_op_write10
SCSI WRITE(10) opcode.
@ k_dcd_trace_code_shift
Code field bit offset.
@ k_dcd_trace_byte_shift
CDB byte-pair packing shift.
@ k_dcd_trace_kind_setup
EP0 SETUP received.
@ k_dcd_trace_kind_ocap
Orphan OUT packet captured.
@ k_dcd_trace_kind_in
Bulk-IN transfer completed.
ra8_usb_dcd_diag_t g_diag
Bridge diagnostic counter block, defined in ux_dcd_ra8_usb.c.
ra8_isr_handler_t priv_pick_isr(ra8_usb_speed_t speed)
Pick the ISR trampoline for a controller.
void priv_dvst_default_state(ra8_usb_speed_t speed)
Process the DVSQ=Default branch of the DVST handler.
ra8_usb_dcd_field_mask_t
Small field masks and sentinels used across the DCD bridge.
@ k_ra8_usb_dvsq_field_mask
3-bit DVSQ/RHST field after shift.
@ k_ra8_usb_state_unknown
Device-state snapshot sentinel.
volatile uint32_t g_dispatch_skip_reason
Last-iteration bitmask of why a SETUP dispatch was skipped or completed.
void priv_usbfs_irq_mask(void)
Mask the USB IRQ at the NVIC to break an interrupt storm.
ra8_setup_byte_idx_t
Wire-format byte indices into the USBX SETUP buffer.
@ k_setup_idx_brq
bRequest (offset 1).
@ k_setup_idx_val_lo
wValue low byte (offset 2).
@ k_setup_idx_idx_hi
wIndex high byte (offset 5).
@ k_setup_idx_val_hi
wValue high byte (offset 3).
@ k_setup_idx_bmrt
bmRequestType (offset 0).
@ k_setup_idx_len_hi
wLength high byte (offset 7).
@ k_setup_idx_len_lo
wLength low byte (offset 6).
@ k_setup_idx_idx_lo
wIndex low byte (offset 4).
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.
void priv_handle_ctrt(ra8_usb_speed_t speed, uint16_t intsts0)
Handle the CTRT (control-transfer-stage) interrupt branch.
ra8_usb_ep_addr_field_t
Bit fields of a USB endpoint address (bEndpointAddress).
@ 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).
volatile uint32_t g_setup_dispatch_count
Count of SETUP packets fed into the chapter-9 dispatcher.
volatile uint32_t g_setup_token_observed
Counter of proven device-side SETUP-token latches.
void priv_irq_dvst_prelude(ra8_usb_speed_t speed, uint16_t intsts0)
Capture DVSTCTR0 / RHST history, mirror speed, dispatch DVST.
uint8_t g_orphan_buf[k_ra8_usb_orphan_bytes]
One held no-receiver bulk-OUT packet.
uint8_t g_orphan_pipe
Pipe the held orphan packet is on.
unsigned int priv_transfer_request(struct UX_SLAVE_TRANSFER_STRUCT *tr)
USBX UX_DCD_TRANSFER_REQUEST dispatcher entry point.
ux_dcd_ra8_usb_orphan_cfg_t
@ k_ra8_usb_orphan_bytes
One full-speed bulk MPS packet.
volatile uint32_t g_isr_spurious_run
Consecutive event-less ISR entries since the last SysTick re-enable.
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_ctrl_out_data(ra8_usb_speed_t speed)
Drain a deferred control-OUT data stage and run chapter-9.