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

USB host-mode HID boot-keyboard over the self-loop (no real keyboard). 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_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 main.c:

Go to the source code of this file.

Enumerations

enum  hid_phase_t : uint32_t {
  k_hid_phase_boot = 0U ,
  k_hid_phase_init = 1U ,
  k_hid_phase_enum = 2U ,
  k_hid_phase_verify = 3U ,
  k_hid_phase_pass = 4U
}
 J-Link probe values marking host-ladder progress. More...
enum  hid_usb_req_t : uint16_t {
  k_hid_bm_std_dev_in = 0x80U ,
  k_hid_bm_std_dev_out = 0x00U ,
  k_hid_breq_get_desc = 0x06U ,
  k_hid_breq_set_addr = 0x05U ,
  k_hid_breq_set_config = 0x09U ,
  k_hid_desc_device = 0x01U ,
  k_hid_dev_desc_len = 18U ,
  k_hid_off_dev_pid = 10U ,
  k_hid_byte_bits = 8U ,
  k_hid_config_value = 1U
}
 Standard chapter-9 request / descriptor constants for the host. More...
enum  hid_enum_tune_t : uint32_t {
  k_hid_vbus_settle_ms = 200U ,
  k_hid_attach_to_ms = 2000U ,
  k_hid_debounce_ms = 500U ,
  k_hid_reset_hold_ms = 50U ,
  k_hid_recovery_ms = 20U ,
  k_hid_addr_settle_ms = 5U ,
  k_hid_enum_tries = 8U ,
  k_hid_attach_spin = 50000000U
}
 Timing / retry tunables for the polled enumeration ladder. More...

Functions

void _tx_timer_interrupt (void)
void SysTick_Handler (void)
 Service the SysTick exception selected by the linked application.
static char hid_keycode_to_ascii (uint8_t kc)
 Decode one HID Usage-Table keycode to its ASCII character.
static ra8_err_t hid_ctrl_get_dev_desc (uint8_t *desc)
 GET_DESCRIPTOR(DEVICE) over the polled control engine.
static ra8_err_t hid_enum_hunt (uint8_t *desc)
 Wait for the device to attach, then bus-reset + read its descriptor.
static ra8_err_t hid_enum_set_address (void)
 SET_ADDRESS to k_hid_dev_addr, then retarget the DCP.
static ra8_err_t hid_enum_set_config (void)
 SET_CONFIGURATION(::k_hid_config_value) on the addressed device.
static ra8_err_t hid_open_pipes (void)
 Open the host receive pipe for the device's HID interrupt-IN endpoint.
static ra8_err_t hid_enumerate (uint32_t *out_pid)
 Run the full enumeration ladder and open the bulk pipes.
static ra8_err_t hid_print_enum (uint32_t pid)
 Print "enumerated pid=0xNNNN" for the looped device.
static ra8_err_t hid_print_pass (void)
 Print the decoded keys + "USB HOST KEYBOARD PASS".
static ra8_err_t hid_read_round (uint32_t round)
 One report round: read an interrupt-IN report, check its body.
static ra8_err_t hid_host_pass (void)
 One full host-side pass: enumerate, then read + check reports.
static VOID hid_host_worker (ULONG arg)
 Host-side worker: retry the full pass until it succeeds.
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 char s_typed [k_hid_nkeys+1U] = {}
 ASCII the host decoded from the read keycodes (filled by the verify).
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.
TX_SEMAPHORE s_usb_host_keyboard_hid_active_sem
 Activation semaphore shared by the device worker and main.c.
static volatile uint32_t s_dbg_phase
 Host-ladder phase marker (hid_phase_t).
static volatile uint32_t s_dbg_rounds_ok
 Reports the host confirmed pattern-equal (expect k_hid_rounds).
static volatile uint32_t s_dbg_pid
 Device-reported product id captured at enumeration.
static volatile uint32_t s_dbg_mismatch = (uint32_t)k_hid_no_mismatch
 First mismatching report round, or k_hid_no_mismatch.
static volatile uint32_t s_dbg_pass_count
 Completed full passes (sticky success counter).
