diff options
| author | hathach <[email protected]> | 2018-11-16 21:56:39 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2018-11-16 21:56:39 +0700 |
| commit | 215f8603b14cc29e08d8a25e08f8eca44ed90826 (patch) | |
| tree | 9059bf9825f3fc71def0ee1f0204ac3f719e8c71 /src/class/hid | |
| parent | b62ca2e5cdacc2f49cce6a0352ee740e4bac64a9 (diff) | |
nrf5x: refactor device control transfer.
- make control transfer as part of usbd. Class driver must use
usbd_control_ API() instead of dcd_ api.
- change the signature of class driver's control_request
- allow control request complete to stall in staus stage
- move control request parser & handling to usbd.
Diffstat (limited to 'src/class/hid')
| -rw-r--r-- | src/class/hid/hid_device.c | 141 | ||||
| -rw-r--r-- | src/class/hid/hid_device.h | 5 |
2 files changed, 74 insertions, 72 deletions
diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index efa602ad6..b5586a488 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -46,7 +46,6 @@ //--------------------------------------------------------------------+
#include "common/tusb_common.h"
#include "hid_device.h"
-#include "device/control.h"
#include "device/usbd_pvt.h"
//--------------------------------------------------------------------+
@@ -403,110 +402,112 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u return TUSB_ERROR_NONE;
}
-tusb_error_t hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request, uint16_t bytes_already_sent)
+// Handle class control request
+// return false to stall control endpoint (e.g unsupported request)
+bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
{
hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) p_request->wIndex );
- TU_ASSERT(p_hid, TUSB_ERROR_FAILED);
+ TU_ASSERT(p_hid);
- //------------- STD Request -------------//
if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD)
{
+ //------------- STD Request -------------//
uint8_t const desc_type = tu_u16_high(p_request->wValue);
uint8_t const desc_index = tu_u16_low (p_request->wValue);
(void) desc_index;
if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT)
{
- // TODO: Handle zero length packet.
- uint16_t remaining_bytes = p_hid->desc_len - bytes_already_sent;
- if (remaining_bytes > 64) {
- remaining_bytes = 64;
- }
- memcpy(_shared_control_buffer, p_hid->desc_report + bytes_already_sent, remaining_bytes);
-
- dcd_edpt_xfer(rhport, TUSB_DIR_IN_MASK, _shared_control_buffer, remaining_bytes);
+ usbd_control_xfer(rhport, p_request, p_hid->desc_report, p_hid->desc_len);
}else
{
- return TUSB_ERROR_FAILED;
+ return false; // stall unsupported request
}
}
- //------------- Class Specific Request -------------//
else if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS)
{
- if( HID_REQ_CONTROL_GET_REPORT == p_request->bRequest )
+ //------------- Class Specific Request -------------//
+ switch( p_request->bRequest )
{
- // 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);
-
- uint16_t xferlen;
- if ( p_hid->get_report_cb )
+ case HID_REQ_CONTROL_GET_REPORT:
{
- xferlen = p_hid->get_report_cb(report_id, (hid_report_type_t) report_type, p_hid->report_buf, p_request->wLength);
- }else
+ // 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);
+
+ uint16_t xferlen;
+ if ( p_hid->get_report_cb )
+ {
+ xferlen = p_hid->get_report_cb(report_id, (hid_report_type_t) report_type, p_hid->report_buf, p_request->wLength);
+ }else
+ {
+ // For boot Interface only: re-use report_buf -> report has no change
+ xferlen = p_request->wLength;
+ }
+
+ TU_ASSERT( xferlen > 0 );
+ usbd_control_xfer(rhport, p_request, p_hid->report_buf, xferlen);
+ }
+ break;
+
+ case HID_REQ_CONTROL_SET_REPORT:
+ usbd_control_xfer(rhport, p_request, p_hid->report_buf, p_request->wLength);
+ break;
+
+ case HID_REQ_CONTROL_SET_IDLE:
+ // TODO idle rate of report
+ p_hid->idle_rate = tu_u16_high(p_request->wValue);
+ usbd_control_status(rhport, p_request);
+ break;
+
+ case HID_REQ_CONTROL_GET_IDLE:
+ // TODO idle rate of report
+ usbd_control_xfer(rhport, p_request, &p_hid->idle_rate, 1);
+ break;
+
+ case HID_REQ_CONTROL_GET_PROTOCOL:
{
- // For boot Interface only: re-use report_buf -> report has no change
- xferlen = p_request->wLength;
+ uint8_t protocol = 1-p_hid->boot_protocol; // 0 is Boot, 1 is Report protocol
+ usbd_control_xfer(rhport, p_request, &protocol, 1);
}
+ break;
- TU_ASSERT( xferlen > 0 );
- dcd_edpt_xfer(rhport, TUSB_DIR_IN_MASK, _shared_control_buffer, xferlen);
- }
- else if ( HID_REQ_CONTROL_SET_REPORT == p_request->bRequest )
- {
- dcd_edpt_xfer(rhport, 0, _shared_control_buffer, p_request->wLength);
- }
- else if (HID_REQ_CONTROL_SET_IDLE == p_request->bRequest)
- {
- // TODO idle rate of report
- p_hid->idle_rate = tu_u16_high(p_request->wValue);
- }
- else if (HID_REQ_CONTROL_GET_IDLE == p_request->bRequest)
- {
- // TODO idle rate of report
- _shared_control_buffer[0] = p_hid->idle_rate;
- dcd_edpt_xfer(rhport, TUSB_DIR_IN_MASK, _shared_control_buffer, 1);
- }
- else if (HID_REQ_CONTROL_GET_PROTOCOL == p_request->bRequest )
- {
- _shared_control_buffer[0] = 1-p_hid->boot_protocol; // 0 is Boot, 1 is Report protocol
- dcd_edpt_xfer(rhport, TUSB_DIR_IN_MASK, _shared_control_buffer, 1);
- }
- else if (HID_REQ_CONTROL_SET_PROTOCOL == p_request->bRequest )
- {
- p_hid->boot_protocol = 1 - p_request->wValue; // 0 is Boot, 1 is Report protocol
- }else
- {
- return TUSB_ERROR_FAILED;
+ case HID_REQ_CONTROL_SET_PROTOCOL:
+ p_hid->boot_protocol = 1 - p_request->wValue; // 0 is Boot, 1 is Report protocol
+ usbd_control_status(rhport, p_request);
+ break;
+
+ default: return false; // stall unsupported request
}
}else
{
- return TUSB_ERROR_FAILED;
+ return false; // stall unsupported request
}
- return TUSB_ERROR_NONE;
+
+ return true;
}
-void hidd_control_request_complete(uint8_t rhport, tusb_control_request_t const * p_request)
+// Invoked when class request DATA stage is finished.
+// return false to stall control endpoint (e.g Host send non-sense DATA)
+bool hidd_control_request_complete(uint8_t rhport, tusb_control_request_t const * p_request)
{
hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) p_request->wIndex );
- if (p_hid == NULL) {
- return;
- }
+ TU_ASSERT(p_hid);
- if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS)
+ if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS &&
+ p_request->bRequest == HID_REQ_CONTROL_SET_REPORT)
{
- if ( HID_REQ_CONTROL_SET_REPORT == p_request->bRequest )
- {
- // 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);
+ // 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);
- if ( p_hid->set_report_cb )
- {
- p_hid->set_report_cb(report_id, (hid_report_type_t) report_type, _shared_control_buffer, p_request->wLength);
- }
+ if ( p_hid->set_report_cb )
+ {
+ p_hid->set_report_cb(report_id, (hid_report_type_t) report_type, p_hid->report_buf, p_request->wLength);
}
}
+
+ return true;
}
tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes)
diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 1dc40af57..7f8cd0fa7 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -378,8 +378,8 @@ ATTR_WEAK void tud_hid_mouse_set_report_cb(uint8_t report_id, hid_report_type_t void hidd_init(void);
tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
-tusb_error_t hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request, uint16_t bytes_already_sent);
-void hidd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
+bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
+bool hidd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes);
void hidd_reset(uint8_t rhport);
@@ -390,3 +390,4 @@ void hidd_reset(uint8_t rhport); #endif
#endif /* _TUSB_HID_DEVICE_H_ */
+
|
