|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
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"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. | |
USB host-mode HID boot-keyboard over the self-loop (no real keyboard).
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:
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.
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_enum_tune_t : uint32_t |
Timing / retry tunables for the polled enumeration ladder.
| enum hid_phase_t : uint32_t |
| enum hid_usb_req_t : uint16_t |
Standard chapter-9 request / descriptor constants for the host.
|
extern |
|
staticnodiscard |
GET_DESCRIPTOR(DEVICE) over the polled control engine.
| [out] | desc | Receives the 18-byte device descriptor. |
| k_ra8_ok | All 18 bytes arrived. |
| k_ra8_err_hw_error | A short descriptor came back. |
desc holds at least k_hid_dev_desc_len bytes. desc carries the device descriptor on success. 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().
|
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.
| [out] | desc | Receives the winning 18-byte device descriptor. |
| k_ra8_ok | The device answered at address 0. |
| k_ra8_err_hw_timeout | Nothing attached / nothing answered. |
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().
|
staticnodiscard |
SET_ADDRESS to k_hid_dev_addr, then retarget the DCP.
| k_ra8_ok | The DCP now targets the operating address. |
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().
|
staticnodiscard |
SET_CONFIGURATION(::k_hid_config_value) on the addressed device.
| k_ra8_ok | The device entered the Configured state. |
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().
|
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.
| [out] | out_pid | Receives the device's idProduct on success. |
| k_ra8_ok | Device enumerated; bulk pipes open. |
out_pid is non-NULL. out_pid holds the device idProduct on success. 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().
|
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.
| k_ra8_ok | The pass printed HID PASS. |
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().
|
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.
| [in] | arg | ThreadX entry argument (unused). |
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().
|
static |
Decode one HID Usage-Table keycode to its ASCII character.
| [in] | kc | Keycode byte from a boot-keyboard report (bytes 2..). |
kc is not in the alphanumeric ranges this self-test uses. 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().
|
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.
| k_ra8_ok | The IN pipe is configured and parked NAK. |
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().
|
static |
Halt forever in WFI – panic stop on init failure.
Last-resort stop; only a debugger or reset recovers.
Definition at line 743 of file main.c.
Referenced by hid_route_usb_or_halt(), hid_setup_or_halt(), and main().
|
staticnodiscard |
Print "enumerated pid=0xNNNN" for the looped device.
| [in] | pid | The device idProduct to report. |
| k_ra8_ok | The line is queued. |
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().
|
staticnodiscard |
Print the decoded keys + "USB HOST KEYBOARD PASS".
"host decoded keys \"RA8D2\" over N reports -- USB HOST KEYBOARD PASS".
| k_ra8_ok | The verdict line is queued. |
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().
|
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.
| [in] | round | The report round index (0..k_hid_rounds-1). |
| k_ra8_ok | The report body matched. |
| k_ra8_err_invalid_size | The report length differed. |
| k_ra8_err_invalid_state | The report body bytes differed. |
round on any mismatch. 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().
|
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 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().
|
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 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().
| 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 849 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 81 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 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().
|
static |
|
static |
|
static |
USBFS VBUS sense pin (P4_07, PSEL = 0x13).
Definition at line 96 of file main.c.
Referenced by hid_route_usb_or_halt().
|
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().
|
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().
|
static |
USBHS_VBUS sense pin (P4_08, PSEL = 0x14).
Definition at line 108 of file main.c.
Referenced by hid_route_usb_or_halt().
|
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().
|
static |
First mismatching report round, or k_hid_no_mismatch.
|
static |
|
static |
Host-ladder phase marker (hid_phase_t).
|
static |
|
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().
|
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 |
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().
| 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.
Defined here; the device worker (sibling TU) and this main.c both reference it via the extern in usb_host_keyboard_steps.h.
Definition at line 163 of file main.c.
Referenced by hid_activate(), hid_device_worker(), and tx_application_define().