3      Copyright (C) Dean Camera, 2009. 
   5   dean [at] fourwalledcubicle [dot] com 
   6       www.fourwalledcubicle.com 
  10   Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, and distribute this software 
  13   and its documentation for any purpose and without fee is hereby 
  14   granted, provided that the above copyright notice appear in all 
  15   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 disclaim 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 
  32 #if defined(USB_CAN_BE_DEVICE) 
  34 #define  INCLUDE_FROM_ENDPOINT_C 
  37 #if !defined(FIXED_CONTROL_ENDPOINT_SIZE) 
  38 uint8_t USB_ControlEndpointSize 
= ENDPOINT_CONTROLEP_DEFAULT_SIZE
; 
  41 #if !defined(STATIC_ENDPOINT_CONFIGURATION) 
  42 bool Endpoint_ConfigureEndpoint(const uint8_t  Number
, const uint8_t Type
, const uint8_t Direction
, 
  43                                             const uint16_t Size
, const uint8_t Banks
) 
  45         Endpoint_SelectEndpoint(Number
); 
  46         Endpoint_EnableEndpoint(); 
  50         UECFG0X 
= ((Type 
<< EPTYPE0
) | Direction
); 
  51         UECFG1X 
= ((1 << ALLOC
) | Banks 
| Endpoint_BytesToEPSizeMask(Size
)); 
  53         return Endpoint_IsConfigured(); 
  56 bool Endpoint_ConfigureEndpointStatic(const uint8_t Number
, const uint8_t UECFG0XData
, const uint8_t UECFG1XData
) 
  58         Endpoint_SelectEndpoint(Number
); 
  59         Endpoint_EnableEndpoint(); 
  63         UECFG0X 
= UECFG0XData
; 
  64         UECFG1X 
= UECFG1XData
; 
  66         return Endpoint_IsConfigured(); 
  70 void Endpoint_ClearEndpoints(void) 
  74         for (uint8_t EPNum 
= 0; EPNum 
< ENDPOINT_TOTAL_ENDPOINTS
; EPNum
++) 
  76                 Endpoint_SelectEndpoint(EPNum
);  
  79                 Endpoint_DeallocateMemory(); 
  80                 Endpoint_DisableEndpoint(); 
  84 uint8_t Endpoint_WaitUntilReady(void) 
  86         uint8_t TimeoutMSRem 
= USB_STREAM_TIMEOUT_MS
; 
  88         USB_INT_Clear(USB_INT_SOFI
); 
  90         while (!(Endpoint_ReadWriteAllowed())) 
  92                 if (!(USB_IsConnected
)) 
  93                   return ENDPOINT_READYWAIT_DeviceDisconnected
; 
  94                 else if (Endpoint_IsStalled()) 
  95                   return ENDPOINT_READYWAIT_EndpointStalled
; 
  97                 if (USB_INT_HasOccurred(USB_INT_SOFI
)) 
  99                         USB_INT_Clear(USB_INT_SOFI
); 
 101                         if (!(TimeoutMSRem
--)) 
 102                           return ENDPOINT_READYWAIT_Timeout
; 
 106         return ENDPOINT_READYWAIT_NoError
