migrate hid device to new control xfer cb

This commit is contained in:
hathach
2020-11-19 22:00:49 +07:00
parent dd07fecc5f
commit dc9a309839
3 changed files with 115 additions and 115 deletions

View File

@@ -211,9 +211,10 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint1
return drv_len; return drv_len;
} }
// Handle class control request // Invoked when a control transfer occurred on an interface of this class
// Driver response accordingly to the request and the transfer stage (setup/data/ack)
// return false to stall control endpoint (e.g unsupported request) // return false to stall control endpoint (e.g unsupported request)
bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request) bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request)
{ {
TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE);
@@ -225,27 +226,29 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request
if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD)
{ {
//------------- STD Request -------------// //------------- STD Request -------------//
uint8_t const desc_type = tu_u16_high(request->wValue); if ( stage == CONTROL_STAGE_SETUP )
uint8_t const desc_index = tu_u16_low (request->wValue); {
(void) desc_index; uint8_t const desc_type = tu_u16_high(request->wValue);
//uint8_t const desc_index = tu_u16_low (request->wValue);
if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID)
{ {
TU_VERIFY(p_hid->hid_descriptor != NULL); TU_VERIFY(p_hid->hid_descriptor != NULL);
TU_VERIFY(tud_control_xfer(rhport, request, (void*) p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); TU_VERIFY(tud_control_xfer(rhport, request, (void*) p_hid->hid_descriptor, p_hid->hid_descriptor->bLength));
} }
else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT)
{ {
uint8_t const * desc_report = tud_hid_descriptor_report_cb( uint8_t const * desc_report = tud_hid_descriptor_report_cb(
#if CFG_TUD_HID > 1 #if CFG_TUD_HID > 1
hid_itf // TODO for backward compatible callback, remove later when appropriate hid_itf // TODO for backward compatible callback, remove later when appropriate
#endif #endif
); );
tud_control_xfer(rhport, request, (void*) desc_report, p_hid->report_desc_len); tud_control_xfer(rhport, request, (void*) desc_report, p_hid->report_desc_len);
} }
else else
{ {
return false; // stall unsupported request return false; // stall unsupported request
}
} }
} }
else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS)
@@ -254,70 +257,98 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request
switch( request->bRequest ) switch( request->bRequest )
{ {
case HID_REQ_CONTROL_GET_REPORT: case HID_REQ_CONTROL_GET_REPORT:
{ if ( stage == CONTROL_STAGE_SETUP )
// wValue = Report Type | Report ID
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t const report_id = tu_u16_low(request->wValue);
uint16_t xferlen = tud_hid_get_report_cb(
#if CFG_TUD_HID > 1
hid_itf, // TODO for backward compatible callback, remove later when appropriate
#endif
report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength
);
TU_ASSERT( xferlen > 0 );
tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen);
}
break;
case HID_REQ_CONTROL_SET_REPORT:
TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf));
tud_control_xfer(rhport, request, p_hid->epout_buf, request->wLength);
break;
case HID_REQ_CONTROL_SET_IDLE:
p_hid->idle_rate = tu_u16_high(request->wValue);
if ( tud_hid_set_idle_cb )
{ {
// stall request if callback return false uint8_t const report_type = tu_u16_high(request->wValue);
TU_VERIFY( tud_hid_set_idle_cb( uint8_t const report_id = tu_u16_low(request->wValue);
#if CFG_TUD_HID > 1
hid_itf, // TODO for backward compatible callback, remove later when appropriate
#endif
p_hid->idle_rate)
);
}
tud_control_status(rhport, request); uint16_t xferlen = tud_hid_get_report_cb(
break;
case HID_REQ_CONTROL_GET_IDLE:
// TODO idle rate of report
tud_control_xfer(rhport, request, &p_hid->idle_rate, 1);
break;
case HID_REQ_CONTROL_GET_PROTOCOL:
{
uint8_t protocol = (uint8_t)(1-p_hid->boot_mode); // 0 is Boot, 1 is Report protocol
tud_control_xfer(rhport, request, &protocol, 1);
}
break;
case HID_REQ_CONTROL_SET_PROTOCOL:
p_hid->boot_mode = 1 - request->wValue; // 0 is Boot, 1 is Report protocol
if (tud_hid_boot_mode_cb)
{
tud_hid_boot_mode_cb(
#if CFG_TUD_HID > 1 #if CFG_TUD_HID > 1
hid_itf, // TODO for backward compatible callback, remove later when appropriate hid_itf, // TODO for backward compatible callback, remove later when appropriate
#endif #endif
p_hid->boot_mode report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength
);
TU_ASSERT( xferlen > 0 );
tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen);
}
break;
case HID_REQ_CONTROL_SET_REPORT:
if ( stage == CONTROL_STAGE_SETUP )
{
TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf));
tud_control_xfer(rhport, request, p_hid->epout_buf, request->wLength);
}
else if ( stage == CONTROL_STAGE_ACK )
{
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t const report_id = tu_u16_low(request->wValue);
tud_hid_set_report_cb(
#if CFG_TUD_HID > 1
hid_itf, // TODO for backward compatible callback, remove later when appropriate
#endif
report_id, (hid_report_type_t) report_type, p_hid->epout_buf, request->wLength
); );
} }
break;
tud_control_status(rhport, request); case HID_REQ_CONTROL_SET_IDLE:
if ( stage == CONTROL_STAGE_SETUP )
{
p_hid->idle_rate = tu_u16_high(request->wValue);
if ( tud_hid_set_idle_cb )
{
// stall request if callback return false
TU_VERIFY( tud_hid_set_idle_cb(
#if CFG_TUD_HID > 1
hid_itf, // TODO for backward compatible callback, remove later when appropriate
#endif
p_hid->idle_rate)
);
}
tud_control_status(rhport, request);
}
break;
case HID_REQ_CONTROL_GET_IDLE:
if ( stage == CONTROL_STAGE_SETUP )
{
// TODO idle rate of report
tud_control_xfer(rhport, request, &p_hid->idle_rate, 1);
}
break;
case HID_REQ_CONTROL_GET_PROTOCOL:
if ( stage == CONTROL_STAGE_SETUP )
{
// 0 is Boot, 1 is Report protocol
uint8_t protocol = (uint8_t)(1-p_hid->boot_mode);
tud_control_xfer(rhport, request, &protocol, 1);
}
break;
case HID_REQ_CONTROL_SET_PROTOCOL:
if ( stage == CONTROL_STAGE_SETUP )
{
// 0 is Boot, 1 is Report protocol
p_hid->boot_mode = 1 - request->wValue;
tud_control_status(rhport, request);
}
else if ( stage == CONTROL_STAGE_ACK )
{
if (tud_hid_boot_mode_cb)
{
tud_hid_boot_mode_cb(
#if CFG_TUD_HID > 1
hid_itf, // TODO for backward compatible callback, remove later when appropriate
#endif
p_hid->boot_mode
);
}
}
break; break;
default: return false; // stall unsupported request default: return false; // stall unsupported request
@@ -330,35 +361,6 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request
return true; return true;
} }
// Invoked when class request DATA stage is finished.
// return false to stall control endpoint (e.g Host send non-sense DATA)
bool hidd_control_complete(uint8_t rhport, tusb_control_request_t const * p_request)
{
(void) rhport;
uint8_t const hid_itf = get_index_by_itfnum((uint8_t) p_request->wIndex);
TU_VERIFY(hid_itf < CFG_TUD_HID);
hidd_interface_t* p_hid = &_hidd_itf[hid_itf];
if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS &&
p_request->bRequest == HID_REQ_CONTROL_SET_REPORT)
{
// wValue = Report Type | Report ID
uint8_t const report_type = tu_u16_high(p_request->wValue);
uint8_t const report_id = tu_u16_low(p_request->wValue);
tud_hid_set_report_cb(
#if CFG_TUD_HID > 1
hid_itf, // TODO for backward compatible callback, remove later when appropriate
#endif
report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength
);
}
return true;
}
bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{ {
(void) result; (void) result;

View File

@@ -359,12 +359,11 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Internal Class Driver API // Internal Class Driver API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void hidd_init (void); void hidd_init (void);
void hidd_reset (uint8_t rhport); void hidd_reset (uint8_t rhport);
uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool hidd_control_request (uint8_t rhport, tusb_control_request_t const * request); bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool hidd_control_complete (uint8_t rhport, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -121,8 +121,7 @@ static usbd_class_driver_t const _usbd_driver[] =
.init = hidd_init, .init = hidd_init,
.reset = hidd_reset, .reset = hidd_reset,
.open = hidd_open, .open = hidd_open,
.control_xfer_cb = hidd_control_request, .control_xfer_cb = hidd_control_xfer_cb,
.control_complete = hidd_control_complete,
.xfer_cb = hidd_xfer_cb, .xfer_cb = hidd_xfer_cb,
.sof = NULL .sof = NULL
}, },