Merge pull request #931 from hathach/more-hid-host
More hid host update
This commit is contained in:
@@ -98,7 +98,7 @@ uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance)
|
||||
return hid_itf->itf_protocol;
|
||||
}
|
||||
|
||||
bool tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance)
|
||||
uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance)
|
||||
{
|
||||
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
|
||||
return hid_itf->protocol_mode;
|
||||
@@ -243,33 +243,37 @@ void hidh_close(uint8_t dev_addr)
|
||||
// Enumeration
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static bool config_get_protocol (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result);
|
||||
static bool config_set_protocol (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result);
|
||||
static bool config_get_report_desc (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result);
|
||||
static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result);
|
||||
|
||||
bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t *p_length)
|
||||
uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
|
||||
{
|
||||
TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass);
|
||||
(void) max_len;
|
||||
|
||||
TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0);
|
||||
|
||||
uint16_t drv_len = sizeof(tusb_desc_interface_t);
|
||||
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
||||
|
||||
//------------- HID descriptor -------------//
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
|
||||
TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType);
|
||||
TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType, 0);
|
||||
|
||||
// not enough interface, try to increase CFG_TUH_HID
|
||||
// TODO multiple devices
|
||||
hidh_device_t* hid_dev = get_dev(dev_addr);
|
||||
TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID);
|
||||
TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID, 0);
|
||||
|
||||
//------------- Endpoint Descriptor -------------//
|
||||
drv_len += tu_desc_len(p_desc);
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType);
|
||||
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType, 0);
|
||||
|
||||
// TODO also open endpoint OUT
|
||||
TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) );
|
||||
TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep), 0 );
|
||||
|
||||
hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count);
|
||||
hid_dev->inst_count++;
|
||||
@@ -282,12 +286,13 @@ 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->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode
|
||||
// Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config
|
||||
hid_itf->protocol_mode = HID_PROTOCOL_BOOT;
|
||||
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);
|
||||
drv_len += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
|
||||
|
||||
return true;
|
||||
return drv_len;
|
||||
}
|
||||
|
||||
bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num)
|
||||
@@ -314,43 +319,49 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num)
|
||||
.wLength = 0
|
||||
};
|
||||
|
||||
TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_get_protocol : config_get_report_desc) );
|
||||
TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_set_protocol : config_get_report_desc) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool config_get_protocol(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result)
|
||||
// Force device to work in BOOT protocol
|
||||
static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result)
|
||||
{
|
||||
// Stall is a valid response for SET_IDLE GET_PROTOCOL, therefore we could ignore its result
|
||||
// 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;
|
||||
uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num);
|
||||
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
|
||||
|
||||
TU_LOG2("HID Get Protocol\r\n");
|
||||
TU_LOG2("HID Set Protocol\r\n");
|
||||
hid_itf->protocol_mode = HID_PROTOCOL_BOOT;
|
||||
tusb_control_request_t const new_request =
|
||||
{
|
||||
.bmRequestType_bit =
|
||||
{
|
||||
.recipient = TUSB_REQ_RCPT_INTERFACE,
|
||||
.type = TUSB_REQ_TYPE_CLASS,
|
||||
.direction = TUSB_DIR_IN
|
||||
.direction = TUSB_DIR_OUT
|
||||
},
|
||||
.bRequest = HID_REQ_CONTROL_GET_PROTOCOL,
|
||||
.wValue = 0,
|
||||
.bRequest = HID_REQ_CONTROL_SET_PROTOCOL,
|
||||
.wValue = HID_PROTOCOL_BOOT,
|
||||
.wIndex = hid_itf->itf_num,
|
||||
.wLength = 1
|
||||
.wLength = 0
|
||||
};
|
||||
|
||||
TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, &hid_itf->protocol_mode, config_get_report_desc) );
|
||||
return false;
|
||||
TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, NULL, config_get_report_desc) );
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result)
|
||||
{
|
||||
// Stall is a valid response for SET_IDLE GET_PROTOCOL, therefore we could ignore its result
|
||||
(void) result;
|
||||
// We can be here after SET_IDLE or SET_PROTOCOL (boot device)
|
||||
// Trigger assert if result is not successful with set protocol
|
||||
if ( request->bRequest != HID_REQ_CONTROL_SET_IDLE )
|
||||
{
|
||||
TU_ASSERT(result == XFER_RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
uint8_t const itf_num = (uint8_t) request->wIndex;
|
||||
uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num);
|
||||
|
||||
@@ -66,9 +66,10 @@ bool tuh_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_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_hid_get_protocol(uint8_t dev_addr, uint8_t instance);
|
||||
// Get current protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1)
|
||||
// Note: Device will be initialized in Boot protocol for simplicity.
|
||||
// Application can use set_protocol() to switch back to Report protocol.
|
||||
uint8_t tuh_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_interface_protocol() != NONE)
|
||||
@@ -118,11 +119,11 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t ins
|
||||
//--------------------------------------------------------------------+
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void hidh_init(void);
|
||||
bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t *p_length);
|
||||
bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num);
|
||||
bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
|
||||
void hidh_close(uint8_t dev_addr);
|
||||
void hidh_init (void);
|
||||
uint16_t hidh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len);
|
||||
bool hidh_set_config (uint8_t dev_addr, uint8_t itf_num);
|
||||
bool hidh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
|
||||
void hidh_close (uint8_t dev_addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user