fix potential error with usbh_control_xfer_subtask in subtask_assert
change back to use task_assert style in usbh_enumeraion change test to task->subtask->subtask style in test/test_osal_none.c
This commit is contained in:
parent
73d5f00a40
commit
d312be7006
|
@ -241,25 +241,47 @@ void flow_control_error_handler(void)
|
||||||
statements[5]++;
|
statements[5]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tusb_error_t sample_flow_control_subtask2(void)
|
||||||
|
{
|
||||||
|
tusb_error_t error;
|
||||||
|
|
||||||
|
OSAL_SUBTASK_BEGIN
|
||||||
|
|
||||||
|
statements[0]++;
|
||||||
|
|
||||||
|
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
|
||||||
|
SUBTASK_ASSERT(TUSB_ERROR_NONE == error);
|
||||||
|
statements[1]++;
|
||||||
|
|
||||||
|
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
|
||||||
|
SUBTASK_ASSERT_STATUS(error);
|
||||||
|
statements[2]++;
|
||||||
|
|
||||||
|
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
|
||||||
|
SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, flow_control_error_handler());
|
||||||
|
statements[3]++;
|
||||||
|
|
||||||
|
OSAL_SUBTASK_END
|
||||||
|
}
|
||||||
|
|
||||||
|
tusb_error_t sample_flow_control_subtask(void)
|
||||||
|
{
|
||||||
|
tusb_error_t error;
|
||||||
|
|
||||||
|
OSAL_SUBTASK_BEGIN
|
||||||
|
|
||||||
|
OSAL_SUBTASK_INVOKED_AND_WAIT (sample_flow_control_subtask2());
|
||||||
|
|
||||||
|
OSAL_SUBTASK_END
|
||||||
|
}
|
||||||
|
|
||||||
tusb_error_t sample_task_flow_control(void)
|
tusb_error_t sample_task_flow_control(void)
|
||||||
{
|
{
|
||||||
tusb_error_t error;
|
tusb_error_t error;
|
||||||
|
|
||||||
OSAL_TASK_LOOP_BEGIN
|
OSAL_TASK_LOOP_BEGIN
|
||||||
|
|
||||||
statements[0]++;
|
OSAL_SUBTASK_INVOKED_AND_WAIT ( sample_flow_control_subtask() );
|
||||||
|
|
||||||
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
|
|
||||||
TASK_ASSERT(TUSB_ERROR_NONE == error);
|
|
||||||
statements[1]++;
|
|
||||||
|
|
||||||
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
|
|
||||||
TASK_ASSERT_STATUS(error);
|
|
||||||
statements[2]++;
|
|
||||||
|
|
||||||
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
|
|
||||||
TASK_ASSERT_STATUS_WITH_HANDLER(error, flow_control_error_handler());
|
|
||||||
statements[3]++;
|
|
||||||
|
|
||||||
OSAL_TASK_LOOP_END
|
OSAL_TASK_LOOP_END
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,12 +155,8 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, tusb_std_request_t cons
|
||||||
|
|
||||||
osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL, &error); // careful of local variable without static
|
osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL, &error); // careful of local variable without static
|
||||||
// TODO make handler for this function general purpose
|
// TODO make handler for this function general purpose
|
||||||
SUBTASK_ASSERT_STATUS_WITH_HANDLER(error || usbh_devices[dev_addr].control.pipe_status == TUSB_INTERFACE_STATUS_ERROR,
|
SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error && usbh_devices[dev_addr].control.pipe_status != TUSB_INTERFACE_STATUS_ERROR,
|
||||||
tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) );
|
tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) );
|
||||||
// if ( TUSB_ERROR_NONE != error || usbh_devices[dev_addr].control.pipe_status == TUSB_INTERFACE_STATUS_ERROR)
|
|
||||||
// {
|
|
||||||
// tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
|
|
||||||
// }
|
|
||||||
|
|
||||||
OSAL_SUBTASK_END
|
OSAL_SUBTASK_END
|
||||||
}
|
}
|
||||||
|
@ -267,194 +263,187 @@ OSAL_TASK_FUNCTION(usbh_enumeration_task)
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
if( 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;
|
||||||
usbh_devices[0].speed = enum_entry.speed;
|
|
||||||
|
|
||||||
if( TUSB_ERROR_NONE == 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 finalize delay after reset, hack delay 100 ms, otherwise speed is detected as LOW in most cases
|
||||||
volatile uint32_t delay_us = 10000;
|
volatile uint32_t delay_us = 10000;
|
||||||
delay_us *= (SystemCoreClock / 1000000) / 3;
|
delay_us *= (SystemCoreClock / 1000000) / 3;
|
||||||
while(delay_us--);
|
while(delay_us--);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
|
//------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
|
||||||
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
||||||
usbh_control_xfer_subtask(
|
usbh_control_xfer_subtask(
|
||||||
0,
|
0,
|
||||||
&(tusb_std_request_t)
|
&(tusb_std_request_t)
|
||||||
{
|
|
||||||
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
|
||||||
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
|
||||||
.wValue = (TUSB_DESC_DEVICE << 8),
|
|
||||||
.wLength = 8
|
|
||||||
},
|
|
||||||
enum_data_buffer
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor
|
|
||||||
|
|
||||||
//------------- Set new address -------------//
|
|
||||||
new_addr = get_new_address();
|
|
||||||
if (new_addr <= TUSB_CFG_HOST_DEVICE_MAX) // TODO notify application we reach max devices
|
|
||||||
{
|
{
|
||||||
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
||||||
usbh_control_xfer_subtask(
|
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
||||||
0,
|
.wValue = (TUSB_DESC_DEVICE << 8),
|
||||||
&(tusb_std_request_t)
|
.wLength = 8
|
||||||
{
|
},
|
||||||
.bmRequestType = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
enum_data_buffer
|
||||||
.bRequest = TUSB_REQUEST_SET_ADDRESS,
|
)
|
||||||
.wValue = new_addr
|
);
|
||||||
},
|
|
||||||
NULL
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
//------------- update port info & close control pipe of addr0 -------------//
|
hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor
|
||||||
usbh_devices[new_addr].core_id = usbh_devices[0].core_id;
|
|
||||||
usbh_devices[new_addr].hub_addr = usbh_devices[0].hub_addr;
|
|
||||||
usbh_devices[new_addr].hub_port = usbh_devices[0].hub_port;
|
|
||||||
usbh_devices[new_addr].speed = usbh_devices[0].speed;
|
|
||||||
usbh_devices[new_addr].state = TUSB_DEVICE_STATE_ADDRESSED;
|
|
||||||
|
|
||||||
usbh_pipe_control_close(0);
|
//------------- Set new address -------------//
|
||||||
usbh_devices[0].state = TUSB_DEVICE_STATE_UNPLUG;
|
new_addr = get_new_address();
|
||||||
|
SUBTASK_ASSERT(new_addr <= TUSB_CFG_HOST_DEVICE_MAX); // TODO notify application we reach max devices
|
||||||
|
|
||||||
// open control pipe for new address
|
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
||||||
if ( TUSB_ERROR_NONE == usbh_pipe_control_open(new_addr, ((tusb_descriptor_device_t*) enum_data_buffer)->bMaxPacketSize0 ) )
|
usbh_control_xfer_subtask(
|
||||||
|
0,
|
||||||
|
&(tusb_std_request_t)
|
||||||
|
{
|
||||||
|
.bmRequestType = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
||||||
|
.bRequest = TUSB_REQUEST_SET_ADDRESS,
|
||||||
|
.wValue = new_addr
|
||||||
|
},
|
||||||
|
NULL
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
//------------- update port info & close control pipe of addr0 -------------//
|
||||||
|
usbh_devices[new_addr].core_id = usbh_devices[0].core_id;
|
||||||
|
usbh_devices[new_addr].hub_addr = usbh_devices[0].hub_addr;
|
||||||
|
usbh_devices[new_addr].hub_port = usbh_devices[0].hub_port;
|
||||||
|
usbh_devices[new_addr].speed = usbh_devices[0].speed;
|
||||||
|
usbh_devices[new_addr].state = TUSB_DEVICE_STATE_ADDRESSED;
|
||||||
|
|
||||||
|
usbh_pipe_control_close(0);
|
||||||
|
usbh_devices[0].state = TUSB_DEVICE_STATE_UNPLUG;
|
||||||
|
|
||||||
|
// open control pipe for new address
|
||||||
|
SUBTASK_ASSERT_STATUS ( usbh_pipe_control_open(new_addr, ((tusb_descriptor_device_t*) enum_data_buffer)->bMaxPacketSize0 ) );
|
||||||
|
|
||||||
|
//------------- Get full device descriptor -------------//
|
||||||
|
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
||||||
|
usbh_control_xfer_subtask(
|
||||||
|
new_addr,
|
||||||
|
&(tusb_std_request_t)
|
||||||
|
{
|
||||||
|
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
||||||
|
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
||||||
|
.wValue = (TUSB_DESC_DEVICE << 8),
|
||||||
|
.wLength = 18
|
||||||
|
},
|
||||||
|
enum_data_buffer
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// update device info TODO alignment issue
|
||||||
|
usbh_devices[new_addr].vendor_id = ((tusb_descriptor_device_t*) enum_data_buffer)->idVendor;
|
||||||
|
usbh_devices[new_addr].product_id = ((tusb_descriptor_device_t*) enum_data_buffer)->idProduct;
|
||||||
|
usbh_devices[new_addr].configure_count = ((tusb_descriptor_device_t*) enum_data_buffer)->bNumConfigurations;
|
||||||
|
|
||||||
|
configure_selected = get_configure_number_for_device((tusb_descriptor_device_t*) enum_data_buffer);
|
||||||
|
SUBTASK_ASSERT(configure_selected <= usbh_devices[new_addr].configure_count); // TODO notify application when invalid configuration
|
||||||
|
|
||||||
|
//------------- Get 9 bytes of configuration descriptor -------------//
|
||||||
|
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
||||||
|
usbh_control_xfer_subtask(
|
||||||
|
new_addr,
|
||||||
|
&(tusb_std_request_t)
|
||||||
|
{
|
||||||
|
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
||||||
|
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
||||||
|
.wValue = (TUSB_DESC_CONFIGURATION << 8) | (configure_selected - 1),
|
||||||
|
.wLength = 9
|
||||||
|
},
|
||||||
|
enum_data_buffer
|
||||||
|
)
|
||||||
|
);
|
||||||
|
SUBTASK_ASSERT_WITH_HANDLER( TUSB_CFG_HOST_ENUM_BUFFER_SIZE > ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength,
|
||||||
|
tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG, NULL) );
|
||||||
|
|
||||||
|
//------------- Get full configuration descriptor -------------//
|
||||||
|
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
||||||
|
usbh_control_xfer_subtask(
|
||||||
|
new_addr,
|
||||||
|
&(tusb_std_request_t)
|
||||||
|
{
|
||||||
|
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
||||||
|
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
||||||
|
.wValue = (TUSB_DESC_CONFIGURATION << 8) | (configure_selected - 1),
|
||||||
|
.wLength = ((tusb_descriptor_configuration_t*) enum_data_buffer)->wTotalLength
|
||||||
|
},
|
||||||
|
enum_data_buffer
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// update configuration info
|
||||||
|
usbh_devices[new_addr].interface_count = ((tusb_descriptor_configuration_t*) enum_data_buffer)->bNumInterfaces;
|
||||||
|
|
||||||
|
//------------- Set Configure -------------//
|
||||||
|
OSAL_SUBTASK_INVOKED_AND_WAIT (
|
||||||
|
usbh_control_xfer_subtask(
|
||||||
|
new_addr,
|
||||||
|
&(tusb_std_request_t)
|
||||||
{
|
{
|
||||||
//------------- Get full device descriptor -------------//
|
.bmRequestType = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
||||||
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
.bRequest = TUSB_REQUEST_SET_CONFIGURATION,
|
||||||
usbh_control_xfer_subtask(
|
.wValue = configure_selected
|
||||||
new_addr,
|
},
|
||||||
&(tusb_std_request_t)
|
NULL
|
||||||
{
|
)
|
||||||
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
);
|
||||||
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
|
||||||
.wValue = (TUSB_DESC_DEVICE << 8),
|
|
||||||
.wLength = 18
|
|
||||||
},
|
|
||||||
enum_data_buffer
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// update device info TODO alignment issue
|
usbh_devices[new_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
|
||||||
usbh_devices[new_addr].vendor_id = ((tusb_descriptor_device_t*) enum_data_buffer)->idVendor;
|
|
||||||
usbh_devices[new_addr].product_id = ((tusb_descriptor_device_t*) enum_data_buffer)->idProduct;
|
|
||||||
usbh_devices[new_addr].configure_count = ((tusb_descriptor_device_t*) enum_data_buffer)->bNumConfigurations;
|
|
||||||
|
|
||||||
configure_selected = get_configure_number_for_device((tusb_descriptor_device_t*) enum_data_buffer);
|
//------------- parse configuration & install drivers -------------//
|
||||||
if(configure_selected <= usbh_devices[new_addr].configure_count) // TODO notify application when invalid configuration
|
p_desc = enum_data_buffer + sizeof(tusb_descriptor_configuration_t);
|
||||||
{
|
|
||||||
//------------- Get 9 bytes of configuration descriptor -------------//
|
|
||||||
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
|
||||||
usbh_control_xfer_subtask(
|
|
||||||
new_addr,
|
|
||||||
&(tusb_std_request_t)
|
|
||||||
{
|
|
||||||
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
|
||||||
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
|
||||||
.wValue = (TUSB_DESC_CONFIGURATION << 8) | (configure_selected - 1),
|
|
||||||
.wLength = 9
|
|
||||||
},
|
|
||||||
enum_data_buffer
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( TUSB_CFG_HOST_ENUM_BUFFER_SIZE <= ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength )
|
// parse each interfaces
|
||||||
{
|
while( p_desc < enum_data_buffer + ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength )
|
||||||
tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG, NULL);
|
{
|
||||||
}else
|
// skip until we see interface descriptor
|
||||||
{
|
if ( TUSB_DESC_INTERFACE != p_desc[DESCRIPTOR_OFFSET_TYPE] )
|
||||||
//------------- Get full configuration descriptor -------------//
|
{
|
||||||
OSAL_SUBTASK_INVOKED_AND_WAIT(
|
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip the descriptor, increase by the descriptor's length
|
||||||
usbh_control_xfer_subtask(
|
}else
|
||||||
new_addr,
|
{
|
||||||
&(tusb_std_request_t)
|
uint8_t class_code = ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass;
|
||||||
{
|
if (class_code == 0)
|
||||||
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
{
|
||||||
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
|
SUBTASK_ASSERT( false ); // corrupted data, abort enumeration
|
||||||
.wValue = (TUSB_DESC_CONFIGURATION << 8) | (configure_selected - 1),
|
}
|
||||||
.wLength = ((tusb_descriptor_configuration_t*) enum_data_buffer)->wTotalLength
|
// supported class TODO custom class
|
||||||
},
|
else if ( class_code < TUSB_CLASS_MAX_CONSEC_NUMBER && usbh_class_drivers[class_code].open_subtask)
|
||||||
enum_data_buffer
|
{
|
||||||
)
|
uint16_t length=0;
|
||||||
);
|
OSAL_SUBTASK_INVOKED_AND_WAIT ( // parameters in task/sub_task must be static storage (static or global)
|
||||||
|
usbh_class_drivers[ ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass ].open_subtask(
|
||||||
|
new_addr, (tusb_descriptor_interface_t*) p_desc, &length) );
|
||||||
|
|
||||||
// update configuration info
|
// TODO check class_open_subtask status
|
||||||
usbh_devices[new_addr].interface_count = ((tusb_descriptor_configuration_t*) enum_data_buffer)->bNumInterfaces;
|
if (length == 0) // Interface open failed, for example a subclass is not supported
|
||||||
|
{
|
||||||
//------------- Set Configure -------------//
|
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
|
||||||
OSAL_SUBTASK_INVOKED_AND_WAIT (
|
// TODO can optimize the length --> open_subtask return a OPEN FAILED status
|
||||||
usbh_control_xfer_subtask(
|
}else
|
||||||
new_addr,
|
{
|
||||||
&(tusb_std_request_t)
|
usbh_devices[new_addr].flag_supported_class |= BIT_(((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass);
|
||||||
{
|
p_desc += length;
|
||||||
.bmRequestType = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
|
|
||||||
.bRequest = TUSB_REQUEST_SET_CONFIGURATION,
|
|
||||||
.wValue = configure_selected
|
|
||||||
},
|
|
||||||
NULL
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
usbh_devices[new_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
|
|
||||||
|
|
||||||
//------------- parse configuration & install drivers -------------//
|
|
||||||
p_desc = enum_data_buffer + sizeof(tusb_descriptor_configuration_t);
|
|
||||||
|
|
||||||
// parse each interfaces
|
|
||||||
while( p_desc < enum_data_buffer + ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength )
|
|
||||||
{
|
|
||||||
// skip until we see interface descriptor
|
|
||||||
if ( TUSB_DESC_INTERFACE != p_desc[DESCRIPTOR_OFFSET_TYPE] )
|
|
||||||
{
|
|
||||||
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip the descriptor, increase by the descriptor's length
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
uint8_t class_code = ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass;
|
|
||||||
|
|
||||||
// supported class TODO add custom class
|
|
||||||
if ( 0 < class_code && class_code < TUSB_CLASS_MAX_CONSEC_NUMBER && usbh_class_drivers[class_code].open_subtask)
|
|
||||||
{
|
|
||||||
uint16_t length=0;
|
|
||||||
OSAL_SUBTASK_INVOKED_AND_WAIT ( // parameters in task/sub_task must be static storage (static or global)
|
|
||||||
usbh_class_drivers[ ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass ].open_subtask(
|
|
||||||
new_addr, (tusb_descriptor_interface_t*) p_desc, &length) );
|
|
||||||
|
|
||||||
if (length == 0) // Interface open failed, for example a subclass is not supported
|
|
||||||
{
|
|
||||||
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
|
|
||||||
// TODO can optimize the length --> open_subtask return a OPEN FAILED status
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
usbh_devices[new_addr].flag_supported_class |= BIT_(((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass);
|
|
||||||
p_desc += length;
|
|
||||||
}
|
|
||||||
} else // unsupported class (not enable or yet implemented)
|
|
||||||
{
|
|
||||||
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tusbh_device_mount_succeed_cb(new_addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else // unsupported class (not enable or yet implemented)
|
||||||
|
{
|
||||||
|
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tusbh_device_mount_succeed_cb(new_addr);
|
||||||
|
|
||||||
OSAL_TASK_LOOP_END
|
OSAL_TASK_LOOP_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,35 +122,29 @@ static inline volatile uint32_t osal_tick_get(void)
|
||||||
}\
|
}\
|
||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
#define OSAL_SUBTASK_BEGIN OSAL_TASK_LOOP_BEGIN
|
#define OSAL_SUBTASK_BEGIN OSAL_TASK_LOOP_BEGIN
|
||||||
#define OSAL_SUBTASK_END OSAL_TASK_LOOP_END
|
#define OSAL_SUBTASK_END OSAL_TASK_LOOP_END
|
||||||
|
|
||||||
//------------- Task Assert -------------//
|
//------------- Task Assert -------------//
|
||||||
#define _TASK_ASSERT_ERROR_HANDLER(error, func_call) \
|
#define _TASK_ASSERT_ERROR_HANDLER(error, func_call) \
|
||||||
func_call; TASK_RESTART; return error
|
func_call; TASK_RESTART; return error
|
||||||
|
|
||||||
#define TASK_ASSERT_STATUS(sts) \
|
#define SUBTASK_ASSERT_STATUS(sts) \
|
||||||
ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, , tusb_error_t status = (tusb_error_t)(sts),\
|
ASSERT_DEFINE_WITH_HANDLER(_TASK_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])
|
||||||
|
|
||||||
#define TASK_ASSERT_STATUS_WITH_HANDLER(sts, func_call) \
|
#define SUBTASK_ASSERT_STATUS_WITH_HANDLER(sts, func_call) \
|
||||||
ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, func_call, tusb_error_t status = (tusb_error_t)(sts),\
|
ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, func_call, 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])
|
||||||
|
|
||||||
#define TASK_ASSERT(condition) \
|
#define SUBTASK_ASSERT(condition) \
|
||||||
ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, , , \
|
ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, , , \
|
||||||
(condition), TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false")
|
(condition), TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false")
|
||||||
|
|
||||||
#define TASK_ASSERT_WITH_HANDLER(condition, func_call) \
|
#define SUBTASK_ASSERT_WITH_HANDLER(condition, func_call) \
|
||||||
ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, func_call, ,\
|
ASSERT_DEFINE_WITH_HANDLER(_TASK_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")
|
||||||
|
|
||||||
//------------- Sub Task Assert -------------//
|
|
||||||
#define SUBTASK_ASSERT_STATUS TASK_ASSERT_STATUS
|
|
||||||
#define SUBTASK_ASSERT_STATUS_WITH_HANDLER TASK_ASSERT_STATUS_WITH_HANDLER
|
|
||||||
#define SUBTASK_ASSERT TASK_ASSERT
|
|
||||||
#define SUBTASK_ASSERT_WITH_HANDLER TASK_ASSERT_WITH_HANDLER
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Semaphore API
|
// Semaphore API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
Loading…
Reference in New Issue