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

Native USB device-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_phid.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef ra8_err_t(* ra8_usb_phid_setup_fn_t) (void *ctx, const ra8_usb_setup_t *setup)
 Caller-supplied HID class-setup handler signature.

Enumerations

enum  ra8_usb_phid_pipe_t : uint8_t {
  k_ra8_phid_pipe_intr_in = 6U ,
  k_ra8_phid_pipe_intr_out = 7U
}
 PIPE numbers used by the device-HID function for the local interrupt endpoints. More...
enum  ra8_usb_phid_ep_t : uint8_t {
  k_ra8_phid_ep_intr_in_addr = 1U ,
  k_ra8_phid_ep_intr_out_addr = 2U
}
 USB endpoint addresses used by the device-HID function. More...
enum  ra8_usb_phid_packet_t : uint16_t {
  k_ra8_phid_intr_max_packet_default = 8U ,
  k_ra8_phid_intr_max_packet_fs = 64U ,
  k_ra8_phid_intr_max_packet_hs = 1024U
}
 Packet sizing for the device-HID interrupt endpoints. More...
enum  ra8_usb_phid_class_t : uint8_t {
  k_ra8_phid_class_hid = 0x03U ,
  k_ra8_phid_subclass_none = 0x00U ,
  k_ra8_phid_subclass_boot = 0x01U ,
  k_ra8_phid_protocol_other = 0x00U ,
  k_ra8_phid_protocol_keyboard = 0x01U ,
  k_ra8_phid_protocol_mouse = 0x02U
}
 Class / subclass / protocol triplet that identifies the local HID function in the configuration descriptor. More...
enum  ra8_usb_phid_request_t : uint8_t {
  k_ra8_phid_req_get_report = 0x01U ,
  k_ra8_phid_req_get_idle = 0x02U ,
  k_ra8_phid_req_get_protocol = 0x03U ,
  k_ra8_phid_req_set_report = 0x09U ,
  k_ra8_phid_req_set_idle = 0x0AU ,
  k_ra8_phid_req_set_protocol = 0x0BU
}
 HID class-specific request codes the host issues to the device. More...
enum  ra8_usb_phid_report_type_t : uint8_t {
  k_ra8_phid_report_type_input = 0x01U ,
  k_ra8_phid_report_type_output = 0x02U ,
  k_ra8_phid_report_type_feature = 0x03U
}
 HID report-type selector encoded in wValue's high byte for GET_REPORT / SET_REPORT. More...
enum  ra8_usb_phid_protocol_select_t : uint8_t {
  k_ra8_phid_proto_boot = 0U ,
  k_ra8_phid_proto_report = 1U
}
 wValue payload for SET_PROTOCOL. More...
enum  ra8_usb_phid_desc_t : uint8_t {
  k_ra8_phid_desc_hid = 0x21U ,
  k_ra8_phid_desc_report = 0x22U ,
  k_ra8_phid_desc_physical = 0x23U
}
 HID-specific descriptor types (USB HID 1.11 sec 7.1). More...

Functions

ra8_err_t ra8_usb_phid_init (ra8_usb_speed_t speed)
 Bring up the device-HID function on a chosen USB controller.
ra8_err_t ra8_usb_phid_close (void)
 Tear down the device-HID function and release the controller.
ra8_err_t ra8_usb_phid_set_descriptors (const uint8_t *report_desc, uint16_t report_desc_len, const uint8_t *hid_desc, uint16_t hid_desc_len)
 Install the caller-supplied HID Report descriptor and HID class descriptor.
ra8_err_t ra8_usb_phid_send_report (uint8_t report_id, const uint8_t *payload, uint16_t len)
 Push a HID input report on the interrupt-IN endpoint.
ra8_err_t ra8_usb_phid_recv_report (uint8_t report_id, uint8_t *buf, uint16_t max_len, uint16_t *got_len)
 Drain a HID output report from the interrupt-OUT endpoint.
ra8_err_t ra8_usb_phid_attach_setup_handler (ra8_usb_phid_setup_fn_t setup_fn, void *ctx)
 Register the application's HID class-setup handler.