static volatile uint32_t s_dbg_last_seq
 Seq byte of the most recent report the host read back.

Detailed Description

USB host-mode HID boot-keyboard over the self-loop (no real keyboard).

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

Validates the USB HID keyboard host path with no real keyboard: the board hosts on one jack and simulates a boot-keyboard peripheral on the other over the loop cable. One image runs both USB stacks:

  • USBFS (J11) = DEVICE (the fake keyboard): a ThreadX + USBX HID class advertising the standard boot-keyboard report descriptor (interface subclass 1 / protocol 1). A worker continuously queues the 8-byte boot report [modifier][reserved][keycode x6] with the keycodes for "RA8D2".
  • USBHS (J7) = HOST: a polled host on the first-party ra8_usb_host_* primitives. It enumerates the keyboard, opens the interrupt-IN endpoint, polls reports, verifies the body, and DECODES the keycodes (bytes 2..) back to ASCII – proving the HID keyboard report path end to end on chip.

This is the boot-keyboard counterpart to usb_selftest_hid (which uses a generic vendor report); the original version needed a real USB keyboard in J7. Verdicts stream over SCI8 (J-Link OB CDC, 115200); s_dbg_* mirror progress for J-Link.

Pinout

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).

Author
Brighton Sikarskie
Date
2026-06-13
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ hid_enum_tune_t

enum hid_enum_tune_t : uint32_t

Timing / retry tunables for the polled enumeration ladder.

Enumerator
k_hid_vbus_settle_ms 

VBUS settle before probing.

k_hid_attach_to_ms 

Wait for the D+ pull-up.

k_hid_debounce_ms 

Post-attach debounce (>=100 ms).

k_hid_reset_hold_ms 

USB bus-reset hold (>=10 ms).

k_hid_recovery_ms 

Post-reset recovery (TRSTRCY).

k_hid_addr_settle_ms 

Post-SET_ADDRESS recovery.

k_hid_enum_tries 

Reset+probe attempts.

k_hid_attach_spin 

Attach spin cap (frozen-tick guard).

Definition at line 233 of file main.c.

◆ hid_phase_t

enum hid_phase_t : uint32_t

J-Link probe values marking host-ladder progress.

Enumerator
k_hid_phase_boot 

Host thread not started.

k_hid_phase_init 

Host controller init.

k_hid_phase_enum 

Enumerating.

k_hid_phase_verify 

Reading + checking reports.

k_hid_phase_pass 

All reports verified.

Definition at line 124 of file main.c.

◆ hid_usb_req_t

enum hid_usb_req_t : uint16_t

Standard chapter-9 request / descriptor constants for the host.

Enumerator
k_hid_bm_std_dev_in 

bmRequestType: Std | Device | In.

k_hid_bm_std_dev_out 

bmRequestType: Std | Device | Out.

k_hid_breq_get_desc 

GET_DESCRIPTOR.

k_hid_breq_set_addr 

SET_ADDRESS.

k_hid_breq_set_config 

SET_CONFIGURATION.

k_hid_desc_device 

DEVICE descriptor type.

k_hid_dev_desc_len 

DEVICE descriptor length.

k_hid_off_dev_pid 

idProduct LSB byte offset.

k_hid_byte_bits 

Bits per byte.

k_hid_config_value 

bConfigurationValue to select.

Definition at line 216 of file main.c.

Function Documentation

◆ _tx_timer_interrupt()

void _tx_timer_interrupt ( void )
extern

◆ hid_ctrl_get_dev_desc()

ra8_err_t hid_ctrl_get_dev_desc ( uint8_t * desc)
staticnodiscard

GET_DESCRIPTOR(DEVICE) over the polled control engine.

Parameters
[out]descReceives the 18-byte device descriptor.
Returns
Read outcome.
Return values
k_ra8_okAll 18 bytes arrived.
k_ra8_err_hw_errorA short descriptor came back.
Precondition
The bus is reset and the DCP targets the device's current address.
desc holds at least k_hid_dev_desc_len bytes.
Postcondition
desc carries the device descriptor on success.
No global state changes.
Note
Blocking (polled control transfer).
Since
0.1.0

