|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Native USB device-side HID class layer implementation. More...
#include "ra8_usb_phid.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_log.h"#include "ra8_usb.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_usb_phid_state_t |
| Singleton shadow state for the device-HID function. More... | |
Enumerations | |
| enum | ra8_usb_phid_setup_field_t : uint8_t { k_ra8_phid_bm_class_iface_in = 0xA1U , k_ra8_phid_bm_class_iface_out = 0x21U , k_ra8_phid_default_idle_rate = 0U , k_ra8_phid_default_protocol = 1U , k_ra8_phid_report_id_prepend_len = 1U } |
| Constants used to decode HID class-specific SETUPs. More... | |
| enum | ra8_usb_phid_byte_shift_t : uint8_t { k_ra8_phid_shift_byte0 = 0U , k_ra8_phid_shift_byte1 = 8U } |
| Per-byte shift constants for wValue decoding. More... | |
| enum | ra8_usb_phid_byte_mask_t : uint16_t { k_ra8_phid_mask_byte = 0xFFU } |
| Per-byte mask constants for wValue decoding. More... | |
Functions | |
| static uint16_t | internal_intr_max_packet (ra8_usb_speed_t speed) |
| Pick the interrupt-max-packet ceiling matching the negotiated speed. | |
| static void | internal_configure_pipes (ra8_usb_speed_t speed) |
| Configure the two HID interrupt pipes. | |
| static void | internal_reset_shadow (ra8_usb_speed_t speed) |
| Reset shadow state to spec defaults. | |
| static bool | internal_is_known_class_request (uint8_t b_request) |
| Recognise a HID class request code we shadow / forward. | |
| static void | internal_apply_class_setup (const ra8_usb_setup_t *setup) |
| Apply SET_IDLE / SET_PROTOCOL to the local shadow. | |
| 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. | |
Variables | |
| static const char * | s_tag = "USBPHID" |
| static ra8_usb_phid_state_t | s_state = {} |
Native USB device-side HID class layer implementation.
Glues the device-mode ra8_usb driver to a HID interface so the EK-RA8D2 enumerates as a USB keyboard, mouse, gamepad, or vendor-defined HID gadget. This file is the native peripheral-HID class layer; FSP's r_usb_phid_driver.c is reference material only, nothing is pulled in verbatim.
Mapping vs FSP (FSP entry point -> our entry point):
Behaviourally the class layer responds to host requests rather than initiating them: the host enumerates, walks GET_DESCRIPTOR(HID) and GET_DESCRIPTOR(Report) over EP0, may issue SET_IDLE / SET_PROTOCOL, and then keeps polling the interrupt-IN pipe for input reports.
Definition in file ra8_usb_phid.c.
| enum ra8_usb_phid_byte_mask_t : uint16_t |
Per-byte mask constants for wValue decoding.
| Enumerator | |
|---|---|
| k_ra8_phid_mask_byte | RA8 phid mask byte. |
Definition at line 79 of file ra8_usb_phid.c.
| enum ra8_usb_phid_byte_shift_t : uint8_t |
Per-byte shift constants for wValue decoding.
| Enumerator | |
|---|---|
| k_ra8_phid_shift_byte0 | RA8 phid shift byte0. |
| k_ra8_phid_shift_byte1 | RA8 phid shift byte1. |
Definition at line 70 of file ra8_usb_phid.c.
| enum ra8_usb_phid_setup_field_t : uint8_t |
Constants used to decode HID class-specific SETUPs.
Per USB HID 1.11 sec 7.2 "Class-Specific Requests" the standard interface-recipient class envelope uses:
Definition at line 58 of file ra8_usb_phid.c.
|
static |
Apply SET_IDLE / SET_PROTOCOL to the local shadow.
wValue.high carries the duration for SET_IDLE; wValue carries 0 (boot) or 1 (report) for SET_PROTOCOL.
| [in] | setup | See implementation. |
Definition at line 243 of file ra8_usb_phid.c.
References ra8_usb_setup_t::b_request, k_ra8_phid_mask_byte, k_ra8_phid_proto_boot, k_ra8_phid_proto_report, k_ra8_phid_req_set_idle, k_ra8_phid_req_set_protocol, k_ra8_phid_shift_byte1, s_state, and ra8_usb_setup_t::w_value.
Referenced by ra8_usb_phid_handle_setup().
|
static |
Configure the two HID interrupt pipes.
See implementation.
| [in] | speed | See implementation. |
Definition at line 157 of file ra8_usb_phid.c.
References internal_intr_max_packet(), k_ra8_phid_ep_intr_in_addr, k_ra8_phid_ep_intr_out_addr, k_ra8_phid_pipe_intr_in, k_ra8_phid_pipe_intr_out, k_ra8_usb_ep_dir_in, k_ra8_usb_ep_dir_out, k_ra8_usb_ep_type_intr, and ra8_usb_configure_endpoint().
|
static |
Pick the interrupt-max-packet ceiling matching the negotiated speed.
See implementation.
| [in] | speed | See implementation. |
speed. | k_ra8_phid_intr_max_packet_hs | speed is k_ra8_usb_speed_hs. |
| k_ra8_phid_intr_max_packet_default | Any other speed. |
Definition at line 138 of file ra8_usb_phid.c.
References k_ra8_phid_intr_max_packet_default, k_ra8_phid_intr_max_packet_hs, and k_ra8_usb_speed_hs.
Referenced by internal_configure_pipes(), and internal_reset_shadow().
|
static |
Recognise a HID class request code we shadow / forward.
See implementation.
| [in] | b_request | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 221 of file ra8_usb_phid.c.
References k_ra8_phid_req_get_idle, k_ra8_phid_req_get_protocol, k_ra8_phid_req_get_report, k_ra8_phid_req_set_idle, k_ra8_phid_req_set_protocol, and k_ra8_phid_req_set_report.
Referenced by ra8_usb_phid_handle_setup().
|
static |
Reset shadow state to spec defaults.
See implementation.
| [in] | speed | See implementation. |
Definition at line 190 of file ra8_usb_phid.c.
References internal_intr_max_packet(), k_ra8_phid_default_idle_rate, k_ra8_phid_ep_intr_in_addr, k_ra8_phid_ep_intr_out_addr, k_ra8_phid_proto_report, and s_state.
Referenced by ra8_usb_phid_init().
|
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.
| [in] | setup_fn | Application's handler. NULL detaches. |
| [in] | ctx | Context pointer threaded back into setup_fn. |
| k_ra8_ok | Handler installed. |
| k_ra8_err_invalid_state | Driver not initialized. |
Definition at line 403 of file ra8_usb_phid.c.
References k_ra8_err_invalid_state, k_ra8_ok, and s_state.
|
nodiscard |
Tear down the device-HID function and release the controller.
| k_ra8_ok | Released. |
| k_ra8_err_invalid_state | Driver was never initialized. |
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.
|
nodiscard |
Read the most-recently negotiated idle rate.
| [out] | out_idle_rate | Receives the 4 ms-tick idle rate (0 = "report only on change"). |
| k_ra8_ok | Value copied. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | out_idle_rate was NULL. |
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.
|
nodiscard |
Read the most-recently negotiated protocol.
| [out] | out_protocol | Receives the protocol selector. |
| k_ra8_ok | Value copied. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | out_protocol was NULL. |
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.
|
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.
| [in] | setup | The SETUP packet returned by ra8_usb_read_setup_if_valid. |
| k_ra8_ok | SETUP handled (status stage queued internally). |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | setup was NULL. |
| k_ra8_err_not_supported | bRequest is not a HID class request this layer cares about. |
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.
|
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.
| [in] | speed | Which USB controller (FS or HS). |
| k_ra8_ok | Device-HID ready. |
| k_ra8_err_invalid_arg | speed out of range. |
| k_ra8_err_hw_init_failed | Underlying ra8_usb_device_init failed. |
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.
|
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.
| [in] | report_id | Report ID (informational; not consumed here). |
| [out] | buf | Receive buffer. |
| [in] | max_len | Capacity of buf, > 0. |
| [out] | got_len | Receives the number of bytes actually placed. |
| k_ra8_ok | Bytes drained; *got_len reflects the count. |
| k_ra8_err_no_data | Pipe was empty. |
| k_ra8_err_null_ptr | buf or got_len was NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_invalid_arg | max_len == 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.
|
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.
| [in] | report_id | HID report ID (0 if device uses a single report). |
| [in] | payload | Report payload. |
| [in] | len | Payload length. |
| k_ra8_ok | Bytes queued onto interrupt-IN. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | payload was NULL with len > 0. |
| k_ra8_err_invalid_arg | len zero with report_id == 0, or too large for the pipe max-packet. |
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.
|
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.
| [in] | report_desc | Pointer to the caller-owned Report descriptor. |
| [in] | report_desc_len | Byte length of report_desc. |
| [in] | hid_desc | Pointer to the caller-owned HID class descriptor. |
| [in] | hid_desc_len | Byte length of hid_desc. |
| k_ra8_ok | Pointers + lengths stored. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | Either pointer was NULL. |
| k_ra8_err_invalid_arg | Either length was 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.
|
static |
Definition at line 114 of file ra8_usb_phid.c.
|
static |
Definition at line 42 of file ra8_usb_phid.c.