change tusb_init(), tusb_rhport_init() to use init struct for expandability
This commit is contained in:
@@ -79,7 +79,7 @@
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Optional API implemented by application if needed
|
||||
// TODO move to a more ovious place/file
|
||||
// TODO move to a more obvious place/file
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// flush data cache
|
||||
|
||||
@@ -118,6 +118,14 @@
|
||||
#define _TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s _TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7)
|
||||
#define _TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s _TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Macro for function default arguments
|
||||
//--------------------------------------------------------------------+
|
||||
#define TU_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
|
||||
|
||||
// function expand with number of arguments
|
||||
#define TU_FUNC_OPTIONAL_ARG(func, ...) TU_XSTRCAT(func##_arg, TU_ARGS_NUM(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Compiler porting with Attribute and Endian
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -50,6 +50,7 @@ typedef enum {
|
||||
TUSB_SPEED_FULL = 0,
|
||||
TUSB_SPEED_LOW = 1,
|
||||
TUSB_SPEED_HIGH = 2,
|
||||
TUSB_SPEED_AUTO = 0xaa,
|
||||
TUSB_SPEED_INVALID = 0xff,
|
||||
} tusb_speed_t;
|
||||
|
||||
@@ -273,6 +274,15 @@ enum {
|
||||
TUSB_INDEX_INVALID_8 = 0xFFu
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
typedef struct {
|
||||
uint8_t rhport;
|
||||
tusb_role_t role;
|
||||
tusb_speed_t speed;
|
||||
} tusb_rhport_init_t;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -93,9 +93,6 @@
|
||||
#define TU_BREAKPOINT() do {} while (0)
|
||||
#endif
|
||||
|
||||
// Helper to implement optional parameter for TU_VERIFY Macro family
|
||||
#define TU_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* TU_VERIFY
|
||||
* - TU_VERIFY_1ARGS : return false if failed
|
||||
|
||||
@@ -448,11 +448,14 @@ bool tud_inited(void) {
|
||||
return _usbd_rhport != RHPORT_INVALID;
|
||||
}
|
||||
|
||||
bool tud_init(uint8_t rhport) {
|
||||
// skip if already initialized
|
||||
if (tud_inited()) return true;
|
||||
bool tud_rhport_init(const tusb_rhport_init_t* rh_init) {
|
||||
if (tud_inited()) {
|
||||
return true; // skip if already initialized
|
||||
}
|
||||
TU_ASSERT(rh_init);
|
||||
|
||||
TU_LOG_USBD("USBD init on controller %u, Highspeed = %u\r\n", rhport, TUD_OPT_HIGH_SPEED);
|
||||
TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rh_init->rhport,
|
||||
rh_init->speed == TUSB_SPEED_HIGH ? "High" : "Full");
|
||||
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t));
|
||||
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t));
|
||||
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t));
|
||||
@@ -484,11 +487,11 @@ bool tud_init(uint8_t rhport) {
|
||||
driver->init();
|
||||
}
|
||||
|
||||
_usbd_rhport = rhport;
|
||||
_usbd_rhport = rh_init->rhport;
|
||||
|
||||
// Init device controller driver
|
||||
dcd_init(rhport);
|
||||
dcd_int_enable(rhport);
|
||||
dcd_init(rh_init->rhport);
|
||||
dcd_int_enable(rh_init->rhport);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,8 +37,21 @@ extern "C" {
|
||||
// Application API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// New API to replace tud_init() to init device stack on specific roothub port
|
||||
bool tud_rhport_init(const tusb_rhport_init_t* rh_init);
|
||||
|
||||
// Init device stack on roothub port
|
||||
bool tud_init (uint8_t rhport);
|
||||
#if TUSB_VERSION_NUMBER > 2000 // 0.20.0
|
||||
TU_ATTR_DEPRECATED("Please use tusb_init(tusb_rhport_init_t*) instead")
|
||||
#endif
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool tud_init (uint8_t rhport) {
|
||||
const tusb_rhport_init_t rh_init = {
|
||||
.rhport = rhport,
|
||||
.role = TUSB_ROLE_DEVICE,
|
||||
.speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL
|
||||
};
|
||||
return tud_rhport_init(&rh_init);
|
||||
}
|
||||
|
||||
// Deinit device stack on roothub port
|
||||
bool tud_deinit(uint8_t rhport);
|
||||
|
||||
@@ -352,11 +352,13 @@ bool tuh_inited(void) {
|
||||
return _usbh_controller != TUSB_INDEX_INVALID_8;
|
||||
}
|
||||
|
||||
bool tuh_init(uint8_t rhport) {
|
||||
// skip if already initialized
|
||||
if (tuh_rhport_is_active(rhport)) return true;
|
||||
bool tuh_rhport_init(const tusb_rhport_init_t* rh_init) {
|
||||
if (tuh_rhport_is_active(rh_init->rhport)) {
|
||||
return true; // skip if already initialized
|
||||
}
|
||||
|
||||
TU_LOG_USBH("USBH init on controller %u\r\n", rhport);
|
||||
TU_LOG_USBH("USBH init on controller %u, speed = %s\r\n", rhport,
|
||||
rh_init->speed == TUSB_SPEED_HIGH ? "High" : "Full");
|
||||
|
||||
// Init host stack if not already
|
||||
if (!tuh_inited()) {
|
||||
@@ -402,9 +404,9 @@ bool tuh_init(uint8_t rhport) {
|
||||
}
|
||||
|
||||
// Init host controller
|
||||
_usbh_controller = rhport;;
|
||||
TU_ASSERT(hcd_init(rhport));
|
||||
hcd_int_enable(rhport);
|
||||
_usbh_controller = rh_init->rhport;
|
||||
TU_ASSERT(hcd_init(rh_init->rhport));
|
||||
hcd_int_enable(rh_init->rhport);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,8 +120,21 @@ void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
|
||||
// - cfg_param: configure data, structure depends on the ID
|
||||
bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);
|
||||
|
||||
// New API to replace tuh_init() to init host stack on specific roothub port
|
||||
bool tuh_rhport_init(const tusb_rhport_init_t* rh_init);
|
||||
|
||||
// Init host stack
|
||||
bool tuh_init(uint8_t rhport);
|
||||
#if TUSB_VERSION_NUMBER > 2000 // 0.20.0
|
||||
TU_ATTR_DEPRECATED("Please use tusb_init(tusb_rhport_init_t*) instead")
|
||||
#endif
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool tuh_init(uint8_t rhport) {
|
||||
const tusb_rhport_init_t rh_init = {
|
||||
.rhport = rhport,
|
||||
.role = TUSB_ROLE_HOST,
|
||||
.speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL,
|
||||
};
|
||||
return tuh_rhport_init(&rh_init);
|
||||
}
|
||||
|
||||
// Deinit host stack on rhport
|
||||
bool tuh_deinit(uint8_t rhport);
|
||||
@@ -149,9 +162,10 @@ extern void hcd_int_handler(uint8_t rhport, bool in_isr);
|
||||
#endif
|
||||
|
||||
// Interrupt handler alias to HCD with in_isr as optional parameter
|
||||
#define _tuh_int_handler_1arg(_rhport) hcd_int_handler(_rhport, true)
|
||||
#define _tuh_int_hanlder_2arg(_rhport, _in_isr) hcd_int_handler(_rhport, _in_isr)
|
||||
#define tuh_int_handler(...) TU_GET_3RD_ARG(__VA_ARGS__, _tuh_int_hanlder_2arg, _tuh_int_handler_1arg, _dummy)(__VA_ARGS__)
|
||||
#define _tuh_int_handler_arg0() TU_VERIFY_STATIC(false, "tuh_int_handler() must have 1 or 2 arguments")
|
||||
#define _tuh_int_handler_arg1(_rhport) hcd_int_handler(_rhport, true)
|
||||
#define _tuh_int_handler_arg2(_rhport, _in_isr) hcd_int_handler(_rhport, _in_isr)
|
||||
#define tuh_int_handler(...) TU_FUNC_OPTIONAL_ARG(_tuh_int_handler, __VA_ARGS__)
|
||||
|
||||
// Check if roothub port is initialized and active as a host
|
||||
bool tuh_rhport_is_active(uint8_t rhport);
|
||||
|
||||
34
src/tusb.c
34
src/tusb.c
@@ -47,19 +47,29 @@ static tusb_role_t _rhport_role[TUP_USBIP_CONTROLLER_NUM] = { 0 };
|
||||
// Public API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
bool _tusb_rhport_init(uint8_t rhport, tusb_role_t role) {
|
||||
bool tusb_rhport_init(const tusb_rhport_init_t* rh_init) {
|
||||
// backward compatible called with tusb_init(void)
|
||||
#if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT)
|
||||
if (rhport == 0xff || role == TUSB_ROLE_INVALID) {
|
||||
if (rh_init == NULL) {
|
||||
#if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT)
|
||||
// init device stack CFG_TUSB_RHPORTx_MODE must be defined
|
||||
TU_ASSERT ( tud_init(TUD_OPT_RHPORT) );
|
||||
const tusb_rhport_init_t dev_init = {
|
||||
.rhport = TUD_OPT_RHPORT,
|
||||
.role = TUSB_ROLE_DEVICE,
|
||||
.speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL
|
||||
};
|
||||
TU_ASSERT ( tud_rhport_init(&dev_init) );
|
||||
_rhport_role[TUD_OPT_RHPORT] = TUSB_ROLE_DEVICE;
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT)
|
||||
// init host stack CFG_TUSB_RHPORTx_MODE must be defined
|
||||
TU_ASSERT( tuh_init(TUH_OPT_RHPORT) );
|
||||
const tusb_rhport_init_t host_init = {
|
||||
.rhport = TUH_OPT_RHPORT,
|
||||
.role = TUSB_ROLE_HOST,
|
||||
.speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL
|
||||
};
|
||||
TU_ASSERT( tuh_rhport_init(&host_init) );
|
||||
_rhport_role[TUH_OPT_RHPORT] = TUSB_ROLE_HOST;
|
||||
#endif
|
||||
|
||||
@@ -68,21 +78,21 @@ bool _tusb_rhport_init(uint8_t rhport, tusb_role_t role) {
|
||||
#endif
|
||||
|
||||
// new API with explicit rhport and role
|
||||
TU_ASSERT(rhport < TUP_USBIP_CONTROLLER_NUM && role != TUSB_ROLE_INVALID);
|
||||
TU_ASSERT(rh_init->rhport < TUP_USBIP_CONTROLLER_NUM && rh_init->role != TUSB_ROLE_INVALID);
|
||||
|
||||
#if CFG_TUD_ENABLED
|
||||
if (role == TUSB_ROLE_DEVICE) {
|
||||
TU_ASSERT( tud_init(rhport) );
|
||||
if (rh_init->role == TUSB_ROLE_DEVICE) {
|
||||
TU_ASSERT( tud_rhport_init(rh_init) );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_ENABLED
|
||||
if (role == TUSB_ROLE_HOST) {
|
||||
TU_ASSERT( tuh_init(rhport) );
|
||||
if (rh_init->role == TUSB_ROLE_HOST) {
|
||||
TU_ASSERT( tuh_rhport_init(rh_init) );
|
||||
}
|
||||
#endif
|
||||
|
||||
_rhport_role[rhport] = role;
|
||||
_rhport_role[rh_init->rhport] = rh_init->role;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -106,13 +116,13 @@ void tusb_int_handler(uint8_t rhport, bool in_isr) {
|
||||
#if CFG_TUD_ENABLED
|
||||
if (_rhport_role[rhport] == TUSB_ROLE_DEVICE) {
|
||||
(void) in_isr;
|
||||
tud_int_handler(rhport);
|
||||
dcd_int_handler(rhport);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_ENABLED
|
||||
if (_rhport_role[rhport] == TUSB_ROLE_HOST) {
|
||||
tuh_int_handler(rhport, in_isr);
|
||||
hcd_int_handler(rhport, in_isr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
16
src/tusb.h
16
src/tusb.h
@@ -129,19 +129,25 @@
|
||||
//--------------------------------------------------------------------+
|
||||
// APPLICATION API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
|
||||
#if CFG_TUH_ENABLED || CFG_TUD_ENABLED
|
||||
|
||||
// Internal helper for backward compatible with tusb_init(void)
|
||||
bool _tusb_rhport_init(uint8_t rhport, tusb_role_t role);
|
||||
bool tusb_rhport_init(const tusb_rhport_init_t* rh_init);
|
||||
|
||||
// Initialize roothub port with device/host role
|
||||
// Note: when using with RTOS, this should be called after scheduler/kernel is started.
|
||||
// Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API.
|
||||
// Note2: defined as macro for backward compatible with tusb_init(void), can be changed to function in the future.
|
||||
#define _tusb_init_0arg() _tusb_rhport_init(0xff, TUSB_ROLE_INVALID)
|
||||
#define _tusb_init_1arg(_rhport) _tusb_rhport_init(_rhport, TUSB_ROLE_INVALID)
|
||||
#define _tusb_init_2arg(_rhport, _role) _tusb_rhport_init(_rhport, _role)
|
||||
#define tusb_init(...) TU_GET_3RD_ARG(__VA_ARGS__, _tusb_init_2arg, _tusb_init_1arg, _tusb_init_0arg)(__VA_ARGS__)
|
||||
#if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT)
|
||||
#define _tusb_init_arg0() tusb_rhport_init(NULL)
|
||||
#else
|
||||
#define _tusb_init_arg0() TU_VERIFY_STATIC(false, "CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE must be defined")
|
||||
#endif
|
||||
|
||||
#define _tusb_init_arg1(_rh_init) tusb_rhport_init(_rh_init)
|
||||
#define tusb_init(...) TU_FUNC_OPTIONAL_ARG(_tusb_init, __VA_ARGS__)
|
||||
|
||||
// Check if stack is initialized
|
||||
bool tusb_inited(void);
|
||||
|
||||
Reference in New Issue
Block a user