Definition at line 261 of file main.c.

References k_hid_bm_std_dev_in, k_hid_breq_get_desc, k_hid_byte_bits, k_hid_desc_device, k_hid_dev_desc_len, k_ra8_err_hw_error, k_ra8_ok, k_ra8_usb_speed_hs, and ra8_usb_host_control_xfer().

Referenced by hid_enum_hunt().

◆ hid_enum_hunt()

ra8_err_t hid_enum_hunt ( uint8_t * desc)
staticnodiscard

Wait for the device to attach, then bus-reset + read its descriptor.

Waits for the D+ pull-up (LNST leaves SE0) plus the spec debounce, then each attempt drives a full bus reset (returns the device to address 0), re-enables SOF, targets address 0, and reads the device descriptor. The first attempt that returns all 18 bytes wins.

Parameters
[out]descReceives the winning 18-byte device descriptor.
Returns
Hunt outcome.
Return values
k_ra8_okThe device answered at address 0.
k_ra8_err_hw_timeoutNothing attached / nothing answered.
Precondition
ra8_usb_host_init ran (host mode up, VBUS supplied).
ra8_time_init has run (ms delays).
Postcondition
On success the DCP targets address 0 with UACT on.
On failure the bus is left in the last attempt's state.
Note
Blocking; worst case a few seconds.
Since
0.1.0

Definition at line 304 of file main.c.

References hid_ctrl_get_dev_desc(), k_hid_attach_spin, k_hid_attach_to_ms, k_hid_debounce_ms, k_hid_enum_tries, k_hid_recovery_ms, k_hid_reset_hold_ms, k_hid_vbus_settle_ms, k_ra8_err_hw_timeout, k_ra8_ok, k_ra8_usb_speed_hs, ra8_delay_ms(), ra8_time_ms(), ra8_usb_host_bus_reset(), ra8_usb_host_line_state(), ra8_usb_host_set_target(), and ra8_usb_host_set_uact().

Referenced by hid_enumerate().

◆ hid_enum_set_address()

ra8_err_t hid_enum_set_address ( void )
staticnodiscard

SET_ADDRESS to k_hid_dev_addr, then retarget the DCP.

Returns
First failing step's error, or k_ra8_ok.
Return values
k_ra8_okThe DCP now targets the operating address.
Precondition
hid_enum_hunt succeeded (device answering at address 0).
The bus is active (UACT on).
Postcondition
Later transfers carry tokens to k_hid_dev_addr.
The set-address recovery delay has elapsed.
Note
Blocking (one control transfer + settle).
Since
0.1.0

Definition at line 347 of file main.c.

References k_hid_addr_settle_ms, k_hid_bm_std_dev_out, k_hid_breq_set_addr, k_hid_dev_addr, k_ra8_ok, k_ra8_usb_speed_hs, ra8_delay_ms(), ra8_usb_host_control_xfer(), and ra8_usb_host_set_target().

Referenced by hid_enumerate().

◆ hid_enum_set_config()

ra8_err_t hid_enum_set_config ( void )
staticnodiscard

SET_CONFIGURATION(::k_hid_config_value) on the addressed device.

Returns
Control-transfer outcome.
Return values
k_ra8_okThe device entered the Configured state.
Precondition
hid_enum_set_address succeeded.
The DCP targets k_hid_dev_addr.
Postcondition
On success the device's endpoints are usable.
No global state changes.
Note
Blocking (one control transfer).
Since
0.1.0

Definition at line 378 of file main.c.

References k_hid_bm_std_dev_out, k_hid_breq_set_config, k_hid_config_value, k_ra8_usb_speed_hs, and ra8_usb_host_control_xfer().

Referenced by hid_enumerate().

◆ hid_enumerate()

ra8_err_t hid_enumerate ( uint32_t * out_pid)
staticnodiscard

Run the full enumeration ladder and open the bulk pipes.