ra8_err_t ra8_usb_phid_handle_setup (const ra8_usb_setup_t *setup)
 Process a class-specific SETUP packet on EP0.
ra8_err_t ra8_usb_phid_get_idle (uint8_t *out_idle_rate)
 Read the most-recently negotiated idle rate.
ra8_err_t ra8_usb_phid_get_protocol (ra8_usb_phid_protocol_select_t *out_protocol)
 Read the most-recently negotiated protocol.

Detailed Description

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

Glues the device-mode ra8_usb controller driver to a USB HID function so the host enumerates the EK-RA8D2 board as a keyboard, mouse, gamepad, or vendor-defined HID gadget. The implementation is from-scratch – no FSP r_usb_phid_driver.c, no CherryUSB usbd_hid.c, no TinyUSB binaries pulled in. It mirrors the surface that FSP's peripheral-HID class exposes:

  • Caller-supplied HID Report Descriptor + HID class descriptor.
  • Interrupt-IN endpoint to push input reports.
  • Interrupt-OUT endpoint (optional) to pull output reports, plus SET_REPORT-on-EP0 fallback.
  • Idle-rate / protocol shadow updated by SET_IDLE / SET_PROTOCOL.
  • Caller-supplied class-setup callback so the application chooses how to answer GET_REPORT / SET_REPORT / GET_IDLE / SET_IDLE / GET_PROTOCOL / SET_PROTOCOL (a mouse driver answers GET_REPORT with the current cursor delta; a keyboard answers with the current scancode set; a generic HID gadget defers to its application logic).

The descriptor table the application installs typically advertises:

  • One configuration with one interface, class = 0x03 (HID).
  • EP0 64-byte default control pipe (provided by ra8_usb).
  • EP1 IN, interrupt, 8..64 bytes (HID input reports).
  • EP2 OUT, interrupt, 8..64 bytes (HID output reports, optional).

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

Definition in file ra8_usb_phid.h.

Typedef Documentation

◆ ra8_usb_phid_setup_fn_t

typedef ra8_err_t(* ra8_usb_phid_setup_fn_t) (void *ctx, const ra8_usb_setup_t *setup)

Caller-supplied HID class-setup handler signature.

The application registers one of these via ra8_usb_phid_attach_setup_handler. The class layer pre-decodes the SETUP envelope (validating it really is a HID class request on the HID interface) and hands the raw SETUP packet plus a pointer to the shadow idle_rate / protocol to the application. The application may modify idle_rate / protocol and / or queue a data-stage payload by calling ra8_usb_queue_in directly.

Parameters
[in]ctxCaller-supplied context registered alongside the handler.
[in]setupThe 8-byte SETUP envelope (class request).
Returns
ra8_err_t error code; k_ra8_ok lets the class layer ACK the status stage, anything else stalls EP0.
Note
Invoked from the dispatch site (typically ISR context) when a HID class SETUP lands.

Definition at line 188 of file ra8_usb_phid.h.

Enumeration Type Documentation

◆ ra8_usb_phid_class_t

enum ra8_usb_phid_class_t : uint8_t

Class / subclass / protocol triplet that identifies the local HID function in the configuration descriptor.

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_phid_class_hid 

HID interface class.

k_ra8_phid_subclass_none 

No subclass.

k_ra8_phid_subclass_boot 

Boot Interface Subclass.

k_ra8_phid_protocol_other 

Non keyboard / mouse.

k_ra8_phid_protocol_keyboard 

Boot keyboard.

k_ra8_phid_protocol_mouse 

Boot mouse.

Definition at line 104 of file ra8_usb_phid.h.

◆ ra8_usb_phid_desc_t

enum ra8_usb_phid_desc_t : uint8_t

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

Enumerator
k_ra8_phid_desc_hid 

HID class descriptor.

k_ra8_phid_desc_report 

HID Report descriptor.

k_ra8_phid_desc_physical 

HID Physical descriptor.

Definition at line 160 of file ra8_usb_phid.h.

◆ ra8_usb_phid_ep_t

enum ra8_usb_phid_ep_t : uint8_t

