2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @ file      usbd . c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @ 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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( INCLUDING ,  BUT  NOT  LIMITED  TO ,  PROCUREMENT  OF  SUBSTITUTE  GOODS  OR  SERVICES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    LOSS  OF  USE ,  DATA ,  OR  PROFITS ;  OR  BUSINESS  INTERRUPTION )  HOWEVER  CAUSED  AND 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ON  ANY  THEORY  OF  LIABILITY ,  WHETHER  IN  CONTRACT ,  STRICT  LIABILITY ,  OR  TORT 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( INCLUDING  NEGLIGENCE  OR  OTHERWISE )  ARISING  IN  ANY  WAY  OUT  OF  THE  USE  OF  THIS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SOFTWARE ,  EVEN  IF  ADVISED  OF  THE  POSSIBILITY  OF  SUCH  DAMAGE . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    This  file  is  part  of  the  tinyusb  stack . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "tusb_option.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# if MODE_DEVICE_SUPPORTED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define _TINY_USB_SOURCE_FILE_ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// INCLUDE
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "tusb.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "usbd_dcd.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MACRO CONSTANT TYPEDEF
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								usbd_device_info_t  usbd_devices [ CONTROLLER_DEVICE_NUMBER ] ;  
						 
					
						
							
								
									
										
										
										
											2014-03-23 10:15:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TUSB_CFG_ATTR_USBRAM  uint8_t  usbd_enum_buffer [ TUSB_CFG_DEVICE_ENUM_BUFFER_SIZE ] ;  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  usbd_class_driver_t  const  usbd_class_drivers [ ]  =  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # if DEVICE_CLASS_HID 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ TUSB_CLASS_HID ]  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . init                     =  hidd_init , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . open                     =  hidd_open , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . control_request_subtask  =  hidd_control_request_subtask , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . xfer_cb                  =  hidd_xfer_cb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . close                    =  hidd_close 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # if TUSB_CFG_DEVICE_MSC 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ TUSB_CLASS_MSC ]  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . init                     =  mscd_init , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . open                     =  mscd_open , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . control_request_subtask  =  mscd_control_request_subtask , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . xfer_cb                  =  mscd_xfer_cb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . close                    =  mscd_close 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # if TUSB_CFG_DEVICE_CDC 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ TUSB_CLASS_CDC ]  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . init                     =  cdcd_init , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . open                     =  cdcd_open , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . control_request_subtask  =  cdcd_control_request_subtask , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . xfer_cb                  =  cdcd_xfer_cb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . close                    =  cdcd_close 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-18 16:58:24 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								enum  {  USBD_CLASS_DRIVER_COUNT  =  sizeof ( usbd_class_drivers )  /  sizeof ( usbd_class_driver_t )  } ;  
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// INTERNAL OBJECT & FUNCTION DECLARATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  tusb_error_t  usbd_set_configure_received ( uint8_t  coreid ,  uint8_t  config_number ) ;  
						 
					
						
							
								
									
										
										
										
											2014-03-23 14:14:00 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  tusb_error_t  get_descriptor ( uint8_t  coreid ,  tusb_control_request_t  const  *  const  p_request ,  uint8_t  const  * *  pp_buffer ,  uint16_t  *  p_length ) ;  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// APPLICATION INTERFACE
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  tusbd_is_configured ( uint8_t  coreid )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  usbd_devices [ coreid ] . state  = =  TUSB_DEVICE_STATE_CONFIGURED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// IMPLEMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//------------- OSAL Task -------------//
  
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:40:28 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								enum  {  USBD_TASK_QUEUE_DEPTH  =  16  } ;  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-05-01 18:45:22 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								typedef  enum  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  USBD_EVENTID_SETUP_RECEIVED  =  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  USBD_EVENTID_XFER_DONE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} usbd_eventid_t ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								typedef  struct  ATTR_ALIGNED ( 4 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  coreid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  event_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  sub_event_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  reserved ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  union  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tusb_control_request_t  setup_received ;  // USBD_EVENTID_SETUP_RECEIVED
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  {  // USBD_EVENTID_XFER_DONE
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      endpoint_handle_t  edpt_hdl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      uint32_t  xferred_byte ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } xfer_done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  usbd_task_event_t ;  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								STATIC_ASSERT ( sizeof ( usbd_task_event_t )  < =  12 ,  " size is not correct " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-28 14:21:31 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifndef TUC_DEVICE_STACKSIZE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define TUC_DEVICE_STACKSIZE 150 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef TUSB_CFG_OS_TASK_PRIO 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define TUSB_CFG_OS_TASK_PRIO 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								OSAL_QUEUE_DEF ( usbd_queue_def ,  USBD_TASK_QUEUE_DEPTH ,  usbd_task_event_t ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OSAL_SEM_DEF ( usbd_control_xfer_semaphore_def ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  osal_queue_handle_t  usbd_queue_hdl ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*static*/  osal_semaphore_handle_t  usbd_control_xfer_sem_hdl ;  // TODO may need to change to static with wrapper function
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// IMPLEMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								tusb_error_t  usbd_control_request_subtask ( uint8_t  coreid ,  tusb_control_request_t  const  *  const  p_request ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  tusb_error_t  usbd_body_subtask ( void ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-28 14:21:31 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  osal_task_t  usbd_hdl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  osal_task_create ( usbd_task ,  " usbd " ,  TUC_DEVICE_STACKSIZE ,  NULL ,  TUSB_CFG_OS_TASK_PRIO ,  & usbd_hdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //------------- Descriptor Check -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ASSERT ( tusbd_descriptor_pointers . p_device  ! =  NULL  & &  tusbd_descriptor_pointers . p_configuration  ! =  NULL ,  TUSB_ERROR_DESCRIPTOR_CORRUPTED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //------------- class init -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( uint8_t  class_code  =  TUSB_CLASS_AUDIO ;  class_code  <  USBD_CLASS_DRIVER_COUNT ;  class_code + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  (  usbd_class_drivers [ class_code ] . init  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usbd_class_drivers [ class_code ] . init ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  TUSB_ERROR_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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.
  
						 
					
						
							
								
									
										
										
										
											2018-02-28 14:21:31 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  usbd_task (  void *  param )  
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2018-02-28 14:21:31 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ( void )  param ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OSAL_TASK_LOOP_BEGIN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  usbd_body_subtask ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OSAL_TASK_LOOP_END 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  tusb_error_t  usbd_body_subtask ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2014-04-09 22:29:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  static  usbd_task_event_t  event ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OSAL_SUBTASK_BEGIN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tusb_error_t  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  error  =  TUSB_ERROR_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:40:28 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  memclr_ ( & event ,  sizeof ( usbd_task_event_t ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  osal_queue_receive ( usbd_queue_hdl ,  & event ,  OSAL_TIMEOUT_WAIT_FOREVER ,  & error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SUBTASK_ASSERT_STATUS ( error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  (  USBD_EVENTID_SETUP_RECEIVED  = =  event . event_id  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    OSAL_SUBTASK_INVOKED_AND_WAIT (  usbd_control_request_subtask ( event . coreid ,  & event . setup_received ) ,  error  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:40:28 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } else  if  ( USBD_EVENTID_XFER_DONE  = =  event . event_id ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint8_t  class_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    class_index  =  std_class_code_to_index (  event . xfer_done . edpt_hdl . class_code  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:40:28 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    SUBTASK_ASSERT ( usbd_class_drivers [ class_index ] . xfer_cb  ! =  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    usbd_class_drivers [ class_index ] . xfer_cb (  event . xfer_done . edpt_hdl ,  ( tusb_event_t )  event . sub_event_id ,  event . xfer_done . xferred_byte ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SUBTASK_ASSERT ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-31 13:12:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OSAL_SUBTASK_END 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// CONTROL REQUEST
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								tusb_error_t  usbd_control_request_subtask ( uint8_t  coreid ,  tusb_control_request_t  const  *  const  p_request )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OSAL_SUBTASK_BEGIN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  tusb_error_t  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  error  =  TUSB_ERROR_NONE ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //------------- 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  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 14:14:00 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      uint8_t  const  *  p_buffer  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      uint16_t  length  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      error  =  get_descriptor ( coreid ,  p_request ,  & p_buffer ,  & length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  (  TUSB_ERROR_NONE  = =  error  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      { 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 14:14:00 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dcd_pipe_control_xfer ( coreid ,  ( tusb_direction_t )  p_request - > bmRequestType_bit . direction ,  ( uint8_t * )  p_buffer ,  length ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  (  TUSB_REQUEST_SET_ADDRESS  = =  p_request - > bRequest  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      dcd_controller_set_address ( coreid ,  ( uint8_t )  p_request - > wValue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usbd_devices [ coreid ] . state  =  TUSB_DEVICE_STATE_ADDRESSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  (  TUSB_REQUEST_SET_CONFIGURATION  = =  p_request - > bRequest  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usbd_set_configure_received ( coreid ,  ( uint8_t )  p_request - > wValue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      error  =  TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //------------- Class/Interface Specific Request -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else  if  (  TUSB_REQUEST_RECIPIENT_INTERFACE  = =  p_request - > bmRequestType_bit . recipient ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-09 22:29:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  uint8_t  class_code ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    class_code  =  usbd_devices [ coreid ] . interface2class [  u16_low_u8 ( p_request - > wIndex )  ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // TODO [Custom] TUSB_CLASS_DIAGNOSTIC, vendor etc ...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  (  ( class_code  >  0 )  & &  ( class_code  <  USBD_CLASS_DRIVER_COUNT )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								         usbd_class_drivers [ class_code ] . control_request_subtask  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      OSAL_SUBTASK_INVOKED_AND_WAIT (  usbd_class_drivers [ class_code ] . control_request_subtask ( coreid ,  p_request ) ,  error  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 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  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TUSB_REQUEST_CLEAR_FEATURE       = =  p_request - > bRequest  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dcd_pipe_clear_stall ( coreid ,  u16_low_u8 ( p_request - > wIndex )  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }  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 ( coreid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    ASSERT(error == TUSB_ERROR_NONE, VOID_RETURN);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } else  if  ( p_request - > wLength  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dcd_pipe_control_xfer ( coreid ,  ( tusb_direction_t )  p_request - > bmRequestType_bit . direction ,  NULL ,  0 ,  false ) ;  // zero length for non-data
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OSAL_SUBTASK_END 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TODO Host (windows) can get HID report descriptor before set configured
  
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// may need to open interface before set configured
  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //------------- parse configuration & open drivers -------------//
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  uint8_t  const  *  p_desc_config  =  tusbd_descriptor_pointers . p_configuration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  const  *  p_desc  =  p_desc_config  +  sizeof ( tusb_descriptor_configuration_t ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  uint16_t  const  config_total_length  =  ( ( tusb_descriptor_configuration_t * ) p_desc_config ) - > wTotalLength ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while (  p_desc  <  p_desc_config  +  config_total_length  ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  (  TUSB_DESC_TYPE_INTERFACE_ASSOCIATION  = =  p_desc [ DESCRIPTOR_OFFSET_TYPE ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-18 18:38:15 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      p_desc  + =  p_desc [ DESCRIPTOR_OFFSET_LENGTH ] ;  // ignore Interface Association
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ASSERT (  TUSB_DESC_TYPE_INTERFACE  = =  p_desc [ DESCRIPTOR_OFFSET_TYPE ] ,  TUSB_ERROR_NOT_SUPPORTED_YET  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      uint8_t  class_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      tusb_descriptor_interface_t *  p_desc_interface  =  ( tusb_descriptor_interface_t * )  p_desc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      class_index  =  p_desc_interface - > bInterfaceClass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:32:01 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      ASSERT (  class_index  ! =  0  & &  class_index  <  USBD_CLASS_DRIVER_COUNT  & &  usbd_class_drivers [ class_index ] . open  ! =  NULL ,  TUSB_ERROR_NOT_SUPPORTED_YET  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      ASSERT (  0  = =  usbd_devices [ coreid ] . interface2class [ p_desc_interface - > bInterfaceNumber ] ,  TUSB_ERROR_FAILED ) ;  // duplicate interface number TODO alternate setting
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usbd_devices [ coreid ] . interface2class [ p_desc_interface - > bInterfaceNumber ]  =  class_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      uint16_t  length = 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ASSERT_STATUS (  usbd_class_drivers [ class_index ] . open (  coreid ,  p_desc_interface ,  & length  )  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ASSERT (  length  > =  sizeof ( tusb_descriptor_interface_t ) ,  TUSB_ERROR_FAILED  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p_desc  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  TUSB_ERROR_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 14:14:00 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  tusb_error_t  get_descriptor ( uint8_t  coreid ,  tusb_control_request_t  const  *  const  p_request ,  uint8_t  const  * *  pp_buffer ,  uint16_t  *  p_length )  
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:18:05 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  tusb_std_descriptor_type_t  const  desc_type  =  ( tusb_std_descriptor_type_t )  u16_high_u8 ( p_request - > wValue ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  uint8_t  const  desc_index  =  u16_low_u8 (  p_request - > wValue  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  uint8_t  const  *  p_data  =  NULL  ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  switch ( desc_type ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TUSB_DESC_TYPE_DEVICE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p_data       =  tusbd_descriptor_pointers . p_device ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ( * p_length )  =  sizeof ( tusb_descriptor_device_t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TUSB_DESC_TYPE_CONFIGURATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p_data       =  tusbd_descriptor_pointers . p_configuration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ( * p_length )  =  ( ( tusb_descriptor_configuration_t * ) tusbd_descriptor_pointers . p_configuration ) - > wTotalLength ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TUSB_DESC_TYPE_STRING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  (  ! ( desc_index  <  100 )  )  return  TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ;  // windows sometimes ask for string at index 238 !!!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      p_data  =  tusbd_descriptor_pointers . p_string_arr [ desc_index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ASSERT (  p_data  ! =  NULL ,  TUSB_ERROR_FAILED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ( * p_length )   =  p_data [ 0 ] ;   // first byte of descriptor is its size
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-03 21:45:16 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // TODO Report Descriptor (HID Generic)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // TODO HID Descriptor
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default :  return  TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( * p_length )  =  min16_of ( p_request - > wLength ,  ( * p_length )  ) ;  // cannot return more than hosts requires
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-23 15:39:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ASSERT (  ( * p_length )  < =  TUSB_CFG_DEVICE_ENUM_BUFFER_SIZE ,  TUSB_ERROR_NOT_ENOUGH_MEMORY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  memcpy ( usbd_enum_buffer ,  p_data ,  ( * p_length ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( * pp_buffer )  =  usbd_enum_buffer ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  TUSB_ERROR_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// USBD-CLASS API
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// USBD-DCD Callback API
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  usbd_dcd_bus_event_isr ( uint8_t  coreid ,  usbd_bus_event_type_t  bus_event )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch ( bus_event ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  USBD_BUS_EVENT_RESET      : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  USBD_BUS_EVENT_UNPLUGGED  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      memclr_ ( & usbd_devices [ coreid ] ,  sizeof ( usbd_device_info_t ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:40:28 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      osal_queue_flush ( usbd_queue_hdl ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-04 12:22:33 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      osal_semaphore_reset ( usbd_control_xfer_sem_hdl ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-14 17:32:01 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      for  ( uint8_t  class_code  =  TUSB_CLASS_AUDIO ;  class_code  <  USBD_CLASS_DRIVER_COUNT ;  class_code + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  (  usbd_class_drivers [ class_code ] . close  )  usbd_class_drivers [ class_code ] . close (  coreid  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  USBD_BUS_EVENT_SUSPENDED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usbd_devices [ coreid ] . state  =  TUSB_DEVICE_STATE_SUSPENDED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default :  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  usbd_setup_received_isr ( uint8_t  coreid ,  tusb_control_request_t  *  p_request )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  usbd_task_event_t  task_event  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      . coreid           =  coreid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      . event_id         =  USBD_EVENTID_SETUP_RECEIVED , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  task_event . setup_received   =  ( * p_request ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:40:28 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ASSERT (  TUSB_ERROR_NONE  = =  osal_queue_send ( usbd_queue_hdl ,  & task_event ) ,  VOID_RETURN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  usbd_xfer_isr ( endpoint_handle_t  edpt_hdl ,  tusb_event_t  event ,  uint32_t  xferred_bytes )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( edpt_hdl . class_code  = =  0  )  // Control Transfer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:57:21 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ASSERT (  TUSB_ERROR_NONE  = =  osal_semaphore_post (  usbd_control_xfer_sem_hdl  ) ,  VOID_RETURN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    usbd_task_event_t  task_event  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . coreid        =  edpt_hdl . coreid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . event_id      =  USBD_EVENTID_XFER_DONE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . sub_event_id  =  event 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    task_event . xfer_done . xferred_byte  =  xferred_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    task_event . xfer_done . edpt_hdl      =  edpt_hdl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-04-24 23:40:28 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ASSERT (  TUSB_ERROR_NONE  = =  osal_queue_send ( usbd_queue_hdl ,  & task_event ) ,  VOID_RETURN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-12 14:01:38 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// HELPER
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif