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

Native USB host-side HID (Human Interface Device) class layer. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_usb.h"
Include dependency graph for ra8_usb_hhid.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_usb_hhid_device_t
 Snapshot of the attached HID device, passed to the attach callback. More...

Typedefs

typedef void(* ra8_usb_hhid_attach_fn_t) (void *ctx, const ra8_usb_hhid_device_t *device)
 Attach-callback signature.

Enumerations

enum  ra8_usb_hhid_pipe_t : uint8_t {
  k_ra8_hhid_pipe_intr_in = 6U ,
  k_ra8_hhid_pipe_intr_out = 7U
}
 PIPE numbers used by the host-HID driver for the attached peripheral's interrupt endpoints. More...
enum  ra8_usb_hhid_packet_t : uint16_t {
  k_ra8_hhid_intr_max_packet_default = 8U ,
  k_ra8_hhid_intr_max_packet_fs = 64U ,
  k_ra8_hhid_intr_max_packet_hs = 1024U
}
 Packet sizing for the attached device's interrupt endpoints. More...
enum  ra8_usb_hhid_class_t : uint8_t {
  k_ra8_hhid_class_hid = 0x03U ,
  k_ra8_hhid_subclass_none = 0x00U ,
  k_ra8_hhid_subclass_boot = 0x01U ,
  k_ra8_hhid_protocol_other = 0x00U ,
  k_ra8_hhid_protocol_keyboard = 0x01U ,
  k_ra8_hhid_protocol_mouse = 0x02U
}
 Class / subclass / protocol triplet that identifies an HID function within an attached USB device's descriptor walk. More...
enum  ra8_usb_hhid_request_t : uint8_t {
  k_ra8_hhid_req_get_report = 0x01U ,
  k_ra8_hhid_req_get_idle = 0x02U ,
  k_ra8_hhid_req_get_protocol = 0x03U ,
  k_ra8_hhid_req_set_report = 0x09U ,
  k_ra8_hhid_req_set_idle = 0x0AU ,
  k_ra8_hhid_req_set_protocol = 0x0BU
}
 HID class-specific request codes the host issues to the attached device. More...
enum  ra8_usb_hhid_report_type_t : uint8_t {
  k_ra8_hhid_report_type_input = 0x01U ,
  k_ra8_hhid_report_type_output = 0x02U ,
  k_ra8_hhid_report_type_feature = 0x03U
}
 HID report-type selector encoded in wValue's high byte for GET_REPORT / SET_REPORT. More...
enum  ra8_usb_hhid_protocol_select_t : uint8_t {
  k_ra8_hhid_proto_boot = 0U ,
  k_ra8_hhid_proto_report = 1U
}
 wValue payload for SET_PROTOCOL. More...
enum  ra8_usb_hhid_desc_t : uint8_t {
  k_ra8_hhid_desc_hid = 0x21U ,
  k_ra8_hhid_desc_report = 0x22U ,
  k_ra8_hhid_desc_physical = 0x23U
}
 HID-specific descriptor types (USB HID 1.11 sec 7.1). More...
enum  ra8_usb_hhid_report_buf_t : uint16_t { k_ra8_hhid_report_desc_max = 256U }
 Compile-time ceiling on the cached HID Report descriptor. More...

Functions

ra8_err_t ra8_usb_hhid_init (ra8_usb_speed_t speed)
 Bring up the host-HID driver on a chosen USB controller.
ra8_err_t ra8_usb_hhid_close (void)
 Tear down the host-HID driver and release the controller.
ra8_err_t ra8_usb_hhid_attach_callback (ra8_usb_hhid_attach_fn_t on_attach, void *ctx)
 Register (or detach) the attach callback.
ra8_err_t ra8_usb_hhid_get_report (ra8_usb_hhid_report_type_t target_report_type, uint8_t target_report_id, uint8_t *out_buf, uint16_t max_len, uint16_t *got_len)
 Issue GET_REPORT (USB HID 1.11 sec 7.2.1) over the DCP.