; 
 109 uint8_t Endpoint_Discard_Stream(uint16_t Length
 
 110 #if !defined(NO_STREAM_CALLBACKS) 
 111                                 , uint8_t (* const Callback
)(void) 
 117         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 122                 if (!(Endpoint_ReadWriteAllowed())) 
 124                         Endpoint_ClearCurrentBank(); 
 126                         #if !defined(NO_STREAM_CALLBACKS) 
 127                         if ((Callback 
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
)) 
 128                           return ENDPOINT_RWSTREAM_ERROR_CallbackAborted
; 
 131                         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 135                 Endpoint_Discard_Byte(); 
 138         return ENDPOINT_RWSTREAM_ERROR_NoError
; 
 141 uint8_t Endpoint_Write_Stream_LE(const void* Buffer
, uint16_t Length
 
 142 #if !defined(NO_STREAM_CALLBACKS) 
 143                                  , uint8_t (* const Callback
)(void) 
 147         uint8_t* DataStream   
= (uint8_t*)Buffer
; 
 150         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 155                 if (!(Endpoint_ReadWriteAllowed())) 
 157                         Endpoint_ClearCurrentBank(); 
 159                         #if !defined(NO_STREAM_CALLBACKS) 
 160                         if ((Callback 
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
)) 
 161                           return ENDPOINT_RWSTREAM_ERROR_CallbackAborted
; 
 164                         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 168                 Endpoint_Write_Byte(*(DataStream
++)); 
 171         return ENDPOINT_RWSTREAM_ERROR_NoError
; 
 174 uint8_t Endpoint_Write_Stream_BE(const void* Buffer
, uint16_t Length
 
 175 #if !defined(NO_STREAM_CALLBACKS) 
 176                                  , uint8_t (* const Callback
)(void) 
 180         uint8_t* DataStream 
= (uint8_t*)(Buffer 
+ Length 
- 1); 
 183         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 188                 if (!(Endpoint_ReadWriteAllowed())) 
 190                         Endpoint_ClearCurrentBank(); 
 192                         #if !defined(NO_STREAM_CALLBACKS) 
 193                         if ((Callback 
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
)) 
 194                           return ENDPOINT_RWSTREAM_ERROR_CallbackAborted
; 
 197                         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 201                 Endpoint_Write_Byte(*(DataStream
--)); 
 204         return ENDPOINT_RWSTREAM_ERROR_NoError
; 
 207 uint8_t Endpoint_Read_Stream_LE(void* Buffer
, uint16_t Length
 
 208 #if !defined(NO_STREAM_CALLBACKS) 
 209                                  , uint8_t (* const Callback
)(void) 
 213         uint8_t* DataStream 
= (uint8_t*)Buffer
; 
 216         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 221                 if (!(Endpoint_ReadWriteAllowed())) 
 223                         Endpoint_ClearCurrentBank(); 
 225                         #if !defined(NO_STREAM_CALLBACKS) 
 226                         if ((Callback 
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
)) 
 227                           return ENDPOINT_RWSTREAM_ERROR_CallbackAborted
; 
 230                         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 234                 *(DataStream
++) = Endpoint_Read_Byte(); 
 237         return ENDPOINT_RWSTREAM_ERROR_NoError
; 
 240 uint8_t Endpoint_Read_Stream_BE(void* Buffer
, uint16_t Length
 
 241 #if !defined(NO_STREAM_CALLBACKS) 
 242                                  , uint8_t (* const Callback
)(void) 
 246         uint8_t* DataStream 
= (uint8_t*)(Buffer 
+ Length 
- 1); 
 249         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 254                 if (!(Endpoint_ReadWriteAllowed())) 
 256                         Endpoint_ClearCurrentBank(); 
 258                         #if !defined(NO_STREAM_CALLBACKS) 
 259                         if ((Callback 
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
)) 
 260                           return ENDPOINT_RWSTREAM_ERROR_CallbackAborted
; 
 263                         if ((ErrorCode 
= Endpoint_WaitUntilReady())) 
 267                 *(DataStream
--) = Endpoint_Read_Byte(); 
 270         return ENDPOINT_RWSTREAM_ERROR_NoError
; 
 273 uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer
, uint16_t Length
) 
 275         uint8_t* DataStream 
= (uint8_t*)Buffer
; 
 278         while (Length 
&& !(Endpoint_IsSetupOUTReceived())) 
 280                 while (!(Endpoint_IsSetupINReady())); 
 282                 while (Length 
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
)) 
 284                         Endpoint_Write_Byte(*(DataStream
++)); 
 289                 SendZLP 
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
); 
 290                 Endpoint_ClearSetupIN(); 
 293         if (Endpoint_IsSetupOUTReceived()) 
 294           return ENDPOINT_RWCSTREAM_ERROR_HostAborted
; 
 298                 while (!(Endpoint_IsSetupINReady())); 
 299                 Endpoint_ClearSetupIN(); 
 302         while (!(Endpoint_IsSetupOUTReceived())); 
 304         return ENDPOINT_RWCSTREAM_ERROR_NoError
; 
 307 uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer
, uint16_t Length
) 
 309         uint8_t* DataStream 
= (uint8_t*)(Buffer 
+ Length 
- 1); 
 312         while (Length 
&& !(Endpoint_IsSetupOUTReceived())) 
 314                 while (!(Endpoint_IsSetupINReady())); 
 316                 while (Length 
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
)) 
 318                         Endpoint_Write_Byte(*(DataStream
--)); 
 323                 SendZLP 
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
); 
 324                 Endpoint_ClearSetupIN(); 
 327         if (Endpoint_IsSetupOUTReceived()) 
 328           return ENDPOINT_RWCSTREAM_ERROR_HostAborted
; 
 332                 while (!(Endpoint_IsSetupINReady())); 
 333                 Endpoint_ClearSetupIN(); 
 336         while (!(Endpoint_IsSetupOUTReceived())); 
 338         return ENDPOINT_RWCSTREAM_ERROR_NoError
; 
 341 uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer
, uint16_t Length
) 
 343         uint8_t* DataStream 
= (uint8_t*)Buffer
; 
 347                 while (!(Endpoint_IsSetupOUTReceived())); 
 349                 while (Length 
&& Endpoint_BytesInEndpoint()) 
 351                         *(DataStream
++) = Endpoint_Read_Byte(); 
 356                 Endpoint_ClearSetupOUT(); 
 359         while (!(Endpoint_IsSetupINReady())); 
 361         return ENDPOINT_RWCSTREAM_ERROR_NoError
; 
 364 uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer
, uint16_t Length
) 
 366         uint8_t* DataStream 
= (uint8_t*)(Buffer 
+ Length 
- 1); 
 370                 while (!(Endpoint_IsSetupOUTReceived())); 
 372                 while (Length 
&& Endpoint_BytesInEndpoint()) 
 374                         *(DataStream
--) = Endpoint_Read_Byte(); 
 379                 Endpoint_ClearSetupOUT(); 
 382         while (!(Endpoint_IsSetupINReady())); 
 384         return ENDPOINT_RWCSTREAM_ERROR_NoError
;