2013-05-06 07:50:19 +02:00
/**************************************************************************/
/*!
2013-05-23 08:22:46 +02:00
@ file usbd . c
2013-05-06 07:50:19 +02:00
@ author hathach ( tinyusb . org )
@ section LICENSE
Software License Agreement ( BSD License )
Copyright ( c ) 2013 , hathach ( tinyusb . org )
All rights reserved .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ' ' AS IS ' ' AND ANY
EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
2013-05-23 08:22:46 +02:00
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
2013-05-06 07:50:19 +02:00
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
2013-05-23 08:22:46 +02:00
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
2013-05-06 07:50:19 +02:00
SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
This file is part of the tinyusb stack .
*/
/**************************************************************************/
2012-11-29 11:52:57 +01:00
2013-05-23 08:22:46 +02:00
# include "tusb_option.h"
2012-11-29 11:52:57 +01:00
2013-05-23 08:22:46 +02:00
# if MODE_DEVICE_SUPPORTED
2012-11-29 11:52:57 +01:00
2013-05-23 08:22:46 +02:00
# define _TINY_USB_SOURCE_FILE_
2013-01-16 06:43:17 +01:00
2013-05-23 08:22:46 +02:00
//--------------------------------------------------------------------+
// INCLUDE
//--------------------------------------------------------------------+
# include "tusb.h"
2013-05-31 13:21:31 +02:00
# include "tusb_descriptors.h" // TODO callback include
2013-06-07 21:50:10 +02:00
# include "usbd_dcd.h"
2012-12-04 12:18:29 +01:00
2013-11-15 10:47:26 +01:00
// Some MCUs cannot transfer more than 64 bytes each queue, thus require special task-alike treatment
2013-11-18 11:29:12 +01:00
# if MCU == MCU_LPC11UXX || MCU == MCU_LPC175X_6X
2013-11-15 10:47:26 +01:00
# define USBD_CONTROL_ONE_PACKET_EACH_XFER // for each Transfer, cannot queue more than packet size
enum {
USBD_COTNROL_MAX_LENGTH_EACH_XFER = 64
} ;
# endif
2013-01-16 06:43:17 +01:00
//--------------------------------------------------------------------+
2013-05-23 08:22:46 +02:00
// MACRO CONSTANT TYPEDEF
2013-01-16 06:43:17 +01:00
//--------------------------------------------------------------------+
2013-06-07 21:50:10 +02:00
usbd_device_info_t usbd_devices [ CONTROLLER_DEVICE_NUMBER ] ;
2013-05-28 10:24:27 +02:00
2013-06-03 09:31:17 +02:00
// TODO fix/compress number of class driver
2013-11-08 06:03:32 +01:00
static usbd_class_driver_t const usbd_class_drivers [ TUSB_CLASS_MAPPED_INDEX_START ] =
2013-06-03 09:31:17 +02:00
{
# if DEVICE_CLASS_HID
2013-11-08 06:03:32 +01:00
[ TUSB_CLASS_HID ] =
{
. init = hidd_init ,
2013-10-29 10:29:48 +01:00
. open = hidd_open ,
2013-06-16 09:41:48 +02:00
. control_request = hidd_control_request ,
2013-11-08 06:03:32 +01:00
. isr = hidd_isr ,
. bus_reset = hidd_bus_reset
2013-06-03 09:31:17 +02:00
} ,
# endif
2013-11-01 06:11:26 +01:00
# if TUSB_CFG_DEVICE_MSC
2013-11-08 06:03:32 +01:00
[ TUSB_CLASS_MSC ] =
{
. init = mscd_init ,
2013-11-01 06:11:26 +01:00
. open = mscd_open ,
. control_request = mscd_control_request ,
2013-11-08 06:03:32 +01:00
. isr = mscd_isr ,
. bus_reset = mscd_bus_reset
} ,
# endif
# if TUSB_CFG_DEVICE_CDC
[ TUSB_CLASS_CDC ] =
{
. init = cdcd_init ,
. open = cdcd_open ,
. control_request = cdcd_control_request ,
. isr = cdcd_isr ,
. bus_reset = cdcd_bus_reset
2013-11-01 06:11:26 +01:00
} ,
# endif
2013-06-03 09:31:17 +02:00
} ;
2012-11-29 11:52:57 +01:00
2013-01-16 06:43:17 +01:00
//--------------------------------------------------------------------+
2013-05-23 08:22:46 +02:00
// INTERNAL OBJECT & FUNCTION DECLARATION
2013-01-16 06:43:17 +01:00
//--------------------------------------------------------------------+
2013-11-15 06:30:22 +01:00
tusb_error_t usbd_set_configure_received ( uint8_t coreid , uint8_t config_number ) ;
2013-11-15 09:05:23 +01:00
tusb_error_t get_descriptor_subtask ( uint8_t coreid , tusb_control_request_t * p_request , uint8_t const * * pp_buffer , uint16_t * p_length ) ;
2013-05-31 16:24:40 +02:00
//--------------------------------------------------------------------+
// APPLICATION INTERFACE
//--------------------------------------------------------------------+
2013-06-14 14:06:33 +02:00
bool tusbd_is_configured ( uint8_t coreid )
{
return usbd_devices [ coreid ] . state = = TUSB_DEVICE_STATE_CONFIGURED ;
}
2013-01-16 06:43:17 +01:00
2013-06-21 08:11:16 +02:00
//--------------------------------------------------------------------+
// IMPLEMENTATION
//--------------------------------------------------------------------+
2013-11-15 06:30:22 +01:00
//------------- OSAL Task -------------//
enum {
USBD_TASK_QUEUE_DEPTH = 8
} ;
typedef enum {
USBD_EVENTID_SETUP_RECEIVED = 1
2013-11-15 07:26:12 +01:00
} usbd_eventid_t ;
2013-11-15 06:30:22 +01:00
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 ) ;
2013-11-15 10:47:26 +01:00
OSAL_SEM_DEF ( usbd_control_xfer_semaphore_def ) ;
2013-11-15 06:30:22 +01:00
static osal_queue_handle_t usbd_queue_hdl ;
2013-11-15 10:47:26 +01:00
static osal_semaphore_handle_t usbd_control_xfer_sem_hdl ;
2013-11-15 06:30:22 +01:00
tusb_error_t usbd_body_subtask ( void )
{
2013-11-15 07:26:12 +01:00
OSAL_SUBTASK_BEGIN
2013-11-15 10:47:26 +01:00
static uint8_t coreid ;
2013-11-15 06:30:22 +01:00
tusb_error_t error = TUSB_ERROR_NONE ;
usbd_task_event_t event ;
osal_queue_receive ( usbd_queue_hdl , & event , OSAL_TIMEOUT_WAIT_FOREVER , & error ) ;
2013-11-15 07:26:12 +01:00
SUBTASK_ASSERT_STATUS ( error ) ;
2013-11-15 06:30:22 +01:00
2013-11-15 10:47:26 +01:00
coreid = event . coreid ;
2013-11-15 06:30:22 +01:00
if ( USBD_EVENTID_SETUP_RECEIVED = = event . event_id )
2013-11-15 10:47:26 +01:00
{ // should copy to setup packet to local variable as the new one may overwrite while we processing here
static tusb_control_request_t control_request ;
control_request = usbd_devices [ coreid ] . control_request ;
2013-11-15 06:30:22 +01:00
//------------- Standard Control such as those in enumeration -------------//
2013-11-15 10:47:26 +01:00
if ( TUSB_REQUEST_RECIPIENT_DEVICE = = control_request . bmRequestType_bit . recipient & &
TUSB_REQUEST_TYPE_STANDARD = = control_request . bmRequestType_bit . type )
2013-11-15 06:30:22 +01:00
{
2013-11-15 10:47:26 +01:00
if ( TUSB_REQUEST_GET_DESCRIPTOR = = control_request . bRequest )
2013-11-15 06:30:22 +01:00
{
2013-11-15 09:05:23 +01:00
static uint8_t const * p_buffer = NULL ;
static uint16_t length = 0 ;
2013-11-15 10:47:26 +01:00
error = get_descriptor_subtask ( coreid , & control_request , & p_buffer , & length ) ;
# ifdef USBD_CONTROL_ONE_PACKET_EACH_XFER
while ( length > USBD_COTNROL_MAX_LENGTH_EACH_XFER & & error = = TUSB_ERROR_NONE )
{
usbd_devices [ coreid ] . is_waiting_control_xfer = true ;
2013-11-15 09:05:23 +01:00
2013-11-15 10:47:26 +01:00
dcd_pipe_control_xfer ( coreid , control_request . bmRequestType_bit . direction , p_buffer , USBD_COTNROL_MAX_LENGTH_EACH_XFER ) ; // zero length
osal_semaphore_wait ( usbd_control_xfer_sem_hdl , OSAL_TIMEOUT_NORMAL , & error ) ;
length - = USBD_COTNROL_MAX_LENGTH_EACH_XFER ;
p_buffer + = USBD_COTNROL_MAX_LENGTH_EACH_XFER ;
2013-11-20 09:34:49 +01:00
usbd_devices [ coreid ] . is_waiting_control_xfer = false ;
2013-11-15 10:47:26 +01:00
}
# endif
if ( TUSB_ERROR_NONE = = error )
{
2013-11-18 11:29:12 +01:00
dcd_pipe_control_xfer ( coreid , control_request . bmRequestType_bit . direction , p_buffer , length ) ;
2013-11-15 10:47:26 +01:00
}
2013-11-15 06:30:22 +01:00
}
2013-11-15 10:47:26 +01:00
else if ( TUSB_REQUEST_SET_ADDRESS = = control_request . bRequest )
2013-11-15 06:30:22 +01:00
{
2013-11-15 10:47:26 +01:00
dcd_controller_set_address ( coreid , ( uint8_t ) control_request . wValue ) ;
usbd_devices [ coreid ] . state = TUSB_DEVICE_STATE_ADDRESSED ;
2013-11-15 06:30:22 +01:00
}
2013-11-15 10:47:26 +01:00
else if ( TUSB_REQUEST_SET_CONFIGURATION = = control_request . bRequest )
2013-11-15 06:30:22 +01:00
{
2013-11-15 10:47:26 +01:00
usbd_set_configure_received ( coreid , ( uint8_t ) control_request . wValue ) ;
2013-11-15 06:30:22 +01:00
} else
{
error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ;
}
}
//------------- Class/Interface Specific Request -------------//
2013-11-15 10:47:26 +01:00
else if ( TUSB_REQUEST_RECIPIENT_INTERFACE = = control_request . bmRequestType_bit . recipient )
2013-11-15 06:30:22 +01:00
{
2013-11-15 10:47:26 +01:00
tusb_std_class_code_t class_code = usbd_devices [ coreid ] . interface2class [ u16_low_u8 ( control_request . wIndex ) ] ;
2013-11-15 06:30:22 +01:00
2013-11-15 07:26:12 +01:00
if ( ( TUSB_CLASS_AUDIO < = class_code ) & & ( class_code < = TUSB_CLASS_AUDIO_VIDEO ) & &
usbd_class_drivers [ class_code ] . control_request )
2013-11-15 06:30:22 +01:00
{
2013-11-15 10:47:26 +01:00
error = usbd_class_drivers [ class_code ] . control_request ( coreid , & control_request ) ;
2013-11-15 06:30:22 +01:00
} else
{
error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ;
}
}
//------------- Endpoint Request -------------//
2013-11-15 10:47:26 +01:00
else if ( TUSB_REQUEST_RECIPIENT_ENDPOINT = = control_request . bmRequestType_bit . recipient & &
TUSB_REQUEST_TYPE_STANDARD = = control_request . bmRequestType_bit . type & &
TUSB_REQUEST_CLEAR_FEATURE = = control_request . bRequest )
2013-11-15 06:30:22 +01:00
{
2013-11-15 10:47:26 +01:00
dcd_pipe_clear_stall ( coreid , u16_low_u8 ( control_request . wIndex ) ) ;
2013-11-15 06:30:22 +01:00
} else
{
error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ;
}
if ( TUSB_ERROR_NONE ! = error )
{ // Response with Protocol Stall if request is not supported
2013-11-15 10:47:26 +01:00
dcd_pipe_control_stall ( coreid ) ;
2013-11-15 06:30:22 +01:00
// ASSERT(error == TUSB_ERROR_NONE, VOID_RETURN);
2013-11-15 08:15:05 +01:00
} else
{ // status phase
2013-11-15 10:47:26 +01:00
dcd_pipe_control_xfer ( coreid , 1 - control_request . bmRequestType_bit . direction , NULL , 0 ) ; // zero length
2013-11-15 06:30:22 +01:00
}
}
OSAL_SUBTASK_END
}
2013-11-15 07:26:12 +01:00
2013-11-15 06:30:22 +01:00
// 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
}
2013-06-07 21:50:10 +02:00
void usbd_bus_reset ( uint32_t coreid )
{
2013-10-29 08:19:56 +01:00
memclr_ ( & usbd_devices [ coreid ] , sizeof ( usbd_device_info_t ) ) ;
2013-11-08 06:03:32 +01:00
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 ] . bus_reset )
{
usbd_class_drivers [ class_code ] . bus_reset ( coreid ) ;
}
}
2013-06-07 21:50:10 +02:00
}
2013-11-01 08:44:14 +01:00
tusb_error_t usbd_init ( void )
{
ASSERT_STATUS ( dcd_init ( ) ) ;
2013-11-15 06:30:22 +01:00
//------------- Task init -------------//
usbd_queue_hdl = osal_queue_create ( OSAL_QUEUE_REF ( usbd_queue_def ) ) ;
ASSERT_PTR ( usbd_queue_hdl , TUSB_ERROR_OSAL_QUEUE_FAILED ) ;
2013-11-15 10:47:26 +01:00
usbd_control_xfer_sem_hdl = osal_semaphore_create ( OSAL_SEM_REF ( usbd_control_xfer_semaphore_def ) ) ;
ASSERT_PTR ( usbd_queue_hdl , TUSB_ERROR_OSAL_SEMAPHORE_FAILED ) ;
2013-11-15 06:30:22 +01:00
ASSERT_STATUS ( osal_task_create ( OSAL_TASK_REF ( usbd_task ) ) ) ;
//------------- class init -------------//
2013-11-08 06:03:32 +01:00
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 )
{
usbd_class_drivers [ class_code ] . init ( ) ;
}
}
2013-11-01 08:44:14 +01:00
return TUSB_ERROR_NONE ;
}
//--------------------------------------------------------------------+
// CONTROL REQUEST
//--------------------------------------------------------------------+
2013-11-14 08:12:07 +01:00
// TODO Host (windows) can get HID report descriptor before set configured
// need to open interface before set configured
2013-11-15 06:30:22 +01:00
tusb_error_t usbd_set_configure_received ( uint8_t coreid , uint8_t config_number )
2013-10-29 08:19:56 +01:00
{
2013-11-14 08:12:07 +01:00
dcd_controller_set_configuration ( coreid ) ;
2013-10-29 08:19:56 +01:00
usbd_devices [ coreid ] . state = TUSB_DEVICE_STATE_CONFIGURED ;
2013-10-30 08:13:06 +01:00
//------------- parse configuration & open drivers -------------//
uint8_t * p_desc_configure = ( uint8_t * ) & app_tusb_desc_configuration ;
uint8_t * p_desc = p_desc_configure + sizeof ( tusb_descriptor_configuration_t ) ;
2013-10-29 08:19:56 +01:00
2013-10-30 08:13:06 +01:00
while ( p_desc < p_desc_configure + ( ( tusb_descriptor_configuration_t * ) p_desc_configure ) - > wTotalLength )
2013-10-29 10:29:48 +01:00
{
2013-11-15 11:20:40 +01:00
if ( TUSB_DESC_TYPE_INTERFACE_ASSOCIATION = = p_desc [ DESCRIPTOR_OFFSET_TYPE ] )
{
p_desc + = p_desc [ DESCRIPTOR_OFFSET_LENGTH ] ; // ignore IAD
} else
{
ASSERT ( TUSB_DESC_TYPE_INTERFACE = = p_desc [ DESCRIPTOR_OFFSET_TYPE ] , TUSB_ERROR_NOT_SUPPORTED_YET ) ;
2013-10-29 08:19:56 +01:00
2013-11-15 11:20:40 +01:00
uint8_t class_index ;
tusb_descriptor_interface_t * p_desc_interface = ( tusb_descriptor_interface_t * ) p_desc ;
2013-10-29 11:16:41 +01:00
2013-11-15 11:20:40 +01:00
class_index = p_desc_interface - > bInterfaceClass ;
2013-10-30 08:13:06 +01:00
2013-11-15 11:20:40 +01:00
ASSERT ( class_index ! = 0 & & usbd_class_drivers [ class_index ] . open ! = NULL , TUSB_ERROR_NOT_SUPPORTED_YET ) ;
ASSERT ( 0 = = usbd_devices [ coreid ] . interface2class [ p_desc_interface - > bInterfaceNumber ] , TUSB_ERROR_FAILED ) ; // duplicate interface number TODO alternate setting
2013-10-30 08:13:06 +01:00
2013-11-15 11:20:40 +01:00
usbd_devices [ coreid ] . interface2class [ p_desc_interface - > bInterfaceNumber ] = class_index ;
2013-10-30 08:13:06 +01:00
2013-11-15 11:20:40 +01:00
uint16_t length = 0 ;
ASSERT_STATUS ( usbd_class_drivers [ class_index ] . open ( coreid , p_desc_interface , & length ) ) ;
2013-10-30 08:13:06 +01:00
2013-11-15 11:20:40 +01:00
ASSERT ( length > = sizeof ( tusb_descriptor_interface_t ) , TUSB_ERROR_FAILED ) ;
p_desc + = length ;
}
2013-10-29 11:16:41 +01:00
}
2013-10-29 08:19:56 +01:00
2013-10-30 06:20:00 +01:00
return TUSB_ERROR_NONE ;
2013-10-29 08:19:56 +01:00
}
2013-11-15 09:05:23 +01:00
tusb_error_t get_descriptor_subtask ( uint8_t coreid , tusb_control_request_t * p_request , uint8_t const * * pp_buffer , uint16_t * p_length )
2013-11-01 06:11:26 +01:00
{
2013-11-15 09:05:23 +01:00
tusb_std_descriptor_type_t const desc_type = u16_high_u8 ( p_request - > wValue ) ;
2013-11-01 06:11:26 +01:00
uint8_t const desc_index = u16_low_u8 ( p_request - > wValue ) ;
2013-11-11 06:48:21 +01:00
2013-11-15 07:26:12 +01:00
if ( TUSB_DESC_TYPE_DEVICE = = desc_type )
2013-11-01 06:11:26 +01:00
{
2013-11-15 09:05:23 +01:00
( * pp_buffer ) = ( uint8_t const * ) & app_tusb_desc_device ;
( * p_length ) = sizeof ( tusb_descriptor_device_t ) ;
2013-11-15 07:26:12 +01:00
}
else if ( TUSB_DESC_TYPE_CONFIGURATION = = desc_type )
{
2013-11-15 09:05:23 +01:00
( * pp_buffer ) = ( uint8_t const * ) & app_tusb_desc_configuration ;
( * p_length ) = sizeof ( app_tusb_desc_configuration ) ;
2013-11-15 07:26:12 +01:00
}
else if ( TUSB_DESC_TYPE_STRING = = desc_type )
{
2013-11-15 09:05:23 +01:00
if ( ! ( desc_index < TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT ) ) return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ;
2013-11-01 06:11:26 +01:00
2013-11-15 09:05:23 +01:00
( * pp_buffer ) = ( uint8_t const * ) desc_str_table [ desc_index ] ;
( * p_length ) = desc_str_table [ desc_index ] - > bLength ;
2013-11-15 07:26:12 +01:00
} else
{
2013-11-15 09:05:23 +01:00
return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ;
2013-11-01 06:11:26 +01:00
}
2013-11-15 09:05:23 +01:00
( * p_length ) = min16_of ( p_request - > wLength , ( * p_length ) ) ; // cannot return more than hosts requires
2013-11-15 07:26:12 +01:00
2013-11-15 09:05:23 +01:00
return TUSB_ERROR_NONE ;
2013-11-01 06:11:26 +01:00
}
2013-11-15 07:26:12 +01:00
//--------------------------------------------------------------------+
// USBD-CLASS API
//--------------------------------------------------------------------+
2013-11-01 06:11:26 +01:00
2013-11-15 06:30:22 +01:00
//--------------------------------------------------------------------+
// DCD Callback API
//--------------------------------------------------------------------+
2013-10-29 05:27:25 +01:00
void usbd_setup_received_isr ( uint8_t coreid , tusb_control_request_t * p_request )
2013-06-07 21:50:10 +02:00
{
2013-11-15 06:30:22 +01:00
usbd_devices [ coreid ] . control_request = ( * p_request ) ;
2013-11-01 06:11:26 +01:00
2013-11-15 06:30:22 +01:00
osal_queue_send ( usbd_queue_hdl ,
& ( usbd_task_event_t ) {
. coreid = coreid ,
. event_id = USBD_EVENTID_SETUP_RECEIVED }
) ;
2013-06-07 21:50:10 +02:00
}
2013-10-29 10:29:48 +01:00
void usbd_xfer_isr ( endpoint_handle_t edpt_hdl , tusb_event_t event , uint32_t xferred_bytes )
{
2013-11-01 06:11:26 +01:00
// usbd_device_info_t *p_device = &usbd_devices[edpt_hdl.coreid];
uint8_t class_index = std_class_code_to_index ( edpt_hdl . class_code ) ;
2013-11-15 10:47:26 +01:00
if ( class_index = = 0 ) // Control Transfer
2013-11-01 06:11:26 +01:00
{
2013-11-15 10:47:26 +01:00
if ( usbd_devices [ edpt_hdl . coreid ] . is_waiting_control_xfer )
{
osal_semaphore_post ( usbd_control_xfer_sem_hdl ) ;
}
2013-11-01 06:11:26 +01:00
} else if ( usbd_class_drivers [ class_index ] . isr )
{
usbd_class_drivers [ class_index ] . isr ( edpt_hdl , event , xferred_bytes ) ;
} else
{
ASSERT ( false , VOID_RETURN ) ; // something wrong, no one claims the isr's source
}
2013-10-29 10:29:48 +01:00
}
2013-06-07 21:50:10 +02:00
2013-05-31 16:24:40 +02:00
//--------------------------------------------------------------------+
// HELPER
//--------------------------------------------------------------------+
2013-06-21 08:11:16 +02:00
# endif