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

USBX HID boot-keyboard device worker for usb_host_keyboard. More...

#include <stdint.h>
#include <string.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_err.h"
#include "ra8_usb.h"
#include "usb_host_keyboard_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"
Include dependency graph for usb_host_keyboard_device.c:

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 hid_fill_report_body (uint8_t *out, uint32_t len)
 Fill the fixed body of a HID report (bytes 1..len-1).
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.
VOID hid_device_worker (ULONG arg)
 Device-side worker: bring the HID device up, then send reports.
void usb_host_keyboard_device_thread_create (void)
 Create + auto-start the USBX HID device worker thread.

Variables

static const uint8_t s_kbd_keys [k_hid_nkeys]
 Keycodes the fake keyboard "types": R, A, 8, D, 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 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 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.

Detailed Description

USBX HID boot-keyboard device worker for usb_host_keyboard.

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

The USBFS (J11) device half carved out of usb_host_keyboard/main.c so each translation unit stays under the 1000-line cap. This TU owns the fake boot-keyboard: the HID report + USB descriptor frameworks, the HID class activate / deactivate callbacks, the USBX system + device-stack bring-up, the interrupt-IN report send loop, and the device worker thread (TCB + stack). main.c's tx_application_define spawns the worker through usb_host_keyboard_device_thread_create. The shared report-pattern builder, the shared activation semaphore, and the shared enums live in usb_host_keyboard_steps.h. Pure code move – no logic change.

Author
Brighton Sikarskie
Date
2026-06-13
Since
0.1.0

Definition in file usb_host_keyboard_device.c.

Enumeration Type Documentation

◆ hid_dev_step_t

enum hid_dev_step_t : uint32_t

J-Link probe values marking device-worker bring-up progress.

Enumerator
k_hid_dev_step_stack 

USBX system + device stack up.

k_hid_dev_step_class 

HID class registered.

k_hid_dev_step_dcd 

DCD bridge initialized.

k_hid_dev_step_attach 

Device attached (DPRPU).

k_hid_dev_step_send 

Report-send loop running.

Definition at line 49 of file usb_host_keyboard_device.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 58 of file usb_host_keyboard_device.c.

Function Documentation

◆ hid_activate()

VOID hid_activate ( VOID * hid_instance)
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.

Parameters
[in]hid_instancePointer to UX_SLAVE_CLASS_HID.
Precondition
Called from the USBX class thread.
SET_CONFIGURATION has just configured the device.
Postcondition
s_hid_class points at the live class.
s_usb_host_keyboard_hid_active_sem is posted so the send worker runs.
Note
USBX serializes this with the deactivate callback.
Since
0.1.0

Definition at line 340 of file usb_host_keyboard_device.c.

References s_hid_class, and s_usb_host_keyboard_hid_active_sem.

Referenced by hid_class_register(), and hid_class_register().

◆ hid_class_register()

UINT hid_class_register ( void )
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.

Returns
UINT UX_SUCCESS on success, propagated USBX error otherwise.
Return values
UX_SUCCESSClass registered.
Precondition
hid_usbx_stack_up has succeeded.
s_report_descriptor is at file scope and valid.
Postcondition
The HID class is bound; the activate callback will fire on SET_CONFIGURATION.
No other class is registered.
Note
Not re-entrant.
Since
0.1.0

Definition at line 455 of file usb_host_keyboard_device.c.

References hid_activate(), hid_deactivate(), hid_get_callback(), and s_report_descriptor.

Referenced by hid_device_worker().

◆ hid_deactivate()

VOID hid_deactivate ( VOID * hid_instance)
static

HID deactivate callback.

Drops the live class pointer.

Parameters
[in]hid_instanceUnused.
Precondition
Called from the USBX class thread.
The HID class is being torn down.
Postcondition
s_hid_class is UX_NULL.
The send worker blocks until the next activate.
Note
USBX serializes this with the activate callback.
Since
0.1.0

Definition at line 363 of file usb_host_keyboard_device.c.

References s_hid_class.

Referenced by hid_class_register(), and hid_class_register().

◆ hid_device_worker()

VOID hid_device_worker ( ULONG arg)

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 the activation semaphore until the host configures the device, then loops to keep the interrupt-IN report queue fed.

