From 036e858543dce1c19ff789b69907680500e28ca6 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jul 2019 18:14:47 +0700 Subject: [PATCH] add tud_control_vendor_request_cb()/tud_control_vendor_complete_cb(), expose usbd control transfer rename usbd_control_transfer/status to tud_control_transfer/status --- examples/device/webusb/src/main.c | 6 --- examples/device/webusb/src/usb_descriptors.c | 38 +++++++++++++++ src/class/cdc/cdc_device.c | 6 +-- src/class/hid/hid_device.c | 14 +++--- src/class/msc/msc_device.c | 4 +- src/device/usbd.c | 50 ++++++++++---------- src/device/usbd.h | 12 +++++ src/device/usbd_control.c | 8 ++-- src/device/usbd_pvt.h | 8 ---- 9 files changed, 92 insertions(+), 54 deletions(-) diff --git a/examples/device/webusb/src/main.c b/examples/device/webusb/src/main.c index 59e93493..5624ff4b 100644 --- a/examples/device/webusb/src/main.c +++ b/examples/device/webusb/src/main.c @@ -30,12 +30,6 @@ #include "bsp/board.h" #include "tusb.h" -/* This MIDI example send sequence of note (on/off) repeatedly. To test on PC, you need to install - * synth software and midi connection management software. On - * - Linux (Ubuntu) : install qsynth, qjackctl. Then connect TinyUSB output port to FLUID Synth input port - * - */ - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ diff --git a/examples/device/webusb/src/usb_descriptors.c b/examples/device/webusb/src/usb_descriptors.c index f1e9dd97..97c05e5d 100644 --- a/examples/device/webusb/src/usb_descriptors.c +++ b/examples/device/webusb/src/usb_descriptors.c @@ -174,3 +174,41 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) return _desc_str; } + +//--------------------------------------------------------------------+ +// WebUSB URL Descriptor +//--------------------------------------------------------------------+ +#define URL "github.com/hathach/tinyusb" + +typedef struct TU_ATTR_PACKED +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bScheme; + char url[]; +} tusb_desc_webusb_url_t; + +const tusb_desc_webusb_url_t desc_url = +{ + .bLength = 3 + sizeof(URL) - 1, + .bDescriptorType = 3, // WEBUSB URL type + .bScheme = 1, // 0: http, 1: https + .url = URL +}; + +bool tud_control_vendor_request_cb(uint8_t rhport, tusb_control_request_t const * request) +{ + if ( request->bRequest == 0x01 ) // webusb vendor code + { + return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength); + }else + { + return false; + } +} + +bool tud_control_vendor_complete_cb(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + return true; +} diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 874f751a..d4952d11 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -334,11 +334,11 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request switch ( request->bRequest ) { case CDC_REQUEST_SET_LINE_CODING: - usbd_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); + tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); break; case CDC_REQUEST_GET_LINE_CODING: - usbd_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); + tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); break; case CDC_REQUEST_SET_CONTROL_LINE_STATE: @@ -349,7 +349,7 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request // This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send) p_cdc->line_state = (uint8_t) request->wValue; - usbd_control_status(rhport, request); + tud_control_status(rhport, request); // Invoke callback if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, tu_bit_test(request->wValue, 0), tu_bit_test(request->wValue, 1)); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 54ba3964..949fd183 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -205,7 +205,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { uint8_t const * desc_report = tud_hid_descriptor_report_cb(); - usbd_control_xfer(rhport, p_request, (void*) desc_report, p_hid->reprot_desc_len); + tud_control_xfer(rhport, p_request, (void*) desc_report, p_hid->reprot_desc_len); }else { return false; // stall unsupported request @@ -225,12 +225,12 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque uint16_t xferlen = tud_hid_get_report_cb(report_id, (hid_report_type_t) report_type, p_hid->epin_buf, p_request->wLength); TU_ASSERT( xferlen > 0 ); - usbd_control_xfer(rhport, p_request, p_hid->epin_buf, xferlen); + tud_control_xfer(rhport, p_request, p_hid->epin_buf, xferlen); } break; case HID_REQ_CONTROL_SET_REPORT: - usbd_control_xfer(rhport, p_request, p_hid->epout_buf, p_request->wLength); + tud_control_xfer(rhport, p_request, p_hid->epout_buf, p_request->wLength); break; case HID_REQ_CONTROL_SET_IDLE: @@ -241,18 +241,18 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque if ( !tud_hid_set_idle_cb(p_hid->idle_rate) ) return false; } - usbd_control_status(rhport, p_request); + tud_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); + tud_control_xfer(rhport, p_request, &p_hid->idle_rate, 1); break; case HID_REQ_CONTROL_GET_PROTOCOL: { uint8_t protocol = 1-p_hid->boot_mode; // 0 is Boot, 1 is Report protocol - usbd_control_xfer(rhport, p_request, &protocol, 1); + tud_control_xfer(rhport, p_request, &protocol, 1); } break; @@ -261,7 +261,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque if (tud_hid_boot_mode_cb) tud_hid_boot_mode_cb(p_hid->boot_mode); - usbd_control_status(rhport, p_request); + tud_control_status(rhport, p_request); break; default: return false; // stall unsupported request diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 86e47ead..ebc2af1d 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -154,7 +154,7 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque { case MSC_REQ_RESET: // TODO: Actually reset interface. - usbd_control_status(rhport, p_request); + tud_control_status(rhport, p_request); break; case MSC_REQ_GET_MAX_LUN: @@ -166,7 +166,7 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque // MAX LUN is minus 1 by specs maxlun--; - usbd_control_xfer(rhport, p_request, &maxlun, 1); + tud_control_xfer(rhport, p_request, &maxlun, 1); } break; diff --git a/src/device/usbd.c b/src/device/usbd.c index b9d9f9d8..6f2a7214 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -67,13 +67,13 @@ static usbd_device_t _usbd_dev = { 0 }; typedef struct { uint8_t class_code; - void (* init ) (void); - bool (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length); - bool (* control_request ) (uint8_t rhport, tusb_control_request_t const * request); + void (* init ) (void); + bool (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length); + bool (* control_request ) (uint8_t rhport, tusb_control_request_t const * request); bool (* control_complete ) (uint8_t rhport, tusb_control_request_t const * request); - bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t, uint32_t); - void (* sof ) (uint8_t rhport); - void (* reset ) (uint8_t); + bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t, uint32_t); + void (* sof ) (uint8_t rhport); + void (* reset ) (uint8_t); } usbd_class_driver_t; static usbd_class_driver_t const usbd_class_drivers[] = @@ -237,7 +237,6 @@ static void usbd_reset(uint8_t rhport) while(1) // the mainloop { application_code(); - tud_task(); // tinyusb device task } } @@ -348,10 +347,13 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const usbd_control_set_complete_callback(NULL); // Vendor request -// if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) -// { -// -// } + if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) + { + TU_VERIFY(tud_control_vendor_request_cb); + + if (tud_control_vendor_complete_cb) usbd_control_set_complete_callback(tud_control_vendor_complete_cb); + return tud_control_vendor_request_cb(rhport, p_request); + } switch ( p_request->bmRequestType_bit.recipient ) { @@ -376,7 +378,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const case TUSB_REQ_GET_CONFIGURATION: { uint8_t cfgnum = _usbd_dev.configured ? 1 : 0; - usbd_control_xfer(rhport, p_request, &cfgnum, 1); + tud_control_xfer(rhport, p_request, &cfgnum, 1); } break; @@ -388,7 +390,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.configured = cfg_num ? 1 : 0; if ( cfg_num ) TU_ASSERT( process_set_config(rhport, cfg_num) ); - usbd_control_status(rhport, p_request); + tud_control_status(rhport, p_request); } break; @@ -402,7 +404,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Host may enable remote wake up before suspending especially HID device _usbd_dev.remote_wakeup_en = true; - usbd_control_status(rhport, p_request); + tud_control_status(rhport, p_request); break; case TUSB_REQ_CLEAR_FEATURE: @@ -411,7 +413,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Host may disable remote wake up after resuming _usbd_dev.remote_wakeup_en = false; - usbd_control_status(rhport, p_request); + tud_control_status(rhport, p_request); break; case TUSB_REQ_GET_STATUS: @@ -420,7 +422,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // - Bit 0: Self Powered // - Bit 1: Remote Wakeup enabled uint16_t status = (_usbd_dev.self_powered ? 1 : 0) | (_usbd_dev.remote_wakeup_en ? 2 : 0); - usbd_control_xfer(rhport, p_request, &status, 2); + tud_control_xfer(rhport, p_request, &status, 2); } break; @@ -437,7 +439,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const TU_VERIFY(drvid < USBD_CLASS_DRIVER_COUNT); - usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete ); + usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); // stall control endpoint if driver return false return usbd_class_drivers[drvid].control_request(rhport, p_request); @@ -454,7 +456,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const case TUSB_REQ_GET_STATUS: { uint16_t status = usbd_edpt_stalled(rhport, tu_u16_low(p_request->wIndex)) ? 0x0001 : 0x0000; - usbd_control_xfer(rhport, p_request, &status, 2); + tud_control_xfer(rhport, p_request, &status, 2); } break; @@ -463,7 +465,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const { usbd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex)); } - usbd_control_status(rhport, p_request); + tud_control_status(rhport, p_request); break; case TUSB_REQ_SET_FEATURE: @@ -471,7 +473,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const { usbd_edpt_stall(rhport, tu_u16_low(p_request->wIndex)); } - usbd_control_status(rhport, p_request); + tud_control_status(rhport, p_request); break; // Unknown/Unsupported request @@ -569,7 +571,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const switch(desc_type) { case TUSB_DESC_DEVICE: - return usbd_control_xfer(rhport, p_request, (void*) tud_descriptor_device_cb(), sizeof(tusb_desc_device_t)); + return tud_control_xfer(rhport, p_request, (void*) tud_descriptor_device_cb(), sizeof(tusb_desc_device_t)); break; case TUSB_DESC_BOS: @@ -581,7 +583,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const uint16_t total_len; memcpy(&total_len, &desc_bos->wTotalLength, 2); // possibly mis-aligned memory - return usbd_control_xfer(rhport, p_request, (void*) desc_bos, total_len); + return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len); } break; @@ -591,7 +593,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const uint16_t total_len; memcpy(&total_len, &desc_config->wTotalLength, 2); // possibly mis-aligned memory - return usbd_control_xfer(rhport, p_request, (void*) desc_config, total_len); + return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len); } break; @@ -608,7 +610,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const TU_ASSERT(desc_str); // first byte of descriptor is its size - return usbd_control_xfer(rhport, p_request, (void*) desc_str, desc_str[0]); + return tud_control_xfer(rhport, p_request, (void*) desc_str, desc_str[0]); } break; diff --git a/src/device/usbd.h b/src/device/usbd.h index 943b1c79..a77110bd 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -59,6 +59,14 @@ static inline bool tud_ready(void) // Remote wake up host, only if suspended and enabled by host bool tud_remote_wakeup(void); +// Carry out Data and Status stage of control transfer +// - If len = 0, it is equivalent to sending status only +// - If len > wLength : it will be truncated +bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len); + +// Send STATUS (zero length) packet +bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request); + //--------------------------------------------------------------------+ // Application Callbacks (WEAK is optional) //--------------------------------------------------------------------+ @@ -92,6 +100,10 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed TU_ATTR_WEAK void tud_resume_cb(void); +// Invoked when received control request with VENDOR TYPE +TU_ATTR_WEAK bool tud_control_vendor_request_cb(uint8_t rhport, tusb_control_request_t const * request); +TU_ATTR_WEAK bool tud_control_vendor_complete_cb(uint8_t rhport, tusb_control_request_t const * request); + //--------------------------------------------------------------------+ // Descriptor Templates //--------------------------------------------------------------------+ diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 49293b83..f4b9d621 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -59,7 +59,7 @@ void usbd_control_reset (uint8_t rhport) tu_varclr(&_control_state); } -bool usbd_control_status(uint8_t rhport, tusb_control_request_t const * request) +bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) { // status direction is reversed to one in the setup packet return dcd_edpt_xfer(rhport, request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN, NULL, 0); @@ -87,7 +87,7 @@ void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_reque _control_state.complete_cb = fp; } -bool usbd_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) +bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) { _control_state.request = (*request); _control_state.buffer = buffer; @@ -103,7 +103,7 @@ bool usbd_control_xfer(uint8_t rhport, tusb_control_request_t const * request, v }else { // Status stage - TU_ASSERT( usbd_control_status(rhport, request) ); + TU_ASSERT( tud_control_status(rhport, request) ); } return true; @@ -139,7 +139,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result if ( is_ok ) { // Send status - TU_ASSERT( usbd_control_status(rhport, &_control_state.request) ); + TU_ASSERT( tud_control_status(rhport, &_control_state.request) ); }else { // Stall both IN and OUT control endpoint diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 706857d4..06f7a3af 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -39,14 +39,6 @@ bool usbd_init (void); // USBD Endpoint API //--------------------------------------------------------------------+ -// Carry out Data and Status stage of control transfer -// - If len = 0, it is equivalent to sending status only -// - If len > wLength : it will be truncated -bool usbd_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len); - -// Send STATUS (zero length) packet -bool usbd_control_status(uint8_t rhport, tusb_control_request_t const * request); - // Submit a usb transfer bool usbd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);