ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ux_dcd_ra8_usb_dvst_default.c
Go to the documentation of this file.
1
21
22#define UX_SOURCE_CODE
23
24#include <stdint.h>
25#include <string.h>
26
27#include "ra8_check.h"
28#include "ra8_elc_regs.h"
29#include "ra8_isr.h"
30#include "ra8_log.h"
31#include "ra8_usb_regs.h"
32#include "tx_api.h"
33#include "ux_api.h"
34#include "ux_dcd_ra8_usb.h"
36#include "ux_device_stack.h"
37#include "ux_system.h"
38#include "ux_utility.h"
39
55volatile uint32_t g_busreset_rearm_count = 0U;
56
75volatile uint16_t g_dcpctr_after_rearm = 0U;
76
92volatile uint16_t g_intenb0_after_rearm = 0U;
93
109volatile uint16_t g_cfifosel_after_rearm = 0U;
110
136volatile uint16_t g_dcpctr_pre_rearm = 0U;
137
162volatile uint32_t g_setup_token_observed = 0U;
163
181static volatile uint16_t s_prev_dcpctr_sqmon = 0U;
182
194volatile uint32_t g_dispatch_attempts = 0U;
195
212volatile uint16_t g_intsts0_at_sqmon_edge = 0U;
213
230volatile uint16_t g_intsts0_observed_or_recent = 0U;
231
247volatile uint16_t g_dcpctr_bit_map_observed = 0U;
248
265volatile uint16_t g_usbreq_first_nonzero = 0U;
266
282volatile uint32_t g_unconditional_dispatch_count = 0U;
283
297volatile uint16_t g_last_dispatched_usbreq = 0U;
298
317typedef enum : uint32_t {
320
325typedef enum : uint16_t {
326 k_ra8_dcpctr_mask_sqmon = (uint16_t)(1U << 6U),
328
353RA8_INTERNAL static void internal_dvst_capture_setup_mirror(uint16_t usbreq_live,
354 uint16_t usbval_live,
355 uint16_t usbindx_live,
356 uint16_t usbleng_live)
357{
358 const bool any_nonzero = ((usbreq_live | usbval_live | usbindx_live | usbleng_live) != 0U);
359 if (!any_nonzero) {
360 return;
361 }
362 g_setup_packet_buffer[k_setup_idx_bmrt] = (uint8_t)(usbreq_live & k_setup_byte_mask);
364 (uint8_t)((usbreq_live >> k_setup_byte_shift) & k_setup_byte_mask);
367 (uint8_t)((usbval_live >> k_setup_byte_shift) & k_setup_byte_mask);
370 (uint8_t)((usbindx_live >> k_setup_byte_shift) & k_setup_byte_mask);
373 (uint8_t)((usbleng_live >> k_setup_byte_shift) & k_setup_byte_mask);
375 if (g_usbreq_first_nonzero == 0U) {
376 g_usbreq_first_nonzero = usbreq_live;
377 }
378}
379
405 uint16_t usbreq_live,
406 uint16_t usbval_live,
407 uint16_t usbindx_live,
408 uint16_t usbleng_live)
409{
410 if (usbreq_live == g_last_dispatched_usbreq) {
411 /* USBREQ unchanged since last dispatch: do not re-fire. */
413 return;
414 }
415 ra8_usb_setup_t setup = {};
416 setup.bm_request_type = (uint8_t)(usbreq_live & k_setup_byte_mask);
417 setup.b_request = (uint8_t)((usbreq_live >> k_setup_byte_shift) & k_setup_byte_mask);
418 setup.w_value = usbval_live;
419 setup.w_index = usbindx_live;
420 setup.w_length = usbleng_live;
421
425 (void)priv_dispatch_setup(&setup);
426 g_last_dispatched_usbreq = usbreq_live;
427
428 /* Post-dispatch W0C-ack of INTSTS0.VALID (HUM Ch 37.2.18 p 2081). */
429 reg->INTSTS0 = (uint16_t)(reg->INTSTS0 & (uint16_t)~(uint16_t)k_ra8_intsts0_mask_valid);
430 /* Pulse DCPCTR write (HUM Ch 37.2.32 p 2093). Benign W0C confirm. */
431 reg->DCPCTR = (uint16_t)(reg->DCPCTR & (uint16_t)~(uint16_t)k_ra8_dcpctr_mask_sqmon);
432}
433
454{
455 /* HUM Ch 37.2.32 DCPCTR p 2093: capture DCPCTR BEFORE the rearm.
456 * DCPCTR.SQMON resets to 1 = DATA1-expected, so "SQMON==1" is NOT
457 * a SETUP-arrival signal -- VALID is the race-immune signal. */
458 volatile r_usb_regs_t* const reg = (speed == k_ra8_usb_speed_hs) ? ra8_usb_hs() : ra8_usb_fs();
459 if (reg != nullptr) {
460 const uint16_t dcpctr_pre = reg->DCPCTR;
461 g_dcpctr_pre_rearm = dcpctr_pre;
462 g_dcpctr_bit_map_observed = (uint16_t)(g_dcpctr_bit_map_observed | dcpctr_pre);
463
464 /* SQMON probe retained for older bisect notes. */
465 const uint16_t now_sqmon = (uint16_t)(dcpctr_pre & (uint16_t)k_ra8_dcpctr_mask_sqmon);
466
468 const uint16_t intsts0_pre = reg->INTSTS0;
469 g_intsts0_at_sqmon_edge = intsts0_pre;
470 g_intsts0_observed_or_recent = intsts0_pre;
471
472 /* Drain persistent SETUP mirrors every Default-state tick. */
473 const uint16_t usbreq_live = reg->USBREQ;
474 const uint16_t usbval_live = reg->USBVAL;
475 const uint16_t usbindx_live = reg->USBINDX;
476 const uint16_t usbleng_live = reg->USBLENG;
477
478 internal_dvst_capture_setup_mirror(usbreq_live, usbval_live, usbindx_live, usbleng_live);
479 internal_dvst_dispatch_if_new(reg, usbreq_live, usbval_live, usbindx_live, usbleng_live);
480 s_prev_dcpctr_sqmon = now_sqmon;
481 }
484 if (reg != nullptr) {
488 }
489}
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
Event Link Controller (ELC) register layout for the Renesas RA8D2.
NVIC + ICU IELSR allocator.
Lightweight Logging Interface for ra8-firmware.
ra8_err_t ra8_usb_device_busreset_rearm(ra8_usb_speed_t speed)
Re-arm the default control pipe (DCP) after a host-issued bus reset.
ra8_usb_speed_t
Selects which controller instance the call targets.
@ k_ra8_usb_speed_hs
High-Speed controller (USBHS @ 0x40351000).
USB Full-Speed + High-Speed controller layout for the Renesas RA8D2.
static volatile r_usb_regs_t * ra8_usb_hs(void)
Get pointer to the USB HS controller register block.
@ k_ra8_intsts0_mask_valid
SETUP packet detect flag.
static volatile r_usb_regs_t * ra8_usb_fs(void)
Compile-time offset and size insurance for r_usb_regs_t.
USB FS / HS register window (device-mode subset).
volatile uint16_t USBINDX
+0x058 USB Request wIndex.
volatile uint16_t DCPCTR
+0x060 DCP Control.
volatile uint16_t USBVAL
+0x056 USB Request wValue.
volatile uint16_t CFIFOSEL
+0x020 Control FIFO select.
volatile uint16_t INTENB0
+0x030 Interrupt Enable 0.
volatile uint16_t INTSTS0
+0x040 Interrupt Status 0.
volatile uint16_t USBLENG
+0x05A USB Request wLength.
volatile uint16_t USBREQ
+0x054 USB Request type/bRequest.
Decoded 8-byte USB SETUP packet.
uint16_t w_length
wLength.
uint8_t b_request
bRequest code.
uint8_t bm_request_type
Request direction / type / recipient.
uint16_t w_index
wIndex.
uint16_t w_value
wValue.
USBX device-controller-driver (DCD) bridge to ra8_usb.
volatile uint32_t g_dispatch_attempts
Count of SQMON-driven dispatch attempts (regardless of outcome).
volatile uint16_t g_intsts0_at_sqmon_edge
Snapshot of INTSTS0 captured immediately before the SQMON-driven ra8_usb_read_setup_unconditional cal...
volatile uint32_t g_unconditional_dispatch_count
Count of unconditional _ux_device_stack_control_request_process invocations made by the Default-state...
volatile uint16_t g_dcpctr_bit_map_observed
Cumulative bitwise-OR of every DCPCTR value sampled at the Default-state DVST entry.
volatile uint16_t g_cfifosel_after_rearm
Snapshot of CFIFOSEL taken at the end of every busreset_rearm.
volatile uint16_t g_dcpctr_after_rearm
Snapshot of DCPCTR taken at the end of every busreset_rearm.
static void internal_dvst_capture_setup_mirror(uint16_t usbreq_live, uint16_t usbval_live, uint16_t usbindx_live, uint16_t usbleng_live)
Capture the persistent SETUP mirror into the JLink-readable probe.
static void internal_dvst_dispatch_if_new(volatile r_usb_regs_t *reg, uint16_t usbreq_live, uint16_t usbval_live, uint16_t usbindx_live, uint16_t usbleng_live)
Unconditionally dispatch a Default-state SETUP if USBREQ changed.
volatile uint16_t g_last_dispatched_usbreq
Last USBREQ (HUM Ch 37.2.26 p 2090) value forwarded to the chapter-9 dispatcher by the unconditional ...
void priv_dvst_default_state(ra8_usb_speed_t speed)
Process the DVSQ=Default branch of internal_handle_dvst.
volatile uint16_t g_intsts0_observed_or_recent
Most-recent INTSTS0 value sampled at the start of the Default-state tight-poll for VALID (HUM Ch 37....
volatile uint16_t g_dcpctr_pre_rearm
Snapshot of DCPCTR taken at the START of every busreset_rearm.
volatile uint16_t g_usbreq_first_nonzero
First non-zero USBREQ value captured by the tight-poll Default-state loop (HUM Ch 37....
volatile uint32_t g_busreset_rearm_count
Number of times ra8_usb_device_busreset_rearm was invoked from the DVST handler in response to a Defa...
volatile uint16_t g_intenb0_after_rearm
Snapshot of INTENB0 taken at the end of every busreset_rearm.
ra8_usb_dcpctr_bits_t
Selected DCPCTR bit masks (HUM Ch 37.2.31 p 2095).
@ k_ra8_dcpctr_mask_sqmon
SQMON (bit 6): SETUP-latched flag.
static volatile uint16_t s_prev_dcpctr_sqmon
Last-observed value of DCPCTR.SQMON (masked to bit 6).
ra8_usb_dcd_default_poll_t
Tight-poll loop sizing for the Default-state VALID hunt.
@ k_ra8_usb_dcd_default_poll_iters
~2 ms upper bound.
USBX device-controller-driver bridge to ra8_usb – per-module cross-translation-unit contract.
volatile uint32_t g_setup_packet_count
Total SETUP packets latched into g_setup_packet_buffer.
@ 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.
@ k_setup_byte_shift
Bits per byte for the hi-byte extraction.
@ k_setup_byte_mask
Low-byte mask after the shift.
volatile uint32_t g_dispatch_skip_reason
Last-iteration bitmask of why a SETUP dispatch was skipped or completed.
@ 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).
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.
unsigned int priv_dispatch_setup(const ra8_usb_setup_t *setup)
Push a decoded SETUP packet into the USBX chapter-9 dispatcher.