simplify hid api

add hid set_protocol() and set_protocol_complete_cb()
This commit is contained in:
hathach 2021-05-22 16:27:28 +07:00
parent 327336e921
commit 99add05aa7
3 changed files with 61 additions and 67 deletions

View File

@ -64,7 +64,7 @@ void tuh_hid_mounted_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_
// Interface protocol
const char* protocol_str[] = { "None", "Keyboard", "Mouse" }; // hid_protocol_type_t
uint8_t const interface_protocol = tuh_n_hid_n_interface_protocol(dev_addr, instance);
uint8_t const interface_protocol = tuh_n_hid_interface_protocol(dev_addr, instance);
printf(", Interface protocol = %s, ", protocol_str[interface_protocol]);
}

View File

@ -51,15 +51,15 @@ typedef struct
uint8_t ep_in;
uint8_t ep_out;
uint8_t itf_protocol; // None, Keyboard, Mouse
uint8_t protocol_mode; // Boot (0) or Report protocol (1)
uint8_t report_desc_type;
uint16_t report_desc_len;
uint16_t epin_size;
uint16_t epout_size;
uint8_t itf_protocol; // None, Keyboard, Mouse
bool boot_mode; // Boot or Report protocol
uint8_t epin_buf[CFG_TUH_HID_EP_BUFSIZE];
uint8_t epout_buf[CFG_TUH_HID_EP_BUFSIZE];
} hidh_interface_t;
@ -76,7 +76,6 @@ static hidh_device_t _hidh_dev[CFG_TUSB_HOST_DEVICE_MAX-1];
TU_ATTR_ALWAYS_INLINE static inline hidh_device_t* get_dev(uint8_t dev_addr);
TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_addr, uint8_t instance);
static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf);
static hidh_interface_t* get_instance_by_itfnum(uint8_t dev_addr, uint8_t itf);
static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr);
TU_ATTR_ALWAYS_INLINE static inline bool hidh_get_report(uint8_t dev_addr, hidh_interface_t* hid_itf)
@ -93,28 +92,64 @@ uint8_t tuh_n_hid_instance_count(uint8_t dev_addr)
return get_dev(dev_addr)->inst_count;
}
bool tuh_n_hid_n_mounted(uint8_t dev_addr, uint8_t instance)
bool tuh_n_hid_mounted(uint8_t dev_addr, uint8_t instance)
{
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
return (hid_itf->ep_in != 0) || (hid_itf->ep_out != 0);
}
uint8_t tuh_n_hid_n_interface_protocol(uint8_t dev_addr, uint8_t instance)
uint8_t tuh_n_hid_interface_protocol(uint8_t dev_addr, uint8_t instance)
{
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
return hid_itf->itf_protocol;
}
bool tuh_n_hid_n_get_protocol(uint8_t dev_addr, uint8_t instance)
bool tuh_n_hid_get_protocol(uint8_t dev_addr, uint8_t instance)
{
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
return hid_itf->boot_mode ? HID_PROTOCOL_BOOT : HID_PROTOCOL_REPORT;
return hid_itf->protocol_mode;
}
// bool tuh_n_hid_n_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol)
//{
//
//}
static bool set_protocol_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result)
{
uint8_t const itf_num = (uint8_t) request->wIndex;
uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num);
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) request->wValue;
if (tuh_hid_set_protocol_complete_cb)
{
tuh_hid_set_protocol_complete_cb(dev_addr, instance, hid_itf->protocol_mode);
}
return true;
}
bool tuh_n_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol)
{
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
TU_VERIFY(hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE);
TU_LOG2("Set Protocol = %d\r\n", protocol);
tusb_control_request_t const request =
{
.bmRequestType_bit =
{
.recipient = TUSB_REQ_RCPT_INTERFACE,
.type = TUSB_REQ_TYPE_CLASS,
.direction = TUSB_DIR_OUT
},
.bRequest = HID_REQ_CONTROL_SET_PROTOCOL,
.wValue = protocol,
.wIndex = hid_itf->itf_num,
.wLength = 0
};
TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, set_protocol_complete) );
return true;
}
//bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance)
//{
@ -209,39 +244,8 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
hid_itf->report_desc_type = desc_hid->bReportType;
hid_itf->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength);
hid_itf->boot_mode = false; // default is report mode
if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass )
{
hid_itf->itf_protocol = desc_itf->bInterfaceProtocol;
if ( HID_ITF_PROTOCOL_KEYBOARD == desc_itf->bInterfaceProtocol)
{
TU_LOG2(" Boot Keyboard\r\n");
// TODO boot protocol may still have more report in report mode
// hid_itf->report_info.count = 1;
// hid_itf->report_info.info[0].usage_page = HID_USAGE_PAGE_DESKTOP;
// hid_itf->report_info.info[0].usage = HID_USAGE_DESKTOP_KEYBOARD;
// hid_itf->report_info.info[0].in_len = 8;
// hid_itf->report_info.info[0].out_len = 1;
}
else if ( HID_ITF_PROTOCOL_MOUSE == desc_itf->bInterfaceProtocol)
{
TU_LOG2(" Boot Mouse\r\n");
// TODO boot protocol may still have more report in report mode
// hid_itf->report_info.count = 1;
// hid_itf->report_info.info[0].usage_page = HID_USAGE_PAGE_DESKTOP;
// hid_itf->report_info.info[0].usage = HID_USAGE_DESKTOP_MOUSE;
// hid_itf->report_info.info[0].in_len = 5;
// hid_itf->report_info.info[0].out_len = 0;
}
else
{
// Unknown protocol
TU_ASSERT(false);
}
}
hid_itf->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode
if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) hid_itf->itf_protocol = desc_itf->bInterfaceProtocol;
*p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
@ -279,9 +283,9 @@ bool config_set_idle_complete(uint8_t dev_addr, tusb_control_request_t const * r
// Stall is a valid response for SET_IDLE, therefore we could ignore its result
(void) result;
uint8_t const itf_num = (uint8_t) request->wIndex;
hidh_interface_t* hid_itf = get_instance_by_itfnum(dev_addr, itf_num);
uint8_t const itf_num = (uint8_t) request->wIndex;
uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num);
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
// Get Report Descriptor
// using usbh enumeration buffer since report descriptor can be very long
@ -509,19 +513,6 @@ TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_a
return &_hidh_dev[dev_addr-1].instances[instance];
}
// Get instance by interface number
static hidh_interface_t* get_instance_by_itfnum(uint8_t dev_addr, uint8_t itf)
{
for ( uint8_t inst = 0; inst < CFG_TUH_HID; inst++ )
{
hidh_interface_t *hid = get_instance(dev_addr, inst);
if ( (hid->itf_num == itf) && (hid->ep_in || hid->ep_out) ) return hid;
}
return NULL;
}
// Get instance ID by interface number
static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf)
{

View File

@ -72,18 +72,18 @@ typedef struct
uint8_t tuh_n_hid_instance_count(uint8_t dev_addr);
// Check if HID instance is mounted
bool tuh_n_hid_n_mounted(uint8_t dev_addr, uint8_t instance);
bool tuh_n_hid_mounted(uint8_t dev_addr, uint8_t instance);
// Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values
uint8_t tuh_n_hid_n_interface_protocol(uint8_t dev_addr, uint8_t instance);
uint8_t tuh_n_hid_interface_protocol(uint8_t dev_addr, uint8_t instance);
// Get current active protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1)
// Note: as HID spec, device will be initialized in Report mode
bool tuh_n_hid_n_get_protocol(uint8_t dev_addr, uint8_t instance);
bool tuh_n_hid_get_protocol(uint8_t dev_addr, uint8_t instance);
// Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1)
// This function is only supported by Boot interface tuh_n_hid_n_boot_interface()
bool tuh_n_hid_n_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol);
// This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE)
bool tuh_n_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol);
// Parse report descriptor into array of report_info struct and return number of reports.
// If return 0, this is a ingle report, otherwise it is composite report with 1st byte as ID.
@ -116,6 +116,9 @@ void tuh_hid_get_report_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* re
// Invoked when Sent Report to device via either regular or control endpoint
TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t xferred_bytes);
// Invoked when Set Protocol request is complete
TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t protocol);
//--------------------------------------------------------------------+
// Application API (Single device)
//--------------------------------------------------------------------+