change tusb_init(), tusb_rhport_init() to use init struct for expandability

This commit is contained in:
hathach
2024-10-11 12:58:18 +07:00
parent a4fb8354e4
commit 92602b9de3
46 changed files with 348 additions and 80 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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