hunt -> SET_ADDRESS -> SET_CONFIGURATION -> open pipes, and extract idProduct from the device descriptor. Each step prints its own failure tag. The caller deinitializes the host controller on error.

Parameters
[out]out_pidReceives the device's idProduct on success.
Returns
First failing step's error, or k_ra8_ok.
Return values
k_ra8_okDevice enumerated; bulk pipes open.
Precondition
ra8_usb_host_init has succeeded on this pass.
out_pid is non-NULL.
Postcondition
out_pid holds the device idProduct on success.
On failure the offending step printed its tag.
Note
Blocking; runs on the low-priority host thread.
Since
0.1.0

Definition at line 439 of file main.c.

References hid_enum_hunt(), hid_enum_set_address(), hid_enum_set_config(), hid_open_pipes(), hid_print_fail(), k_hid_byte_bits, k_hid_dev_desc_len, k_hid_off_dev_pid, and k_ra8_ok.

Referenced by hid_host_pass().

◆ hid_host_pass()

ra8_err_t hid_host_pass ( void )
staticnodiscard

One full host-side pass: enumerate, then read + check reports.

Phases mirror hid_phase_t. On any failure the host controller is deinitialized so the next retry starts from a clean attach.

Returns
First failing step's error, or k_ra8_ok.
Return values
k_ra8_okThe pass printed HID PASS.
Precondition
Device-side HID class is registered and sending (other thread).
The self-loop cable connects J7 to J11.
Postcondition
On success s_dbg_pass_count advanced and LED2 is on.
On failure the host controller is deinitialized.
Note
Blocking; runs on the low-priority host thread.
Since
0.1.0

Definition at line 605 of file main.c.

References hid_enumerate(), hid_print(), hid_print_enum(), hid_print_fail(), hid_print_pass(), hid_read_round(), k_hid_phase_enum, k_hid_phase_init, k_hid_phase_pass, k_hid_phase_verify, k_hid_rounds, k_ra8_board_led2, k_ra8_ok, k_ra8_usb_speed_hs, ra8_board_led_on(), ra8_usb_host_deinit(), ra8_usb_host_init(), s_dbg_pass_count, s_dbg_phase, s_dbg_pid, and s_dbg_rounds_ok.

Referenced by hid_host_worker().

◆ hid_host_worker()

VOID hid_host_worker ( ULONG arg)
static

Host-side worker: retry the full pass until it succeeds.

Waits for the device side to attach, then loops hid_host_pass with a retry pause until every report round verifies; afterwards parks so the verdict stays on the wire.

Parameters
[in]argThreadX entry argument (unused).
Precondition
tx_application_define created this thread.
The HS host pins, expander switch, and PLL are up (main).
Postcondition
On success the pass counter and LED2 are latched.
Retries forever otherwise; each failure prints its step.
Note
Blocking calls; ms timeouts via ra8_time.
Since
0.1.0

Definition at line 669 of file main.c.

References hid_host_pass(), k_hid_boot_wait_ticks, k_hid_idle_ticks, k_hid_retry_ticks, k_ra8_ok, and tx_thread_sleep.

Referenced by tx_application_define().

◆ hid_keycode_to_ascii()

char hid_keycode_to_ascii ( uint8_t kc)
static

Decode one HID Usage-Table keycode to its ASCII character.

Parameters
[in]kcKeycode byte from a boot-keyboard report (bytes 2..).
Returns
The ASCII letter ('A'..'Z') / digit ('0'..'9'), or '?' if kc is not in the alphanumeric ranges this self-test uses.
Since
0.1.0

Definition at line 194 of file main.c.

References k_hid_kc_0, k_hid_kc_1, k_hid_kc_a, and k_hid_kc_z.

Referenced by hid_read_round().

◆ hid_open_pipes()

ra8_err_t hid_open_pipes ( void )
staticnodiscard

Open the host receive pipe for the device's HID interrupt-IN endpoint.

Pipe k_hid_pipe_in -> device EP1 IN (host receives), 64-byte MPS. The endpoint is interrupt on the device; the host SIE drives it as a receive pipe (issues IN tokens on demand), which is sufficient for the polled report read. HID is input-only, so there is no OUT pipe.

