ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c File Reference

ThreadX + USBX HID boot-mouse demo for EK-RA8D2 (USB-FS). 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 "tx_api.h"
#include "ux_api.h"
#include "ux_dcd_ra8_usb.h"
#include "ux_device_class_hid.h"
#include "ux_device_stack.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  demo_config_t : uint32_t {
  k_demo_thread_stack = 4096U ,
  k_demo_usbx_pool_bytes = 32768U ,
  k_demo_jiggle_period_ticks = 100U
}
 Compile-time settings for the worker thread + USBX pool. More...
enum  demo_hid_report_t : uint8_t {
  k_demo_hid_report_bytes = 3U ,
  k_demo_hid_idx_buttons = 0U ,
  k_demo_hid_idx_dx = 1U ,
  k_demo_hid_idx_dy = 2U
}
 Sizing for the boot-protocol mouse input report. More...
enum  demo_jiggle_t : int8_t {
  k_demo_jiggle_step = 4 ,
  k_demo_jiggle_zero = 0 ,
  k_demo_jiggle_neg = -4
}
 Per-step cursor delta values for the autonomous jiggle. More...
enum  demo_phase_t : uint8_t {
  k_demo_phase_right = 0U ,
  k_demo_phase_down = 1U ,
  k_demo_phase_left = 2U ,
  k_demo_phase_up = 3U ,
  k_demo_phase_count = 4U
}
 Index into the four-step jiggle pattern. More...
enum  usb_langid_byte_t : uint8_t {
  k_usb_langid_en_us_lo = 0x09U ,
  k_usb_langid_en_us_hi = 0x04U
}

Functions

static VOID demo_hid_activate (VOID *hid_instance)
 HID activate callback.
static VOID demo_hid_deactivate (VOID *hid_instance)
 HID deactivate callback.
static UINT demo_hid_get_callback (UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *hid_event)
 HID GET_REPORT / SET_REPORT control-pipe callback.
static void demo_build_jiggle (demo_phase_t phase, UCHAR *report)
 Build the boot-mouse report for one phase of the jiggle.
static UINT demo_usbx_stack_up (void)
 Brings the USBX system and FS device stack up.
static UINT demo_hid_class_register (void)
 Registers the HID class with the configured report descriptor.
static void demo_jiggle_send (demo_phase_t *phase)
 Push a single HID jiggle event in the given phase.
static VOID demo_worker (ULONG arg)
VOID tx_application_define (VOID *first_unused_memory)
 ThreadX application-define hook.
static void demo_panic_halt (void)
 Halt forever in WFI – panic stop on init failure.
static ra8_err_t demo_pins_init (void)
 Route the four USB-FS pins to the USBFS controller.
void main (void)
 Application entry.

Variables

static const ra8_port_pin_t k_demo_pin_vbus = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbus
 USB-FS pin identifiers, packed ra8_port_pin_t (port << 8 | pin).
static const ra8_port_pin_t k_demo_pin_vbusen = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbusen
static const ra8_port_pin_t k_demo_pin_dp = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dp
static const ra8_port_pin_t k_demo_pin_dm = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dm
static TX_THREAD s_demo_thread
 ThreadX TCB for the USBX worker thread.
static UCHAR s_demo_stack [k_demo_thread_stack]
 Stack backing storage for s_demo_thread.
static UCHAR s_usbx_pool [k_demo_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.
volatile uint32_t g_usb_hid_match = 0U
 HIL liveness counter – incremented on every successful _ux_device_class_hid_event_set (a HID report queued to the host).
volatile uint32_t g_usb_hid_mismatch = 0U
 HIL failure counter – incremented when _ux_device_class_hid_event_set returns a non-success status (queue full, class disconnected mid-loop, ...).
static UCHAR s_report_descriptor []
 HID Report Descriptor for the boot mouse.
static UCHAR s_device_framework_fs []
static UCHAR s_string_framework []
static UCHAR s_language_id_framework [] = {k_usb_langid_en_us_lo, k_usb_langid_en_us_hi}

Detailed Description

ThreadX + USBX HID boot-mouse demo for EK-RA8D2 (USB-FS).

Tag
[Ring 6 / APP] {World: S}

Brings the chip up via ra8_cgc_init() (XTAL -> PLL1 -> CPUCLK0 = 1 GHz, PCLKA = 125 MHz), routes the four USB-FS pins per the EK-RA8D2 v1 User's Manual to the on-board USB-FS receptacle, hands control to ThreadX, and brings the HID class up through Eclipse USBX's class layer (ux_device_class_hid_initialize). Same hardware test as the previous bare-metal version of this app, but driving USBX's class abstraction (which sits on top of port/usbx/ux_dcd_ra8_usb -> ra8_usb – HUM Ch. 36) instead of the hand-rolled ra8_usb_phid layer. The host actually enumerates the device because USBX's chapter-9 state machine answers SETUP packets through the DCD bridge.

Once enumerated, the worker thread pushes a 4-pixel cursor jiggle (right, down, left, up) to the host every second on the interrupt-IN pipe via _ux_device_class_hid_event_set. LED1 toggles per send.

The HID Report Descriptor is the canonical 3-button + X/Y boot- protocol mouse described in USB HID 1.11 sec E.10. Reports are 3 bytes:

  • byte 0: button bitmap (B1=left, B2=right, B3=middle).
  • byte 1: signed X delta (-127 .. +127).
  • byte 2: signed Y delta (-127 .. +127).

Pinout (USB-FS, FSP-aligned)

Net Pin PFS PSEL
USB_FS_VBUS P4_07 k_ra8_psel_usb_fs (0x13)
USB_FS_VBUSEN P5_00 k_ra8_psel_usb_fs (0x13)
USB_FS_DP P8_14 k_ra8_psel_usb_fs (0x13)
USB_FS_DM P8_15 k_ra8_psel_usb_fs (0x13)

Sequence

  1. ra8_cgc_init() – standard FSP-quickstart clock tree.
  2. ra8_time_init for back-off delays.
  3. ra8_pfs_route_peripheral for the four USB-FS pins.
  4. ra8_board_led_init(k_ra8_board_led1) for visual heartbeat.
  5. ThreadX tx_kernel_enter() – spins the scheduler.
  6. tx_application_define – spawns one worker thread that:
    • Allocates USBX memory pool and calls _ux_system_initialize + _ux_device_stack_initialize.
    • Calls _ux_device_stack_class_register for the HID class.
    • Calls ux_dcd_ra8_usb_initialize(k_ra8_usb_speed_fs) to plug our DCD bridge into USBX.
    • Calls ra8_usb_device_attach(true) so the host begins enumeration.
    • Drops into the jiggle loop: _ux_device_class_hid_event_set once per second, LED1 toggle per send.

Verification (macOS)

After flashing, the EK-RA8D2's USB-FS receptacle (J11) enumerates as an HID Mouse. system_profiler SPUSBDataType lists the device under "USB Bus" with class HID. The cursor moves on screen in a 4-pixel square; no driver install needed (the OS uses its built-in boot-mouse class driver).

Author
Brighton Sikarskie
Date
2026-05-02
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ demo_config_t

enum demo_config_t : uint32_t

Compile-time settings for the worker thread + USBX pool.

Enumerator
k_demo_thread_stack 

Worker thread stack (bytes).

k_demo_usbx_pool_bytes 

USBX pool: 32 KiB; HID enum exhausts 16 KiB.

k_demo_jiggle_period_ticks 

ThreadX ticks between sends.

Definition at line 128 of file main.c.

◆ demo_hid_report_t

enum demo_hid_report_t : uint8_t

Sizing for the boot-protocol mouse input report.

Per USB HID 1.11 sec E.10 the boot-mouse input report is 3 bytes wide: { buttons, dx, dy }.

Enumerator
k_demo_hid_report_bytes 

Boot mouse report width.

k_demo_hid_idx_buttons 

Byte offset for buttons.

k_demo_hid_idx_dx 

Byte offset for X delta.

k_demo_hid_idx_dy 

Byte offset for Y delta.

Definition at line 141 of file main.c.

◆ demo_jiggle_t

enum demo_jiggle_t : int8_t

Per-step cursor delta values for the autonomous jiggle.

A 4-pixel right / down / left / up square so the cursor drifts in place. int8_t because the report field is signed 8-bit per HID Usage Tables sec 4 "Generic Desktop Usage Page".

Enumerator
k_demo_jiggle_step 

Magnitude of each jiggle step.

k_demo_jiggle_zero 

No motion on the inactive axis.

k_demo_jiggle_neg 

Reverse of k_step.

Definition at line 156 of file main.c.

◆ demo_phase_t

enum demo_phase_t : uint8_t

Index into the four-step jiggle pattern.

Enumerator
k_demo_phase_right 

+X, 0Y.

k_demo_phase_down 

0X, +Y.

k_demo_phase_left 

-X, 0Y.

k_demo_phase_up 

0X, -Y.

k_demo_phase_count 

Modulus.

Definition at line 166 of file main.c.

◆ usb_langid_byte_t

enum usb_langid_byte_t : uint8_t
Enumerator
k_usb_langid_en_us_lo 

LANGID 0x0409 low byte.

k_usb_langid_en_us_hi 

LANGID 0x0409 high byte.

Definition at line 448 of file main.c.

Function Documentation

◆ demo_build_jiggle()

void demo_build_jiggle ( demo_phase_t phase,
UCHAR * report )
static

Build the boot-mouse report for one phase of the jiggle.

Parameters
[in]phasePosition in the 4-step square pattern.
[out]reportDestination buffer; must hold k_demo_hid_report_bytes.
Precondition
report is non-NULL.
phase < k_demo_phase_count.
Postcondition
All three report bytes written.
Note
Reentrant; no shared state.
Since
0.1.0

Definition at line 540 of file main.c.

References k_demo_hid_idx_buttons, k_demo_hid_idx_dx, k_demo_hid_idx_dy, k_demo_jiggle_neg, k_demo_jiggle_step, k_demo_jiggle_zero, k_demo_phase_count, k_demo_phase_down, k_demo_phase_left, k_demo_phase_right, and k_demo_phase_up.

Referenced by demo_jiggle_send().

◆ demo_hid_activate()

VOID demo_hid_activate ( VOID * hid_instance)
static

HID activate callback.

Captures the live class instance.

Parameters
[in]hid_instancePointer to UX_SLAVE_CLASS_HID.
Precondition
Called from the USBX class thread.
Postcondition
s_hid_class points at the live HID class.
Note
USBX guarantees serialization with the deactivate callback.
Since
0.1.0

Definition at line 470 of file main.c.

References s_hid_class.

Referenced by demo_hid_class_register().

◆ demo_hid_class_register()

UINT demo_hid_class_register ( void )
static

Registers the HID class with the configured report descriptor.

Returns
UINT UX_SUCCESS on success, propagated USBX error otherwise.
Return values
UX_SUCCESSClass registered.
Precondition
demo_usbx_stack_up has succeeded.
s_report_descriptor is at file scope and valid.
Postcondition
HID class bound to configuration 1, interface 0.
demo_hid_activate will fire on SET_CONFIGURATION.
Note
Not re-entrant.
Since
0.1.0

Definition at line 610 of file main.c.

References demo_hid_activate(), demo_hid_deactivate(), demo_hid_get_callback(), and s_report_descriptor.

Referenced by demo_worker().

◆ demo_hid_deactivate()

VOID demo_hid_deactivate ( VOID * hid_instance)
static

HID deactivate callback.

Drops the live-class pointer.

Parameters
[in]hid_instancePointer to UX_SLAVE_CLASS_HID (unused).
Precondition
Called from the USBX class thread.
Postcondition
s_hid_class is UX_NULL.
Note
USBX guarantees serialization with the activate callback.
Since
0.1.0

Definition at line 486 of file main.c.

References s_hid_class.

Referenced by demo_hid_class_register().

◆ demo_hid_get_callback()

UINT demo_hid_get_callback ( UX_SLAVE_CLASS_HID * hid,
UX_SLAVE_CLASS_HID_EVENT * hid_event )
static

HID GET_REPORT / SET_REPORT control-pipe callback.

Boot mouse: hosts that issue GET_REPORT(input) get a zero- deltas neutral report so they don't see stale state. SET_REPORT (output / feature) is silently consumed – the boot-mouse profile has no LED bitmap.

Parameters
[in,out]hidUSBX HID class instance (unused).
[in,out]hid_eventPre-allocated event slot to fill.
Returns
UX_SUCCESS always.
Precondition
hid_event is non-NULL (USBX guarantee).
Postcondition
Event buffer holds a 3-byte neutral report.
Note
Called from USBX's control-pipe thread.
Since
0.1.0

Definition at line 511 of file main.c.

References k_demo_hid_idx_buttons, k_demo_hid_idx_dx, k_demo_hid_idx_dy, and k_demo_hid_report_bytes.

Referenced by demo_hid_class_register().

◆ demo_jiggle_send()

void demo_jiggle_send ( demo_phase_t * phase)
static

Push a single HID jiggle event in the given phase.

Parameters
[in,out]phaseCurrent jiggle phase; advanced on successful send.
Precondition
Worker thread context; s_hid_class is non-NULL.
phase points to a valid demo_phase_t.
Postcondition
On UX_SUCCESS: LED1 toggled and *phase advanced.
On failure: *phase unchanged.
Note
Caller paces invocations with tx_thread_sleep.
Since
0.1.0

Definition at line 643 of file main.c.

References demo_build_jiggle(), g_usb_hid_match, g_usb_hid_mismatch, k_demo_hid_report_bytes, k_demo_phase_count, k_ra8_board_led1, memset(), ra8_board_led_toggle(), and s_hid_class.

Referenced by demo_worker().

◆ demo_panic_halt()

void demo_panic_halt ( void )
static

Halt forever in WFI – panic stop on init failure.

Precondition
Called only after a fatal error in boot.
Postcondition
CPU is parked; only debugger / external reset wakes it.
Note
Not thread-safe; not reachable post-boot.
Since
0.1.0

Definition at line 739 of file main.c.

◆ demo_pins_init()

ra8_err_t demo_pins_init ( void )
staticnodiscard

Route the four USB-FS pins to the USBFS controller.

Returns
Error from the first failing route call, or k_ra8_ok.
Return values
k_ra8_okAll four pins routed.
Precondition
IOPORT module is reachable.
Single-threaded init context.
Postcondition
On success the four USB-FS pins are in USB peripheral mode.
Note
Not thread-safe.
Since
0.1.0

Definition at line 759 of file main.c.

References k_demo_pin_dm, k_demo_pin_dp, k_demo_pin_vbus, k_demo_pin_vbusen, k_ra8_level_low, k_ra8_ok, k_ra8_psel_usb_fs, ra8_gpio_output_init(), and ra8_pfs_route_peripheral().

◆ demo_usbx_stack_up()

UINT demo_usbx_stack_up ( void )
static

Brings the USBX system and FS device stack up.

Returns
UINT UX_SUCCESS on success.
Return values
UX_SUCCESSStack ready.
Precondition
File-scope s_usbx_pool is reserved.
Caller is in thread context.
Postcondition
Device stack accepts class registrations.
On failure, USBX state is undefined.
Note
Call once per worker bring-up.
Since
0.1.0

Definition at line 580 of file main.c.

References k_demo_usbx_pool_bytes, s_device_framework_fs, s_language_id_framework, s_string_framework, and s_usbx_pool.

◆ demo_worker()

◆ main()

void main ( void )

Application entry.

The application entry point Reset_Handler hands control to.

Brings up CGC + USB-FS pins + LED1 + ThreadX.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the CPU stays in tx_kernel_enter forever.
On any HAL init failure the function halts in WFI.
Note
Single entry point; not re-entrant.
Since
0.1.0

Definition at line 789 of file main.c.

References demo_panic_halt(), demo_pins_init(), k_ra8_board_led1, k_ra8_clock_id_cpuclk0, k_ra8_ok, ra8_board_led_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_cgc_usbfs_clock_enable(), ra8_isr_globals_enable(), and ra8_time_init().

◆ tx_application_define()

VOID tx_application_define ( VOID * first_unused_memory)

ThreadX application-define hook.

Spawns the demo worker.

Parameters
[in]first_unused_memorySentinel (unused; we use static stacks).
Precondition
Called from tx_kernel_enter after scheduler init.
Postcondition
One auto-start worker thread is queued.
Note
Called once at boot; not thread-safe.
Since
0.1.0

Definition at line 708 of file main.c.

References demo_worker(), k_demo_thread_stack, s_demo_stack, s_demo_thread, s_thread_name, TX_AUTO_START, TX_NO_TIME_SLICE, and tx_thread_create.

Variable Documentation

◆ g_usb_hid_match

volatile uint32_t g_usb_hid_match = 0U

HIL liveness counter – incremented on every successful _ux_device_class_hid_event_set (a HID report queued to the host).

Read externally via SWD by scripts/hil/jlink_memprobe.sh. If the host has enumerated the device and the worker is pumping reports, this advances at the jiggle-period cadence (~50 Hz). If USBX bring-up failed or the host isn't attached, it stays at 0.

Note
Read externally only.
Since
0.1.0

Definition at line 225 of file main.c.

Referenced by demo_jiggle_send().

◆ g_usb_hid_mismatch

volatile uint32_t g_usb_hid_mismatch = 0U

HIL failure counter – incremented when _ux_device_class_hid_event_set returns a non-success status (queue full, class disconnected mid-loop, ...).

Note
Read externally only.
Since
0.1.0

Definition at line 235 of file main.c.

Referenced by demo_jiggle_send().

◆ k_demo_pin_dm

Definition at line 118 of file main.c.

◆ k_demo_pin_dp

Definition at line 117 of file main.c.

◆ k_demo_pin_vbus

const ra8_port_pin_t k_demo_pin_vbus = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbus
static

USB-FS pin identifiers, packed ra8_port_pin_t (port << 8 | pin).

Built as a runtime cast so clang-tidy's enum-range check is happy with the otherwise out-of-enum value.

Since
0.1.0

Definition at line 115 of file main.c.

◆ k_demo_pin_vbusen

const ra8_port_pin_t k_demo_pin_vbusen = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbusen
static

Definition at line 116 of file main.c.

◆ s_demo_stack

UCHAR s_demo_stack[k_demo_thread_stack]
static

Stack backing storage for s_demo_thread.

Since
0.1.0

Definition at line 195 of file main.c.

◆ s_demo_thread

TX_THREAD s_demo_thread
static

ThreadX TCB for the USBX worker thread.

Owned by tx_application_define; one thread services USBX init + the jiggle loop.

Note
Single-writer (worker only); readers must not mutate.
Since
0.1.0

Definition at line 188 of file main.c.

◆ s_device_framework_fs

UCHAR s_device_framework_fs[]
static

Definition at line 318 of file main.c.

◆ s_hid_class

UX_SLAVE_CLASS_HID* s_hid_class = UX_NULL
static

Active HID class instance, captured by the activate callback.

Note
Read by worker thread; written by USBX class thread.
Since
0.1.0

Definition at line 210 of file main.c.

◆ s_language_id_framework

UCHAR s_language_id_framework[] = {k_usb_langid_en_us_lo, k_usb_langid_en_us_hi}
static

Definition at line 453 of file main.c.

◆ s_report_descriptor

UCHAR s_report_descriptor[]
static
Initial value:
= {
0x05U, 0x01U,
0x09U, 0x02U,
0xA1U, 0x01U,
0x09U, 0x01U,
0xA1U, 0x00U,
0x05U, 0x09U,
0x19U, 0x01U,
0x29U, 0x03U,
0x15U, 0x00U,
0x25U, 0x01U,
0x95U, 0x03U,
0x75U, 0x01U,
0x81U, 0x02U,
0x95U, 0x01U,
0x75U, 0x05U,
0x81U, 0x03U,
0x05U, 0x01U,
0x09U, 0x30U,
0x09U, 0x31U,
0x15U, 0x81U,
0x25U, 0x7FU,
0x75U, 0x08U,
0x95U, 0x02U,
0x81U, 0x06U,
0xC0U,
0xC0U,
}

HID Report Descriptor for the boot mouse.

Decoded sequence per USB HID 1.11 sec E.10: 05 01 Usage Page (Generic Desktop) 09 02 Usage (Mouse) A1 01 Collection (Application) 09 01 Usage (Pointer) A1 00 Collection (Physical) 05 09 Usage Page (Buttons) 19 01 Usage Min (1) 29 03 Usage Max (3) 15 00 Logical Min (0) 25 01 Logical Max (1) 95 03 Report Count (3) 75 01 Report Size (1) 81 02 Input (Data,Var,Abs) 95 01 Report Count (1) 75 05 Report Size (5) 81 03 Input (Cnst,Var,Abs) – 5 padding bits 05 01 Usage Page (Generic Desktop) 09 30 Usage (X) 09 31 Usage (Y) 15 81 Logical Min (-127) 25 7F Logical Max ( 127) 75 08 Report Size (8) 95 02 Report Count (2) 81 06 Input (Data,Var,Rel) C0 End Collection (Physical) C0 End Collection (Application)

Note
Pure 7-bit ASCII; bytes are hex literals.
Since
0.1.0

Definition at line 276 of file main.c.

◆ s_string_framework

UCHAR s_string_framework[]
static

Definition at line 385 of file main.c.

◆ s_usbx_pool

UCHAR s_usbx_pool[k_demo_usbx_pool_bytes]
static

USBX memory pool (USBX uses tx_byte_pool internally).

Since
0.1.0

Definition at line 202 of file main.c.