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

USB HID self-loop host side: polled enumerate + interrupt-IN read. More...

#include <stdint.h>
#include <string.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_err.h"
#include "ra8_time.h"
#include "ra8_usb.h"
#include "usb_selftest_hid_steps.h"
#include "tx_api.h"
Include dependency graph for usb_selftest_hid_host.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

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 "N reports verified -- USB SELFTEST HID 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.
VOID hid_host_worker (ULONG arg)
 Host-side worker: retry the full pass until it succeeds.

Variables

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 HID self-loop host side: polled enumerate + interrupt-IN read.

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

The host-side cluster split out of the usb_selftest_hid main translation unit. A self-contained polled USB host built on the first-party ra8_usb_host_* primitives: it waits for the looped FS device to attach, drives the chapter-9 enumeration ladder (bus reset -> GET_DESCRIPTOR -> SET_ADDRESS -> SET_CONFIGURATION), opens the HID interrupt-IN endpoint (EP1 IN) as a receive pipe, then polls several reports, byte-checking the fixed pattern in each. hid_host_worker retries the full pass until every report round verifies.

The host worker entry is declared in usb_selftest_hid_steps.h; the device side, the ThreadX workers' creation, and startup live in main.c.

Author
Brighton Sikarskie
Date
2026-06-13
Since
0.1.0

Definition in file usb_selftest_hid_host.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 95 of file usb_selftest_hid_host.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 45 of file usb_selftest_hid_host.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 78 of file usb_selftest_hid_host.c.

Function Documentation

◆ 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 123 of file usb_selftest_hid_host.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 166 of file usb_selftest_hid_host.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 209 of file usb_selftest_hid_host.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 240 of file usb_selftest_hid_host.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 301 of file usb_selftest_hid_host.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 455 of file usb_selftest_hid_host.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)

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

Waits for the device side to attach, then loops the full 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 502 of file usb_selftest_hid_host.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.

◆ 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 271 of file usb_selftest_hid_host.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_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 344 of file usb_selftest_hid_host.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 "N reports verified -- USB SELFTEST HID 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.
SCI8 init already ran.
Postcondition
One ASCII verdict line is in the SCI8 TX FIFO.
No other state changes.
Note
Blocking polled TX.
Since
0.1.0

Definition at line 371 of file usb_selftest_hid_host.c.

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

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 408 of file usb_selftest_hid_host.c.

References hid_fill_report_body(), hid_print_fail(), k_hid_body_idx, 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, and s_dbg_mismatch.

Referenced by hid_host_pass().

Variable Documentation

◆ 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 68 of file usb_selftest_hid_host.c.

◆ 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 64 of file usb_selftest_hid_host.c.

◆ s_dbg_pass_count

volatile uint32_t s_dbg_pass_count
static

Completed full passes (sticky success counter).

Definition at line 66 of file usb_selftest_hid_host.c.

◆ s_dbg_phase

volatile uint32_t s_dbg_phase
static

Host-ladder phase marker (hid_phase_t).

Definition at line 58 of file usb_selftest_hid_host.c.

◆ s_dbg_pid

volatile uint32_t s_dbg_pid
static

Device-reported product id captured at enumeration.

Definition at line 62 of file usb_selftest_hid_host.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 60 of file usb_selftest_hid_host.c.