|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
USB self-loop: HS host reads + verifies a HID device's interrupt reports. More...
#include <stdint.h>#include <string.h>#include "ra8_board_ek_ra8d2.h"#include "ra8_boot_entry.h"#include "ra8_cgc.h"#include "ra8_err.h"#include "ra8_gpio_constants.h"#include "ra8_isr.h"#include "ra8_port_constants.h"#include "ra8_port_utils.h"#include "ra8_time.h"#include "ra8_usb.h"#include "usb_selftest_hid_steps.h"#include "tx_api.h"#include "ux_api.h"#include "ux_dcd_ra8_usb.h"#include "ux_device_class_hid.h"#include "ux_device_stack.h"Go to the source code of this file.
Enumerations | |
| enum | hid_dev_step_t : uint32_t { k_hid_dev_step_stack = 1U , k_hid_dev_step_class = 2U , k_hid_dev_step_dcd = 3U , k_hid_dev_step_attach = 4U , k_hid_dev_step_send = 5U } |
| J-Link probe values marking device-worker bring-up progress. More... | |
| enum | usb_langid_byte_t : uint8_t { k_usb_langid_en_us_lo = 0x09U , k_usb_langid_en_us_hi = 0x04U } |
Functions | |
| void | _tx_timer_interrupt (void) |
| void | SysTick_Handler (void) |
| Service the SysTick exception selected by the linked application. | |
| void | hid_fill_report_body (uint8_t *out, uint32_t len) |
| Implementation of hid_fill_report_body() – fixed i*7 + 0x5A body. | |
| static VOID | hid_activate (VOID *hid_instance) |
| HID activate callback. | |
| static VOID | hid_deactivate (VOID *hid_instance) |
| HID deactivate callback. | |
| static UINT | hid_usbx_stack_up (void) |
| Bring USBX system + device stack up with the HID framework. | |
| static UINT | hid_get_callback (UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event) |
| HID GET_REPORT control-pipe callback: hand back a neutral report. | |
| static UINT | hid_class_register (void) |
| Register the HID class against configuration 1, interface 0. | |
| static void | hid_send_iter (uint32_t *seq) |
| One device send iteration: queue a fresh input report. | |
| static VOID | hid_device_worker (ULONG arg) |
| Device-side worker: bring the HID device up, then send reports. | |
| VOID | tx_application_define (VOID *first_unused_memory) |
| ThreadX application-define hook. | |
| static void | hid_panic_halt (void) |
| Halt forever in WFI – panic stop on init failure. | |
| static void | hid_route_usb_or_halt (void) |
| Route both ports' pins: FS as device, HS as host. | |
| static void | hid_setup_or_halt (void) |
| Bring CGC + both USB clocks + SysTick + SCI8 + LEDs + pins up. | |
| void | main (void) |
| Application entry: bring the board up, then hand off to ThreadX. | |
Variables | |
| static volatile bool | s_tx_kernel_up = false |
| Set in tx_application_define; gates ThreadX tick delivery. | |
| static const ra8_port_pin_t | k_hid_pin_fs_vbus = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbus |
| USBFS VBUS sense pin (P4_07, PSEL = 0x13). | |
| static const ra8_port_pin_t | k_hid_pin_fs_vbusen = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbusen |
| USBFS VBUSEN (P5_00) – GPIO LOW for the device role. | |
| static const ra8_port_pin_t | k_hid_pin_fs_dp = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dp |
| USBFS D+ (P8_14). | |
| static const ra8_port_pin_t | k_hid_pin_fs_dm = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dm |
| USBFS D- (P8_15). | |
| static const ra8_port_pin_t | k_hid_pin_hs_vbus = (ra8_port_pin_t)k_ra8_board_usbhs_pin_vbus |
| USBHS_VBUS sense pin (P4_08, PSEL = 0x14). | |
| static const ra8_port_pin_t | k_hid_pin_hs_pwr = (ra8_port_pin_t)k_ra8_board_usbhs_pin_pwr |
| J7 host-power switch (PD07): HIGH = U18 supplies VBUS (UM 6.2). | |
| static TX_THREAD | s_device_thread |
| ThreadX TCB for the USBX device-side worker thread. | |
| static UCHAR | s_device_stack [k_hid_thread_stack] |
| Stack backing storage for s_device_thread. | |
| static TX_THREAD | s_host_thread |
| ThreadX TCB for the host-side worker thread. | |
| static UCHAR | s_host_stack [k_hid_host_stack] |
| Stack backing storage for s_host_thread. | |
| static UCHAR | s_usbx_pool [k_hid_usbx_pool_bytes] |
| USBX memory pool (USBX uses tx_byte_pool internally). | |
| static UX_SLAVE_CLASS_HID * | s_hid_class = UX_NULL |
| Active HID class instance, captured by the activate callback. | |
| static TX_SEMAPHORE | s_hid_active_sem |
| Posted by the activate callback so the send worker blocks on it instead of polling s_hid_class with tx_thread_sleep (which has been observed never returning on this silicon under load). | |
| static volatile uint32_t | s_dbg_dev_sent |
| Device-side report-queue successes (one hid_event_set each). | |
| static volatile uint32_t | s_dbg_dev_step |
| Device worker progress: 1 stack, 2 class, 3 dcd, 4 attach, 5 send. | |
| static volatile uint32_t | s_dbg_dev_err |
| Device worker first failing return code (0 = none). | |
| static UCHAR | s_report_descriptor [] |
| static UCHAR | s_device_framework_fs [] |
| static UCHAR | s_string_framework [] |
| USBX string descriptor table (vendor / product / serial). | |
| static UCHAR | s_language_id_framework [] = {k_usb_langid_en_us_lo, k_usb_langid_en_us_hi} |
| USBX language-id table – US English. | |
USB self-loop: HS host reads + verifies a HID device's interrupt reports.
The HID interrupt-IN self-loop – it exercises the device->host interrupt report path through a real HID device class. The two USB ports are cabled to EACH OTHER and one firmware image runs both USB stacks:
Each report is 8 bytes (well under the 64-byte endpoint MPS), so it arrives as a single short packet. The seq byte advances per report so the host can also see the reports are fresh, not one stale buffer. No OS HID driver is involved; raw interrupt-IN reads only.
The link runs at 12 Mbps (FS device ceiling; HS host serves an FS downstream device).
Verdicts stream over SCI8 (J-Link OB CDC console, 115200) and are mirrored in J-Link-readable probes (s_dbg_*).
FS device: P4_07 VBUS sense, P5_00 VBUSEN GPIO LOW (device role), P8_14 D+, P8_15 D- (PSEL usb_fs). HS host: SW4-8 to Host via the U15 expander, PD07 HIGH (U18 supplies J7 VBUS), P4_08 USBHS_VBUS (PSEL usb_hs). Console: PD_02/PD_03 SCI8 (PSEL sci_async).
Definition in file main.c.
| enum hid_dev_step_t : uint32_t |
J-Link probe values marking device-worker bring-up progress.
| enum usb_langid_byte_t : uint8_t |
|
extern |
|
static |
HID activate callback.
Captures the live class instance.
Pins ux_slave_device_state at CONFIGURED (works around a residual DVSQ-poll race on this silicon that can demote it back to ATTACHED after SET_CONFIGURATION), then posts the semaphore the send worker blocks on so it begins queuing reports.
| [in] | hid_instance | Pointer to UX_SLAVE_CLASS_HID. |
Definition at line 427 of file main.c.
References s_hid_active_sem, and s_hid_class.
|
static |
Register the HID class against configuration 1, interface 0.
Binds hid_activate / hid_deactivate and publishes the vendor report descriptor so the host's enumeration sees a real HID interface.
| UX_SUCCESS | Class registered. |
Definition at line 542 of file main.c.
References hid_activate(), hid_deactivate(), hid_get_callback(), and s_report_descriptor.
Referenced by hid_device_worker().
|
static |
HID deactivate callback.
Drops the live class pointer.
| [in] | hid_instance | Unused. |
Definition at line 450 of file main.c.
References s_hid_class.
|
static |
Device-side worker: bring the HID device up, then send reports.
USBX system + device stack + HID class + DCD bridge on the USBFS controller, then DPRPU attach. Blocks on s_hid_active_sem until the host configures the device, then loops hid_send_iter to keep the interrupt-IN report queue fed.
| [in] | arg | ThreadX entry argument (unused). |
Definition at line 620 of file main.c.
References hid_class_register(), hid_send_iter(), hid_usbx_stack_up(), k_hid_dev_step_attach, k_hid_dev_step_class, k_hid_dev_step_dcd, k_hid_dev_step_send, k_hid_dev_step_stack, k_ra8_ok, k_ra8_usb_speed_fs, ra8_usb_device_attach(), s_dbg_dev_err, s_dbg_dev_step, s_hid_active_sem, s_hid_class, TX_WAIT_FOREVER, and ux_dcd_ra8_usb_initialize().
| void hid_fill_report_body | ( | uint8_t * | out, |
| uint32_t | len ) |
Implementation of hid_fill_report_body() – fixed i*7 + 0x5A body.
Fill the fixed body of a HID report (bytes 1..len-1).
Definition at line 397 of file main.c.
References k_hid_body_idx, k_hid_byte_mask, k_hid_key0_idx, k_hid_nkeys, k_hid_pat_bias, k_hid_pat_idx_mul, and s_kbd_keys.
Referenced by hid_get_callback(), hid_read_round(), hid_read_round(), and hid_send_iter().
|
static |
HID GET_REPORT control-pipe callback: hand back a neutral report.
The host in this self-loop only reads the interrupt-IN pipe and never issues GET_REPORT, but USBX requires a get callback. Fill the same fixed body with a zero seq so any control GET_REPORT is well-formed.
| [in,out] | hid | USBX HID class instance (unused). |
| [in,out] | hid_event | Pre-allocated event slot to fill. |
| UX_SUCCESS | The event buffer holds a neutral report. |
hid_event is non-NULL (USBX guarantee). Definition at line 513 of file main.c.
References hid_fill_report_body(), k_hid_report_len, and k_hid_seq_idx.
|
static |
Halt forever in WFI – panic stop on init failure.
Last-resort stop; only a debugger or reset recovers.
|
static |
Route both ports' pins: FS as device, HS as host.
FS device: P4_07 VBUS sense, P5_00 VBUSEN GPIO LOW (else peripheral routing forces host VBUSEN and blocks device enum), P8_14/P8_15 data. HS host: SW4-8 to Host via the U15 expander, PD07 HIGH (U18 supplies J7), P4_08 VBUS sense.
Definition at line 749 of file main.c.
References hid_panic_halt(), k_hid_pin_fs_dm, k_hid_pin_fs_dp, k_hid_pin_fs_vbus, k_hid_pin_fs_vbusen, k_hid_pin_hs_pwr, k_hid_pin_hs_vbus, k_ra8_level_high, k_ra8_level_low, k_ra8_ok, k_ra8_psel_usb_fs, k_ra8_psel_usb_hs, ra8_board_io_expander_set_usbhs_host_mode(), ra8_gpio_output_init(), and ra8_pfs_route_peripheral().
|
static |
One device send iteration: queue a fresh input report.
Pins CONFIGURED (DVSQ-poll race guard), builds a report { seq, fixed body }, queues it with _ux_device_class_hid_event_set on the interrupt-IN endpoint, and yields one tick. The yield lets the lower-priority host thread drain the queue; when the queue is full the event_set fails harmlessly and the seq does not advance.
| [in,out] | seq | Rolling report sequence; advanced on a queued report. |
seq is non-NULL. seq incremented. Definition at line 581 of file main.c.
References hid_fill_report_body(), k_hid_byte_mask, k_hid_report_len, k_hid_seq_idx, k_ra8_board_led1, memset(), ra8_board_led_toggle(), s_dbg_dev_sent, s_hid_class, and tx_thread_sleep.
Referenced by hid_device_worker().
|
static |
Bring CGC + both USB clocks + SysTick + SCI8 + LEDs + pins up.
USBFS needs the 48 MHz PLL2 reference; USBHS needs its UTMI PLL. SCI8 is the J-Link OB CDC console at 115200.
Definition at line 788 of file main.c.
References hid_panic_halt(), hid_route_usb_or_halt(), k_hid_baud, k_ra8_board_led1, k_ra8_board_led2, k_ra8_clock_id_cpuclk0, k_ra8_ok, ra8_board_led_init(), ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_cgc_usbfs_clock_enable(), ra8_cgc_usbhs_pll_enable(), and ra8_time_init().
|
static |
Bring USBX system + device stack up with the HID framework.
One-shot USBX pool + device-stack init (FS-only framework).
| UX_SUCCESS | Stack ready. |
Definition at line 476 of file main.c.
References k_hid_usbx_pool_bytes, s_device_framework_fs, s_language_id_framework, s_string_framework, and s_usbx_pool.
Referenced by hid_device_worker().
| void main | ( | void | ) |
Application entry: bring the board up, then hand off to ThreadX.
The application entry point Reset_Handler hands control to.
Both USB controllers' clocks and pins come up before the kernel so the workers only deal with stack bring-up.
Definition at line 832 of file main.c.
References hid_panic_halt(), hid_setup_or_halt(), and ra8_isr_globals_enable().
| void SysTick_Handler | ( | void | ) |
Service the SysTick exception selected by the linked application.
Service one SysTick event for the core timebase.
Service one SysTick event for the core timebase.
Resolves to the weak core timebase handler unless a strong RTOS or application handler overrides it. The vector table references the selected implementation without owning its subsystem policy.
The weak firmware implementation advances the millisecond counter, then services linked ThreadX and USB hooks when their weak symbols and readiness state permit. The host-test implementation advances only the counter. An application may replace either weak definition with a strong handler.
Service the SysTick exception selected by the linked application.
The weak firmware implementation advances the millisecond counter, then services linked ThreadX and USB hooks when their weak symbols and readiness state permit. The host-test implementation advances only the counter. An application may replace either weak definition with a strong handler.
Service the SysTick exception selected by the linked application.
Definition at line 92 of file main.c.
References _tx_timer_interrupt(), ra8_time_on_tick(), s_tx_kernel_up, and ux_dcd_ra8_usb_irq_reenable().
| VOID tx_application_define | ( | VOID * | first_unused_memory | ) |
ThreadX application-define hook.
Spawns both workers.
Creates the activation semaphore, then the device worker at priority 8 and the host worker at 24 (below the USBX class threads). Sets s_tx_kernel_up so SysTick may feed ThreadX from here on.
| [in] | first_unused_memory | Sentinel (unused; static stacks). |
Definition at line 677 of file main.c.
References hid_device_worker(), hid_host_worker(), k_hid_dev_priority, k_hid_host_priority, k_hid_host_stack, k_hid_thread_stack, s_device_stack, s_device_thread, s_device_thread_name, s_hid_active_sem, s_host_stack, s_host_thread, s_host_thread_name, s_tx_kernel_up, TX_AUTO_START, TX_NO_TIME_SLICE, and tx_thread_create.
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
Posted by the activate callback so the send worker blocks on it instead of polling s_hid_class with tx_thread_sleep (which has been observed never returning on this silicon under load).
Definition at line 209 of file main.c.
Referenced by hid_activate(), hid_device_worker(), and tx_application_define().
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
Set in tx_application_define; gates ThreadX tick delivery.
main() starts SysTick before tx_kernel_enter and the setup window is long (U15 expander I2C blocks for ms), so the tick fires pre-kernel; feeding _tx_timer_interrupt into ThreadX's zeroed timer state bus-faults. Gate it until the kernel runs.
|
static |