implement hcd_port_speed_get

move port reset & speed detection from isr context to usbh enumeration task
- decrease time in isr significantly from 50 ms to 580us
fix bug with osal_task_delay for freeRTOS buil
This commit is contained in:
hathach
2013-04-25 17:48:55 +07:00
parent 3763e22c9a
commit c0104b996e
7 changed files with 27 additions and 16 deletions

View File

@@ -68,7 +68,7 @@ void tearDown(void)
void test_isr_device_connect_highspeed(void) void test_isr_device_connect_highspeed(void)
{ {
usbh_device_plugged_isr_Expect(hostid, TUSB_SPEED_HIGH); usbh_device_plugged_isr_Expect(hostid);
//------------- Code Under Test -------------// //------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_HIGH); ehci_controller_device_plug(hostid, TUSB_SPEED_HIGH);
@@ -76,7 +76,7 @@ void test_isr_device_connect_highspeed(void)
void test_isr_device_connect_fullspeed(void) void test_isr_device_connect_fullspeed(void)
{ {
usbh_device_plugged_isr_Expect(hostid, TUSB_SPEED_FULL); usbh_device_plugged_isr_Expect(hostid);
//------------- Code Under Test -------------// //------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_FULL); ehci_controller_device_plug(hostid, TUSB_SPEED_FULL);
@@ -84,7 +84,7 @@ void test_isr_device_connect_fullspeed(void)
void test_isr_device_connect_slowspeed(void) void test_isr_device_connect_slowspeed(void)
{ {
usbh_device_plugged_isr_Expect(hostid, TUSB_SPEED_LOW); usbh_device_plugged_isr_Expect(hostid);
//------------- Code Under Test -------------// //------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_LOW); ehci_controller_device_plug(hostid, TUSB_SPEED_LOW);

View File

@@ -55,9 +55,10 @@ usbh_enumerate_t const enum_connect = {
.core_id = 0, .core_id = 0,
.hub_addr = 0, .hub_addr = 0,
.hub_port = 0, .hub_port = 0,
.speed = TUSB_SPEED_FULL
}; };
tusb_speed_t device_speed = TUSB_SPEED_FULL;
void queue_recv_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call); void queue_recv_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call);
void semaphore_wait_success_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call); void semaphore_wait_success_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call);
tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_std_request_t * const p_request, uint8_t data[], int num_call); tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_std_request_t * const p_request, uint8_t data[], int num_call);
@@ -71,6 +72,8 @@ void setUp(void)
hcd_pipe_control_xfer_StubWithCallback(control_xfer_stub); hcd_pipe_control_xfer_StubWithCallback(control_xfer_stub);
hcd_port_connect_status_ExpectAndReturn(enum_connect.core_id, true); hcd_port_connect_status_ExpectAndReturn(enum_connect.core_id, true);
hcd_port_reset_Expect(enum_connect.core_id);
hcd_port_speed_get_ExpectAndReturn(enum_connect.core_id, device_speed);
osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl );
hcd_pipe_control_open_ExpectAndReturn(0, 8, TUSB_ERROR_NONE); hcd_pipe_control_open_ExpectAndReturn(0, 8, TUSB_ERROR_NONE);
} }

View File