Returns
The pipe-setup error, or k_ra8_ok.
Return values
k_ra8_okThe IN pipe is configured and parked NAK.
Precondition
hid_enum_set_config succeeded.
The pipe is not currently armed.
Postcondition
The pipe targets k_hid_dev_addr EP1 with DATA0 forced.
The pipe's status bits are cleared.
Note
Not thread-safe.
Since
0.1.0

Definition at line 409 of file main.c.

References k_hid_dev_addr, k_hid_ep_in_num, k_hid_mps, k_hid_pipe_in, k_ra8_usb_speed_hs, and ra8_usb_host_pipe_setup().

Referenced by hid_enumerate().

◆ hid_panic_halt()

void hid_panic_halt ( void )
static

Halt forever in WFI – panic stop on init failure.

Last-resort stop; only a debugger or reset recovers.

Precondition
Called only after a fatal boot error.
Interrupts may be in any state.
Postcondition
CPU is parked.
No further code runs.
Note
Not reachable post-boot.
Since
0.1.0

Definition at line 743 of file main.c.

Referenced by hid_route_usb_or_halt(), hid_setup_or_halt(), and main().

◆ hid_print_enum()

ra8_err_t hid_print_enum ( uint32_t pid)
staticnodiscard

Print "enumerated pid=0xNNNN" for the looped device.

Parameters
[in]pidThe device idProduct to report.
Returns
ra8_err_t propagated from the SCI helpers.
Return values
k_ra8_okThe line is queued.
Precondition
hid_enumerate succeeded.
SCI8 init already ran.
Postcondition
One ASCII line is in the SCI8 TX FIFO.
No other state changes.
Note
Blocking polled TX.
Since
0.1.0

Definition at line 482 of file main.c.

References hid_print(), hid_print_hex(), k_hid_hex_chars_u16, and k_ra8_ok.

Referenced by hid_host_pass().

◆ hid_print_pass()

ra8_err_t hid_print_pass ( void )
staticnodiscard

Print the decoded keys + "USB HOST KEYBOARD PASS".

"host decoded keys \"RA8D2\" over N reports -- USB HOST KEYBOARD PASS".

Returns
ra8_err_t propagated from the SCI helpers.
Return values
k_ra8_okThe verdict line is queued.
Precondition
All k_hid_rounds report rounds verified; s_typed is populated.
SCI8 init already ran.
Postcondition
One ASCII verdict line is in the SCI8 TX FIFO.
Note
Blocking polled TX.
Since
0.1.0

Definition at line 510 of file main.c.

References hid_print(), hid_print_dec(), k_hid_rounds, k_ra8_ok, and s_typed.

Referenced by hid_host_pass().

◆ hid_read_round()

ra8_err_t hid_read_round ( uint32_t round)
staticnodiscard

One report round: read an interrupt-IN report, check its body.

Polls one report off the device's interrupt-IN endpoint, checks the read length equals k_hid_report_len, and byte-checks the fixed body (bytes 1..N-1) against hid_fill_report_body. Byte 0 (the seq) is recorded in s_dbg_last_seq as a liveness witness. Each report is well under the endpoint MPS, so it arrives as one short packet.

Parameters
[in]roundThe report round index (0..k_hid_rounds-1).
Returns
ra8_err_t verdict.
Return values
k_ra8_okThe report body matched.
k_ra8_err_invalid_sizeThe report length differed.
k_ra8_err_invalid_stateThe report body bytes differed.
Precondition
The interrupt-IN pipe was opened by hid_open_pipes.
The device send worker is queuing reports.
Postcondition
s_dbg_mismatch records round on any mismatch.
s_dbg_last_seq holds the read report's seq on success.
Note
Blocking; one interrupt-IN read over the self-loop.
Since
0.1.0

Definition at line 552 of file main.c.

