2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  The  MIT  License  ( MIT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2019  Ha  Thach  ( tinyusb . org ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-25 22:45:05 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "tusb_option.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 17:03:54 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if CFG_TUH_ENABLED && defined(TUP_USBIP_OHCI) 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 23:09:48 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// INCLUDE
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "osal/osal.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 23:09:48 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "host/hcd.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "ohci.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// TODO remove
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "chip.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// MACRO CONSTANT TYPEDEF
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define OHCI_REG               ((ohci_registers_t *) LPC_USB_BASE) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_FUNCSTATE_RESET  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_FUNCSTATE_RESUME , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_FUNCSTATE_OPERATIONAL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_FUNCSTATE_SUSPEND 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_CONTROL_BULK_RATIO            =  3 ,  ///< This specifies the service ratio between Control and Bulk EDs. 0 = 1:1, 3 = 4:1
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK     =  TU_BIT ( 2 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_LIST_ISOCHRONOUS_ENABLE_MASK  =  TU_BIT ( 3 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK      =  TU_BIT ( 4 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CONTROL_LIST_BULK_ENABLE_MASK         =  TU_BIT ( 5 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_FMINTERVAL_FI     =  0x2EDF ,  // 7.3.1 nominal (reset) value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_FMINTERVAL_FSMPS  =  ( 6 * ( OHCI_FMINTERVAL_FI - 210 ) )  /  7 ,  // 5.4 calculated based on maximum overhead + bit stuffing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_PERIODIC_START  =  0x3E67 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_SCHEDULING_OVERUN_MASK     =  TU_BIT ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_WRITEBACK_DONEHEAD_MASK    =  TU_BIT ( 1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_SOF_MASK                   =  TU_BIT ( 2 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_RESUME_DETECTED_MASK       =  TU_BIT ( 3 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_UNRECOVERABLE_ERROR_MASK   =  TU_BIT ( 4 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_FRAME_OVERFLOW_MASK        =  TU_BIT ( 5 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_RHPORT_STATUS_CHANGE_MASK  =  TU_BIT ( 6 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_OWNERSHIP_CHANGE_MASK      =  TU_BIT ( 30 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_MASTER_ENABLE_MASK         =  TU_BIT ( 31 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:41:08 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  RHPORT_CURRENT_CONNECT_STATUS_MASK       =  TU_BIT ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_ENABLE_STATUS_MASK           =  TU_BIT ( 1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_SUSPEND_STATUS_MASK          =  TU_BIT ( 2 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_OVER_CURRENT_INDICATOR_MASK  =  TU_BIT ( 3 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_RESET_STATUS_MASK            =  TU_BIT ( 4 ) ,  ///< write '1' to reset port
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_POWER_STATUS_MASK            =  TU_BIT ( 8 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_LOW_SPEED_DEVICE_ATTACHED_MASK    =  TU_BIT ( 9 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_CONNECT_STATUS_CHANGE_MASK        =  TU_BIT ( 16 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_ENABLE_CHANGE_MASK           =  TU_BIT ( 17 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_SUSPEND_CHANGE_MASK          =  TU_BIT ( 18 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_OVER_CURRENT_CHANGE_MASK          =  TU_BIT ( 19 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_PORT_RESET_CHANGE_MASK            =  TU_BIT ( 20 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  RHPORT_ALL_CHANGE_MASK  =  RHPORT_CONNECT_STATUS_CHANGE_MASK  |  RHPORT_PORT_ENABLE_CHANGE_MASK  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    RHPORT_PORT_SUSPEND_CHANGE_MASK  |  RHPORT_OVER_CURRENT_CHANGE_MASK  |  RHPORT_PORT_RESET_CHANGE_MASK 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CCODE_NO_ERROR               =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_CCODE_CRC                    =  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_BIT_STUFFING           =  2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_DATA_TOGGLE_MISMATCH   =  3 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_STALL                  =  4 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_DEVICE_NOT_RESPONDING  =  5 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_PID_CHECK_FAILURE      =  6 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_UNEXPECTED_PID         =  7 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_DATA_OVERRUN           =  8 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_DATA_UNDERRUN          =  9 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_BUFFER_OVERRUN         =  12 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_BUFFER_UNDERRUN        =  13 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OHCI_CCODE_NOT_ACCESSED           =  14 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_ON_COMPLETE_YES  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_INT_ON_COMPLETE_NO   =  TU_BIN8 ( 111 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GTD_DT_TOGGLE_CARRY  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GTD_DT_DATA0  =  TU_BIT ( 1 )  |  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GTD_DT_DATA1  =  TU_BIT ( 1 )  |  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  PID_SETUP  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  PID_OUT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  PID_IN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  PID_FROM_TD  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// INTERNAL OBJECT & FUNCTION DECLARATION
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								CFG_TUSB_MEM_SECTION  TU_ATTR_ALIGNED ( 256 )  static  ohci_data_t  ohci_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  ohci_ed_t  *  const  p_ed_head [ ]  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ TUSB_XFER_CONTROL ]      =  & ohci_data . control [ 0 ] . ed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ TUSB_XFER_BULK    ]      =  & ohci_data . bulk_head_ed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ TUSB_XFER_INTERRUPT ]    =  & ohci_data . period_head_ed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ TUSB_XFER_ISOCHRONOUS ]  =  NULL  // TODO Isochronous
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ed_list_insert ( ohci_ed_t  *  p_pre ,  ohci_ed_t  *  p_ed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ed_list_remove_by_addr ( ohci_ed_t  *  p_head ,  uint8_t  dev_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// USBH-HCD API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Initialization according to 5.1.1.4
 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 19:45:53 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  hcd_init ( uint8_t  rhport ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 19:45:53 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  //------------- Data Structure init -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  tu_memclr ( & ohci_data ,  sizeof ( ohci_data_t ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for ( uint8_t  i = 0 ;  i < 32 ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  {  // assign all interrupt pointes to period head ed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_data . hcca . interrupt_table [ i ]  =  ( uint32_t )  & ohci_data . period_head_ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_data . control [ 0 ] . ed . skip   =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_data . bulk_head_ed . skip    =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_data . period_head_ed . skip  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // reset controller
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > command_status_bit . controller_reset  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while (  OHCI_REG - > command_status_bit . controller_reset  )  { }  // should not take longer than 10 us
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //------------- init ohci registers -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > control_head_ed  =  ( uint32_t )  & ohci_data . control [ 0 ] . ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > bulk_head_ed     =  ( uint32_t )  & ohci_data . bulk_head_ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > hcca             =  ( uint32_t )  & ohci_data . hcca ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > interrupt_disable  =  OHCI_REG - > interrupt_enable ;  // disable all interrupts
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > interrupt_status   =  OHCI_REG - > interrupt_status ;  // clear current set bits
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > interrupt_enable   =  OHCI_INT_WRITEBACK_DONEHEAD_MASK  |  OHCI_INT_RESUME_DETECTED_MASK  | 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 21:45:34 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      OHCI_INT_UNRECOVERABLE_ERROR_MASK  |  OHCI_INT_FRAME_OVERFLOW_MASK  |  OHCI_INT_RHPORT_STATUS_CHANGE_MASK  | 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      OHCI_INT_MASTER_ENABLE_MASK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > control  | =  OHCI_CONTROL_CONTROL_BULK_RATIO  |  OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								       OHCI_CONTROL_LIST_BULK_ENABLE_MASK  |  OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK ;  // TODO Isochronous
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > frame_interval  =  ( OHCI_FMINTERVAL_FSMPS  < <  16 )  |  OHCI_FMINTERVAL_FI ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > periodic_start  =  ( OHCI_FMINTERVAL_FI  *  9 )  /  10 ;  // Periodic start is 90% of frame interval
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > control_bit . hc_functional_state  =  OHCI_CONTROL_FUNCSTATE_OPERATIONAL ;  // make HC's state to operational state TODO use this to suspend (save power)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > rh_status_bit . local_power_status_change  =  1 ;  // set global power for ports
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								uint32_t  hcd_frame_number ( uint8_t  rhport ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 21:45:34 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  return  ( ohci_data . frame_number_hi  < <  16 )  |  OHCI_REG - > frame_number ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 21:45:34 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// PORT API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  hcd_port_reset ( uint8_t  hostid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  hostid ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:41:08 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  OHCI_REG - > rhport_status [ 0 ]  =  RHPORT_PORT_RESET_STATUS_MASK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  hcd_port_connect_status ( uint8_t  hostid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  hostid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  OHCI_REG - > rhport_status_bit [ 0 ] . current_connect_status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								tusb_speed_t  hcd_port_speed_get ( uint8_t  hostid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  hostid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  OHCI_REG - > rhport_status_bit [ 0 ] . low_speed_device_attached  ?  TUSB_SPEED_LOW  :  TUSB_SPEED_FULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// endpoints are tied to an address, which only reclaim after a long delay when enumerating
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// thus there is no need to make sure ED is not in HC's cahed as it will not for sure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  hcd_device_close ( uint8_t  rhport ,  uint8_t  dev_addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // TODO OHCI
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // addr0 serves as static head --> only set skip bit
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  dev_addr  = =  0  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_data . control [ 0 ] . ed . skip  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // remove control
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ed_list_remove_by_addr (  p_ed_head [ TUSB_XFER_CONTROL ] ,  dev_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // remove bulk
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ed_list_remove_by_addr ( p_ed_head [ TUSB_XFER_BULK ] ,  dev_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // remove interrupt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ed_list_remove_by_addr ( p_ed_head [ TUSB_XFER_INTERRUPT ] ,  dev_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // TODO remove ISO
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Controller API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// List Helper
 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  tusb_xfer_type_t  ed_get_xfer_type ( ohci_ed_t  const  *  const  p_ed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  return  ( p_ed - > ep_number  = =  0    )  ?  TUSB_XFER_CONTROL      : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         ( p_ed - > is_iso            )  ?  TUSB_XFER_ISOCHRONOUS  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         ( p_ed - > is_interrupt_xfer )  ?  TUSB_XFER_INTERRUPT    :  TUSB_XFER_BULK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ed_init ( ohci_ed_t  * p_ed ,  uint8_t  dev_addr ,  uint16_t  ep_size ,  uint8_t  ep_addr ,  uint8_t  xfer_type ,  uint8_t  interval ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // address 0 is used as async head, which always on the list --> cannot be cleared
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( dev_addr  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    tu_memclr ( p_ed ,  sizeof ( ohci_ed_t ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-23 17:00:41 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  hcd_devtree_info_t  devtree_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  hcd_devtree_get_info ( dev_addr ,  & devtree_info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  p_ed - > dev_addr           =  dev_addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > ep_number          =  ep_addr  &  0x0F ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > pid                =  ( xfer_type  = =  TUSB_XFER_CONTROL )  ?  PID_FROM_TD  :  ( tu_edpt_dir ( ep_addr )  ?  PID_IN  :  PID_OUT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-23 17:00:41 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  p_ed - > speed              =  devtree_info . speed ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  p_ed - > is_iso             =  ( xfer_type  = =  TUSB_XFER_ISOCHRONOUS )  ?  1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  p_ed - > max_packet_size    =  ep_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > used               =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > is_interrupt_xfer  =  ( xfer_type  = =  TUSB_XFER_INTERRUPT  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  gtd_init ( ohci_gtd_t *  p_td ,  uint8_t *  data_ptr ,  uint16_t  total_bytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  tu_memclr ( p_td ,  sizeof ( ohci_gtd_t ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_td - > used                    =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_td - > expected_bytes          =  total_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_td - > buffer_rounding         =  1 ;  // less than queued length is not a error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_td - > delay_interrupt         =  OHCI_INT_ON_COMPLETE_NO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_td - > condition_code          =  OHCI_CCODE_NOT_ACCESSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_td - > current_buffer_pointer  =  data_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  p_td - > buffer_end              =  total_bytes  ?  ( data_ptr  +  total_bytes - 1 )  :  data_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-06 11:49:00 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  ohci_ed_t  *  ed_from_addr ( uint8_t  dev_addr ,  uint8_t  ep_addr ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  tu_edpt_number ( ep_addr )  = =  0  )  return  & ohci_data . control [ dev_addr ] . ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_ed_t *  ed_pool  =  ohci_data . ed_pool ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for ( uint32_t  i = 0 ;  i < HCD_MAX_ENDPOINT ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  (  ( ed_pool [ i ] . dev_addr  = =  dev_addr )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          ep_addr  = =  tu_edpt_addr ( ed_pool [ i ] . ep_number ,  ed_pool [ i ] . pid  = =  PID_IN )  ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  & ed_pool [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-06 11:49:00 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  ohci_ed_t  *  ed_find_free ( void ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_ed_t *  ed_pool  =  ohci_data . ed_pool ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for ( uint8_t  i  =  0 ;  i  <  HCD_MAX_ENDPOINT ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  (  ! ed_pool [ i ] . used  )  return  & ed_pool [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ed_list_insert ( ohci_ed_t  *  p_pre ,  ohci_ed_t  *  p_ed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > next  =  p_pre - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_pre - > next  =  ( uint32_t )  p_ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ed_list_remove_by_addr ( ohci_ed_t  *  p_head ,  uint8_t  dev_addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_ed_t *  p_prev  =  p_head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while (  p_prev - > next  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_ed_t *  ed  =  ( ohci_ed_t * )  p_prev - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ed - > dev_addr  = =  dev_addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // unlink ed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      p_prev - > next  =  ed - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // point the removed ED's next pointer to list head to make sure HC can always safely move away from this ED
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ed - > next  =  ( uint32_t )  p_head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ed - > used  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // check next valid since we could remove it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( p_prev - > next )  p_prev  =  ( ohci_ed_t * )  p_prev - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  ohci_gtd_t  *  gtd_find_free ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for ( uint8_t  i = 0 ;  i  <  HCD_MAX_XFER ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  (  ! ohci_data . gtd_pool [ i ] . used  )  return  & ohci_data . gtd_pool [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  td_insert_to_ed ( ohci_ed_t *  p_ed ,  ohci_gtd_t  *  p_gtd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // tail is always NULL
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  tu_align16 ( p_ed - > td_head . address )  = =  0  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  {  // TD queue is empty --> head = TD
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    p_ed - > td_head . address  | =  ( uint32_t )  p_gtd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  {  // TODO currently only support queue up to 2 TD each endpoint at a time
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( ( ohci_gtd_t * )  tu_align16 ( p_ed - > td_head . address ) ) - > next  =  ( uint32_t )  p_gtd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Endpoint API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  hcd_edpt_open ( uint8_t  rhport ,  uint8_t  dev_addr ,  tusb_desc_endpoint_t  const  *  ep_desc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // TODO iso support
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  TU_ASSERT ( ep_desc - > bmAttributes . xfer  ! =  TUSB_XFER_ISOCHRONOUS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //------------- Prepare Queue Head -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_ed_t  *  p_ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  ep_desc - > bEndpointAddress  = =  0  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    p_ed  =  & ohci_data . control [ dev_addr ] . ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    p_ed  =  ed_find_free ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  TU_ASSERT ( p_ed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 13:11:21 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  ed_init (  p_ed ,  dev_addr ,  tu_edpt_packet_size ( ep_desc ) ,  ep_desc - > bEndpointAddress , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            ep_desc - > bmAttributes . xfer ,  ep_desc - > bInterval  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // control of dev0 is used as static async head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  dev_addr  = =  0  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    p_ed - > skip  =  0 ;  // only need to clear skip bit
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ed_list_insert (  p_ed_head [ ep_desc - > bmAttributes . xfer ] ,  p_ed  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  hcd_setup_send ( uint8_t  rhport ,  uint8_t  dev_addr ,  uint8_t  const  setup_packet [ 8 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_ed_t *  ed    =  & ohci_data . control [ dev_addr ] . ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_gtd_t  * qtd  =  & ohci_data . control [ dev_addr ] . gtd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  gtd_init ( qtd ,  ( uint8_t * )  setup_packet ,  8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  qtd - > index            =  dev_addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  qtd - > pid              =  PID_SETUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  qtd - > data_toggle      =  GTD_DT_DATA0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  qtd - > delay_interrupt  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //------------- Attach TDs list to Control Endpoint -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ed - > td_head . address  =  ( uint32_t )  qtd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > command_status_bit . control_list_filled  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  hcd_edpt_xfer ( uint8_t  rhport ,  uint8_t  dev_addr ,  uint8_t  ep_addr ,  uint8_t  *  buffer ,  uint16_t  buflen ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  ( void )  rhport ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  uint8_t  const  epnum  =  tu_edpt_number ( ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uint8_t  const  dir    =  tu_edpt_dir ( ep_addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  (  epnum  = =  0  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_ed_t *   ed   =  & ohci_data . control [ dev_addr ] . ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_gtd_t *  gtd  =  & ohci_data . control [ dev_addr ] . gtd ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    gtd_init ( gtd ,  buffer ,  buflen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    gtd - > index            =  dev_addr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    gtd - > pid              =  dir  ?  PID_IN  :  PID_OUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    gtd - > data_toggle      =  GTD_DT_DATA1 ;  // Both Data and Ack stage start with DATA1
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    gtd - > delay_interrupt  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ed - > td_head . address  =  ( uint32_t )  gtd ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    OHCI_REG - > command_status_bit . control_list_filled  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_ed_t  *  ed  =  ed_from_addr ( dev_addr ,  ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_gtd_t *  gtd  =  gtd_find_free ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    TU_ASSERT ( gtd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    gtd_init ( gtd ,  buffer ,  buflen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    gtd - > index  =  ed - ohci_data . ed_pool ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    gtd - > delay_interrupt  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    td_insert_to_ed ( ed ,  gtd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 16:34:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    tusb_xfer_type_t  xfer_type  =  ed_get_xfer_type (  ed_from_addr ( dev_addr ,  ep_addr )  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( TUSB_XFER_BULK  = =  xfer_type )  OHCI_REG - > command_status_bit . bulk_list_filled  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  hcd_edpt_clear_stall ( uint8_t  dev_addr ,  uint8_t  ep_addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_ed_t  *  const  p_ed  =  ed_from_addr ( dev_addr ,  ep_addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > is_stalled  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > td_tail     & =  0x0Ful ;  // set tail pointer back to NULL
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > td_head . toggle  =  0 ;  // reset data toggle
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  p_ed - > td_head . halted  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  TUSB_XFER_BULK  = =  ed_get_xfer_type ( p_ed )  )  OHCI_REG - > command_status_bit . bulk_list_filled  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// OHCI Interrupt Handler
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  ohci_td_item_t *  list_reverse ( ohci_td_item_t *  td_head ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_td_item_t *  td_reverse_head  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while ( td_head  ! =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  next  =  td_head - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // make current's item become reverse's first item
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    td_head - > next  =  ( uint32_t )  td_reverse_head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    td_reverse_head   =  td_head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    td_head  =  ( ohci_td_item_t * )  next ;  // advance to next item
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  td_reverse_head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  bool  gtd_is_control ( ohci_gtd_t  const  *  const  p_qtd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  ( ( uint32_t )  p_qtd )  <  ( ( uint32_t )  ohci_data . gtd_pool ) ;  // check ohci_data_t for memory layout
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  ohci_ed_t *  gtd_get_ed ( ohci_gtd_t  const  *  const  p_qtd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  gtd_is_control ( p_qtd )  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  & ohci_data . control [ p_qtd - > index ] . ed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  & ohci_data . ed_pool [ p_qtd - > index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  uint32_t  gtd_xfer_byte_left ( uint32_t  buffer_end ,  uint32_t  current_buffer ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // 5.2.9 OHCI sample code
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // CBP is 0 mean all data is transferred
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( current_buffer  = =  0 )  return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  return  ( tu_align4k ( buffer_end  ^  current_buffer )  ?  0x1000  :  0 )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      tu_offset4k ( buffer_end )  -  tu_offset4k ( current_buffer )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  done_queue_isr ( uint8_t  hostid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( void )  hostid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // done head is written in reversed order of completion --> need to reverse the done queue first
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ohci_td_item_t *  td_head  =  list_reverse  (  ( ohci_td_item_t * )  tu_align16 ( ohci_data . hcca . done_head )  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while (  td_head  ! =  NULL  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // TODO check if td_head is iso td
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //------------- Non ISO transfer -------------//
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ohci_gtd_t  *  const  qtd  =  ( ohci_gtd_t  * )  td_head ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    xfer_result_t  const  event  =  ( qtd - > condition_code  = =  OHCI_CCODE_NO_ERROR )  ?  XFER_RESULT_SUCCESS  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                ( qtd - > condition_code  = =  OHCI_CCODE_STALL )  ?  XFER_RESULT_STALLED  :  XFER_RESULT_FAILED ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    qtd - > used  =  0 ;  // free TD
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  (  ( qtd - > delay_interrupt  = =  OHCI_INT_ON_COMPLETE_YES )  | |  ( event  ! =  XFER_RESULT_SUCCESS )  ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ohci_ed_t  *  const  ed   =  gtd_get_ed ( qtd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      uint32_t  const  xferred_bytes  =  qtd - > expected_bytes  -  gtd_xfer_byte_left ( ( uint32_t )  qtd - > buffer_end ,  ( uint32_t )  qtd - > current_buffer_pointer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // NOTE Assuming the current list is BULK and there is no other EDs in the list has queued TDs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // When there is a error resulting this ED is halted, and this EP still has other queued TD
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // --> the Bulk list only has this halted EP queueing TDs (remaining)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // --> Bulk list will be considered as not empty by HC !!! while there is no attempt transaction on this list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // --> HC will not process Control list (due to service ratio when Bulk list not empty)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // To walk-around this, the halted ED will have TailP = HeadP (empty list condition), when clearing halt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // the TailP must be set back to NULL for processing remaining TDs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ( event  ! =  XFER_RESULT_SUCCESS ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ed - > td_tail  & =  0x0Ful ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ed - > td_tail  | =  tu_align16 ( ed - > td_head . address ) ;  // mark halted EP as empty queue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  (  event  = =  XFER_RESULT_STALLED  )  ed - > is_stalled  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      uint8_t  dir  =  ( ed - > ep_number  = =  0 )  ?  ( qtd - > pid  = =  PID_IN )  :  ( ed - > pid  = =  PID_IN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      hcd_event_xfer_complete ( ed - > dev_addr ,  tu_edpt_addr ( ed - > ep_number ,  dir ) ,  xferred_bytes ,  event ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    td_head  =  ( ohci_td_item_t * )  td_head - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-03 13:12:09 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  hcd_int_handler ( uint8_t  hostid ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uint32_t  const  int_en      =  OHCI_REG - > interrupt_enable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uint32_t  const  int_status  =  OHCI_REG - > interrupt_status  &  int_en ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( int_status  = =  0 )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 21:45:34 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // Frame number overflow
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  int_status  &  OHCI_INT_FRAME_OVERFLOW_MASK  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ohci_data . frame_number_hi + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  //------------- RootHub status -------------//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  (  int_status  &  OHCI_INT_RHPORT_STATUS_CHANGE_MASK  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:41:08 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    uint32_t  const  rhport_status  =  OHCI_REG - > rhport_status [ 0 ]  &  RHPORT_ALL_CHANGE_MASK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // TODO dual port is not yet supported
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:41:08 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  (  rhport_status  &  RHPORT_CONNECT_STATUS_CHANGE_MASK  ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // TODO check if remote wake-up
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  (  OHCI_REG - > rhport_status_bit [ 0 ] . current_connect_status  ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // TODO reset port immediately, without this controller will got 2-3 (debouncing connection status change)
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:41:08 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        OHCI_REG - > rhport_status [ 0 ]  =  RHPORT_PORT_RESET_STATUS_MASK ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-05 15:45:03 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        hcd_event_device_attach ( hostid ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      } else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-05 15:45:03 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        hcd_event_device_remove ( hostid ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:41:08 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  (  rhport_status  &  RHPORT_PORT_SUSPEND_CHANGE_MASK ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    OHCI_REG - > rhport_status [ 0 ]  =  rhport_status ;  // acknowledge all interrupt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //------------- Transfer Complete -------------//
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 18:16:07 +07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( int_status  &  OHCI_INT_WRITEBACK_DONEHEAD_MASK ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-14 23:30:39 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    done_queue_isr ( hostid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  OHCI_REG - > interrupt_status  =  int_status ;  // Acknowledge handled interrupt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// HELPER
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//--------------------------------------------------------------------+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif