cleanup SUBTASK macros

This commit is contained in:
hathach 2018-03-03 12:30:38 +07:00
parent fe0e79864b
commit f6137903bc
6 changed files with 80 additions and 45 deletions

View File

@ -328,7 +328,7 @@ void dcd_pipe_control_stall(uint8_t coreid)
// control transfer does not need to use qtd find function // control transfer does not need to use qtd find function
// follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism
tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete) bool dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete)
{ {
LPC_USB0_Type* const lpc_usb = LPC_USB[coreid]; LPC_USB0_Type* const lpc_usb = LPC_USB[coreid];
dcd_data_t* const p_dcd = dcd_data_ptr[coreid]; dcd_data_t* const p_dcd = dcd_data_ptr[coreid];
@ -340,7 +340,7 @@ tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t
while(lpc_usb->ENDPTSETUPSTAT & BIT_(0)) {} // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out while(lpc_usb->ENDPTSETUPSTAT & BIT_(0)) {} // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
// while(p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active) {}; // wait until previous device request is completed TODO add timeout // while(p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active) {}; // wait until previous device request is completed TODO add timeout
ASSERT_FALSE(p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active, TUSB_ERROR_FAILED); VERIFY( !(p_dcd->qhd[0].qtd_overlay.active || p_dcd->qhd[1].qtd_overlay.active) );
//------------- Data Phase -------------// //------------- Data Phase -------------//
if (length > 0) if (length > 0)
@ -361,7 +361,7 @@ tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t
lpc_usb->ENDPTPRIME = BIT_(edpt_phy2pos(ep_status)); lpc_usb->ENDPTPRIME = BIT_(edpt_phy2pos(ep_status));
return TUSB_ERROR_NONE; return true;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -61,22 +61,16 @@
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#if TUSB_CFG_DEBUG >= 1 #if TUSB_CFG_DEBUG >= 1
// #define VERIFY_MESS(format, ...) cprintf("[%08ld] %s: %d: verify failed\n", get_millis(), __func__, __LINE__) // #define VERIFY_MESS(format, ...) cprintf("[%08ld] %s: %d: verify failed\n", get_millis(), __func__, __LINE__)
#define VERIFY_MESS(_status) cprintf("%s: %d: verify failed, error = %s\n", __PRETTY_FUNCTION__, __LINE__, dbg_err_str(_status)); #define VERIFY_MESS(_status) printf("%s: %d: verify failed, error = %s\n", __PRETTY_FUNCTION__, __LINE__, TUSB_ErrorStr[_status]);
#else #else
#define VERIFY_MESS(_status) #define VERIFY_MESS(_status)
#endif #endif
#define VERIFY_DEFINE(_status, _error) \
if ( 0 != _status ) { \
VERIFY_MESS(_status) \
return _error; \
}
/** /**
* Helper to implement optional parameter for VERIFY Macro family * Helper to implement optional parameter for VERIFY Macro family
*/ */
#define VERIFY_GETARGS(arg1, arg2, arg3, ...) arg3 #define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* VERIFY STATUS /* VERIFY STATUS
@ -84,15 +78,15 @@
* - VERIFY_STS_2ARGS : return provided status code if failed * - VERIFY_STS_2ARGS : return provided status code if failed
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#define VERIFY_STS_1ARGS(sts) \ #define VERIFY_STS_1ARGS(sts) \
do { \ do { \
uint32_t _status = (uint32_t)(sts); \ uint32_t _status = (uint32_t)(sts); \
VERIFY_DEFINE(_status, _status);\ if ( 0 != _status ) { VERIFY_MESS(_status) return _status; } \
} while(0) } while(0)
#define VERIFY_STS_2ARGS(sts, _error) \ #define VERIFY_STS_2ARGS(sts, _error) \
do { \ do { \
uint32_t _status = (uint32_t)(sts); \ uint32_t _status = (uint32_t)(sts); \
VERIFY_DEFINE(_status, _error);\ if ( 0 != _status ) { VERIFY_MESS(_status) return _error; }\
} while(0) } while(0)
/** /**
@ -100,26 +94,54 @@
* - status value if called with 1 parameter e.g VERIFY_STATUS(status) * - status value if called with 1 parameter e.g VERIFY_STATUS(status)
* - 2 parameter if called with 2 parameters e.g VERIFY_STATUS(status, errorcode) * - 2 parameter if called with 2 parameters e.g VERIFY_STATUS(status, errorcode)
*/ */
#define VERIFY_STATUS(...) VERIFY_GETARGS(__VA_ARGS__, VERIFY_STS_2ARGS, VERIFY_STS_1ARGS)(__VA_ARGS__) #define VERIFY_STATUS(...) GET_3RD_ARG(__VA_ARGS__, VERIFY_STS_2ARGS, VERIFY_STS_1ARGS)(__VA_ARGS__)
/*------------------------------------------------------------------*/
/* VERIFY STATUS WITH HANDLER
* - VERIFY_STS_HDLR_2ARGS : execute handler, return status if failed
* - VERIFY_STS_HDLR_3ARGS : execute handler, return provided error if failed
*------------------------------------------------------------------*/
#define VERIFY_STS_HDLR_2ARGS(sts, _handler) \
do { \
uint32_t _status = (uint32_t)(sts); \
if ( 0 != _status ) { VERIFY_MESS(_status) _handler; return _status; }\
} while(0)
#define VERIFY_STS_HDLR_3ARGS(sts, _handler, _error) \
do { \
uint32_t _status = (uint32_t)(sts); \
if ( 0 != _status ) { VERIFY_MESS(_status) _handler; return _error; }\
} while(0)
#define VERIFY_STATUS_HDLR(...) GET_4TH_ARG(__VA_ARGS__, VERIFY_STS_HDLR_3ARGS, VERIFY_STS_HDLR_2ARGS)(__VA_ARGS__)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* VERIFY /* VERIFY
* - VERIFY_1ARGS : return condition if failed (false) * - VERIFY_1ARGS : return false if failed
* - VERIFY_2ARGS : return provided value if failed * - VERIFY_2ARGS : return provided value if failed
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#define VERIFY_1ARGS(cond) if (!(cond)) return false; #define VERIFY_1ARGS(cond) do { if (!(cond)) return false; } while(0)
#define VERIFY_2ARGS(cond, _error) if (!(cond)) return _error; #define VERIFY_2ARGS(cond, _error) do { if (!(cond)) return _error; } while(0)
/** /**
* Check if condition is success (true), otherwise return * Check if condition is success (true), otherwise return
* - false value if called with 1 parameter e.g VERIFY(condition) * - false value if called with 1 parameter e.g VERIFY(condition)
* - 2 parameter if called with 2 parameters e.g VERIFY(condition, errorcode) * - 2 parameter if called with 2 parameters e.g VERIFY(condition, errorcode)
*/ */
#define VERIFY(...) VERIFY_GETARGS(__VA_ARGS__, VERIFY_2ARGS, VERIFY_1ARGS)(__VA_ARGS__) #define VERIFY(...) GET_3RD_ARG(__VA_ARGS__, VERIFY_2ARGS, VERIFY_1ARGS)(__VA_ARGS__)
// TODO VERIFY with final statement /*------------------------------------------------------------------*/
/* VERIFY WITH HANDLER
* - VERIFY_HDLR_2ARGS : execute handler, return false if failed
* - VERIFY_HDLR_3ARGS : execute handler, return provided error if failed
*------------------------------------------------------------------*/
#define VERIFY_HDLR_2ARGS(cond, _handler) \
do { if ( !(cond) ) { _handler; return false; } } while(0)
#define VERIFY_HDLR_3ARGS(cond, _handler, _error) \
do { if ( !(cond) ) { _handler; return _error; } } while(0)
#define VERIFY_HDLR(...) GET_4TH_ARG(__VA_ARGS__, VERIFY_HDLR_3ARGS, VERIFY_HDLR_2ARGS)(__VA_ARGS__)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -79,7 +79,7 @@ void hal_dcd_set_address(uint8_t coreid, uint8_t dev_addr);
void hal_dcd_set_config (uint8_t coreid, uint8_t config_num); void hal_dcd_set_config (uint8_t coreid, uint8_t config_num);
//------------- PIPE API -------------// //------------- PIPE API -------------//
tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete); bool dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete);
void dcd_pipe_control_stall(uint8_t coreid); void dcd_pipe_control_stall(uint8_t coreid);
endpoint_handle_t dcd_pipe_open(uint8_t coreid, tusb_descriptor_endpoint_t const * p_endpoint_desc, uint8_t class_code); endpoint_handle_t dcd_pipe_open(uint8_t coreid, tusb_descriptor_endpoint_t const * p_endpoint_desc, uint8_t class_code);

View File

@ -378,11 +378,11 @@ void dcd_pipe_control_stall(uint8_t coreid)
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK); sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK);
} }
tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete) bool dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete)
{ {
(void) coreid; (void) coreid;
ASSERT( !(length != 0 && p_buffer == NULL), TUSB_ERROR_INVALID_PARA); VERIFY( !(length != 0 && p_buffer == NULL) );
// determine Endpoint where Data & Status phase occurred (IN or OUT) // determine Endpoint where Data & Status phase occurred (IN or OUT)
uint8_t const ep_data = (dir == TUSB_DIR_DEV_TO_HOST) ? 1 : 0; uint8_t const ep_data = (dir == TUSB_DIR_DEV_TO_HOST) ? 1 : 0;
@ -397,16 +397,16 @@ tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t
dcd_data.control_dma.remaining_bytes = length; dcd_data.control_dma.remaining_bytes = length;
// lpc17xx already received the first DATA OUT packet by now // lpc17xx already received the first DATA OUT packet by now
ASSERT_STATUS ( pipe_control_xfer(ep_data, p_buffer, length) ); VERIFY_STATUS ( pipe_control_xfer(ep_data, p_buffer, length), false );
} }
//------------- Status Phase (opposite direct to Data) -------------// //------------- Status Phase (opposite direct to Data) -------------//
if (dir == TUSB_DIR_HOST_TO_DEV) if (dir == TUSB_DIR_HOST_TO_DEV)
{ // only write for CONTROL OUT, CONTROL IN data will be retrieved in dcd_isr // TODO ???? { // only write for CONTROL OUT, CONTROL IN data will be retrieved in dcd_isr // TODO ????
ASSERT_STATUS ( pipe_control_write(NULL, 0) ); VERIFY_STATUS ( pipe_control_write(NULL, 0), false );
} }
return TUSB_ERROR_NONE; return true;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -380,7 +380,7 @@ void dcd_pipe_control_stall(uint8_t coreid)
dcd_data.qhd[0][0].stall = dcd_data.qhd[1][0].stall = 1; dcd_data.qhd[0][0].stall = dcd_data.qhd[1][0].stall = 1;
} }
tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete) bool dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete)
{ {
(void) coreid; (void) coreid;
@ -405,7 +405,7 @@ tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t
queue_xfer_to_buffer(ep_status, 0, 0, 0); queue_xfer_to_buffer(ep_status, 0, 0, 0);
return TUSB_ERROR_NONE; return true;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -69,6 +69,8 @@ uint32_t tusb_tick_get(void);
// //
// OSAL_TASK_LOOP_ENG // OSAL_TASK_LOOP_ENG
// } // }
//
// NOTE: no switch statement is allowed in Task and subtask
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
typedef void (*osal_func_t)(void *param); typedef void (*osal_func_t)(void *param);
typedef void* osal_task_t; typedef void* osal_task_t;
@ -100,13 +102,20 @@ static inline osal_task_t osal_task_create(osal_func_t code, const char* name, u
do {\ do {\
timeout = osal_tick_get();\ timeout = osal_tick_get();\
state = __LINE__; case __LINE__:\ state = __LINE__; case __LINE__:\
if ( timeout + osal_tick_from_msec(msec) > osal_tick_get() ) /* time out */ \ if ( timeout + osal_tick_from_msec(msec) > osal_tick_get() ) \
return TUSB_ERROR_OSAL_WAITING;\ return TUSB_ERROR_OSAL_WAITING;\
}while(0) }while(0)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// SUBTASK (a sub function that uses OS blocking services & called by a task // SUBTASK (a sub function that uses OS blocking services & called by a task
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#define OSAL_SUBTASK_BEGIN OSAL_TASK_BEGIN
#define OSAL_SUBTASK_END \
default:\
TASK_RESTART;\
}}\
return TUSB_ERROR_NONE;
#define OSAL_SUBTASK_INVOKED_AND_WAIT(subtask, status) \ #define OSAL_SUBTASK_INVOKED_AND_WAIT(subtask, status) \
do {\ do {\
state = __LINE__; case __LINE__:\ state = __LINE__; case __LINE__:\
@ -117,22 +126,22 @@ static inline osal_task_t osal_task_create(osal_func_t code, const char* name, u
}\ }\
}while(0) }while(0)
#define OSAL_SUBTASK_BEGIN OSAL_TASK_BEGIN
#define OSAL_SUBTASK_END \
default:\
TASK_RESTART;\
}}\
return TUSB_ERROR_NONE;
//------------- Sub Task Assert -------------// //------------- Sub Task Assert -------------//
#define SUBTASK_EXIT(error) \ #define SUBTASK_EXIT(error) \
do {\ do { TASK_RESTART; return error; } while(0)
TASK_RESTART; return error;\
}while(0)
#define _SUBTASK_ASSERT_ERROR_HANDLER(error, func_call) \ #define _SUBTASK_ASSERT_ERROR_HANDLER(error, func_call) \
func_call; TASK_RESTART; return error do { func_call; TASK_RESTART; return error; } while(0)
#define SUBTASK_ASSERT_STATUS(sts) VERIFY_STATUS_HDLR(sts, TASK_RESTART)
#define SUBTASK_ASSERT_STATUS_WITH_HANDLER(sts, func_call) VERIFY_STATUS_HDLR(sts, func_call; TASK_RESTART )
#define SUBTASK_ASSERT(condition) VERIFY_HDLR(condition, TASK_RESTART)
// TODO remove assert with handler by catching error in enum main task
#define SUBTASK_ASSERT_WITH_HANDLER(condition, func_call) VERIFY_HDLR(condition, func_call; TASK_RESTART)
/*
#define SUBTASK_ASSERT_STATUS(sts) \ #define SUBTASK_ASSERT_STATUS(sts) \
ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, , tusb_error_t status = (tusb_error_t)(sts),\ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, , tusb_error_t status = (tusb_error_t)(sts),\
TUSB_ERROR_NONE == status, status, "%s", TUSB_ErrorStr[status]) TUSB_ERROR_NONE == status, status, "%s", TUSB_ErrorStr[status])
@ -150,6 +159,10 @@ static inline osal_task_t osal_task_create(osal_func_t code, const char* name, u
ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, func_call, ,\ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, func_call, ,\
condition, TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false") condition, TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false")
*/
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// QUEUE API // QUEUE API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+