From fc68439b746a466aa3d0bf197ee3f70cfa079f24 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 15 Nov 2013 12:30:22 +0700 Subject: add usbd_task to handle event task eg setup received --- tinyusb/class/msc_device.h | 3 + tinyusb/device/dcd_lpc_11uxx_13uxx.c | 6 +- tinyusb/device/usbd.c | 205 ++++++++++++++++++++++------------- tinyusb/device/usbd_dcd.h | 1 + tinyusb/host/usbh.c | 4 +- tinyusb/osal/osal_none.h | 1 + tinyusb/tusb.c | 2 +- 7 files changed, 140 insertions(+), 82 deletions(-) (limited to 'tinyusb') diff --git a/tinyusb/class/msc_device.h b/tinyusb/class/msc_device.h index fd117da95..3e6d9737f 100644 --- a/tinyusb/class/msc_device.h +++ b/tinyusb/class/msc_device.h @@ -53,6 +53,9 @@ // p_length [in,out] allocated/maximum length, application update with actual length msc_csw_status_t tusbd_msc_scsi_received_isr (uint8_t coreid, uint8_t lun, uint8_t scsi_cmd[16], void ** pp_buffer, uint16_t* p_length); +tusb_error_t tusbd_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT; +tusb_error_t tusbh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT; + //--------------------------------------------------------------------+ // USBD-CLASS DRIVER API //--------------------------------------------------------------------+ diff --git a/tinyusb/device/dcd_lpc_11uxx_13uxx.c b/tinyusb/device/dcd_lpc_11uxx_13uxx.c index 37952311f..3c0b2e3b0 100644 --- a/tinyusb/device/dcd_lpc_11uxx_13uxx.c +++ b/tinyusb/device/dcd_lpc_11uxx_13uxx.c @@ -73,6 +73,7 @@ enum { CMDSTAT_MASK_RESET_CHANGE = BIT_(26), }; +#if 0 typedef struct { union { struct { @@ -101,7 +102,7 @@ typedef struct { } reg_dev_cmd_stat_t; STATIC_ASSERT( sizeof(reg_dev_cmd_stat_t) == 4, "size is not correct" ); - +#endif // buffer input must be 64 byte alignment typedef struct { @@ -233,7 +234,7 @@ void dcd_isr(uint8_t coreid) if ( BIT_TEST_(int_status, 0) && (dev_cmd_stat & CMDSTAT_MASK_SETUP_RECEIVED) ) { // received control request from host // copy setup request & acknowledge so that the next setup can be received by hw - tusb_control_request_t control_request = dcd_data.setup_request; + usbd_setup_received_isr(coreid, &dcd_data.setup_request); // NXP control flowchart clear Active & Stall on both Control IN/OUT endpoints dcd_data.qhd[0][0].stall = dcd_data.qhd[1][0].stall = 0; @@ -241,7 +242,6 @@ void dcd_isr(uint8_t coreid) LPC_USB->DEVCMDSTAT |= CMDSTAT_MASK_SETUP_RECEIVED; dcd_data.qhd[0][1].buff_addr_offset = addr_offset(&dcd_data.setup_request); - usbd_setup_received_isr(coreid, &control_request); } //------------- Non-Control Endpoints -------------// diff --git a/tinyusb/device/usbd.c b/tinyusb/device/usbd.c index e16dafc97..83eabf5ae 100644 --- a/tinyusb/device/usbd.c +++ b/tinyusb/device/usbd.c @@ -95,6 +95,8 @@ static usbd_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_STAR //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +tusb_error_t usbd_set_configure_received(uint8_t coreid, uint8_t config_number); +tusb_error_t std_get_descriptor(uint8_t coreid, tusb_control_request_t * p_request); //--------------------------------------------------------------------+ // APPLICATION INTERFACE @@ -107,6 +109,117 @@ bool tusbd_is_configured(uint8_t coreid) //--------------------------------------------------------------------+ // IMPLEMENTATION //--------------------------------------------------------------------+ + +//------------- OSAL Task -------------// +enum { + USBD_TASK_QUEUE_DEPTH = 8 +}; + +typedef enum { + USBD_EVENTID_SETUP_RECEIVED = 1 +}; + +typedef struct { + uint8_t coreid; + uint8_t event_id; + uint8_t reserved[2]; +}usbd_task_event_t; + +OSAL_TASK_DEF(usbd_task, 150, TUSB_CFG_OS_TASK_PRIO); +OSAL_QUEUE_DEF(usbd_queue_def, USBD_TASK_QUEUE_DEPTH, usbd_task_event_t); + +static osal_queue_handle_t usbd_queue_hdl; + +tusb_error_t usbd_body_subtask(void) +{ + tusb_error_t error = TUSB_ERROR_NONE; + usbd_task_event_t event; + + OSAL_SUBTASK_BEGIN + + osal_queue_receive(usbd_queue_hdl, &event, OSAL_TIMEOUT_WAIT_FOREVER, &error); + + if ( USBD_EVENTID_SETUP_RECEIVED == event.event_id ) + { + usbd_device_info_t *p_device = &usbd_devices[event.coreid]; + tusb_control_request_t* p_request = &p_device->control_request; + + //------------- Standard Control such as those in enumeration -------------// + if( TUSB_REQUEST_RECIPIENT_DEVICE == p_request->bmRequestType_bit.recipient && + TUSB_REQUEST_TYPE_STANDARD == p_request->bmRequestType_bit.type ) + { + if ( TUSB_REQUEST_GET_DESCRIPTOR == p_request->bRequest ) + { + error = std_get_descriptor(event.coreid, p_request); + } + else if ( TUSB_REQUEST_SET_ADDRESS == p_request->bRequest ) + { + dcd_controller_set_address(event.coreid, (uint8_t) p_request->wValue); + p_device->state = TUSB_DEVICE_STATE_ADDRESSED; + dcd_pipe_control_xfer(event.coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0); // zero length + } + else if ( TUSB_REQUEST_SET_CONFIGURATION == p_request->bRequest ) + { + usbd_set_configure_received(event.coreid, (uint8_t) p_request->wValue); + dcd_pipe_control_xfer(event.coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0); // zero length + }else + { + error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; + } + } + //------------- Class/Interface Specific Request -------------// + else if ( TUSB_REQUEST_RECIPIENT_INTERFACE == p_request->bmRequestType_bit.recipient) + { + tusb_std_class_code_t class_code = p_device->interface2class[ u16_low_u8(p_request->wIndex) ]; + ASSERT_INT_WITHIN(TUSB_CLASS_AUDIO, TUSB_CLASS_AUDIO_VIDEO, class_code, VOID_RETURN); + + if ( usbd_class_drivers[class_code].control_request ) + { + error = usbd_class_drivers[class_code].control_request(event.coreid, p_request); + }else + { + error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; + } + } + //------------- Endpoint Request -------------// + else if ( TUSB_REQUEST_RECIPIENT_ENDPOINT == p_request->bmRequestType_bit.recipient && + TUSB_REQUEST_TYPE_STANDARD == p_request->bmRequestType_bit.type ) + { + if ( TUSB_REQUEST_CLEAR_FEATURE == p_request->bRequest ) + { + dcd_pipe_clear_stall(event.coreid, u16_low_u8(p_request->wIndex) ); + dcd_pipe_control_xfer(event.coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0); // zero length + } else + { + error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; + } + } else + { + error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; + } + + if(TUSB_ERROR_NONE != error) + { // Response with Protocol Stall if request is not supported + dcd_pipe_control_stall(event.coreid); + // ASSERT(error == TUSB_ERROR_NONE, VOID_RETURN); + } + } + + OSAL_SUBTASK_END +} +// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper +// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with +// forever loop cannot have any return at all. +OSAL_TASK_FUNCTION(usbd_task) (void* p_task_para) +{ + OSAL_TASK_LOOP_BEGIN + + usbd_body_subtask(); + + OSAL_TASK_LOOP_END +} + + void usbd_bus_reset(uint32_t coreid) { memclr_(&usbd_devices[coreid], sizeof(usbd_device_info_t)); @@ -124,6 +237,11 @@ tusb_error_t usbd_init (void) { ASSERT_STATUS ( dcd_init() ); + //------------- Task init -------------// + usbd_queue_hdl = osal_queue_create( OSAL_QUEUE_REF(usbd_queue_def) ); + ASSERT_PTR(usbd_queue_hdl, TUSB_ERROR_OSAL_QUEUE_FAILED); + ASSERT_STATUS( osal_task_create( OSAL_TASK_REF(usbd_task) )); + #if (TUSB_CFG_CONTROLLER_0_MODE & TUSB_MODE_DEVICE) dcd_controller_connect(0); #endif @@ -132,6 +250,7 @@ tusb_error_t usbd_init (void) dcd_controller_connect(1); #endif + //------------- class init -------------// for (tusb_std_class_code_t class_code = TUSB_CLASS_AUDIO; class_code <= TUSB_CLASS_AUDIO_VIDEO; class_code++) { if ( usbd_class_drivers[class_code].init ) @@ -148,7 +267,7 @@ tusb_error_t usbd_init (void) //--------------------------------------------------------------------+ // TODO Host (windows) can get HID report descriptor before set configured // need to open interface before set configured -tusb_error_t usbh_set_configure_received(uint8_t coreid, uint8_t config_number) +tusb_error_t usbd_set_configure_received(uint8_t coreid, uint8_t config_number) { dcd_controller_set_configuration(coreid); usbd_devices[coreid].state = TUSB_DEVICE_STATE_CONFIGURED; @@ -213,84 +332,18 @@ tusb_error_t std_get_descriptor(uint8_t coreid, tusb_control_request_t * p_reque return TUSB_ERROR_NONE; } +//--------------------------------------------------------------------+ +// DCD Callback API +//--------------------------------------------------------------------+ void usbd_setup_received_isr(uint8_t coreid, tusb_control_request_t * p_request) { - usbd_device_info_t *p_device = &usbd_devices[coreid]; - tusb_error_t error = TUSB_ERROR_NONE; + usbd_devices[coreid].control_request = (*p_request); - switch(p_request->bmRequestType_bit.recipient) - { - //------------- Standard Control such as those in enumeration -------------// - case TUSB_REQUEST_RECIPIENT_DEVICE: - if (p_request->bmRequestType_bit.type != TUSB_REQUEST_TYPE_STANDARD) - { - error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; - }else - { - switch ( p_request->bRequest ) - { - case TUSB_REQUEST_GET_DESCRIPTOR: - error = std_get_descriptor(coreid, p_request); - break; - - case TUSB_REQUEST_SET_ADDRESS: - dcd_controller_set_address(coreid, (uint8_t) p_request->wValue); - usbd_devices[coreid].state = TUSB_DEVICE_STATE_ADDRESSED; - - dcd_pipe_control_xfer(coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0); // zero length - break; - - case TUSB_REQUEST_SET_CONFIGURATION: - usbh_set_configure_received(coreid, (uint8_t) p_request->wValue); - - dcd_pipe_control_xfer(coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0); // zero length - break; - - default: error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; break; - } - } - break; - - //------------- Class/Interface Specific Reqequest -------------// - case TUSB_REQUEST_RECIPIENT_INTERFACE: - { - tusb_std_class_code_t class_code = p_device->interface2class[ u16_low_u8(p_request->wIndex) ]; - ASSERT_INT_WITHIN(TUSB_CLASS_AUDIO, TUSB_CLASS_AUDIO_VIDEO, class_code, VOID_RETURN); - - if ( usbd_class_drivers[class_code].control_request ) - { - error = usbd_class_drivers[class_code].control_request(coreid, p_request); - } - } - break; - - //------------- Endpoint Request -------------// - case TUSB_REQUEST_RECIPIENT_ENDPOINT: - if (p_request->bmRequestType_bit.type != TUSB_REQUEST_TYPE_STANDARD) - { - error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; - break; - } - - switch ( p_request->bRequest ) - { - case TUSB_REQUEST_CLEAR_FEATURE: - dcd_pipe_clear_stall(coreid, u16_low_u8(p_request->wIndex) ); - dcd_pipe_control_xfer(coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0); // zero length - break; - - default: error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; break; - } - break; - - default: error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; break; - } - - if(TUSB_ERROR_NONE != error) - { // Response with Protocol Stall if request is not supported - dcd_pipe_control_stall(coreid); -// ASSERT(error == TUSB_ERROR_NONE, VOID_RETURN); - } + osal_queue_send(usbd_queue_hdl, + &(usbd_task_event_t){ + .coreid = coreid, + .event_id = USBD_EVENTID_SETUP_RECEIVED} + ); } diff --git a/tinyusb/device/usbd_dcd.h b/tinyusb/device/usbd_dcd.h index e2a8ad24a..4a466a112 100644 --- a/tinyusb/device/usbd_dcd.h +++ b/tinyusb/device/usbd_dcd.h @@ -61,6 +61,7 @@ typedef struct { volatile uint8_t state; + tusb_control_request_t control_request; uint8_t interface2class[USBD_MAX_INTERFACE]; // determine interface number belongs to which class }usbd_device_info_t; diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index 1de0f0ae0..d058f8b66 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -266,7 +266,7 @@ void usbh_hub_port_plugged_isr(uint8_t hub_addr, uint8_t hub_port) { osal_queue_send(enum_queue_hdl, &(usbh_enumerate_t){ - .core_id = usbh_devices[hub_addr].core_id, + .core_id = usbh_devices[hub_addr].core_id, .hub_addr = hub_addr, .hub_port = hub_port} ); @@ -276,7 +276,7 @@ void usbh_hcd_rhport_plugged_isr(uint8_t hostid) { osal_queue_send(enum_queue_hdl, &(usbh_enumerate_t){ - .core_id = hostid, + .core_id = hostid, .hub_addr = 0, .hub_port = 0} ); diff --git a/tinyusb/osal/osal_none.h b/tinyusb/osal/osal_none.h index 80ae80fd3..008264265 100644 --- a/tinyusb/osal/osal_none.h +++ b/tinyusb/osal/osal_none.h @@ -92,6 +92,7 @@ static inline uint32_t osal_tick_get(void) // } //--------------------------------------------------------------------+ #define OSAL_TASK_DEF(code, stack_depth, prio) +#define OSAL_TASK_REF #define osal_task_create(x) TUSB_ERROR_NONE #define OSAL_TASK_FUNCTION(task_func) \ diff --git a/tinyusb/tusb.c b/tinyusb/tusb.c index 800fa0a2d..f9a457599 100644 --- a/tinyusb/tusb.c +++ b/tinyusb/tusb.c @@ -85,7 +85,7 @@ void tusb_task_runner(void) #endif #if MODE_DEVICE_SUPPORTED - + usbd_task(NULL); #endif } #endif -- cgit v1.3.1