3      Copyright (C) Dean Camera, 2015. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2015  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, distribute, and sell this 
  13   software and its documentation for any purpose is hereby granted 
  14   without fee, provided that the above copyright notice appear in 
  15   all copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting 
  17   documentation, and that the name of the author not be used in 
  18   advertising or publicity pertaining to distribution of the 
  19   software without specific, written prior permission. 
  21   The author disclaims all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #include "../../../../Common/Common.h" 
  32 #if (ARCH == ARCH_AVR8) 
  34 #define  __INCLUDE_FROM_USB_DRIVER 
  35 #include "../USBMode.h" 
  37 #if defined(USB_CAN_BE_HOST) 
  41 uint8_t USB_Host_ControlPipeSize 
= PIPE_CONTROLPIPE_DEFAULT_SIZE
; 
  43 bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t
* const Table
, 
  44                              const uint8_t Entries
) 
  46         for (uint8_t i 
= 0; i 
< Entries
; i
++) 
  48                 if (!(Table
[i
].Address
)) 
  51                 if (!(Pipe_ConfigurePipe(Table
[i
].Address
, Table
[i
].Type
, Table
[i
].EndpointAddress
, Table
[i
].Size
, Table
[i
].Banks
))) 
  60 bool Pipe_ConfigurePipe(const uint8_t Address
, 
  62                         const uint8_t EndpointAddress
, 
  66         uint8_t Number 
= (Address 
& PIPE_EPNUM_MASK
); 
  67         uint8_t Token  
= (Address 
& PIPE_DIR_IN
) ? PIPE_TOKEN_IN 
: PIPE_TOKEN_OUT
; 
  69         if (Number 
>= PIPE_TOTAL_PIPES
) 
  72         if (Type 
== EP_TYPE_CONTROL
) 
  73           Token 
= PIPE_TOKEN_SETUP
; 
  75 #if defined(ORDERED_EP_CONFIG) 
  76         Pipe_SelectPipe(Number
); 
  81         UPCFG0X 
= ((Type 
<< EPTYPE0
) | Token 
| ((EndpointAddress 
& PIPE_EPNUM_MASK
) << PEPNUM0
)); 
  82         UPCFG1X 
= ((1 << ALLOC
) | ((Banks 
> 1) ? 
(1 << EPBK0
) : 0) | Pipe_BytesToEPSizeMask(Size
)); 
  84         Pipe_SetInfiniteINRequests(); 
  86         return Pipe_IsConfigured(); 
  88         for (uint8_t PNum 
= Number
; PNum 
< PIPE_TOTAL_PIPES
; PNum
++) 
  95                 Pipe_SelectPipe(PNum
); 
  99                         UPCFG0XTemp 
= ((Type 
<< EPTYPE0
) | Token 
| ((EndpointAddress 
& PIPE_EPNUM_MASK
) << PEPNUM0
)); 
 100                         UPCFG1XTemp 
= ((1 << ALLOC
) | ((Banks 
> 1) ? 
(1 << EPBK0
) : 0) | Pipe_BytesToEPSizeMask(Size
)); 
 106                         UPCFG0XTemp 
= UPCFG0X
; 
 107                         UPCFG1XTemp 
= UPCFG1X
; 
 108                         UPCFG2XTemp 
= UPCFG2X
; 
 112                 if (!(UPCFG1XTemp 
& (1 << ALLOC
))) 
 116                 UPCFG1X 
&= ~(1 << ALLOC
); 
 119                 UPCFG0X 
= UPCFG0XTemp
; 
 120                 UPCFG1X 
= UPCFG1XTemp
; 
 121                 UPCFG2X 
= UPCFG2XTemp
; 
 124                 Pipe_SetInfiniteINRequests(); 
 126                 if (!(Pipe_IsConfigured())) 
 130         Pipe_SelectPipe(Number
); 
 135 void Pipe_ClearPipes(void) 
 139         for (uint8_t PNum 
= 0; PNum 
< PIPE_TOTAL_PIPES
; PNum
++) 
 141                 Pipe_SelectPipe(PNum
); 
 149 bool Pipe_IsEndpointBound(const uint8_t EndpointAddress
) 
 151         uint8_t PrevPipeNumber 
= Pipe_GetCurrentPipe(); 
 153         for (uint8_t PNum 
= 0; PNum 
< PIPE_TOTAL_PIPES
; PNum
++) 
 155                 Pipe_SelectPipe(PNum
); 
 157                 if (!(Pipe_IsConfigured())) 
 160                 if (Pipe_GetBoundEndpointAddress() == EndpointAddress
) 
 164         Pipe_SelectPipe(PrevPipeNumber
); 
 168 uint8_t Pipe_WaitUntilReady(void) 
 170         #if (USB_STREAM_TIMEOUT_MS < 0xFF) 
 171         uint8_t  TimeoutMSRem 
= USB_STREAM_TIMEOUT_MS
; 
 173         uint16_t TimeoutMSRem 
= USB_STREAM_TIMEOUT_MS
; 
 176         uint16_t PreviousFrameNumber 
= USB_Host_GetFrameNumber(); 
 180                 if (Pipe_GetPipeToken() == PIPE_TOKEN_IN
) 
 182                         if (Pipe_IsINReceived()) 
 183                           return PIPE_READYWAIT_NoError
; 
 187                         if (Pipe_IsOUTReady()) 
 188                           return PIPE_READYWAIT_NoError
; 
 191                 if (Pipe_IsStalled()) 
 192                   return PIPE_READYWAIT_PipeStalled
; 
 193                 else if (USB_HostState 
== HOST_STATE_Unattached
) 
 194                   return PIPE_READYWAIT_DeviceDisconnected
; 
 196                 uint16_t CurrentFrameNumber 
= USB_Host_GetFrameNumber(); 
 198                 if (CurrentFrameNumber 
!= PreviousFrameNumber
) 
 200                         PreviousFrameNumber 
= CurrentFrameNumber
; 
 202                         if (!(TimeoutMSRem
--)) 
 203                           return PIPE_READYWAIT_Timeout
;