USB endpoint addresses used by the device-HID function.

Enumerator
k_ra8_phid_ep_intr_in_addr 

EP1 IN address.

k_ra8_phid_ep_intr_out_addr 

EP2 OUT address.

Definition at line 75 of file ra8_usb_phid.h.

◆ ra8_usb_phid_packet_t

enum ra8_usb_phid_packet_t : uint16_t

Packet sizing for the device-HID 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. Boot-protocol keyboard / mouse devices use 8.

Enumerator
k_ra8_phid_intr_max_packet_default 

Boot-protocol default.

k_ra8_phid_intr_max_packet_fs 

FS ceiling.

k_ra8_phid_intr_max_packet_hs 

HS ceiling.

Definition at line 89 of file ra8_usb_phid.h.

◆ ra8_usb_phid_pipe_t

enum ra8_usb_phid_pipe_t : uint8_t

PIPE numbers used by the device-HID function for the local interrupt endpoints.

FSP / RA8D2 PIPE assignment rules constrain interrupt pipes to PIPE6..PIPE9. Device-side HID uses PIPE6 for input reports (interrupt IN) and PIPE7 for output reports (interrupt OUT). See USB HID 1.11 sec 4.4 "Interrupt Pipes".

Enumerator
k_ra8_phid_pipe_intr_in 

PIPE6 -> EP1 IN (intr).

k_ra8_phid_pipe_intr_out 

PIPE7 -> EP2 OUT (intr).

Definition at line 66 of file ra8_usb_phid.h.

◆ ra8_usb_phid_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_phid_proto_boot 

Boot protocol.

k_ra8_phid_proto_report 

Report protocol.

Definition at line 151 of file ra8_usb_phid.h.

◆ ra8_usb_phid_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_phid_report_type_input 

Input report.

k_ra8_phid_report_type_output 

Output report.

k_ra8_phid_report_type_feature 

Feature report.

Definition at line 138 of file ra8_usb_phid.h.

◆ ra8_usb_phid_request_t

enum ra8_usb_phid_request_t : uint8_t

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

Per USB HID 1.11 sec 7.2 "Class-Specific Requests". Numeric values match the standard HID class request register so a static assertion in the test suite can pin them to the spec.

Enumerator
k_ra8_phid_req_get_report 

GET_REPORT.

k_ra8_phid_req_get_idle 

GET_IDLE.

k_ra8_phid_req_get_protocol 

GET_PROTOCOL.

k_ra8_phid_req_set_report 

SET_REPORT.

k_ra8_phid_req_set_idle 

SET_IDLE.

k_ra8_phid_req_set_protocol 

SET_PROTOCOL.

Definition at line 122 of file ra8_usb_phid.h.

Function Documentation

◆ ra8_usb_phid_attach_setup_handler()

ra8_err_t ra8_usb_phid_attach_setup_handler ( ra8_usb_phid_setup_fn_t setup_fn,
void * ctx )
nodiscard

Register the application's HID class-setup handler.

The class layer drains the SETUP envelope from the controller, then forwards it to the registered handler if its bmRequestType indicates a class-recipient-interface request and its bRequest is one of GET_REPORT / SET_REPORT / GET_IDLE / SET_IDLE / GET_PROTOCOL / SET_PROTOCOL. Pass NULL for setup_fn to detach.

Parameters
[in]setup_fnApplication's handler. NULL detaches.
[in]ctxContext pointer threaded back into setup_fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okHandler installed.
k_ra8_err_invalid_stateDriver not initialized.
Precondition
ra8_usb_phid_init succeeded.
Postcondition
On the next class SETUP, setup_fn(ctx, &setup) fires.
Note
Not thread-safe.
Since
0.1.0

Definition at line 403 of file ra8_usb_phid.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.

◆ ra8_usb_phid_close()

ra8_err_t ra8_usb_phid_close ( void )
nodiscard

Tear down the device-HID function 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_device_deinit ran; D+ pull-up dropped; subsequent device-HID API calls return k_ra8_err_invalid_state.
Note
Not thread-safe.
Since
0.1.0

Definition at line 294 of file ra8_usb_phid.c.

References k_ra8_err_invalid_state, ra8_usb_device_attach(), ra8_usb_device_deinit(), and s_state.

◆ ra8_usb_phid_get_idle()

ra8_err_t ra8_usb_phid_get_idle ( uint8_t * out_idle_rate)
nodiscard

Read the most-recently negotiated idle rate.

Parameters
[out]out_idle_rateReceives the 4 ms-tick idle rate (0 = "report only on change").
Returns
ra8_err_t error code.
Return values
k_ra8_okValue copied.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrout_idle_rate was NULL.
Precondition
out_idle_rate non-NULL.
Postcondition
No internal state mutated.
Note
Not thread-safe.
Since
0.1.0

Definition at line 449 of file ra8_usb_phid.c.

References k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.

◆ ra8_usb_phid_get_protocol()

ra8_err_t ra8_usb_phid_get_protocol ( ra8_usb_phid_protocol_select_t * out_protocol)
nodiscard

Read the most-recently negotiated protocol.

Parameters
[out]out_protocolReceives the protocol selector.
Returns
ra8_err_t error code.
Return values
k_ra8_okValue copied.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrout_protocol was NULL.
Precondition
out_protocol non-NULL.
Postcondition
No internal state mutated.
Note
Not thread-safe.
Since
0.1.0

Definition at line 459 of file ra8_usb_phid.c.

References k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.

◆ ra8_usb_phid_handle_setup()

ra8_err_t ra8_usb_phid_handle_setup ( const ra8_usb_setup_t * setup)
nodiscard

Process a class-specific SETUP packet on EP0.

Switches on b_request and (a) updates the local idle-rate / protocol shadow for SET_IDLE / SET_PROTOCOL, then (b) forwards the SETUP to the registered application handler if any. Standard (non-class) SETUPs are rejected with k_ra8_err_not_supported so the caller can fall back to its own standard-request handler.

Parameters
[in]setupThe SETUP packet returned by ra8_usb_read_setup_if_valid.
Returns
ra8_err_t error code.
Return values
k_ra8_okSETUP handled (status stage queued internally).
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrsetup was NULL.
k_ra8_err_not_supportedbRequest is not a HID class request this layer cares about.
Precondition
ra8_usb_phid_init succeeded.
Postcondition
Idle-rate / protocol shadow updated as appropriate.
Note
Call from the CTRT ISR path of ra8_usb.
Since
0.1.0

Definition at line 418 of file ra8_usb_phid.c.

References ra8_usb_setup_t::b_request, ra8_usb_setup_t::bm_request_type, internal_apply_class_setup(), internal_is_known_class_request(), k_ra8_err_invalid_state, k_ra8_err_not_supported, k_ra8_ok, k_ra8_phid_bm_class_iface_in, k_ra8_phid_bm_class_iface_out, RA8_CHECK_NULL_PTR, ra8_usb_control_response(), s_state, and s_tag.

◆ ra8_usb_phid_init()

ra8_err_t ra8_usb_phid_init ( ra8_usb_speed_t speed)
nodiscard

Bring up the device-HID function on a chosen USB controller.

Initialises the underlying ra8_usb driver in DEVICE mode for speed, configures PIPE6 (interrupt IN) and PIPE7 (interrupt OUT), resets the idle-rate / protocol shadow to spec defaults (idle_rate = 0 = "report only on change", protocol = report), and leaves the D+ pull-up dropped. The caller raises it via ra8_usb_device_attach once descriptors are set.

Parameters
[in]speedWhich USB controller (FS or HS).
Returns
ra8_err_t error code.
Return values
k_ra8_okDevice-HID ready.
k_ra8_err_invalid_argspeed out of range.
k_ra8_err_hw_init_failedUnderlying ra8_usb_device_init failed.
Precondition
Single-threaded init context.
ra8_mstp_init and ra8_pwr_init already ran.
Postcondition
Internal state machine armed; descriptor pointers cleared.
Pipe6 / pipe7 configured at the speed's default packet size.
Note
Not thread-safe.
See also
ra8_usb_phid_set_descriptors
ra8_usb_phid_close
Since
0.1.0

Definition at line 275 of file ra8_usb_phid.c.

References internal_configure_pipes(), internal_reset_shadow(), k_ra8_err_hw_init_failed, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_speed_fs, k_ra8_usb_speed_hs, ra8_log_error_val, ra8_log_info_val, ra8_usb_device_init(), s_state, and s_tag.

◆ ra8_usb_phid_recv_report()

ra8_err_t ra8_usb_phid_recv_report ( uint8_t report_id,
uint8_t * buf,
uint16_t max_len,
uint16_t * got_len )
nodiscard

Drain a HID output report from the interrupt-OUT endpoint.

Pulls bytes off PIPE7 (interrupt OUT) into buf. Some HID gadgets (notably keyboards announcing LED state) instead deliver output reports via SET_REPORT on EP0; that path is handled by the caller-installed setup callback.

Parameters
[in]report_idReport ID (informational; not consumed here).
[out]bufReceive buffer.
[in]max_lenCapacity of 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_ptrbuf or got_len was NULL.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_invalid_argmax_len == 0.
Precondition
ra8_usb_phid_init succeeded.
buf non-NULL, got_len non-NULL.
Postcondition
On success *got_len reflects the actual byte count.
Note
Not thread-safe.
Since
0.1.0

Definition at line 372 of file ra8_usb_phid.c.

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

◆ ra8_usb_phid_send_report()

ra8_err_t ra8_usb_phid_send_report ( uint8_t report_id,
const uint8_t * payload,
uint16_t len )
nodiscard

Push a HID input report on the interrupt-IN endpoint.

If report_id == 0 the device uses a single unnamed report and the payload goes straight onto PIPE6. If report_id != 0 the byte is prepended to the payload as the spec requires (USB HID 1.11 sec 8 "Report Protocol"). The caller is responsible for not exceeding the configured pipe max-packet.

Parameters
[in]report_idHID report ID (0 if device uses a single report).
[in]payloadReport payload.
[in]lenPayload length.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes queued onto interrupt-IN.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrpayload was NULL with len > 0.
k_ra8_err_invalid_arglen zero with report_id == 0, or too large for the pipe max-packet.
Precondition
ra8_usb_phid_init succeeded.
payload non-NULL when len > 0.
Postcondition
len (or len + 1 if report_id != 0) bytes sit on PIPE6.
Note
Not thread-safe.
Since
0.1.0

Definition at line 339 of file ra8_usb_phid.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_phid_pipe_intr_in, k_ra8_phid_report_id_prepend_len, RA8_RETURN_ON_ERROR, ra8_usb_queue_in(), s_state, and s_tag.

◆ ra8_usb_phid_set_descriptors()

ra8_err_t ra8_usb_phid_set_descriptors ( const uint8_t * report_desc,
uint16_t report_desc_len,
const uint8_t * hid_desc,
uint16_t hid_desc_len )
nodiscard

Install the caller-supplied HID Report descriptor and HID class descriptor.

The class layer keeps just a pointer + length pair for each descriptor; the application owns the storage. When the host issues GET_DESCRIPTOR(Report) on the HID interface, the class layer hands the buffered Report descriptor to the EP0 data stage. When the host issues GET_DESCRIPTOR(HID), the same is done for the HID class descriptor.

Parameters
[in]report_descPointer to the caller-owned Report descriptor.
[in]report_desc_lenByte length of report_desc.
[in]hid_descPointer to the caller-owned HID class descriptor.
[in]hid_desc_lenByte length of hid_desc.
Returns
ra8_err_t error code.
Return values
k_ra8_okPointers + lengths stored.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrEither pointer was NULL.
k_ra8_err_invalid_argEither length was 0.
Precondition
ra8_usb_phid_init succeeded.
Both pointers non-NULL, both lengths > 0.
Postcondition
Subsequent GET_DESCRIPTOR(Report) / GET_DESCRIPTOR(HID) requests serve the supplied buffers.
Note
Not thread-safe.
Since
0.1.0

Definition at line 314 of file ra8_usb_phid.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.