ra8_err_t ra8_usb_hhid_set_report (ra8_usb_hhid_report_type_t target_report_type, uint8_t target_report_id, const uint8_t *in_buf, uint16_t len)
 Issue SET_REPORT (USB HID 1.11 sec 7.2.2) over the DCP.
ra8_err_t ra8_usb_hhid_set_idle (uint8_t duration, uint8_t report_id)
 Issue SET_IDLE (USB HID 1.11 sec 7.2.4) over the DCP.
ra8_err_t ra8_usb_hhid_set_protocol (ra8_usb_hhid_protocol_select_t boot_or_report)
 Issue SET_PROTOCOL (USB HID 1.11 sec 7.2.6) over the DCP.
ra8_err_t ra8_usb_hhid_get_input_report (uint8_t *out_buf, uint16_t max_len, uint16_t *got_len)
 Drain the next input report from the interrupt-IN pipe.
ra8_err_t ra8_usb_hhid_step (void)
 Drive the enumeration step machine forward by one step.

Detailed Description

Native USB host-side HID (Human Interface Device) class layer.

Glues the host-mode bring-up paths in ra8_usb to a USB HID peripheral - typically a keyboard, mouse, or gamepad - attached on the EK-RA8D2's USB-host port. Mirrors FSP's r_usb_hhid host-HID class flow but compiled as part of this tree with no FSP / CherryUSB / TinyUSB binaries pulled in.

Lifecycle (mirrors ra8_usb_hcdc.h / ra8_usb_hmsc.h shape):

  1. ra8_usb_hhid_init(speed) flips the controller to host mode, primes the internal step machine to idle, and leaves the bus in the "wait for attach" state (UACT cleared).
  2. The driver runs the chapter-9 enumeration step machine (Reset -> SET_ADDRESS -> GET_DEVICE_DESCRIPTOR -> GET_CONFIG_DESCRIPTOR -> SET_CONFIG -> SET_INTERFACE) over the DCP, walks the configuration descriptor for the HID interface (class=0x03), pulls out the interrupt-IN endpoint plus the HID class descriptor (descriptor type 0x21).
  3. When enumeration completes the registered attach callback fires once with the discovered interrupt-IN pipe handle, max-packet, subclass+protocol (1=keyboard / 2=mouse / 0=other), and VID/PID.
  4. HID class control transfers (_get_report, _set_report, _set_idle, _set_protocol) are layered on top of the DCP per USB HID 1.11 sec 7.2.
  5. ra8_usb_hhid_get_input_report polls the interrupt-IN pipe non- blockingly to drain the next input report.
  6. ra8_usb_hhid_close() drops bus power and releases the device.

The starter only tracks a single attached HID device; hubs and multi-interface composite HID devices are deferred follow-ups.

Reference: USB Device Class Definition for Human Interface Devices (HID) revision 1.11 (USB-IF, 2001-06-27).

Definition in file ra8_usb_hhid.h.

Typedef Documentation

◆ ra8_usb_hhid_attach_fn_t

typedef void(* ra8_usb_hhid_attach_fn_t) (void *ctx, const ra8_usb_hhid_device_t *device)

Attach-callback signature.

Parameters
[in]ctxCaller-supplied context registered with ra8_usb_hhid_attach_callback.
[in]deviceSnapshot of the attached HID device. The pointer remains valid only for the duration of the call; copy out anything you need.
Note
Invoked from the dispatch site (typically ISR context) after enumeration completes successfully.

Definition at line 215 of file ra8_usb_hhid.h.

Enumeration Type Documentation

◆ ra8_usb_hhid_class_t

enum ra8_usb_hhid_class_t : uint8_t

Class / subclass / protocol triplet that identifies an HID function within an attached USB device's descriptor walk.

Numbered from the USB-IF "Class Codes" registry and USB HID 1.11 sec 4.2 "Subclass". Subclass 1 = "Boot Interface Subclass", protocol 1 = keyboard, protocol 2 = mouse.

Enumerator
k_ra8_hhid_class_hid 

