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
This commit is contained in:
hathach 2019-07-16 18:14:47 +07:00
parent cb4e6837e9
commit 036e858543
9 changed files with 92 additions and 54 deletions

View File

@ -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
//--------------------------------------------------------------------+

View File

@ -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;
}

View File

@ -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));

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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
//--------------------------------------------------------------------+

View File

@ -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

View File

@ -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);