29#if (CFG_TUH_ENABLED && CFG_TUH_HID)
37#ifndef CFG_TUH_HID_LOG_LEVEL
38 #define CFG_TUH_HID_LOG_LEVEL CFG_TUH_LOG_LEVEL
41#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_HID_LOG_LEVEL, __VA_ARGS__)
63 CFG_TUH_MEM_ALIGN uint8_t epin_buf[CFG_TUH_HID_EPIN_BUFSIZE];
64 CFG_TUH_MEM_ALIGN uint8_t epout_buf[CFG_TUH_HID_EPOUT_BUFSIZE];
76 TU_ASSERT(
daddr > 0 && idx < CFG_TUH_HID, NULL);
83 for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) {
86 (p_hid->
ep_in == ep_addr || p_hid->
ep_out == ep_addr)) {
94 for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
105 for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
113 for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
127 TU_VERIFY(p_hid &&
info);
137 desc->bAlternateSetting = 0;
138 desc->bNumEndpoints = (uint8_t) ((p_hid->
ep_in ? 1u : 0u) + (p_hid->
ep_out ? 1u : 0u));
142 desc->iInterface = 0;
148 for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) {
170 uint8_t
const itf_num = (uint8_t) tu_le16toh(
xfer->setup->wIndex);
192 TU_LOG_DRV(
"HID Set Protocol = %d\r\n", protocol);
226 TU_LOG_DRV(
"HID Get Report complete\r\n");
229 uint8_t
const itf_num = (uint8_t) tu_le16toh(
xfer->setup->wIndex);
243 TU_LOG_DRV(
"HID Get Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len);
252 .wValue = tu_htole16(
tu_u16(report_type, report_id)),
253 .wIndex = tu_htole16((uint16_t) p_hid->
itf_num),
270 TU_LOG_DRV(
"HID Set Report complete\r\n");
273 uint8_t
const itf_num = (uint8_t) tu_le16toh(
xfer->setup->wIndex);
287 TU_LOG_DRV(
"HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len);
296 .wValue = tu_htole16(
tu_u16(report_type, report_id)),
297 .wIndex = tu_htole16((uint16_t) p_hid->
itf_num),
316 TU_LOG_DRV(
"HID Set Idle \r\n");
325 .wValue = tu_htole16(idle_rate),
326 .wIndex = tu_htole16((uint16_t) itf_num),
380 TU_LOG_DRV(
"HID Send Report %d\r\n", report_id);
388 }
else if (len > CFG_TUH_HID_EPOUT_BUFSIZE ||
389 (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1))) {
397 if (report_id == 0) {
439 TU_LOG_DRV(
" Get Report callback (%u, %u)\r\n",
daddr, idx);
440 TU_LOG3_MEM(p_hid->
epin_buf, xferred_bytes, 2);
452 for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
455 TU_LOG_DRV(
" HIDh close addr = %u index = %u\r\n",
daddr, i);
474 uint16_t
const drv_len = (uint16_t) (
sizeof(
tusb_desc_interface_t) +
sizeof(tusb_hid_descriptor_hid_t) +
476 TU_ASSERT(max_len >= drv_len);
477 uint8_t
const* p_desc = (uint8_t
const*) desc_itf;
481 tusb_hid_descriptor_hid_t
const* desc_hid = (tusb_hid_descriptor_hid_t
const*) p_desc;
562 uint8_t
const itf_num = (uint8_t) tu_le16toh(
xfer->setup->wIndex);
572 const uint16_t idle_rate = 0;
587 TU_LOG_DRV(
"HID Skip Report Descriptor since it is too large %u bytes\r\n", p_hid->
report_desc_len);
600 uint16_t
const desc_len = tu_le16toh(
xfer->setup->wLength);
628 uint8_t
const* desc_report, uint16_t desc_len) {
641 uint8_t report_num = 0;
648 uint8_t ri_collection_depth = 0;
649 while (desc_len && report_num < arr_count) {
650 header.byte = *desc_report++;
653 uint8_t
const tag =
header.tag;
654 uint8_t
const type =
header.type;
655 uint8_t
const size =
header.size;
657 uint8_t
const data8 = desc_report[0];
659 TU_LOG(3,
"tag = %d, type = %d, size = %d, data = ", tag, type, size);
660 for (uint32_t i = 0; i < size; i++) {
661 TU_LOG(3,
"%02X ", desc_report[i]);
672 ri_collection_depth++;
676 ri_collection_depth--;
677 if (ri_collection_depth == 0) {
691 if (ri_collection_depth == 0)
memcpy(&
info->usage_page, desc_report, size);
700 info->report_id = data8;
724 if (ri_collection_depth == 0)
info->usage = data8;
748 for (uint8_t i = 0; i < report_num; i++) {
749 info = report_info_arr + i;
750 TU_LOG_DRV(
"%u: id = %u, usage_page = %u, usage = %u\r\n", i,
info->report_id,
info->usage_page,
info->usage);
xfer_td_t xfer[EP_CBI_COUNT+1][2]
static usb_descriptor_buffers_t desc
@ HID_REQ_CONTROL_SET_REPORT
Set Report.
@ HID_REQ_CONTROL_GET_REPORT
Get Report.
@ HID_REQ_CONTROL_SET_PROTOCOL
Set Protocol.
@ HID_REQ_CONTROL_SET_IDLE
Set Idle.
@ HID_SUBCLASS_BOOT
Boot Interface Subclass.
@ HID_SUBCLASS_NONE
No Subclass.
@ HID_ITF_PROTOCOL_NONE
None.
@ HID_DESC_TYPE_HID
HID Descriptor.
@ RI_LOCAL_DESIGNATOR_MIN
@ RI_LOCAL_DESIGNATOR_MAX
@ RI_LOCAL_DESIGNATOR_INDEX
@ RI_GLOBAL_UNIT_EXPONENT
uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num)
void hidh_close(uint8_t daddr)
bool tuh_hid_mounted(uint8_t daddr, uint8_t idx)
static hidh_interface_t * find_new_itf(void)
bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx)
uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t *report_info_arr, uint8_t arr_count, uint8_t const *desc_report, uint16_t desc_len)
static TU_ATTR_ALWAYS_INLINE hidh_interface_t * get_hid_itf(uint8_t daddr, uint8_t idx)
static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const *desc_report, uint16_t desc_len)
static void process_set_config(tuh_xfer_t *xfer)
static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx)
bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol)
static void set_protocol_complete(tuh_xfer_t *xfer)
static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr)
static void get_report_complete(tuh_xfer_t *xfer)
uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx)
bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx)
static void set_report_complete(tuh_xfer_t *xfer)
bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
void tuh_hid_set_default_protocol(uint8_t protocol)
bool hidh_set_config(uint8_t daddr, uint8_t itf_num)
tu_static uint8_t _hidh_default_protocol
bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t *info)
uint8_t tuh_hid_itf_get_total_count(void)
bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx)
static bool _hidh_set_protocol(uint8_t daddr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
uint8_t tuh_hid_get_protocol(uint8_t daddr, uint8_t idx)
bool tuh_hid_get_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report, uint16_t len)
bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const void *report, uint16_t len)
bool tuh_hid_set_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report, uint16_t len)
CFG_TUH_MEM_SECTION tu_static hidh_interface_t _hidh_itf[CFG_TUH_HID]
uint8_t tuh_hid_itf_get_count(uint8_t daddr)
TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len)
TU_ATTR_WEAK void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, uint8_t const *report_desc, uint16_t desc_len)
TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const *report, uint16_t len)
TU_ATTR_WEAK void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len)
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, uint8_t const *report, uint16_t len)
TU_ATTR_WEAK void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t idx)
TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t protocol)
static void * memcpy(void *dst, const void *src, size_t n)
AUDIO Channel Cluster Descriptor (4.1)
uint32_t tag
Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTa...
uint8_t type
Request type tusb_request_type_t.
struct TU_ATTR_PACKED::@16::TU_ATTR_PACKED bmRequestType_bit
uint8_t bDescriptorType
Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bInterfaceClass
Class code (assigned by the USB-IF).
uint8_t bInterfaceSubClass
Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bInterfaceCla...
uint8_t bNumEndpoints
Number of endpoints used by this interface (excluding endpoint zero). If this value is zero,...
uint8_t bInterfaceProtocol
Protocol code (assigned by the USB). These codes are qualified by the value of the bInterfaceClass ...
uint8_t bInterfaceNumber
Number of this interface. Zero-based value identifying the index in the array of concurrent interface...
CFG_TUH_MEM_ALIGN uint8_t epout_buf[CFG_TUH_HID_EPOUT_BUFSIZE]
CFG_TUH_MEM_ALIGN uint8_t epin_buf[CFG_TUH_HID_EPIN_BUFSIZE]
static TU_ATTR_ALWAYS_INLINE uint8_t tu_u16_low(uint16_t ui16)
static TU_ATTR_ALWAYS_INLINE uint8_t tu_u16_high(uint16_t ui16)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_unaligned_read16(const void *mem)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_u16(uint8_t high, uint8_t low)
@ TUSB_REQ_RCPT_INTERFACE
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
struct TU_ATTR_PACKED tusb_desc_interface_t
USB Interface Descriptor.
static TU_ATTR_ALWAYS_INLINE uint8_t const * tu_desc_next(void const *desc)
void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
CFG_TUH_MEM_ALIGN tusb_control_request_t request
bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
uint8_t * usbh_get_enum_buf(void)
bool tuh_control_xfer(tuh_xfer_t *xfer)
bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
tuh_xfer_cb_t complete_cb
bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const *desc_ep)
bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void *buffer, uint16_t len, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr)
void(* tuh_xfer_cb_t)(tuh_xfer_t *xfer)
static TU_ATTR_ALWAYS_INLINE bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)