@@ -137,7 +137,7 @@ void hcd_port_reset(uint8_t hostid)
#ifndef _TEST_ #ifndef _TEST_
// NXP specific, port reset will automatically be 0 when reset sequence complete // NXP specific, port reset will automatically be 0 when reset sequence complete
// there is chance device is unplugged while reset sequence is not complete // there is chance device is unplugged while reset sequence is not complete
while( regs->portsc_bit.port_reset) {} while( regs->portsc_bit.port_reset) {} // TODO use task delay to remove blocking
#endif #endif
} }
@@ -146,6 +146,11 @@ bool hcd_port_connect_status(uint8_t hostid)
return get_operational_register(hostid)->portsc_bit.current_connect_status; return get_operational_register(hostid)->portsc_bit.current_connect_status;
} }
tusb_speed_t hcd_port_speed_get(uint8_t hostid)
{
return get_operational_register(hostid)->portsc_bit.nxp_port_speed; // NXP specific port speed
}
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Controller API // Controller API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@@ -479,8 +484,7 @@ void port_connect_status_change_isr(uint8_t hostid)
if (regs->portsc_bit.current_connect_status) // device plugged if (regs->portsc_bit.current_connect_status) // device plugged
{ {
hcd_port_reset(hostid); usbh_device_plugged_isr(hostid);
usbh_device_plugged_isr(hostid, regs->portsc_bit.nxp_port_speed); // NXP specific port speed
}else // device unplugged }else // device unplugged
{ {
usbh_device_unplugged_isr(hostid); usbh_device_unplugged_isr(hostid);

View File

@@ -105,8 +105,9 @@ tusb_error_t hcd_pipe_cancel()ATTR_WARN_UNUSED_RESULT;
// PORT API // PORT API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
/// return the current connect status of roothub port /// return the current connect status of roothub port
bool hcd_port_connect_status(uint8_t core_id) ATTR_CONST ATTR_WARN_UNUSED_RESULT; bool hcd_port_connect_status(uint8_t hostid) ATTR_PURE ATTR_WARN_UNUSED_RESULT; // TODO make inline if possible
void hcd_port_reset(uint8_t core_id); void hcd_port_reset(uint8_t hostid);
tusb_speed_t hcd_port_speed_get(uint8_t hostid) ATTR_PURE ATTR_WARN_UNUSED_RESULT; // TODO make inline if possible
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -202,10 +202,10 @@ void usbh_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event)
} }
} }
void usbh_device_plugged_isr(uint8_t hostid, tusb_speed_t speed) void usbh_device_plugged_isr(uint8_t hostid)
{ {
osal_queue_send(enum_queue_hdl, osal_queue_send(enum_queue_hdl,
&(usbh_enumerate_t){ .core_id = hostid, .speed = speed} ); &(usbh_enumerate_t){ .core_id = hostid} );
} }
void usbh_device_unplugged_isr(uint8_t hostid) void usbh_device_unplugged_isr(uint8_t hostid)
@@ -277,16 +277,19 @@ tusb_error_t enumeration_body_subtask(void)
osal_queue_receive(enum_queue_hdl, &enum_entry, OSAL_TIMEOUT_WAIT_FOREVER, &error); osal_queue_receive(enum_queue_hdl, &enum_entry, OSAL_TIMEOUT_WAIT_FOREVER, &error);
SUBTASK_ASSERT( hcd_port_connect_status(enum_entry.core_id) ); // ensure device is still plugged SUBTASK_ASSERT( hcd_port_connect_status(enum_entry.core_id) ); // ensure device is still plugged
usbh_devices[0].core_id = enum_entry.core_id; // TODO refractor integrate to device_pool usbh_devices[0].core_id = enum_entry.core_id; // TODO refractor integrate to device_pool
usbh_devices[0].hub_addr = enum_entry.hub_addr; usbh_devices[0].hub_addr = enum_entry.hub_addr;
usbh_devices[0].hub_port = enum_entry.hub_port; usbh_devices[0].hub_port = enum_entry.hub_port;
usbh_devices[0].speed = enum_entry.speed;
hcd_port_reset( usbh_devices[0].core_id ); // port must be reset to have correct speed operation
usbh_devices[0].speed = hcd_port_speed_get( usbh_devices[0].core_id );
SUBTASK_ASSERT_STATUS( usbh_pipe_control_open(0, 8) ); SUBTASK_ASSERT_STATUS( usbh_pipe_control_open(0, 8) );
usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED; usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED;
#ifndef _TEST_ #ifndef _TEST_
// TODO finalize delay after reset, hack delay 100 ms, otherwise speed is detected as LOW in most cases // TODO hack delay 100 ms for slow device (use retry on the 1st xfer instead later)
osal_task_delay(100); osal_task_delay(100);
#endif #endif

View File

@@ -72,7 +72,7 @@ typedef struct ATTR_ALIGNED(4){
uint8_t core_id; uint8_t core_id;
uint8_t hub_addr; uint8_t hub_addr;
uint8_t hub_port; uint8_t hub_port;
uint8_t speed; uint8_t reserve;
} usbh_enumerate_t; } usbh_enumerate_t;
typedef struct { // TODO internal structure, re-order members typedef struct { // TODO internal structure, re-order members
@@ -107,7 +107,7 @@ extern usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1]; // including
//------------- callback from HCD ISR-------------// //------------- callback from HCD ISR-------------//
void usbh_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event); void usbh_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event);
void usbh_device_plugged_isr(uint8_t hostid, tusb_speed_t speed); void usbh_device_plugged_isr(uint8_t hostid);
void usbh_device_unplugged_isr(uint8_t hostid); void usbh_device_unplugged_isr(uint8_t hostid);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -99,7 +99,7 @@ static inline tusb_error_t osal_task_create(osal_task_t *task)
static inline void osal_task_delay(uint32_t msec) ATTR_ALWAYS_INLINE; static inline void osal_task_delay(uint32_t msec) ATTR_ALWAYS_INLINE;
static inline void osal_task_delay(uint32_t msec) static inline void osal_task_delay(uint32_t msec)
{ {
vTaskDelay(TUSB_CFG_OS_TICKS_PER_SECOND * msec); vTaskDelay( (TUSB_CFG_OS_TICKS_PER_SECOND * msec) / 1000 );
} }
#define OSAL_TASK_LOOP_BEGIN \ #define OSAL_TASK_LOOP_BEGIN \