2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  MIT  License  ( MIT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020  Raspberry  Pi  ( Trading )  Ltd . 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 18:26:41 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021  Ha  Thach  ( tinyusb . org )  for  Double  Buffered 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Permission  is  hereby  granted ,  free  of  charge ,  to  any  person  obtaining  a  copy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  of  this  software  and  associated  documentation  files  ( the  " Software " ) ,  to  deal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  in  the  Software  without  restriction ,  including  without  limitation  the  rights 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  to  use ,  copy ,  modify ,  merge ,  publish ,  distribute ,  sublicense ,  and / or  sell 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  copies  of  the  Software ,  and  to  permit  persons  to  whom  the  Software  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  furnished  to  do  so ,  subject  to  the  following  conditions : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  above  copyright  notice  and  this  permission  notice  shall  be  included  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  all  copies  or  substantial  portions  of  the  Software . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  THE  SOFTWARE  IS  PROVIDED  " AS IS " ,  WITHOUT  WARRANTY  OF  ANY  KIND ,  EXPRESS  OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  IMPLIED ,  INCLUDING  BUT  NOT  LIMITED  TO  THE  WARRANTIES  OF  MERCHANTABILITY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  FITNESS  FOR  A  PARTICULAR  PURPOSE  AND  NONINFRINGEMENT .  IN  NO  EVENT  SHALL  THE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY  CLAIM ,  DAMAGES  OR  OTHER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  LIABILITY ,  WHETHER  IN  AN  ACTION  OF  CONTRACT ,  TORT  OR  OTHERWISE ,  ARISING  FROM , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  OUT  OF  OR  IN  CONNECTION  WITH  THE  SOFTWARE  OR  THE  USE  OR  OTHER  DEALINGS  IN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  THE  SOFTWARE . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  file  is  part  of  the  TinyUSB  stack . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "tusb_option.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-02 12:22:20 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB 
  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "pico.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "rp2040_usb.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// INCLUDE
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "osal/osal.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "host/hcd.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "host/usbh.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-01 23:55:53 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// port 0 is native USB port, other is counted as software PIO
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RHPORT_NATIVE 0 
  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Low level rp2040 controller functions
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef PICO_USB_HOST_INTERRUPT_ENDPOINTS 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define PICO_USB_HOST_INTERRUPT_ENDPOINTS (USB_MAX_ENDPOINTS - 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static_assert ( PICO_USB_HOST_INTERRUPT_ENDPOINTS  < =  USB_MAX_ENDPOINTS ,  " " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Host mode uses one shared endpoint register for non-interrupt endpoint
  
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  hw_endpoint  ep_pool [ 1  +  PICO_USB_HOST_INTERRUPT_ENDPOINTS ] ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define epx (ep_pool[0]) 
  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define usb_hw_set   hw_set_alias(usb_hw) 
  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define usb_hw_clear hw_clear_alias(usb_hw) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Flags we set by default in sie_ctrl (we add other bits on top)
  
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								enum  {  
						 
					
						
							
								
									
										
										
										
											2021-08-11 20:06:57 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  SIE_CTRL_BASE  =  USB_SIE_CTRL_SOF_EN_BITS       |  USB_SIE_CTRL_KEEP_ALIVE_EN_BITS  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  USB_SIE_CTRL_PULLDOWN_EN_BITS  |  USB_SIE_CTRL_EP0_INT_1BUF_BITS 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  hw_endpoint  * get_dev_ep ( uint8_t  dev_addr ,  uint8_t  ep_addr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:18:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  uint8_t  num  =  tu_edpt_number ( ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  (  num  = =  0  )  return  & epx ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:18:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  (  uint32_t  i  =  1 ;  i  <  TU_ARRAY_SIZE ( ep_pool ) ;  i + +  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  hw_endpoint  * ep  =  & ep_pool [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  (  ep - > configured  & &  ( ep - > dev_addr  = =  dev_addr )  & &  ( ep - > ep_addr  = =  ep_addr )  )  return  ep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:18:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 16:08:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TU_ATTR_ALWAYS_INLINE  static  inline  uint8_t  dev_speed ( void )  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( usb_hw - > sie_status  &  USB_SIE_STATUS_SPEED_BITS )  > >  USB_SIE_STATUS_SPEED_LSB ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  need_pre ( uint8_t  dev_addr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // If this device is different to the speed of the root device
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // (i.e. is a low speed device on a full speed hub) then need pre
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-24 12:30:57 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  hcd_port_speed_get ( 0 )  ! =  tuh_speed_get ( dev_addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 16:08:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __no_inline_not_in_flash_func ( hw_xfer_complete ) ( struct  hw_endpoint  * ep ,  xfer_result_t  xfer_result )  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Mark transfer as done before we tell the tinyusb stack
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint8_t  dev_addr  =  ep - > dev_addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint8_t  ep_addr  =  ep - > ep_addr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:58:29 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    uint  xferred_len  =  ep - > xferred_len ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    hw_endpoint_reset_transfer ( ep ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    hcd_event_xfer_complete ( dev_addr ,  ep_addr ,  xferred_len ,  xfer_result ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 16:08:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __no_inline_not_in_flash_func ( _handle_buff_status_bit ) ( uint  bit ,  struct  hw_endpoint  * ep )  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    usb_hw_clear - > buf_status  =  bit ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:34:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  done  =  hw_endpoint_xfer_continue ( ep ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( done ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        hw_xfer_complete ( ep ,  XFER_RESULT_SUCCESS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 16:08:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __no_inline_not_in_flash_func ( hw_handle_buff_status ) ( void )  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint32_t  remaining_buffers  =  usb_hw - > buf_status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pico_trace ( " buf_status 0x%08x \n " ,  remaining_buffers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Check EPX first
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint  bit  =  0 b1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( remaining_buffers  &  bit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        remaining_buffers  & =  ~ bit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        struct  hw_endpoint  * ep  =  & epx ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        uint32_t  ep_ctrl  =  * ep - > endpoint_control ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ep_ctrl  &  EP_CTRL_DOUBLE_BUFFERED_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 18:53:56 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          TU_LOG ( 3 ,  " Double Buffered:  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 18:53:56 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          TU_LOG ( 3 ,  " Single Buffered:  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 18:53:56 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TU_LOG_HEX ( 3 ,  ep_ctrl ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        _handle_buff_status_bit ( bit ,  ep ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Check interrupt endpoints
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( uint  i  =  1 ;  i  < =  USB_HOST_INTERRUPT_ENDPOINTS  & &  remaining_buffers ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // EPX is bit 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // IEP1 is bit 2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // IEP2 is bit 4
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // IEP3 is bit 6
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // etc
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bit  =  1  < <  ( i * 2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( remaining_buffers  &  bit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            remaining_buffers  & =  ~ bit ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            _handle_buff_status_bit ( bit ,  & ep_pool [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( remaining_buffers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        panic ( " Unhandled buffer %d \n " ,  remaining_buffers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 16:08:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __no_inline_not_in_flash_func ( hw_trans_complete ) ( void )  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:27:20 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( usb_hw - > sie_ctrl  &  USB_SIE_CTRL_SEND_SETUP_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pico_trace ( " Sent setup packet \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 09:39:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    struct  hw_endpoint  * ep  =  & epx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( ep - > active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:27:20 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    hw_xfer_complete ( ep ,  XFER_RESULT_SUCCESS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Don't care. Will handle this in buff status
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 16:08:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __no_inline_not_in_flash_func ( hcd_rp2040_irq ) ( void )  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint32_t  status  =  usb_hw - > ints ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint32_t  handled  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( status  &  USB_INTS_HOST_CONN_DIS_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handled  | =  USB_INTS_HOST_CONN_DIS_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( dev_speed ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-01 23:55:53 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            hcd_event_device_attach ( RHPORT_NATIVE ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-01 23:55:53 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            hcd_event_device_remove ( RHPORT_NATIVE ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Clear speed change interrupt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usb_hw_clear - > sie_status  =  USB_SIE_STATUS_SPEED_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 18:26:41 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( status  &  USB_INTS_BUFF_STATUS_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handled  | =  USB_INTS_BUFF_STATUS_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TU_LOG ( 2 ,  " Buffer complete \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        hw_handle_buff_status ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( status  &  USB_INTS_TRANS_COMPLETE_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handled  | =  USB_INTS_TRANS_COMPLETE_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usb_hw_clear - > sie_status  =  USB_SIE_STATUS_TRANS_COMPLETE_BITS ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TU_LOG ( 2 ,  " Transfer complete \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        hw_trans_complete ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( status  &  USB_INTS_STALL_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We have rx'd a stall from the device
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pico_trace ( " Stall REC \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handled  | =  USB_INTS_STALL_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usb_hw_clear - > sie_status  =  USB_SIE_STATUS_STALL_REC_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        hw_xfer_complete ( & epx ,  XFER_RESULT_STALLED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( status  &  USB_INTS_ERROR_RX_TIMEOUT_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handled  | =  USB_INTS_ERROR_RX_TIMEOUT_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usb_hw_clear - > sie_status  =  USB_SIE_STATUS_RX_TIMEOUT_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( status  &  USB_INTS_ERROR_DATA_SEQ_BITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usb_hw_clear - > sie_status  =  USB_SIE_STATUS_DATA_SEQ_ERROR_BITS ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 16:52:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TU_LOG ( 3 ,  "   Seq Error: [0] = 0x%04u  [1] = 0x%04x \r \n " ,  tu_u32_low16 ( * epx . buffer_control ) ,  tu_u32_high16 ( * epx . buffer_control ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        panic ( " Data Seq Error  \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( status  ^  handled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        panic ( " Unhandled IRQ 0x%x \n " ,  ( uint )  ( status  ^  handled ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 16:08:27 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  __no_inline_not_in_flash_func ( hcd_int_handler ) ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  hcd_rp2040_irq ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  struct  hw_endpoint  * _next_free_interrupt_ep ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  hw_endpoint  * ep  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( uint  i  =  1 ;  i  <  TU_ARRAY_SIZE ( ep_pool ) ;  i + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ep  =  & ep_pool [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( ! ep - > configured ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Will be configured by _hw_endpoint_init / _hw_endpoint_allocate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ep - > interrupt_num  =  i  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  hw_endpoint  * _hw_endpoint_allocate ( uint8_t  transfer_type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  hw_endpoint  * ep  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( transfer_type  = =  TUSB_XFER_INTERRUPT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep  =  _next_free_interrupt_ep ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pico_info ( " Allocate interrupt ep %d \n " ,  ep - > interrupt_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        assert ( ep ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep - > buffer_control  =  & usbh_dpram - > int_ep_buffer_ctrl [ ep - > interrupt_num ] . ctrl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep - > endpoint_control  =  & usbh_dpram - > int_ep_ctrl [ ep - > interrupt_num ] . ctrl ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // 0 for epx (double buffered): TODO increase to 1024 for ISO
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2x64 for intep0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 3x64 for intep1
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // etc
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ep - > hw_data_buf  =  & usbh_dpram - > epx_data [ 64  *  ( ep - > interrupt_num  +  2 ) ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep  =  & epx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep - > buffer_control  =  & usbh_dpram - > epx_buf_ctrl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep - > endpoint_control  =  & usbh_dpram - > epx_ctrl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep - > hw_data_buf  =  & usbh_dpram - > epx_data [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  ep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  _hw_endpoint_init ( struct  hw_endpoint  * ep ,  uint8_t  dev_addr ,  uint8_t  ep_addr ,  uint  wMaxPacketSize ,  uint8_t  transfer_type ,  uint8_t  bmInterval )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Already has data buffer, endpoint control, and buffer control allocated at this point
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( ep - > endpoint_control ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( ep - > buffer_control ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( ep - > hw_data_buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 14:54:12 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    uint8_t  const  num  =  tu_edpt_number ( ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tusb_dir_t  const  dir  =  tu_edpt_dir ( ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    ep - > ep_addr  =  ep_addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ep - > dev_addr  =  dev_addr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 14:54:12 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // For host, IN to host == RX, anything else rx == false
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 14:54:12 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ep - > rx  =  ( dir  = =  TUSB_DIR_IN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // Response to a setup packet on EP0 starts with pid of 1
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ep - > next_pid  =  ( num  = =  0  ?  1u  :  0u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    ep - > wMaxPacketSize  =  wMaxPacketSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ep - > transfer_type  =  transfer_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 10:09:09 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    pico_trace ( " hw_endpoint_init dev %d ep %d %s xfer %d \n " ,  ep - > dev_addr ,  tu_edpt_number ( ep - > ep_addr ) ,  ep_dir_string [ tu_edpt_dir ( ep - > ep_addr ) ] ,  ep - > transfer_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pico_trace ( " dev %d ep %d %s setup buffer @ 0x%p \n " ,  ep - > dev_addr ,  tu_edpt_number ( ep - > ep_addr ) ,  ep_dir_string [ tu_edpt_dir ( ep - > ep_addr ) ] ,  ep - > hw_data_buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    uint  dpram_offset  =  hw_data_offset ( ep - > hw_data_buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Bits 0-5 should be 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( ! ( dpram_offset  &  0 b111111 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Fill in endpoint control register with buffer offset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    uint32_t  ep_reg  =   EP_CTRL_ENABLE_BITS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  |  EP_CTRL_INTERRUPT_PER_BUFFER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  |  ( ep - > transfer_type  < <  EP_CTRL_BUFFER_TYPE_LSB ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  |  dpram_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ep_reg  | =  bmInterval  ?  ( bmInterval  -  1 )  < <  EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * ep - > endpoint_control  =  ep_reg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pico_trace ( " endpoint control (0x%p) <- 0x%x \n " ,  ep - > endpoint_control ,  ep_reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ep - > configured  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( bmInterval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // This is an interrupt endpoint
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // so need to set up interrupt endpoint address control register with:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // device address
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // endpoint number / direction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // preamble
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 14:54:12 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        uint32_t  reg  =  dev_addr  |  ( num  < <  USB_ADDR_ENDP1_ENDPOINT_LSB ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 12:25:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( dir  = =  TUSB_DIR_OUT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            reg  | =  USB_ADDR_ENDP1_INTEP_DIR_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( need_pre ( dev_addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            reg  | =  USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usb_hw - > int_ep_addr_ctrl [ ep - > interrupt_num ]  =  reg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Finally, enable interrupt that endpoint
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usb_hw_set - > int_ep_ctrl  =  1  < <  ( ep - > interrupt_num  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // If it's an interrupt endpoint we need to set up the buffer control
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // register
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// HCD API
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
									
										
										
										
											2021-02-25 15:48:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  hcd_init ( uint8_t  rhport )  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-02-25 15:48:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    pico_trace ( " hcd_init %d \n " ,  rhport ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( rhport  = =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Reset any previous state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rp2040_usb_init ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-11 20:06:57 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Force VBUS detect to always present, for now we assume vbus is always provided (without using VBUS En)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    usb_hw - > pwr  =  USB_USB_PWR_VBUS_DETECT_BITS  |  USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    irq_set_exclusive_handler ( USBCTRL_IRQ ,  hcd_rp2040_irq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // clear epx and interrupt eps
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    memset ( & ep_pool ,  0 ,  sizeof ( ep_pool ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Enable in host mode with SOF / Keep alive on
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    usb_hw - > main_ctrl  =  USB_MAIN_CTRL_CONTROLLER_EN_BITS  |  USB_MAIN_CTRL_HOST_NDEVICE_BITS ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:18:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    usb_hw - > sie_ctrl  =  SIE_CTRL_BASE ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    usb_hw - > inte  =  USB_INTE_BUFF_STATUS_BITS       |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                   USB_INTE_HOST_CONN_DIS_BITS     |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                   USB_INTE_HOST_RESUME_BITS       |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                   USB_INTE_STALL_BITS             |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                   USB_INTE_TRANS_COMPLETE_BITS    | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                   USB_INTE_ERROR_RX_TIMEOUT_BITS  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                   USB_INTE_ERROR_DATA_SEQ_BITS    ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  hcd_port_reset ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pico_trace ( " hcd_port_reset \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( rhport  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // TODO: Nothing to do here yet. Perhaps need to reset some state?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-02 12:33:47 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  hcd_port_reset_end ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								bool  hcd_port_connect_status ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pico_trace ( " hcd_port_connect_status \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( rhport  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  usb_hw - > sie_status  &  USB_SIE_STATUS_SPEED_BITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								tusb_speed_t  hcd_port_speed_get ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( rhport  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // TODO: Should enumval this register
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( dev_speed ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  TUSB_SPEED_LOW ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  TUSB_SPEED_FULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            panic ( " Invalid speed \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  TUSB_SPEED_INVALID ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Close all opened endpoint belong to this device
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  hcd_device_close ( uint8_t  rhport ,  uint8_t  dev_addr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-30 17:36:52 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  pico_trace ( " hcd_device_close %d \n " ,  dev_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 17:36:52 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( dev_addr  = =  0 )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( size_t  i  =  1 ;  i  <  TU_ARRAY_SIZE ( ep_pool ) ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    hw_endpoint_t *  ep  =  & ep_pool [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ep - > dev_addr  = =  dev_addr  & &  ep - > configured ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 14:58:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 17:36:52 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      // in case it is an interrupt endpoint, disable it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usb_hw_clear - > int_ep_ctrl  =  ( 1  < <  ( ep - > interrupt_num  +  1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usb_hw - > int_ep_addr_ctrl [ ep - > interrupt_num ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // unconfigure the endpoint
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ep - > configured  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      * ep - > endpoint_control  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      * ep - > buffer_control  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      hw_endpoint_reset_transfer ( ep ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 14:58:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 17:36:52 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								uint32_t  hcd_frame_number ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  usb_hw - > sof_rd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  hcd_int_enable ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( rhport  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    irq_set_enabled ( USBCTRL_IRQ ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  hcd_int_disable ( uint8_t  rhport )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // todo we should check this is disabling from the correct core; note currently this is never called
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( rhport  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    irq_set_enabled ( USBCTRL_IRQ ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Endpoint API
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//--------------------------------------------------------------------+
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  hcd_edpt_open ( uint8_t  rhport ,  uint8_t  dev_addr ,  tusb_desc_endpoint_t  const  *  ep_desc )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pico_trace ( " hcd_edpt_open dev_addr %d, ep_addr %d \n " ,  dev_addr ,  ep_desc - > bEndpointAddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Allocated differently based on if it's an interrupt endpoint or not
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  hw_endpoint  * ep  =  _hw_endpoint_allocate ( ep_desc - > bmAttributes . xfer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    _hw_endpoint_init ( ep , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dev_addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep_desc - > bEndpointAddress , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 13:11:21 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        tu_edpt_packet_size ( ep_desc ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ep_desc - > bmAttributes . xfer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ep_desc - > bInterval ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								bool  hcd_edpt_xfer ( uint8_t  rhport ,  uint8_t  dev_addr ,  uint8_t  ep_addr ,  uint8_t  *  buffer ,  uint16_t  buflen )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    pico_trace ( " hcd_edpt_xfer dev_addr %d, ep_addr 0x%x, len %d \n " ,  dev_addr ,  ep_addr ,  buflen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    uint8_t  const  ep_num  =  tu_edpt_number ( ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tusb_dir_t  const  ep_dir  =  tu_edpt_dir ( ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // Get appropriate ep. Either EPX or interrupt endpoint
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  hw_endpoint  * ep  =  get_dev_ep ( dev_addr ,  ep_addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 20:19:10 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    assert ( ep ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:27:20 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Control endpoint can change direction 0x00 <-> 0x80
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  (  ep_addr  ! =  ep - > ep_addr  ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 15:27:20 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      assert ( ep_num  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // Direction has flipped on endpoint control so re init it but with same properties
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      _hw_endpoint_init ( ep ,  dev_addr ,  ep_addr ,  ep - > wMaxPacketSize ,  ep - > transfer_type ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // If a normal transfer (non-interrupt) then initiate using
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // sie ctrl registers. Otherwise interrupt ep registers should
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // already be configured
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ep  = =  & epx )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:34:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        hw_endpoint_xfer_start ( ep ,  buffer ,  buflen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // That has set up buffer control, endpoint control etc
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // for host we have to initiate the transfer
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        usb_hw - > dev_addr_ctrl  =  dev_addr  |  ( ep_num  < <  USB_ADDR_ENDP_ENDPOINT_LSB ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:18:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        uint32_t  flags  =  USB_SIE_CTRL_START_TRANS_BITS  |  SIE_CTRL_BASE  | 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                         ( ep_dir  ?  USB_SIE_CTRL_RECEIVE_DATA_BITS  :  USB_SIE_CTRL_SEND_DATA_BITS ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // Set pre if we are a low speed device on full speed hub
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        flags  | =  need_pre ( dev_addr )  ?  USB_SIE_CTRL_PREAMBLE_EN_BITS  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        usb_hw - > sie_ctrl  =  flags ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:34:51 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      hw_endpoint_xfer_start ( ep ,  buffer ,  buflen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  hcd_setup_send ( uint8_t  rhport ,  uint8_t  dev_addr ,  uint8_t  const  setup_packet [ 8 ] )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // Copy data into setup packet buffer
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-20 17:25:30 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# pragma GCC diagnostic push 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma GCC diagnostic ignored "-Warray-bounds" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma GCC diagnostic ignored "-Wstringop-overflow" 
  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    memcpy ( ( void * ) & usbh_dpram - > setup_packet [ 0 ] ,  setup_packet ,  8 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-20 17:25:30 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# pragma GCC diagnostic pop 
  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Configure EP0 struct with setup info for the trans complete
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  hw_endpoint  * ep  =  _hw_endpoint_allocate ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // EP0 out
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    _hw_endpoint_init ( ep ,  dev_addr ,  0x00 ,  ep - > wMaxPacketSize ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( ep - > configured ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:58:29 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ep - > remaining_len  =  8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ep - > active         =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Set device address
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    usb_hw - > dev_addr_ctrl  =  dev_addr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // Set pre if we are a low speed device on full speed hub
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 13:18:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    uint32_t  const  flags  =  SIE_CTRL_BASE  |  USB_SIE_CTRL_SEND_SETUP_BITS  |  USB_SIE_CTRL_START_TRANS_BITS  | 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                           ( need_pre ( dev_addr )  ?  USB_SIE_CTRL_PREAMBLE_EN_BITS  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    usb_hw - > sie_ctrl  =  flags ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 22:00:59 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 17:19:21 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//{
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    // EPX is shared, so multiple device addresses and endpoint addresses share that
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    // on that device
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr);
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr);
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    assert(ep);
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    bool busy = ep->active;
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    pico_trace("busy == %d\n", busy);
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    return busy;
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//}
  
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  hcd_edpt_clear_stall ( uint8_t  dev_addr ,  uint8_t  ep_addr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ( void )  dev_addr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 17:05:49 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ( void )  ep_addr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 23:29:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 19:52:07 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    panic ( " hcd_clear_stall " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif