|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
USBX device-controller-driver bridge to ra8_usb – NVIC ISR trampolines. 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"Go to the source code of this file.
Macros | |
| #define | UX_SOURCE_CODE |
Enumerations | |
| enum | ra8_usb_storm_cfg_t : uint32_t { k_ra8_usb_storm_mask_run = 8U } |
| Tuning constant for the USBFS interrupt-storm guard. More... | |
Functions | |
| static void | internal_isr_bump_counts (uint16_t intsts0) |
| Bump the per-bit ISR counters for an INTSTS0 snapshot. | |
| static void | internal_usbfs_isr (void *ctx) |
| NVIC ISR entry point for the USBFS controller. | |
| static void | internal_ack_spurious (ra8_usb_speed_t speed, uint16_t intsts0) |
| W0C-ack RSME/SOFR on a spurious USB ISR re-entry. | |
| static void | internal_usbhs_isr (void *ctx) |
| NVIC ISR entry point for the USBHS controller. | |
| 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. | |
Variables | |
| volatile uint32_t | g_isr_invocations = 0U |
| Counter of NVIC ISR entries through internal_usbfs_isr or internal_usbhs_isr. | |
| volatile uint16_t | g_isr_intsts0_or = 0U |
| Cumulative bitwise-OR of every INTSTS0 value observed at the entry of internal_usbhs_isr. | |
| volatile uint32_t | g_isr_dvst_count = 0U |
| Per-bit ISR counter for INTSTS0.DVST (bit 12) entries. | |
| volatile uint32_t | g_isr_ctrt_count = 0U |
| Per-bit ISR counter for INTSTS0.CTRT (bit 11) entries. | |
| volatile uint32_t | g_isr_valid_count = 0U |
| Per-bit ISR counter for INTSTS0.VALID (bit 3) entries. | |
| volatile uint32_t | g_isr_brdy_count = 0U |
| Per-bit ISR counter for INTSTS0.BRDY (bit 8) entries. | |
| volatile uint32_t | g_isr_bemp_count = 0U |
| Per-bit ISR counter for INTSTS0.BEMP (bit 10) entries. | |
| volatile uint32_t | g_isr_nrdy_count = 0U |
| Per-bit ISR counter for INTSTS0.NRDY (bit 9) entries. | |
| volatile uint32_t | g_isr_sofr_count = 0U |
| Per-bit ISR counter for INTSTS0.SOFR (bit 13) entries. | |
| volatile uint32_t | g_dcd_irq_spurious_mask_count = 0U |
USBX device-controller-driver bridge to ra8_usb – NVIC ISR trampolines.
USBFS / USBHS NVIC interrupt entry points, the per-bit ISR counters, the spurious-entry storm acknowledgement, and the controller-selection helpers that route the polled / interrupt dispatch back into USBX.
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.
Definition in file ux_dcd_ra8_usb_isr.c.
| #define UX_SOURCE_CODE |
Definition at line 22 of file ux_dcd_ra8_usb_isr.c.
| enum ra8_usb_storm_cfg_t : uint32_t |
Tuning constant for the USBFS interrupt-storm guard.
Definition at line 188 of file ux_dcd_ra8_usb_isr.c.
|
static |
W0C-ack RSME/SOFR on a spurious USB ISR re-entry.
The RA8 USB controller asserts its NVIC line for RSME (resume detect) and SOFR (start-of-frame) independent of INTENB0 – on USBHS via the PHY's USBR signal, and on USBFS the same applies (confirmed on the bench: SOFR/RSME entries occur with INTENB0.SOFR and INTENB0.RSME both clear). While the host hammers a NAK'ing pipe the FS resume detector re-asserts RSME continuously, which – without this short-circuit – drives the full dispatch + pipe-walk ~10^5 times/second and starves RTOS thread mode. When the snapshot has no real event bit we W0C-clear the stuck RSME/SOFR flags, bump the spurious counter, and return cheaply.
| [in] | speed | Which controller the spurious entry came from. |
| [in] | intsts0 | The just-snapshotted INTSTS0 value. |
Definition at line 342 of file ux_dcd_ra8_usb_isr.c.
References g_dcd_irq_spurious_mask_count, r_usb_regs_t::INTSTS1, k_ra8_int0_bit_rsme, k_ra8_int0_bit_sofr, k_ra8_int1_bit_attch, k_ra8_int1_bit_bchg, k_ra8_int1_bit_dtch, k_ra8_usb_speed_hs, RA8_INTERNAL, ra8_usb_clear_status(), and ra8_usb_hs().
Referenced by internal_usbhs_isr().
|
static |
Bump the per-bit ISR counters for an INTSTS0 snapshot.
Each s_isr_*_count counter is a JLink-readable probe so a bench reader can correlate g_isr_intsts0_or with which event bits fired this tick. Shared by the FS and HS ISRs to keep each outer ISR within the NASA P10 Rule 4 size cap.
| [in] | intsts0 | Snapshot of INTSTS0 read at the top of the ISR. |
Definition at line 222 of file ux_dcd_ra8_usb_isr.c.
References g_isr_bemp_count, g_isr_brdy_count, g_isr_ctrt_count, g_isr_dvst_count, g_isr_nrdy_count, g_isr_sofr_count, g_isr_valid_count, k_ra8_int0_bit_bemp, k_ra8_int0_bit_brdy, k_ra8_int0_bit_ctrt, k_ra8_int0_bit_dvst, k_ra8_int0_bit_nrdy, k_ra8_int0_bit_sofr, k_ra8_intsts0_mask_valid, and RA8_INTERNAL.
Referenced by internal_usbfs_isr(), and internal_usbhs_isr().
|
static |
NVIC ISR entry point for the USBFS controller.
Registered with ra8_isr_register(k_ra8_elc_event_usbfs_int, ...) during ux_dcd_ra8_usb_initialize. Snapshots INTSTS0, classifies the entry, then forwards it to ra8_usb_dispatch – the dispatch is unconditional, identical to the pre-storm-guard behaviour, so this ISR is behaviour-neutral for the working CDC / HID apps.
The only added behaviour is the storm guard. An entry with no real event bit (only RSME / SOFR / status bits – these assert the NVIC line independent of INTENB0) increments g_isr_spurious_run; a real event resets it. ux_dcd_ra8_usb_irq_reenable (called from the per-app 1 ms SysTick_Handler) zeroes the counter, so it gauges the event-less rate. Once it crosses k_ra8_usb_storm_mask_run within a millisecond a genuine storm is in progress, and priv_usbfs_irq_mask disables the USB IRQ so RTOS thread mode – the otherwise-starved USBX class thread (GitHub issue #6) – gets the CPU back. The SysTick handler re-enables the line within 1 ms. Normal idle SOFR (~1/ms) never trips the guard.
| [in] | ctx | Unused; kept to match ra8_isr_handler_t. |
Definition at line 286 of file ux_dcd_ra8_usb_isr.c.
References g_dcd_irq_spurious_mask_count, g_isr_intsts0_or, g_isr_invocations, g_isr_spurious_run, internal_isr_bump_counts(), k_ra8_int0_bit_bemp, k_ra8_int0_bit_brdy, k_ra8_int0_bit_ctrt, k_ra8_int0_bit_dvst, k_ra8_int0_bit_nrdy, k_ra8_int0_bit_vbse, k_ra8_intsts0_mask_valid, k_ra8_usb_speed_fs, k_ra8_usb_storm_mask_run, priv_usbfs_irq_mask(), RA8_INTERNAL, ra8_usb_dispatch(), and ra8_usb_intsts0_snapshot().
Referenced by priv_pick_isr().
|
static |
NVIC ISR entry point for the USBHS controller.
Snapshot INTSTS0 and gate the rest of the ISR on the event bits (8..15 plus the VALID flag). Spurious / USBR-driven re-entry is short-circuited via internal_ack_spurious. Real events are forwarded to ra8_usb_dispatch, which performs the canonical W0C ack and invokes the USBX-side handler.
| [in] | ctx | Opaque ISR context (unused; kept for the ICU callback ABI). |
Definition at line 387 of file ux_dcd_ra8_usb_isr.c.
References g_isr_intsts0_or, g_isr_invocations, g_isr_spurious_run, internal_ack_spurious(), internal_isr_bump_counts(), k_ra8_int0_bit_bemp, k_ra8_int0_bit_brdy, k_ra8_int0_bit_ctrt, k_ra8_int0_bit_dvst, k_ra8_int0_bit_nrdy, k_ra8_int0_bit_vbse, k_ra8_intsts0_mask_valid, k_ra8_usb_speed_hs, k_ra8_usb_storm_mask_run, priv_usbfs_irq_mask(), RA8_INTERNAL, ra8_usb_dispatch(), and ra8_usb_intsts0_snapshot().
Referenced by priv_pick_isr().
| void priv_event_cb | ( | void * | ctx, |
| ra8_usb_speed_t | speed, | ||
| uint16_t | status_mask ) |
ra8_usb_attach_handler trampoline.
ra8_usb_attach_handler trampoline into ux_dcd_ra8_usb_irq.
See implementation for details.
| [in,out] | ctx | See function signature. |
| [in,out] | speed | See function signature. |
| [in,out] | status_mask | See function signature. |
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().
| ra8_elc_event_t priv_pick_event | ( | ra8_usb_speed_t | speed | ) |
Pick the ELC event number for a controller.
| [in] | speed | Which controller (FS or HS). |
See implementation for details.
| 0 | Success or default value. |
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().
| ra8_isr_handler_t priv_pick_isr | ( | ra8_usb_speed_t | speed | ) |
Pick the ISR trampoline for a controller.
| [in] | speed | Which controller (FS or HS). |
See implementation for details.
| 0 | Success or default value. |
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().
| volatile uint32_t g_dcd_irq_spurious_mask_count = 0U |
Definition at line 159 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_ack_spurious(), and internal_usbfs_isr().
| volatile uint32_t g_isr_bemp_count = 0U |
Per-bit ISR counter for INTSTS0.BEMP (bit 10) entries.
Definition at line 133 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_isr_bump_counts().
| volatile uint32_t g_isr_brdy_count = 0U |
Per-bit ISR counter for INTSTS0.BRDY (bit 8) entries.
Definition at line 124 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_isr_bump_counts().
| volatile uint32_t g_isr_ctrt_count = 0U |
Per-bit ISR counter for INTSTS0.CTRT (bit 11) entries.
Sibling of g_isr_dvst_count for the control-transfer- stage-transition bit (HUM Ch 36.2.14 p 1985).
Definition at line 102 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_isr_bump_counts().
| volatile uint32_t g_isr_dvst_count = 0U |
Per-bit ISR counter for INTSTS0.DVST (bit 12) entries.
Incremented inside internal_usbhs_isr whenever the snapshot has the device-state-transition bit set. Distinguishes "ISR fired with DVST" from the bridge-side g_dvst_irq_count which counts events after they have already been forwarded to the USBX stack.
Definition at line 90 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_isr_bump_counts().
| volatile uint16_t g_isr_intsts0_or = 0U |
Cumulative bitwise-OR of every INTSTS0 value observed at the entry of internal_usbhs_isr.
Each ISR entry samples INTSTS0 (HUM Ch 36.2.14 p 1985) and folds it into this accumulator with |=. JLink-readable: the set bits tell which event sources have ever fired since boot (BRDY/NRDY/BEMP/CTRT/DVST/SOFR/RSME/VBSE in bits 8..15, plus VALID in bit 3 and the read-only DVSQ/VBSTS status fields). Used to distinguish "ISR runs but no event bits set" (interrupt storm from an un-acked source) from "ISR runs with real events".
Definition at line 75 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_usbfs_isr(), and internal_usbhs_isr().
| volatile uint32_t g_isr_invocations = 0U |
Counter of NVIC ISR entries through internal_usbfs_isr or internal_usbhs_isr.
Reaches non-zero on the first USB IRQ delivered through ra8_isr_register / NVIC. Stays at 0 if the IELSR slot was never routed, the NVIC line was masked, or the vector trampoline did not land in the substrate dispatcher (e.g. weak Default_Handler still winning the link). Read via JLink to confirm interrupts fire. HUM Ch 13 NVIC + Ch 14 ICU IELSR.
Definition at line 56 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_usbfs_isr(), and internal_usbhs_isr().
| volatile uint32_t g_isr_nrdy_count = 0U |
Per-bit ISR counter for INTSTS0.NRDY (bit 9) entries.
Storm-localisation probe: a value in the millions after a failed MSC scan means a pipe is NAK'ing host tokens and the NRDY status is re-asserting INTSTS0.NRDY faster than the dispatcher clears it. Written by internal_usbfs_isr and internal_usbhs_isr.
Definition at line 145 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_isr_bump_counts().
| volatile uint32_t g_isr_sofr_count = 0U |
Per-bit ISR counter for INTSTS0.SOFR (bit 13) entries.
Storm-localisation probe. SOFR fires once per USB frame (1 kHz on full-speed); a count far above 1000 * uptime_s means the ISR is re-entering on a bit other than SOFR while SOFR happens to be co-asserted. Written by internal_usbfs_isr and internal_usbhs_isr.
Definition at line 157 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_isr_bump_counts().
| volatile uint32_t g_isr_valid_count = 0U |
Per-bit ISR counter for INTSTS0.VALID (bit 3) entries.
Counts ISR entries where the SETUP-detect flag was already latched at snapshot time. The actual SETUP drain is performed by ux_dcd_ra8_usb_irq via ra8_usb_dispatch -> priv_event_cb.
Definition at line 115 of file ux_dcd_ra8_usb_isr.c.
Referenced by internal_isr_bump_counts().