References hid_fill_report_body(), hid_keycode_to_ascii(), hid_print_fail(), k_hid_body_idx, k_hid_key0_idx, k_hid_nkeys, k_hid_pipe_in, k_hid_read_buf, k_hid_report_len, k_hid_seq_idx, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_usb_speed_hs, memcmp(), ra8_usb_host_bulk_in(), s_dbg_last_seq, s_dbg_mismatch, and s_typed.

Referenced by hid_host_pass().

◆ hid_route_usb_or_halt()

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

Precondition
IOPORT and the U15 expander are reachable.
Called once from hid_setup_or_halt.
Postcondition
FS pins carry the device role, HS pins the host role.
PD07 is HIGH (J7 powered).
Note
Panic-halts on any routing failure.
Since
0.1.0

Definition at line 766 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().

Referenced by hid_setup_or_halt().

◆ hid_setup_or_halt()

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

Precondition
Reset_Handler finished C runtime init.
SystemInit has run.
Postcondition
Console works; both USB ports' pins and clocks are live.
LED1/LED2 are initialized.
Note
Panic-halts on any failure; called once from main.
Since
0.1.0

Definition at line 805 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().

Referenced by main().

◆ main()

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.

Precondition
Reset_Handler copied .data and zeroed .bss.
SystemInit set VTOR, FPU, 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 849 of file main.c.

References hid_panic_halt(), hid_setup_or_halt(), and ra8_isr_globals_enable().

◆ SysTick_Handler()

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.

Precondition
Entered for a SysTick exception with a valid exception frame.
The selected handler's timebase or scheduler state is initialised.
Postcondition
The selected implementation has processed one SysTick event.
The vector table itself remains unchanged.
Note
Runs in handler mode; thread-safety follows the selected implementation.
Since
0.1.0

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.

Precondition
The handler is entered for one SysTick event or a host-test equivalent.
On target, ra8_time_init() configured the SysTick period.
Postcondition
s_tick_ms has advanced by exactly one.
Optional subsystem hooks run only when linked and ready.
Note
IRQ-safe; the weak symbol may be overridden by an application handler.
Since
0.1.0

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.

Precondition
The handler is entered for one SysTick event or a host-test equivalent.
On target, ra8_time_init() configured the SysTick period.
Postcondition
s_tick_ms has advanced by exactly one.
Optional subsystem hooks run only when linked and ready.
Note
IRQ-safe; the weak symbol may be overridden by an application handler.
Since
0.1.0

Service the SysTick exception selected by the linked application.

Precondition
Called from exception context (IPSR == 15).
_tx_initialize_low_level has programmed SysTick.
Postcondition
One ThreadX tick elapsed; PendSV may be pending.

Definition at line 81 of file main.c.

References _tx_timer_interrupt(), ra8_time_on_tick(), s_tx_kernel_up, and ux_dcd_ra8_usb_irq_reenable().

◆ tx_application_define()

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.

Parameters
[in]first_unused_memorySentinel (unused; static stacks).
Precondition
Called from tx_kernel_enter after scheduler init.
Static stacks are reserved at file scope.
Postcondition
s_usb_host_keyboard_hid_active_sem exists and two auto-start workers are queued.
s_tx_kernel_up is true.
Note
Called once at boot; not thread-safe.
Since
0.1.0

Definition at line 704 of file main.c.

References hid_host_worker(), k_hid_host_priority, k_hid_host_stack, s_host_stack, s_host_thread, s_host_thread_name, s_tx_kernel_up, s_usb_host_keyboard_hid_active_sem, TX_AUTO_START, TX_NO_TIME_SLICE, tx_thread_create, and usb_host_keyboard_device_thread_create().

Variable Documentation

◆ k_hid_pin_fs_dm

const ra8_port_pin_t k_hid_pin_fs_dm = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dm
static

USBFS D- (P8_15).

Definition at line 105 of file main.c.

Referenced by hid_route_usb_or_halt().

◆ k_hid_pin_fs_dp

const ra8_port_pin_t k_hid_pin_fs_dp = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dp
static

USBFS D+ (P8_14).

Definition at line 102 of file main.c.

Referenced by hid_route_usb_or_halt().