HID interface class.

k_ra8_hhid_subclass_none 

No subclass.

k_ra8_hhid_subclass_boot 

Boot Interface Subclass.

k_ra8_hhid_protocol_other 

Non keyboard / mouse.

k_ra8_hhid_protocol_keyboard 

Boot keyboard.

k_ra8_hhid_protocol_mouse 

Boot mouse.

Definition at line 99 of file ra8_usb_hhid.h.

◆ ra8_usb_hhid_desc_t

enum ra8_usb_hhid_desc_t : uint8_t

HID-specific descriptor types (USB HID 1.11 sec 7.1).

Enumerator
k_ra8_hhid_desc_hid 

HID class descriptor.

k_ra8_hhid_desc_report 

HID Report descriptor.

k_ra8_hhid_desc_physical 

HID Physical descriptor.

Definition at line 154 of file ra8_usb_hhid.h.

◆ ra8_usb_hhid_packet_t

enum ra8_usb_hhid_packet_t : uint16_t

Packet sizing for the attached device's interrupt endpoints.

Per USB HID 1.11 sec 8.2 "Maximum Packet Size", a low- / full-speed HID interrupt endpoint is at most 64 bytes, and a high- speed one is at most 1024 bytes. Most keyboards / mice land at 8.

Enumerator
k_ra8_hhid_intr_max_packet_default 

Boot-protocol default.

k_ra8_hhid_intr_max_packet_fs 

FS ceiling.

k_ra8_hhid_intr_max_packet_hs 

HS ceiling.

Definition at line 84 of file ra8_usb_hhid.h.

◆ ra8_usb_hhid_pipe_t

enum ra8_usb_hhid_pipe_t : uint8_t

PIPE numbers used by the host-HID driver for the attached peripheral's interrupt endpoints.

FSP / RA8D2 PIPE assignment rules constrain interrupt pipes to PIPE6..PIPE9. The host-HID class only uses two pipes: an interrupt-IN pipe to drain input reports, and an optional interrupt-OUT pipe (used by some keyboards for LED state). See USB HID 1.11 sec 4.4 "Interrupt Pipes".

Enumerator
k_ra8_hhid_pipe_intr_in 

PIPE6 -> attached EP intr IN.

k_ra8_hhid_pipe_intr_out 

PIPE7 -> attached EP intr OUT.

Definition at line 71 of file ra8_usb_hhid.h.

◆ ra8_usb_hhid_protocol_select_t

wValue payload for SET_PROTOCOL.

Per USB HID 1.11 sec 7.2.6 "Set_Protocol Request". 0 = boot protocol, 1 = report protocol.

Enumerator
k_ra8_hhid_proto_boot 

Boot protocol.

k_ra8_hhid_proto_report 

Report protocol.

Definition at line 145 of file ra8_usb_hhid.h.

◆ ra8_usb_hhid_report_buf_t

enum ra8_usb_hhid_report_buf_t : uint16_t

Compile-time ceiling on the cached HID Report descriptor.

The HID spec puts an absolute ceiling at 65535 bytes (wDescriptorLength is 16-bit), but real-world HID descriptors are essentially always under 256 bytes. We pick a small-but-generous ceiling here so the starter doesn't carry a kilobyte of zeroes around.

Enumerator
k_ra8_hhid_report_desc_max 

Cached Report desc max len.

Definition at line 170 of file ra8_usb_hhid.h.

◆ ra8_usb_hhid_report_type_t

HID report-type selector encoded in wValue's high byte for GET_REPORT / SET_REPORT.

Per USB HID 1.11 sec 7.2.1 "Get_Report Request".

Enumerator
k_ra8_hhid_report_type_input 

Input report.

k_ra8_hhid_report_type_output 

Output report.

k_ra8_hhid_report_type_feature 

Feature report.

Definition at line 132 of file ra8_usb_hhid.h.

◆ ra8_usb_hhid_request_t

enum ra8_usb_hhid_request_t : uint8_t

HID class-specific request codes the host issues to the attached device.

