|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
USBX device-controller-driver (DCD) bridge to ra8_usb. More...
#include "ra8_usb.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_usb_dcd_state_t : uint8_t { k_ux_dcd_ra8_usb_state_uninit = 0U , k_ux_dcd_ra8_usb_state_ready = 1U , k_ux_dcd_ra8_usb_state_active = 2U } |
| Run-state of the DCD bridge. More... | |
| enum | ra8_usb_dcd_limits_t : uint8_t { k_ux_dcd_ra8_usb_max_pipes = 10U } |
| Compile-time sizing of the bridge. More... | |
Functions | |
| ra8_err_t | ux_dcd_ra8_usb_initialize (ra8_usb_speed_t speed) |
| Register the ra8_usb bridge as the active USBX DCD. | |
| ra8_err_t | ux_dcd_ra8_usb_uninitialize (void) |
| Tear down the ra8_usb DCD bridge. | |
| void | ux_dcd_ra8_usb_irq (ra8_usb_speed_t speed, uint16_t intsts0) |
| ISR-context bottom-half. | |
| ra8_usb_dcd_state_t | ux_dcd_ra8_usb_state (void) |
| Read the bridge run-state. | |
| void | ux_dcd_ra8_usb_auto_echo_enable (uint8_t out_pipe, uint8_t in_pipe) |
| Enable ISR-side auto-echo from a bulk OUT pipe to a bulk IN pipe. | |
| void | ux_dcd_ra8_usb_irq_reenable (void) |
| Re-enable the USB NVIC IRQ at the controller level. | |
| unsigned int | _ux_dcd_ra8_usb_function (struct UX_SLAVE_DCD_STRUCT *dcd, unsigned int function, void *parameter) |
| ux dcd ra usb function. | |
USBX device-controller-driver (DCD) bridge to ra8_usb.
Plumbs Eclipse USBX's device stack onto the project's hand-written ra8_usb_* register-level driver (libs/ra8_hal/inc/ra8_usb.h). The shim implements the eight-function dispatch contract that USBX expects to find behind UX_SLAVE_DCD::ux_slave_dcd_function and is what _ux_device_stack_initialize ultimately reaches when the application calls ux_device_class_cdc_acm_initialize and brings a class up.
The dispatch table _ux_dcd_ra8_usb_function switches on the UX_DCD_* command codes:
The bridge is intentionally thin: it never allocates, never owns any host-stack state, and never blocks. Class-layer threads (the CDC bulk-in / bulk-out threads in particular) supply the UX_SLAVE_TRANSFER semaphore that ux_dcd_ra8_usb_irq posts on BRDY completion.
Definition in file ux_dcd_ra8_usb.h.
| enum ra8_usb_dcd_limits_t : uint8_t |
Compile-time sizing of the bridge.
Independent of UX_MAX_ED so we can statically pin the pipe table without dragging in ux_api.h from this header.
| Enumerator | |
|---|---|
| k_ux_dcd_ra8_usb_max_pipes | DCP + 9 PIPE entries (HUM 36.1). |
Definition at line 83 of file ux_dcd_ra8_usb.h.
| enum ra8_usb_dcd_state_t : uint8_t |
Run-state of the DCD bridge.
| Enumerator | |
|---|---|
| k_ux_dcd_ra8_usb_state_uninit | Bridge not yet initialized. |
| k_ux_dcd_ra8_usb_state_ready | Bridge installed; bus idle. |
| k_ux_dcd_ra8_usb_state_active | Class-layer transfers active. |
Definition at line 70 of file ux_dcd_ra8_usb.h.
| unsigned int _ux_dcd_ra8_usb_function | ( | struct UX_SLAVE_DCD_STRUCT * | dcd, |
| unsigned int | function, | ||
| void * | parameter ) |
ux dcd ra usb function.
See implementation for details.
| [in,out] | dcd | See function signature for type and usage. |
| [in,out] | function | See function signature for type and usage. |
| [in,out] | parameter | See function signature for type and usage. |
| 0 | Success or default value. |
ux dcd ra usb function.
Stamped into UX_SLAVE_DCD::ux_slave_dcd_function during ux_dcd_ra8_usb_initialize. The USBX device stack calls this with a UX_DCD_* selector to request endpoint create/destroy, transfer request, transfer abort, stall, and similar primitives; the trampoline routes each to the matching internal_* helper.
| [in,out] | dcd | USBX DCD ownership block (currently unused; the bridge keeps its own static state in g_dcd). |
| [in] | function | USBX UX_DCD_* selector (e.g. UX_DCD_TRANSFER_REQUEST). |
| [in,out] | parameter | Selector-dependent argument (UX_SLAVE_TRANSFER* / UX_SLAVE_ENDPOINT* / opaque). |
| UX_SUCCESS | Function handled. |
| UX_CONTROLLER_UNKNOWN | Bridge has not been initialized. |
| UX_ERROR | Selector unsupported, or helper rejected the call. |
| UX_TRANSFER_ERROR | Transfer-request helper failed. |
Definition at line 281 of file ux_dcd_ra8_usb_ep.c.
References g_dcd, internal_count_change_state(), internal_endpoint_create(), internal_endpoint_destroy(), internal_endpoint_stall(), k_ux_dcd_ra8_usb_state_active, k_ux_dcd_ra8_usb_state_ready, k_ux_dcd_ra8_usb_state_uninit, and priv_transfer_request().
Referenced by internal_init_bind_owner(), and internal_init_setup_ep0().
| void ux_dcd_ra8_usb_auto_echo_enable | ( | uint8_t | out_pipe, |
| uint8_t | in_pipe ) |
Enable ISR-side auto-echo from a bulk OUT pipe to a bulk IN pipe.
Workaround for a ThreadX scheduling failure on this silicon where the application worker thread blocks indefinitely on tx_semaphore_get after the CDC class activates. With auto-echo on, the bridge's internal_irq_walk_pipe drains the OUT pipe in-place and re-queues the data on the IN pipe entirely inside the USB IRQ – no thread-mode dispatch required.
| [in] | out_pipe | Pipe index of the bulk OUT endpoint (e.g. 2 for CDC). |
| [in] | in_pipe | Pipe index of the bulk IN endpoint (e.g. 1 for CDC). |
Enable ISR-side auto-echo from a bulk OUT pipe to a bulk IN pipe.
All data arriving on out_pipe (bulk OUT) is drained and re-queued onto in_pipe (bulk IN) from inside the IRQ path. Workaround for ThreadX worker thread scheduling failure on this silicon. Once enabled, the loop runs whenever internal_irq_walk_pipe encounters an OUT pipe with no waiter; see internal_irq_auto_echo for the body.
| [in] | out_pipe | Pipe index to drain on (bulk OUT). |
| [in] | in_pipe | Pipe index to re-queue on (bulk IN). |
Definition at line 141 of file ux_dcd_ra8_usb.c.
References g_dcd_auto_echo_enable, g_dcd_auto_echo_in_pipe, and g_dcd_auto_echo_out_pipe.
Referenced by demo_cdc_activate(), demo_cdc_activate(), and ns_cdc_activate().
|
nodiscard |
Register the ra8_usb bridge as the active USBX DCD.
Wraps ra8_usb_device_init and stamps the global _ux_system_slave -> ux_system_slave_dcd so subsequent ux_device_class_*_initialize calls land on this bridge. The D+ pull-up is left off; the caller raises it via ra8_usb_device_attach / ra8_nsc_usb_attach once descriptors are wired up.
| [in] | speed | Which controller (FS or HS). |
| k_ra8_ok | DCD installed; ready for class init. |
| k_ra8_err_invalid_arg | speed out of range. |
| k_ra8_err_hw_init_failed | ra8_usb_device_init failed. |
Register the ra8_usb bridge as the active USBX DCD.
Initialises the underlying ra8_usb_* register layer for the given speed (FS or HS), attaches the bridge's priv_event_cb so the dispatcher can re-enter USBX, binds the controller into the USBX DCD ownership block (_ux_system_slave), wires the matching ELC event into the NVIC, parses the active device descriptor framework, and stamps EP0 so the chapter-9 dispatcher accepts the host's first SETUP token. Idempotent across calls: re-running with the same speed is a no-op once g_dcd.state has reached ready.
| [in] | speed | Which controller to bring up (k_ra8_usb_speed_fs or k_ra8_usb_speed_hs). |
| k_ra8_ok | Bridge fully initialized and ready for enumeration. |
| k_ra8_err_invalid_arg | speed out of range. |
| k_ra8_err_internal | A fallible driver or ownership initialisation step failed. |
Definition at line 521 of file ux_dcd_ra8_usb.c.
References g_dcd, g_lpsts_after_dcd_init, g_syscfg_after_dcd_init, internal_init_bind_owner(), internal_init_parse_framework(), internal_init_setup_ep0(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_speed_hs, priv_event_cb(), ra8_log_info, RA8_RETURN_ON_ERROR, ra8_usb_attach_handler(), ra8_usb_device_init(), ra8_usb_hs(), ra8_usbhs_lpsts(), s_tag, and r_usb_regs_t::SYSCFG.
Referenced by cdc_device_worker(), demo_worker(), demo_worker_start_dcd(), dfu_device_worker(), hid_device_worker(), hid_device_worker(), microsd_device_worker(), mlun_device_worker(), ns_usb_worker(), ospirw_device_worker(), sdmsc_device_worker(), selftest_device_worker(), selftest_device_worker(), and wlun_device_worker().
| void ux_dcd_ra8_usb_irq | ( | ra8_usb_speed_t | speed, |
| uint16_t | intsts0 ) |
ISR-context bottom-half.
Decodes INTSTS0 and posts the relevant USBX transfer semaphore.
Wired into the project's USB ISR via ra8_usb_attach_handler during ux_dcd_ra8_usb_initialize. The handler walks the BRDY / BEMP / CTRT bits, looks up the active UX_SLAVE_TRANSFER, copies bytes in / out of the pipe FIFO via ra8_usb_queue_in / ra8_usb_queue_out, and posts the request semaphore on completion.
| [in] | speed | Which controller fired (passed through from ra8_usb_dispatch). |
| [in] | intsts0 | Snapshot of INTSTS0 at the time of the IRQ. |
ISR-context bottom-half.
See implementation for details.
| [in,out] | speed | See function signature for type and usage. |
| [in,out] | intsts0 | See function signature for type and usage. |
Definition at line 709 of file ux_dcd_ra8_usb_irq.c.
References g_ctrt_irq_count, g_dcd, g_intsts0_last_dispatch, g_intsts0_observed_or, internal_irq_record_snapshot(), internal_irq_walk_pipe(), k_ra8_int0_bit_ctrt, k_ra8_int0_bit_dvst, k_ra8_intsts0_mask_valid, k_ux_dcd_ra8_usb_max_pipes, k_ux_dcd_ra8_usb_state_uninit, priv_handle_ctrl_out_data(), priv_handle_ctrt(), and priv_irq_dvst_prelude().
Referenced by priv_event_cb().
| void ux_dcd_ra8_usb_irq_reenable | ( | void | ) |
Re-enable the USB NVIC IRQ at the controller level.
Call from a periodic context (SysTick, watchdog) to recover after the ISR's spurious-entry path masked the line to stop a USBR-driven IRQ storm. Writes 1 to NVIC ISER[0] bit 0.
Re-enable the USB NVIC IRQ at the controller level.
The recovery half of the USBFS interrupt-storm guard. Each USB-FS app's SysTick_Handler calls this every 1 ms. Zeroing g_isr_spurious_run makes that counter a per-millisecond rate gauge – so normal idle SOFR can never accumulate to the mask threshold – and re-enabling the NVIC line undoes any mask internal_usbfs_isr applied. Re-enabling an already-enabled line is a no-op, so calling this outside a storm is harmless. SysTick is used rather than a ThreadX TX_TIMER because it is an exception handler: it keeps running even while a storm has thread mode – and the ThreadX timer subsystem – starved.
Definition at line 260 of file ux_dcd_ra8_usb.c.
| ra8_usb_dcd_state_t ux_dcd_ra8_usb_state | ( | void | ) |
Read the bridge run-state.
Test-only; not part of the USBX contract.
See implementation for details.
| 0 | Success or default value. |
Read the bridge run-state.
See implementation for details.
| 0 | Success or default value. |
Definition at line 603 of file ux_dcd_ra8_usb.c.
References g_dcd.
|
nodiscard |
Tear down the ra8_usb DCD bridge.
| k_ra8_ok | Bridge released. |
| k_ra8_err_invalid_state | Bridge was never initialized. |
Tear down the ra8_usb DCD bridge.
See implementation for details.
| 0 | Success or default value. |
Definition at line 569 of file ux_dcd_ra8_usb.c.
References g_dcd, k_ra8_err_invalid_state, k_ra8_ok, k_ux_dcd_ra8_usb_state_uninit, ra8_usb_attach_handler(), and ra8_usb_device_deinit().