◆ k_hid_pin_fs_vbus

const ra8_port_pin_t k_hid_pin_fs_vbus = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbus
static

USBFS VBUS sense pin (P4_07, PSEL = 0x13).

Definition at line 96 of file main.c.

Referenced by hid_route_usb_or_halt().

◆ k_hid_pin_fs_vbusen

const ra8_port_pin_t k_hid_pin_fs_vbusen = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbusen
static

USBFS VBUSEN (P5_00) – GPIO LOW for the device role.

Definition at line 99 of file main.c.

Referenced by hid_route_usb_or_halt().

◆ k_hid_pin_hs_pwr

const ra8_port_pin_t k_hid_pin_hs_pwr = (ra8_port_pin_t)k_ra8_board_usbhs_pin_pwr
static

J7 host-power switch (PD07): HIGH = U18 supplies VBUS (UM 6.2).

Definition at line 111 of file main.c.

Referenced by hid_route_usb_or_halt().

◆ k_hid_pin_hs_vbus

const ra8_port_pin_t k_hid_pin_hs_vbus = (ra8_port_pin_t)k_ra8_board_usbhs_pin_vbus
static

USBHS_VBUS sense pin (P4_08, PSEL = 0x14).

Definition at line 108 of file main.c.

Referenced by hid_route_usb_or_halt().

◆ s_dbg_last_seq

volatile uint32_t s_dbg_last_seq
static

Seq byte of the most recent report the host read back.

Definition at line 180 of file main.c.

Referenced by hid_read_round(), and hid_read_round().

◆ s_dbg_mismatch

volatile uint32_t s_dbg_mismatch = (uint32_t)k_hid_no_mismatch
static

First mismatching report round, or k_hid_no_mismatch.

Definition at line 176 of file main.c.

◆ s_dbg_pass_count

volatile uint32_t s_dbg_pass_count
static

Completed full passes (sticky success counter).

Definition at line 178 of file main.c.

◆ s_dbg_phase

volatile uint32_t s_dbg_phase
static

Host-ladder phase marker (hid_phase_t).

Definition at line 170 of file main.c.

◆ s_dbg_pid

volatile uint32_t s_dbg_pid
static

Device-reported product id captured at enumeration.

Definition at line 174 of file main.c.

◆ s_dbg_rounds_ok

volatile uint32_t s_dbg_rounds_ok
static

Reports the host confirmed pattern-equal (expect k_hid_rounds).

Definition at line 172 of file main.c.

Referenced by cdc_host_pass(), hid_host_pass(), and hid_host_pass().

◆ s_host_stack

UCHAR s_host_stack[k_hid_host_stack]
static

Stack backing storage for s_host_thread.

Since
0.1.0

Definition at line 151 of file main.c.

◆ s_host_thread

TX_THREAD s_host_thread
static

ThreadX TCB for the host-side worker thread.

Note
Single-writer (worker only).
Since
0.1.0

Definition at line 144 of file main.c.

◆ s_tx_kernel_up

volatile bool s_tx_kernel_up = false
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.

Since
0.1.0

Definition at line 78 of file main.c.

◆ s_typed

char s_typed[k_hid_nkeys+1U] = {}
static

ASCII the host decoded from the read keycodes (filled by the verify).

Definition at line 118 of file main.c.

Referenced by hid_print_pass(), and hid_read_round().

◆ s_usb_host_keyboard_hid_active_sem

TX_SEMAPHORE s_usb_host_keyboard_hid_active_sem

Activation semaphore shared by the device worker and main.c.

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).

Posted by the HID activate callback (device sibling) so the send worker blocks on it instead of polling; created by tx_application_define in main.c. Defined once in main.c.

Note
Single-producer (class thread), single-consumer (send worker).
Since
0.1.0

Defined here; the device worker (sibling TU) and this main.c both reference it via the extern in usb_host_keyboard_steps.h.

Note
Single-producer (class thread), single-consumer (send worker).
Since
0.1.0

Definition at line 163 of file main.c.

Referenced by hid_activate(), hid_device_worker(), and tx_application_define().