Per USB HID 1.11 sec 7.2 "Class-Specific Requests". Values match the standard HID class request register.

Enumerator
k_ra8_hhid_req_get_report 

GET_REPORT.

k_ra8_hhid_req_get_idle 

GET_IDLE.

k_ra8_hhid_req_get_protocol 

GET_PROTOCOL.

k_ra8_hhid_req_set_report 

SET_REPORT.

k_ra8_hhid_req_set_idle 

SET_IDLE.

k_ra8_hhid_req_set_protocol 

SET_PROTOCOL.

Definition at line 116 of file ra8_usb_hhid.h.

Function Documentation

◆ ra8_usb_hhid_attach_callback()

ra8_err_t ra8_usb_hhid_attach_callback ( ra8_usb_hhid_attach_fn_t on_attach,
void * ctx )
nodiscard

Register (or detach) the attach callback.

The supplied callback fires exactly once per attach event, after the descriptor walk identifies an HID interface (class=0x03) and the matching interrupt-IN endpoint and HID class descriptor are cached. Pass NULL to detach.

Parameters
[in]on_attachCallback. NULL detaches.
[in]ctxContext pointer threaded back into on_attach.
Returns
ra8_err_t error code.
Return values
k_ra8_okCallback installed.
k_ra8_err_invalid_stateDriver was never initialized.
Precondition
ra8_usb_hhid_init has run.
Postcondition
On a subsequent attach, on_attach(ctx, &device) fires once.
Note
Not thread-safe.
Since
0.1.0

Definition at line 700 of file ra8_usb_hhid.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.

◆ ra8_usb_hhid_close()

ra8_err_t ra8_usb_hhid_close ( void )
nodiscard

Tear down the host-HID driver and release the controller.

Returns
ra8_err_t error code.
Return values
k_ra8_okReleased.
k_ra8_err_invalid_stateDriver was never initialized.
Precondition
Single-threaded shutdown context.
Postcondition
ra8_usb_host_deinit ran; SOF generation halted; bus power dropped; subsequent host-HID API calls return k_ra8_err_invalid_state.
Note
Not thread-safe.
Since
0.1.0

Definition at line 679 of file ra8_usb_hhid.c.

References k_ra8_err_invalid_state, k_ra8_hhid_step_idle, ra8_usb_host_deinit(), ra8_usb_host_set_uact(), and s_state.

◆ ra8_usb_hhid_get_input_report()

ra8_err_t ra8_usb_hhid_get_input_report ( uint8_t * out_buf,
uint16_t max_len,
uint16_t * got_len )
nodiscard

Drain the next input report from the interrupt-IN pipe.

Polling / non-blocking. Pulls bytes from the configured PIPE6 (interrupt IN) into out_buf. Returns k_ra8_err_no_data if the pipe has no bytes ready.

Parameters
[out]out_bufDestination buffer.
[in]max_lenCapacity of out_buf, > 0.
[out]got_lenReceives the number of bytes actually placed.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes drained; *got_len reflects the count.
k_ra8_err_no_dataPipe was empty.
k_ra8_err_null_ptrout_buf or got_len was NULL.
k_ra8_err_invalid_stateDriver not initialized, or no device attached.
k_ra8_err_invalid_argmax_len == 0.
Precondition
ra8_usb_hhid_init succeeded.
Attach callback already fired.
Postcondition
On success *got_len reflects the actual byte count.
Note
Not thread-safe.
Since
0.1.0

Definition at line 961 of file ra8_usb_hhid.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_hhid_pipe_intr_in, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_usb_queue_out(), s_state, and s_tag.

◆ ra8_usb_hhid_get_report()

ra8_err_t ra8_usb_hhid_get_report ( ra8_usb_hhid_report_type_t target_report_type,
uint8_t target_report_id,
uint8_t * out_buf,
uint16_t max_len,
uint16_t * got_len )
nodiscard

Issue GET_REPORT (USB HID 1.11 sec 7.2.1) over the DCP.

