Merge pull request #2412 from hathach/change-weak-event-hook-style

change tuh_event_hook_cb, tud_event_hook_cb to weak default implementation
This commit is contained in:
Ha Thach 2024-01-12 16:22:09 +07:00 committed by GitHub
commit 39f397e25c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 284 additions and 318 deletions

View File

@ -38,11 +38,19 @@
//--------------------------------------------------------------------+
// USBD Configuration
//--------------------------------------------------------------------+
#ifndef CFG_TUD_TASK_QUEUE_SZ
#define CFG_TUD_TASK_QUEUE_SZ 16
#endif
//--------------------------------------------------------------------+
// Callback weak stubs (called if application does not provide)
//--------------------------------------------------------------------+
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
(void)rhport;
(void)eventid;
(void)in_isr;
}
//--------------------------------------------------------------------+
// Device Data
//--------------------------------------------------------------------+
@ -50,10 +58,8 @@
// Invalid driver ID in itf2drv[] ep2drv[][] mapping
enum { DRVID_INVALID = 0xFFu };
typedef struct
{
struct TU_ATTR_PACKED
{
typedef struct {
struct TU_ATTR_PACKED {
volatile uint8_t connected : 1;
volatile uint8_t addressed : 1;
volatile uint8_t suspended : 1;
@ -85,151 +91,150 @@ tu_static usbd_device_t _usbd_dev;
#endif
// Built-in class drivers
tu_static usbd_class_driver_t const _usbd_driver[] =
{
#if CFG_TUD_CDC
{
DRIVER_NAME("CDC")
.init = cdcd_init,
.reset = cdcd_reset,
.open = cdcd_open,
.control_xfer_cb = cdcd_control_xfer_cb,
.xfer_cb = cdcd_xfer_cb,
.sof = NULL
},
#endif
tu_static usbd_class_driver_t const _usbd_driver[] = {
#if CFG_TUD_CDC
{
DRIVER_NAME("CDC")
.init = cdcd_init,
.reset = cdcd_reset,
.open = cdcd_open,
.control_xfer_cb = cdcd_control_xfer_cb,
.xfer_cb = cdcd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_MSC
{
DRIVER_NAME("MSC")
.init = mscd_init,
.reset = mscd_reset,
.open = mscd_open,
.control_xfer_cb = mscd_control_xfer_cb,
.xfer_cb = mscd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_MSC
{
DRIVER_NAME("MSC")
.init = mscd_init,
.reset = mscd_reset,
.open = mscd_open,
.control_xfer_cb = mscd_control_xfer_cb,
.xfer_cb = mscd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_HID
{
DRIVER_NAME("HID")
.init = hidd_init,
.reset = hidd_reset,
.open = hidd_open,
.control_xfer_cb = hidd_control_xfer_cb,
.xfer_cb = hidd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_HID
{
DRIVER_NAME("HID")
.init = hidd_init,
.reset = hidd_reset,
.open = hidd_open,
.control_xfer_cb = hidd_control_xfer_cb,
.xfer_cb = hidd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_AUDIO
{
DRIVER_NAME("AUDIO")
.init = audiod_init,
.reset = audiod_reset,
.open = audiod_open,
.control_xfer_cb = audiod_control_xfer_cb,
.xfer_cb = audiod_xfer_cb,
.sof = audiod_sof_isr
},
#endif
#if CFG_TUD_AUDIO
{
DRIVER_NAME("AUDIO")
.init = audiod_init,
.reset = audiod_reset,
.open = audiod_open,
.control_xfer_cb = audiod_control_xfer_cb,
.xfer_cb = audiod_xfer_cb,
.sof = audiod_sof_isr
},
#endif
#if CFG_TUD_VIDEO
{
DRIVER_NAME("VIDEO")
.init = videod_init,
.reset = videod_reset,
.open = videod_open,
.control_xfer_cb = videod_control_xfer_cb,
.xfer_cb = videod_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_VIDEO
{
DRIVER_NAME("VIDEO")
.init = videod_init,
.reset = videod_reset,
.open = videod_open,
.control_xfer_cb = videod_control_xfer_cb,
.xfer_cb = videod_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_MIDI
{
DRIVER_NAME("MIDI")
.init = midid_init,
.open = midid_open,
.reset = midid_reset,
.control_xfer_cb = midid_control_xfer_cb,
.xfer_cb = midid_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_MIDI
{
DRIVER_NAME("MIDI")
.init = midid_init,
.open = midid_open,
.reset = midid_reset,
.control_xfer_cb = midid_control_xfer_cb,
.xfer_cb = midid_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_VENDOR
{
DRIVER_NAME("VENDOR")
.init = vendord_init,
.reset = vendord_reset,
.open = vendord_open,
.control_xfer_cb = tud_vendor_control_xfer_cb,
.xfer_cb = vendord_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_VENDOR
{
DRIVER_NAME("VENDOR")
.init = vendord_init,
.reset = vendord_reset,
.open = vendord_open,
.control_xfer_cb = tud_vendor_control_xfer_cb,
.xfer_cb = vendord_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_USBTMC
{
DRIVER_NAME("TMC")
.init = usbtmcd_init_cb,
.reset = usbtmcd_reset_cb,
.open = usbtmcd_open_cb,
.control_xfer_cb = usbtmcd_control_xfer_cb,
.xfer_cb = usbtmcd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_USBTMC
{
DRIVER_NAME("TMC")
.init = usbtmcd_init_cb,
.reset = usbtmcd_reset_cb,
.open = usbtmcd_open_cb,
.control_xfer_cb = usbtmcd_control_xfer_cb,
.xfer_cb = usbtmcd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_DFU_RUNTIME
{
DRIVER_NAME("DFU-RUNTIME")
.init = dfu_rtd_init,
.reset = dfu_rtd_reset,
.open = dfu_rtd_open,
.control_xfer_cb = dfu_rtd_control_xfer_cb,
.xfer_cb = NULL,
.sof = NULL
},
#endif
#if CFG_TUD_DFU_RUNTIME
{
DRIVER_NAME("DFU-RUNTIME")
.init = dfu_rtd_init,
.reset = dfu_rtd_reset,
.open = dfu_rtd_open,
.control_xfer_cb = dfu_rtd_control_xfer_cb,
.xfer_cb = NULL,
.sof = NULL
},
#endif
#if CFG_TUD_DFU
{
DRIVER_NAME("DFU")
.init = dfu_moded_init,
.reset = dfu_moded_reset,
.open = dfu_moded_open,
.control_xfer_cb = dfu_moded_control_xfer_cb,
.xfer_cb = NULL,
.sof = NULL
},
#endif
#if CFG_TUD_DFU
{
DRIVER_NAME("DFU")
.init = dfu_moded_init,
.reset = dfu_moded_reset,
.open = dfu_moded_open,
.control_xfer_cb = dfu_moded_control_xfer_cb,
.xfer_cb = NULL,
.sof = NULL
},
#endif
#if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
{
DRIVER_NAME("NET")
.init = netd_init,
.reset = netd_reset,
.open = netd_open,
.control_xfer_cb = netd_control_xfer_cb,
.xfer_cb = netd_xfer_cb,
.sof = NULL,
},
#endif
#if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
{
DRIVER_NAME("NET")
.init = netd_init,
.reset = netd_reset,
.open = netd_open,
.control_xfer_cb = netd_control_xfer_cb,
.xfer_cb = netd_xfer_cb,
.sof = NULL,
},
#endif
#if CFG_TUD_BTH
{
DRIVER_NAME("BTH")
.init = btd_init,
.reset = btd_reset,
.open = btd_open,
.control_xfer_cb = btd_control_xfer_cb,
.xfer_cb = btd_xfer_cb,
.sof = NULL
},
#endif
#if CFG_TUD_BTH
{
DRIVER_NAME("BTH")
.init = btd_init,
.reset = btd_reset,
.open = btd_open,
.control_xfer_cb = btd_control_xfer_cb,
.xfer_cb = btd_xfer_cb,
.sof = NULL
},
#endif
};
enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
@ -275,7 +280,7 @@ tu_static osal_queue_t _usbd_q;
TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) {
bool ret = osal_queue_send(_usbd_q, event, in_isr);
if (tud_event_hook_cb) tud_event_hook_cb(event->rhport, event->event_id, in_isr);
tud_event_hook_cb(event->rhport, event->event_id, in_isr);
return ret;
}
@ -297,27 +302,23 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
// Debug
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
{
"Invalid" ,
"Bus Reset" ,
"Unplugged" ,
"SOF" ,
"Suspend" ,
"Resume" ,
"Setup Received" ,
"Xfer Complete" ,
"Func Call"
tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = {
"Invalid",
"Bus Reset",
"Unplugged",
"SOF",
"Suspend",
"Resume",
"Setup Received",
"Xfer Complete",
"Func Call"
};
// for usbd_control to print the name of control complete driver
void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
{
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++)
{
usbd_class_driver_t const * driver = get_driver(i);
if ( driver && driver->control_xfer_cb == callback )
{
void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) {
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
usbd_class_driver_t const* driver = get_driver(i);
if (driver && driver->control_xfer_cb == callback) {
TU_LOG_USBD(" %s control complete\r\n", driver->name);
return;
}
@ -329,43 +330,36 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
tusb_speed_t tud_speed_get(void)
{
tusb_speed_t tud_speed_get(void) {
return (tusb_speed_t) _usbd_dev.speed;
}
bool tud_connected(void)
{
bool tud_connected(void) {
return _usbd_dev.connected;
}
bool tud_mounted(void)
{
bool tud_mounted(void) {
return _usbd_dev.cfg_num ? true : false;
}
bool tud_suspended(void)
{
bool tud_suspended(void) {
return _usbd_dev.suspended;
}
bool tud_remote_wakeup(void)
{
bool tud_remote_wakeup(void) {
// only wake up host if this feature is supported and enabled and we are suspended
TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en );
TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en);
dcd_remote_wakeup(_usbd_rhport);
return true;
}
bool tud_disconnect(void)
{
bool tud_disconnect(void) {
TU_VERIFY(dcd_disconnect);
dcd_disconnect(_usbd_rhport);
return true;
}
bool tud_connect(void)
{
bool tud_connect(void) {
TU_VERIFY(dcd_connect);
dcd_connect(_usbd_rhport);
return true;

View File

@ -147,7 +147,7 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en);
TU_ATTR_WEAK void tud_resume_cb(void);
// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext()
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
// Invoked when received control request with VENDOR TYPE
TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -32,24 +32,32 @@
#include "tusb.h"
#include "device/usbd_pvt.h"
//--------------------------------------------------------------------+
// Callback weak stubs (called if application does not provide)
//--------------------------------------------------------------------+
TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) {
(void) rhport;
(void) request;
}
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
#endif
enum
{
enum {
EDPT_CTRL_OUT = 0x00,
EDPT_CTRL_IN = 0x80
EDPT_CTRL_IN = 0x80
};
typedef struct
{
typedef struct {
tusb_control_request_t request;
uint8_t* buffer;
uint16_t data_len;
uint16_t total_xferred;
usbd_control_xfer_cb_t complete_cb;
} usbd_control_xfer_t;
@ -63,20 +71,18 @@ tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
//--------------------------------------------------------------------+
// Queue ZLP status transaction
static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const * request)
{
static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) {
// Opposite to endpoint in Data Phase
uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN;
return usbd_edpt_xfer(rhport, ep_addr, NULL, 0);
}
// Status phase
bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request)
{
_ctrl_xfer.request = (*request);
_ctrl_xfer.buffer = NULL;
bool tud_control_status(uint8_t rhport, tusb_control_request_t const* request) {
_ctrl_xfer.request = (*request);
_ctrl_xfer.buffer = NULL;
_ctrl_xfer.total_xferred = 0;
_ctrl_xfer.data_len = 0;
_ctrl_xfer.data_len = 0;
return _status_stage_xact(rhport, request);
}
@ -84,16 +90,15 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request)
// Queue a transaction in Data Stage
// Each transaction has up to Endpoint0's max packet size.
// This function can also transfer an zero-length packet
static bool _data_stage_xact(uint8_t rhport)
{
uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE);
static bool _data_stage_xact(uint8_t rhport) {
uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred,
CFG_TUD_ENDPOINT0_SIZE);
uint8_t ep_addr = EDPT_CTRL_OUT;
if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN )
{
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) {
ep_addr = EDPT_CTRL_IN;
if ( xact_len ) {
if (xact_len) {
TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len));
}
}
@ -103,29 +108,24 @@ static bool _data_stage_xact(uint8_t rhport)
// Transmit data to/from the control endpoint.
// If the request's wLength is zero, a status packet is sent instead.
bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len)
{
_ctrl_xfer.request = (*request);
_ctrl_xfer.buffer = (uint8_t*) buffer;
bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, void* buffer, uint16_t len) {
_ctrl_xfer.request = (*request);
_ctrl_xfer.buffer = (uint8_t*) buffer;
_ctrl_xfer.total_xferred = 0U;
_ctrl_xfer.data_len = tu_min16(len, request->wLength);
_ctrl_xfer.data_len = tu_min16(len, request->wLength);
if (request->wLength > 0U)
{
if(_ctrl_xfer.data_len > 0U)
{
if (request->wLength > 0U) {
if (_ctrl_xfer.data_len > 0U) {
TU_ASSERT(buffer);
}
// TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len);
// Data stage
TU_ASSERT( _data_stage_xact(rhport) );
}
else
{
TU_ASSERT(_data_stage_xact(rhport));
} else {
// Status stage
TU_ASSERT( _status_stage_xact(rhport, request) );
TU_ASSERT(_status_stage_xact(rhport, request));
}
return true;
@ -134,58 +134,42 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo
//--------------------------------------------------------------------+
// USBD API
//--------------------------------------------------------------------+
TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request)
{
(void)rhport;
(void)request;
// this is the default implementation that is called when no "real" implementation
// of the function exists
}
void usbd_control_reset(void);
void usbd_control_set_request(tusb_control_request_t const *request);
void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp );
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void usbd_control_set_request(tusb_control_request_t const* request);
void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp);
bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void usbd_control_reset(void)
{
void usbd_control_reset(void) {
tu_varclr(&_ctrl_xfer);
}
// Set complete callback
void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp )
{
void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp) {
_ctrl_xfer.complete_cb = fp;
}
// for dcd_set_address where DCD is responsible for status response
void usbd_control_set_request(tusb_control_request_t const *request)
{
_ctrl_xfer.request = (*request);
_ctrl_xfer.buffer = NULL;
void usbd_control_set_request(tusb_control_request_t const* request) {
_ctrl_xfer.request = (*request);
_ctrl_xfer.buffer = NULL;
_ctrl_xfer.total_xferred = 0;
_ctrl_xfer.data_len = 0;
_ctrl_xfer.data_len = 0;
}
// callback when a transaction complete on
// - DATA stage of control endpoint or
// - Status stage
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{
bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
(void) result;
// Endpoint Address is opposite to direction bit, this is Status Stage complete event
if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction )
{
if (tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction) {
TU_ASSERT(0 == xferred_bytes);
// invoke optional dcd hook if available
dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request);
if (_ctrl_xfer.complete_cb)
{
if (_ctrl_xfer.complete_cb) {
// TODO refactor with usbd_driver_print_control_complete_name
_ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request);
}
@ -193,8 +177,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
return true;
}
if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT )
{
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) {
TU_VERIFY(_ctrl_xfer.buffer);
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
@ -205,15 +188,14 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
// Data Stage is complete when all request's length are transferred or
// a short packet is sent including zero-length packet.
if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || (xferred_bytes < CFG_TUD_ENDPOINT0_SIZE) )
{
if ((_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) ||
(xferred_bytes < CFG_TUD_ENDPOINT0_SIZE)) {
// DATA stage is complete
bool is_ok = true;
// invoke complete callback if set
// callback can still stall control in status phase e.g out data does not make sense
if ( _ctrl_xfer.complete_cb )
{
if (_ctrl_xfer.complete_cb) {
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb);
#endif
@ -221,21 +203,17 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request);
}
if ( is_ok )
{
if (is_ok) {
// Send status
TU_ASSERT( _status_stage_xact(rhport, &_ctrl_xfer.request) );
}else
{
TU_ASSERT(_status_stage_xact(rhport, &_ctrl_xfer.request));
} else {
// Stall both IN and OUT control endpoint
dcd_edpt_stall(rhport, EDPT_CTRL_OUT);
dcd_edpt_stall(rhport, EDPT_CTRL_IN);
}
}
else
{
} else {
// More data to transfer
TU_ASSERT( _data_stage_xact(rhport) );
TU_ASSERT(_data_stage_xact(rhport));
}
return true;

View File

@ -36,7 +36,6 @@
//--------------------------------------------------------------------+
// USBH Configuration
//--------------------------------------------------------------------+
#ifndef CFG_TUH_TASK_QUEUE_SZ
#define CFG_TUH_TASK_QUEUE_SZ 16
#endif
@ -45,12 +44,19 @@
#define CFG_TUH_INTERFACE_MAX 8
#endif
//--------------------------------------------------------------------+
// Callback weak stubs (called if application does not provide)
//--------------------------------------------------------------------+
TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
(void) rhport;
(void) eventid;
(void) in_isr;
}
//--------------------------------------------------------------------+
// USBH-HCD common data structure
//--------------------------------------------------------------------+
typedef struct
{
typedef struct {
// port
uint8_t rhport;
uint8_t hub_addr;
@ -112,60 +118,58 @@ typedef struct {
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
#define DRIVER_NAME(_name) .name = _name,
#else
#define DRIVER_NAME(_name)
#endif
static usbh_class_driver_t const usbh_class_drivers[] =
{
#if CFG_TUH_CDC
static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_CDC
{
DRIVER_NAME("CDC")
.init = cdch_init,
.open = cdch_open,
.set_config = cdch_set_config,
.xfer_cb = cdch_xfer_cb,
.close = cdch_close
DRIVER_NAME("CDC")
.init = cdch_init,
.open = cdch_open,
.set_config = cdch_set_config,
.xfer_cb = cdch_xfer_cb,
.close = cdch_close
},
#endif
#endif
#if CFG_TUH_MSC
#if CFG_TUH_MSC
{
DRIVER_NAME("MSC")
.init = msch_init,
.open = msch_open,
.set_config = msch_set_config,
.xfer_cb = msch_xfer_cb,
.close = msch_close
DRIVER_NAME("MSC")
.init = msch_init,
.open = msch_open,
.set_config = msch_set_config,
.xfer_cb = msch_xfer_cb,
.close = msch_close
},
#endif
#endif
#if CFG_TUH_HID
#if CFG_TUH_HID
{
DRIVER_NAME("HID")
.init = hidh_init,
.open = hidh_open,
.set_config = hidh_set_config,
.xfer_cb = hidh_xfer_cb,
.close = hidh_close
DRIVER_NAME("HID")
.init = hidh_init,
.open = hidh_open,
.set_config = hidh_set_config,
.xfer_cb = hidh_xfer_cb,
.close = hidh_close
},
#endif
#endif
#if CFG_TUH_HUB
#if CFG_TUH_HUB
{
DRIVER_NAME("HUB")
.init = hub_init,
.open = hub_open,
.set_config = hub_set_config,
.xfer_cb = hub_xfer_cb,
.close = hub_close
DRIVER_NAME("HUB")
.init = hub_init,
.open = hub_open,
.set_config = hub_set_config,
.xfer_cb = hub_xfer_cb,
.close = hub_close
},
#endif
#endif
#if CFG_TUH_VENDOR
#if CFG_TUH_VENDOR
{
DRIVER_NAME("VENDOR")
.init = cush_init,
@ -173,7 +177,7 @@ static usbh_class_driver_t const usbh_class_drivers[] =
.xfer_cb = cush_isr,
.close = cush_close
}
#endif
#endif
};
enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) };
@ -233,8 +237,7 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE];
// Control transfers: since most controllers do not support multiple control transfers
// on multiple devices concurrently and control transfers are not used much except for
// enumeration, we will only execute control transfers one at a time.
CFG_TUH_MEM_SECTION struct
{
CFG_TUH_MEM_SECTION struct {
CFG_TUH_MEM_ALIGN tusb_control_request_t request;
uint8_t* buffer;
tuh_xfer_cb_t complete_cb;
@ -268,7 +271,7 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) {
TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) {
bool ret = osal_queue_send(_usbh_q, event, in_isr);
if (tuh_event_hook_cb) tuh_event_hook_cb(event->rhport, event->event_id, in_isr);
tuh_event_hook_cb(event->rhport, event->event_id, in_isr);
return ret;
}
@ -367,17 +370,14 @@ bool tuh_init(uint8_t controller_id) {
tu_memclr(_usbh_devices, sizeof(_usbh_devices));
tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer));
for(uint8_t i=0; i<TOTAL_DEVICES; i++)
{
for(uint8_t i=0; i<TOTAL_DEVICES; i++) {
clear_device(&_usbh_devices[i]);
}
// Class drivers
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++)
{
usbh_class_driver_t const * driver = get_driver(drv_id);
if ( driver )
{
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
usbh_class_driver_t const* driver = get_driver(drv_id);
if (driver) {
TU_LOG_USBH("%s init\r\n", driver->name);
driver->init();
}
@ -545,8 +545,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
// Control transfer
//--------------------------------------------------------------------+
static void _control_blocking_complete_cb(tuh_xfer_t* xfer)
{
static void _control_blocking_complete_cb(tuh_xfer_t* xfer) {
// update result
*((xfer_result_t*) xfer->user_data) = xfer->result;
}
@ -625,21 +624,18 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
return true;
}
TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage)
{
TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) {
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
_ctrl_xfer.stage = stage;
(void) osal_mutex_unlock(_usbh_mutex);
}
static void _xfer_complete(uint8_t daddr, xfer_result_t result)
{
static void _xfer_complete(uint8_t daddr, xfer_result_t result) {
TU_LOG_USBH("\r\n");
// duplicate xfer since user can execute control transfer within callback
tusb_control_request_t const request = _ctrl_xfer.request;
tuh_xfer_t xfer_temp =
{
tuh_xfer_t xfer_temp = {
.daddr = daddr,
.ep_addr = 0,
.result = result,
@ -652,8 +648,7 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result)
_set_control_xfer_stage(CONTROL_STAGE_IDLE);
if (xfer_temp.complete_cb)
{
if (xfer_temp.complete_cb) {
xfer_temp.complete_cb(&xfer_temp);
}
}
@ -710,17 +705,16 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
//
//--------------------------------------------------------------------+
bool tuh_edpt_xfer(tuh_xfer_t* xfer)
{
uint8_t const daddr = xfer->daddr;
bool tuh_edpt_xfer(tuh_xfer_t* xfer) {
uint8_t const daddr = xfer->daddr;
uint8_t const ep_addr = xfer->ep_addr;
TU_VERIFY(daddr && ep_addr);
TU_VERIFY(usbh_edpt_claim(daddr, ep_addr));
if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data) )
{
if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen,
xfer->complete_cb, xfer->user_data)) {
usbh_edpt_release(daddr, ep_addr);
return false;
}

View File

@ -94,7 +94,7 @@ TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr);
TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr);
// Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext()
TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
//--------------------------------------------------------------------+
// APPLICATION API