Parameters
[in]argThreadX entry argument (unused).
Precondition
tx_application_define created this thread.
USB-FS pins + 48 MHz clock are up (main did both).
Postcondition
The FS device is attached and streaming input reports.
On any bring-up failure the thread exits.
Note
Runs once; loops forever on success.
Since
0.1.0

Definition at line 515 of file usb_host_keyboard_device.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_class, s_usb_host_keyboard_hid_active_sem, TX_WAIT_FOREVER, and ux_dcd_ra8_usb_initialize().

Referenced by tx_application_define(), and usb_host_keyboard_device_thread_create().

◆ hid_fill_report_body()

void hid_fill_report_body ( uint8_t * out,
uint32_t len )

Fill the fixed body of a HID report (bytes 1..len-1).

Boot-keyboard report: byte 1 = reserved, bytes 2.. = the typed "RA8D2" keycodes, the remainder 0. Byte 0 (the seq) is left untouched. Both the device (to build) and the host (to verify) compute the same body.

Parameters
[out]outReport buffer.
[in]lenReport width in bytes (>= 1).
Precondition
out has len writable bytes.
len is at most k_hid_read_buf.
Postcondition
out[1..len-1] hold the fixed pattern bytes.
out[0] is unchanged.
Note
Pure function (apart from the caller's buffer).
Since
0.1.0

Definition at line 302 of file usb_host_keyboard_device.c.

Referenced by hid_get_callback(), and hid_send_iter().

◆ hid_get_callback()

UINT hid_get_callback ( UX_SLAVE_CLASS_HID * hid,
UX_SLAVE_CLASS_HID_EVENT * hid_event )
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.

Parameters
[in,out]hidUSBX HID class instance (unused).
[in,out]hid_eventPre-allocated event slot to fill.
Returns
Always UX_SUCCESS.
Return values
UX_SUCCESSThe event buffer holds a neutral report.
Precondition
hid_event is non-NULL (USBX guarantee).
The HID class is live.
Postcondition
The event buffer holds a k_hid_report_len-byte report.
No global state changes.
Note
Called from USBX's control-pipe thread.
Since
0.1.0

Definition at line 426 of file usb_host_keyboard_device.c.

References hid_fill_report_body(), k_hid_report_len, and k_hid_seq_idx.

Referenced by hid_class_register(), and hid_class_register().

◆ hid_send_iter()

void hid_send_iter ( uint32_t * seq)
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.

Parameters
[in,out]seqRolling report sequence; advanced on a queued report.
Precondition
s_hid_class is non-NULL (class activated).
seq is non-NULL.
Postcondition
On a queued report s_dbg_dev_sent advanced and seq incremented.
The worker yielded one tick.
Note
Runs on the device worker thread.
Since
0.1.0

Definition at line 494 of file usb_host_keyboard_device.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().

◆ hid_usbx_stack_up()

UINT hid_usbx_stack_up ( void )
static

Bring USBX system + device stack up with the HID framework.

One-shot USBX pool + device-stack init (FS-only framework).

Returns
UINT UX_SUCCESS on success.
Return values
UX_SUCCESSStack ready.
Precondition
File-scope pool reserved.
Thread context.
Postcondition
Device stack accepts class registrations.
On failure USBX state is undefined.
Note
Single-call; not idempotent.
Since
0.1.0

Definition at line 389 of file usb_host_keyboard_device.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().

◆ usb_host_keyboard_device_thread_create()

void usb_host_keyboard_device_thread_create ( void )

Create + auto-start the USBX HID device worker thread.

Owns the device thread's TCB + stack storage at file scope in the device sibling and spawns hid_device_worker at k_hid_dev_priority. Called once from tx_application_define in main.c.

Precondition
Called from tx_kernel_enter after scheduler init.
The activation semaphore exists.
Postcondition
One auto-start device worker is queued.
The device thread runs at k_hid_dev_priority.
Note
Called once at boot; not thread-safe.
Since
0.1.0

Definition at line 555 of file usb_host_keyboard_device.c.

References hid_device_worker(), k_hid_dev_priority, k_hid_thread_stack, s_device_stack, s_device_thread, s_device_thread_name, TX_AUTO_START, TX_NO_TIME_SLICE, and tx_thread_create.

Referenced by tx_application_define().

Variable Documentation

◆ s_dbg_dev_err

volatile uint32_t s_dbg_dev_err
static

Device worker first failing return code (0 = none).

Definition at line 119 of file usb_host_keyboard_device.c.

◆ s_dbg_dev_sent

volatile uint32_t s_dbg_dev_sent
static

Device-side report-queue successes (one hid_event_set each).

Definition at line 115 of file usb_host_keyboard_device.c.

Referenced by hid_send_iter(), and hid_send_iter().

◆ s_dbg_dev_step

volatile uint32_t s_dbg_dev_step
static

Device worker progress: 1 stack, 2 class, 3 dcd, 4 attach, 5 send.

Definition at line 117 of file usb_host_keyboard_device.c.

◆ s_device_framework_fs

UCHAR s_device_framework_fs[]
static

Definition at line 165 of file usb_host_keyboard_device.c.

◆ s_device_stack

UCHAR s_device_stack[k_hid_thread_stack]
static

Stack backing storage for s_device_thread.

Since
0.1.0

Definition at line 93 of file usb_host_keyboard_device.c.

◆ s_device_thread

TX_THREAD s_device_thread
static

ThreadX TCB for the USBX device-side worker thread.

Note
Single-writer (worker only).
Since
0.1.0

Definition at line 86 of file usb_host_keyboard_device.c.

◆ s_hid_class

UX_SLAVE_CLASS_HID* s_hid_class = UX_NULL
static

Active HID class instance, captured by the activate callback.

Note
Written by the USBX class thread; read by the device send worker.
Since
0.1.0

Definition at line 108 of file usb_host_keyboard_device.c.

Referenced by demo_hid_activate(), demo_hid_deactivate(), demo_jiggle_send(), demo_worker(), hid_activate(), hid_activate(), hid_deactivate(), hid_deactivate(), hid_device_worker(), hid_device_worker(), hid_send_iter(), and hid_send_iter().

◆ s_kbd_keys

const uint8_t s_kbd_keys[k_hid_nkeys]
static
Initial value:
= {
(uint8_t)k_hid_kc_r,
(uint8_t)k_hid_kc_a,
(uint8_t)k_hid_kc_8,
(uint8_t)k_hid_kc_d,
(uint8_t)k_hid_kc_2,
}
@ k_hid_kc_a
Keycode for 'a' / 'A'.
@ k_hid_kc_d
Keycode for 'd' / 'D'.
@ k_hid_kc_r
Keycode for 'r' / 'R'.
@ k_hid_kc_8
Keycode for '8'.
@ k_hid_kc_2
Keycode for '2'.

Keycodes the fake keyboard "types": R, A, 8, D, 2.

Definition at line 68 of file usb_host_keyboard_device.c.

Referenced by hid_fill_report_body().

◆ s_language_id_framework

UCHAR s_language_id_framework[] = {k_usb_langid_en_us_lo, k_usb_langid_en_us_hi}
static

USBX language-id table – US English.

Since
0.1.0

Definition at line 296 of file usb_host_keyboard_device.c.

◆ s_report_descriptor

UCHAR s_report_descriptor[]
static
Initial value:
= {
0x05U, 0x01U,
0x09U, 0x06U,
0xA1U, 0x01U,
0x05U, 0x07U,
0x19U, 0xE0U,
0x29U, 0xE7U,
0x15U, 0x00U,
0x25U, 0x01U,
0x75U, 0x01U,
0x95U, 0x08U,
0x81U, 0x02U,
0x95U, 0x01U,
0x75U, 0x08U,
0x81U, 0x01U,
0x95U, 0x06U,
0x75U, 0x08U,
0x15U, 0x00U,
0x25U, 0x65U,
0x05U, 0x07U,
0x19U, 0x00U,
0x29U, 0x65U,
0x81U, 0x00U,
0xC0U,
}

Definition at line 130 of file usb_host_keyboard_device.c.

Referenced by demo_hid_class_register(), hid_class_register(), and hid_class_register().

◆ s_string_framework

UCHAR s_string_framework[]
static

USBX string descriptor table (vendor / product / serial).

Each entry: 2 bytes lang-id, 1 byte string index, 1 byte length, then ASCII bytes.

Since
0.1.0

Definition at line 233 of file usb_host_keyboard_device.c.

◆ s_usbx_pool

UCHAR s_usbx_pool[k_hid_usbx_pool_bytes]
static

USBX memory pool (USBX uses tx_byte_pool internally).

Since
0.1.0

Definition at line 100 of file usb_host_keyboard_device.c.