Builds an 8-byte SETUP packet with bmRequestType = 0xA1 (Class | Interface | Device-to-Host), bRequest = 0x01 (GET_REPORT), and wValue = (report_type << 8) | report_id. Hands it to ra8_usb_host_setup_request; the controller drives the data + status stages.

Parameters
[in]target_report_typeInput / Output / Feature.
[in]target_report_idReport ID (0 if the device uses a single unnamed report).
[out]out_bufDestination buffer for the report payload.
[in]max_lenCapacity of out_buf, > 0.
[out]got_lenReceives the number of bytes actually received.
Returns
ra8_err_t error code.
Return values
k_ra8_okControl transfer queued; on completion *got_len reflects the count.
k_ra8_err_null_ptrout_buf or got_len was NULL.
k_ra8_err_invalid_stateDriver not initialized, or no device attached.
k_ra8_err_invalid_argBogus target_report_type or max_len == 0.
k_ra8_err_busyController busy with a prior SETUP.
Precondition
ra8_usb_hhid_init succeeded.
Attach callback already fired.
Postcondition
On success the SETUP mirror registers hold the GET_REPORT request envelope.
Note
Not thread-safe.
Since
0.1.0

Definition at line 820 of file ra8_usb_hhid.c.

References internal_dcp_in_drain(), internal_pick_regs(), internal_report_type_ok(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_hhid_bm_class_iface_in, k_ra8_hhid_req_get_report, k_ra8_hhid_shift_byte1, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_usb_host_setup_request(), s_state, and s_tag.

◆ ra8_usb_hhid_init()

ra8_err_t ra8_usb_hhid_init ( ra8_usb_speed_t speed)
nodiscard

Bring up the host-HID driver on a chosen USB controller.

Initialises the underlying ra8_usb driver in HOST mode for speed, leaves the bus in the "wait for attach" state (UACT cleared), and arms the internal enumeration step machine.

Parameters
[in]speedWhich USB controller (FS or HS).
Returns
ra8_err_t error code.
Return values
k_ra8_okHost-HID ready, awaiting attach.
k_ra8_err_invalid_argspeed out of range.
k_ra8_err_hw_init_failedUnderlying ra8_usb_host_init failed.
Precondition
Single-threaded init context.
ra8_mstp_init and ra8_pwr_init already ran.
Postcondition
ra8_usb_host_init succeeded for speed.
Internal step machine armed; attach callback has not fired.
Note
Not thread-safe.
See also
ra8_usb_hhid_attach_callback
ra8_usb_hhid_close
Since
0.1.0

Definition at line 656 of file ra8_usb_hhid.c.

References k_ra8_err_hw_init_failed, k_ra8_err_invalid_arg, k_ra8_hhid_step_idle, k_ra8_ok, k_ra8_usb_speed_fs, k_ra8_usb_speed_hs, ra8_log_error_val, ra8_log_info_val, ra8_usb_host_init(), s_state, and s_tag.

◆ ra8_usb_hhid_set_idle()

ra8_err_t ra8_usb_hhid_set_idle ( uint8_t duration,
uint8_t report_id )
nodiscard

Issue SET_IDLE (USB HID 1.11 sec 7.2.4) over the DCP.

Tells the device how often to silently re-send an unchanged input report. duration is in 4 ms units (0 = "only report on change"). Builds bmRequestType = 0x21, bRequest = 0x0A, wValue = (duration << 8) | report_id.

Parameters
[in]durationIdle rate, in 4 ms ticks (0..255).
[in]report_idReport ID, or 0 for "all reports".
Returns
ra8_err_t error code.
Return values
k_ra8_okControl transfer queued.
k_ra8_err_invalid_stateDriver not initialized, or no device attached.
k_ra8_err_busyController busy with a prior SETUP.
Precondition
ra8_usb_hhid_init succeeded.
Attach callback already fired.
Postcondition
On success the SETUP mirror registers hold the SET_IDLE request envelope.
Note
Not thread-safe.
Since
0.1.0

Definition at line 910 of file ra8_usb_hhid.c.

References k_ra8_err_invalid_state, k_ra8_hhid_bm_class_iface_out, k_ra8_hhid_req_set_idle, k_ra8_hhid_shift_byte1, ra8_usb_host_setup_request(), and s_state.

◆ ra8_usb_hhid_set_protocol()

ra8_err_t ra8_usb_hhid_set_protocol ( ra8_usb_hhid_protocol_select_t boot_or_report)
nodiscard

Issue SET_PROTOCOL (USB HID 1.11 sec 7.2.6) over the DCP.

Switches the device between boot protocol (wValue = 0) and report protocol (wValue = 1). Builds bmRequestType = 0x21, bRequest = 0x0B.

Parameters
[in]boot_or_reportBoot or report protocol selector.
Returns
ra8_err_t error code.
Return values
k_ra8_okControl transfer queued.
k_ra8_err_invalid_stateDriver not initialized, or no device attached.
k_ra8_err_invalid_argboot_or_report out of range.
k_ra8_err_busyController busy with a prior SETUP.
Precondition
ra8_usb_hhid_init succeeded.
Attach callback already fired.
Postcondition
On success the SETUP mirror registers hold the SET_PROTOCOL request envelope.
Note
Not thread-safe.
Since
0.1.0

Definition at line 935 of file ra8_usb_hhid.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_hhid_bm_class_iface_out, k_ra8_hhid_proto_boot, k_ra8_hhid_proto_report, k_ra8_hhid_req_set_protocol, ra8_usb_host_setup_request(), and s_state.

◆ ra8_usb_hhid_set_report()

ra8_err_t ra8_usb_hhid_set_report ( ra8_usb_hhid_report_type_t target_report_type,
uint8_t target_report_id,
const uint8_t * in_buf,
uint16_t len )
nodiscard

Issue SET_REPORT (USB HID 1.11 sec 7.2.2) over the DCP.

Builds an 8-byte SETUP packet with bmRequestType = 0x21 (Class | Interface | Host-to-Device), bRequest = 0x09 (SET_REPORT), and wValue = (report_type << 8) | report_id. The data stage payload is in_buf[0..len-1].

Parameters
[in]target_report_typeInput / Output / Feature.
[in]target_report_idReport ID.
[in]in_bufReport payload.
[in]lenPayload length.
Returns
ra8_err_t error code.
Return values
k_ra8_okControl transfer queued.
k_ra8_err_null_ptrin_buf was NULL with non-zero len.
k_ra8_err_invalid_stateDriver not initialized, or no device attached.
k_ra8_err_invalid_argBogus target_report_type.
k_ra8_err_busyController busy with a prior SETUP.
Precondition
ra8_usb_hhid_init succeeded.
Attach callback already fired.
Postcondition
On success the SETUP mirror registers hold the SET_REPORT request envelope.
Note
Not thread-safe.
Since
0.1.0

Definition at line 870 of file ra8_usb_hhid.c.

References internal_report_type_ok(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_hhid_bm_class_iface_out, k_ra8_hhid_req_set_report, k_ra8_hhid_shift_byte1, ra8_usb_host_setup_request(), and s_state.

◆ ra8_usb_hhid_step()

ra8_err_t ra8_usb_hhid_step ( void )
nodiscard

Drive the enumeration step machine forward by one step.

Test / debug entry point. The production path drives this from the ra8_usb_dispatch callback when the controller fires a CTRT or BRDY interrupt; tests call it directly to walk the state machine deterministically.

Returns
ra8_err_t error code.
Return values
k_ra8_okStep advanced.
k_ra8_err_invalid_stateDriver not initialized.
Precondition
ra8_usb_hhid_init succeeded.
Postcondition
Internal enumeration step counter advances by one. When the step machine reaches the terminal state the registered attach callback fires.
Note
Not thread-safe.
Since
0.1.0

Definition at line 990 of file ra8_usb_hhid.c.

References internal_step_advance(), k_ra8_err_invalid_state, and s_state.