Fixed PDI/TPI programming speed of ~250KHz in the AVRISP-MKII Clone project, instead...
[pub/USBasp.git] / LUFA / Drivers / USB / LowLevel / Endpoint.h
index 0b0a472..ea2e8cc 100644 (file)
@@ -1,21 +1,21 @@
 /*
              LUFA Library
      Copyright (C) Dean Camera, 2010.
 /*
              LUFA Library
      Copyright (C) Dean Camera, 2010.
-              
+
   dean [at] fourwalledcubicle [dot] com
   dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
+           www.lufa-lib.org
 */
 
 /*
   Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
 */
 
 /*
   Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
-  Permission to use, copy, modify, distribute, and sell this 
+  Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
   software and its documentation for any purpose is hereby granted
-  without fee, provided that the above copyright notice appear in 
+  without fee, provided that the above copyright notice appear in
   all copies and that both that the copyright notice and this
   all copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting 
-  documentation, and that the name of the author not be used in 
-  advertising or publicity pertaining to distribution of the 
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
   software without specific, written prior permission.
 
   The author disclaim all warranties with regard to this
   software without specific, written prior permission.
 
   The author disclaim all warranties with regard to this
  *
  *  Functions, macros, variables, enums and types related to data reading and writing from and to endpoints.
  */
  *
  *  Functions, macros, variables, enums and types related to data reading and writing from and to endpoints.
  */
+
 /** \ingroup Group_EndpointRW
  *  @defgroup Group_EndpointPrimitiveRW Read/Write of Primitive Data Types
  *
  *  Functions, macros, variables, enums and types related to data reading and writing of primitive data types
  *  from and to endpoints.
 /** \ingroup Group_EndpointRW
  *  @defgroup Group_EndpointPrimitiveRW Read/Write of Primitive Data Types
  *
  *  Functions, macros, variables, enums and types related to data reading and writing of primitive data types
  *  from and to endpoints.
- */ 
+ */
 
 /** \ingroup Group_EndpointManagement
  *  @defgroup Group_EndpointPacketManagement Endpoint Packet Management
 
 /** \ingroup Group_EndpointManagement
  *  @defgroup Group_EndpointPacketManagement Endpoint Packet Management
@@ -77,7 +77,7 @@
                #include "../../../Common/Common.h"
                #include "../HighLevel/USBTask.h"
                #include "USBInterrupt.h"
                #include "../../../Common/Common.h"
                #include "../HighLevel/USBTask.h"
                #include "USBInterrupt.h"
-               
+
        /* Enable C linkage for C++ Compilers: */
                #if defined(__cplusplus)
                        extern "C" {
        /* Enable C linkage for C++ Compilers: */
                #if defined(__cplusplus)
                        extern "C" {
                /* Macros: */
                        #define _ENDPOINT_GET_MAXSIZE(EPIndex)         _ENDPOINT_GET_MAXSIZE2(ENDPOINT_DETAILS_EP ## EPIndex)
                        #define _ENDPOINT_GET_MAXSIZE2(EPDetails)      _ENDPOINT_GET_MAXSIZE3(EPDetails)
                /* Macros: */
                        #define _ENDPOINT_GET_MAXSIZE(EPIndex)         _ENDPOINT_GET_MAXSIZE2(ENDPOINT_DETAILS_EP ## EPIndex)
                        #define _ENDPOINT_GET_MAXSIZE2(EPDetails)      _ENDPOINT_GET_MAXSIZE3(EPDetails)
-                       #define _ENDPOINT_GET_MAXSIZE3(MaxSize, DB)    (MaxSize)
+                       #define _ENDPOINT_GET_MAXSIZE3(MaxSize, Banks) (MaxSize)
+
+                       #define _ENDPOINT_GET_BANKS(EPIndex)           _ENDPOINT_GET_BANKS2(ENDPOINT_DETAILS_EP ## EPIndex)
+                       #define _ENDPOINT_GET_BANKS2(EPDetails)        _ENDPOINT_GET_BANKS3(EPDetails)
+                       #define _ENDPOINT_GET_BANKS3(MaxSize, Banks)   (Banks)
 
 
-                       #define _ENDPOINT_GET_DOUBLEBANK(EPIndex)      _ENDPOINT_GET_DOUBLEBANK2(ENDPOINT_DETAILS_EP ## EPIndex)
-                       #define _ENDPOINT_GET_DOUBLEBANK2(EPDetails)   _ENDPOINT_GET_DOUBLEBANK3(EPDetails)
-                       #define _ENDPOINT_GET_DOUBLEBANK3(MaxSize, DB) (DB)
-                       
                        #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
                        #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
-                               #define ENDPOINT_DETAILS_EP0               64,  true
-                               #define ENDPOINT_DETAILS_EP1               256, true
-                               #define ENDPOINT_DETAILS_EP2               64,  true
-                               #define ENDPOINT_DETAILS_EP3               64,  true
-                               #define ENDPOINT_DETAILS_EP4               64,  true
-                               #define ENDPOINT_DETAILS_EP5               64,  true
-                               #define ENDPOINT_DETAILS_EP6               64,  true
+                               #define ENDPOINT_DETAILS_MAXEP             7
+
+                               #define ENDPOINT_DETAILS_EP0               64,  2
+                               #define ENDPOINT_DETAILS_EP1               256, 2
+                               #define ENDPOINT_DETAILS_EP2               64,  2
+                               #define ENDPOINT_DETAILS_EP3               64,  2
+                               #define ENDPOINT_DETAILS_EP4               64,  2
+                               #define ENDPOINT_DETAILS_EP5               64,  2
+                               #define ENDPOINT_DETAILS_EP6               64,  2
                        #else
                        #else
-                               #define ENDPOINT_DETAILS_EP0               64,  true
-                               #define ENDPOINT_DETAILS_EP1               64,  false
-                               #define ENDPOINT_DETAILS_EP2               64,  false
-                               #define ENDPOINT_DETAILS_EP3               64,  true
-                               #define ENDPOINT_DETAILS_EP4               64,  true                    
+                               #define ENDPOINT_DETAILS_MAXEP             5
+
+                               #define ENDPOINT_DETAILS_EP0               64,  2
+                               #define ENDPOINT_DETAILS_EP1               64,  1
+                               #define ENDPOINT_DETAILS_EP2               64,  1
+                               #define ENDPOINT_DETAILS_EP3               64,  2
+                               #define ENDPOINT_DETAILS_EP4               64,  2
                        #endif
 
                /* Inline Functions: */
                        #endif
 
                /* Inline Functions: */
                        {
                                uint8_t  MaskVal    = 0;
                                uint16_t CheckBytes = 8;
                        {
                                uint8_t  MaskVal    = 0;
                                uint16_t CheckBytes = 8;
-                               
+
                                while (CheckBytes < Bytes)
                                {
                                        MaskVal++;
                                        CheckBytes <<= 1;
                                }
                                while (CheckBytes < Bytes)
                                {
                                        MaskVal++;
                                        CheckBytes <<= 1;
                                }
-                               
+
                                return (MaskVal << EPSIZE0);
                        }
 
                                return (MaskVal << EPSIZE0);
                        }
 
                                                            const uint8_t UECFG1XData);
 
        #endif
                                                            const uint8_t UECFG1XData);
 
        #endif
-       
+
        /* Public Interface - May be used in end-application: */
                /* Macros: */
        /* Public Interface - May be used in end-application: */
                /* Macros: */
+                       /** \name Endpoint Direction Masks */
+                       //@{
                        /** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
                         *  should be initialized in the OUT direction - i.e. data flows from host to device.
                         */
                        /** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
                         *  should be initialized in the OUT direction - i.e. data flows from host to device.
                         */
-                       #define ENDPOINT_DIR_OUT                      (0 << EPDIR)
+                       #define ENDPOINT_DIR_OUT                        (0 << EPDIR)
 
                        /** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
                         *  should be initialized in the IN direction - i.e. data flows from device to host.
                         */
 
                        /** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
                         *  should be initialized in the IN direction - i.e. data flows from device to host.
                         */
-                       #define ENDPOINT_DIR_IN                       (1 << EPDIR)
-
+                       #define ENDPOINT_DIR_IN                         (1 << EPDIR)
+                       //@}
+                       
+                       /** \name Endpoint Bank Mode Masks */
+                       //@{
                        /** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
                         *  that the endpoint should have one single bank, which requires less USB FIFO memory but results
                         *  in slower transfers as only one USB device (the AVR or the host) can access the endpoint's
                         *  bank at the one time.
                         */
                        /** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
                         *  that the endpoint should have one single bank, which requires less USB FIFO memory but results
                         *  in slower transfers as only one USB device (the AVR or the host) can access the endpoint's
                         *  bank at the one time.
                         */
-                       #define ENDPOINT_BANK_SINGLE                  (0 << EPBK0)
+                       #define ENDPOINT_BANK_SINGLE                    (0 << EPBK0)
 
                        /** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
                         *  that the endpoint should have two banks, which requires more USB FIFO memory but results
                         *  in faster transfers as one USB device (the AVR or the host) can access one bank while the other
                         *  accesses the second bank.
                         */
 
                        /** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
                         *  that the endpoint should have two banks, which requires more USB FIFO memory but results
                         *  in faster transfers as one USB device (the AVR or the host) can access one bank while the other
                         *  accesses the second bank.
                         */
-                       #define ENDPOINT_BANK_DOUBLE                  (1 << EPBK0)
+                       #define ENDPOINT_BANK_DOUBLE                    (1 << EPBK0)
+                       //@}
                        
                        /** Endpoint address for the default control endpoint, which always resides in address 0. This is
                         *  defined for convenience to give more readable code when used with the endpoint macros.
                         */
                        
                        /** Endpoint address for the default control endpoint, which always resides in address 0. This is
                         *  defined for convenience to give more readable code when used with the endpoint macros.
                         */
-                       #define ENDPOINT_CONTROLEP                    0
+                       #define ENDPOINT_CONTROLEP                      0
 
                        #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
 
                        #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
-                               /** Default size of the default control endpoint's bank, until altered by the control endpoint bank size 
+                               /** Default size of the default control endpoint's bank, until altered by the control endpoint bank size
                                 *  value in the device descriptor. Not available if the FIXED_CONTROL_ENDPOINT_SIZE token is defined.
                                 */
                                 *  value in the device descriptor. Not available if the FIXED_CONTROL_ENDPOINT_SIZE token is defined.
                                 */
-                               #define ENDPOINT_CONTROLEP_DEFAULT_SIZE   8
+                               #define ENDPOINT_CONTROLEP_DEFAULT_SIZE     8
                        #endif
                        #endif
-                       
+
                        /** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
                         *  numerical address in the device.
                         */
                        /** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
                         *  numerical address in the device.
                         */
-                       #define ENDPOINT_EPNUM_MASK                   0x07
+                       #define ENDPOINT_EPNUM_MASK                     0x07
 
                        /** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's
                         *  direction for comparing with the ENDPOINT_DESCRIPTOR_DIR_* masks.
                         */
 
                        /** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's
                         *  direction for comparing with the ENDPOINT_DESCRIPTOR_DIR_* masks.
                         */
-                       #define ENDPOINT_EPDIR_MASK                   0x80
+                       #define ENDPOINT_EPDIR_MASK                     0x80
 
                        /** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's
                         *  bank size in the device.
                         */
 
                        /** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's
                         *  bank size in the device.
                         */
-                       #define ENDPOINT_EPSIZE_MASK                  0x7F
-                       
+                       #define ENDPOINT_EPSIZE_MASK                    0x7F
+
                        /** Maximum size in bytes of a given endpoint.
                         *
                        /** Maximum size in bytes of a given endpoint.
                         *
-                        *  \param[in] n  Endpoint number, a value between 0 and (ENDPOINT_TOTAL_ENDPOINTS - 1)
-                        */                             
-                       #define ENDPOINT_MAX_SIZE(n)                  _ENDPOINT_GET_MAXSIZE(n)
+                        *  \param[in] EPIndex  Endpoint number, a value between 0 and (ENDPOINT_TOTAL_ENDPOINTS - 1)
+                        */
+                       #define ENDPOINT_MAX_SIZE(EPIndex)              _ENDPOINT_GET_MAXSIZE(EPIndex)
 
 
-                       /** Indicates if the given endpoint supports double banking.
+                       /** Indicates the total number of banks supported by the given endpoint.
                         *
                         *
-                        *  \param[in] n  Endpoint number, a value between 0 and (ENDPOINT_TOTAL_ENDPOINTS - 1)
-                        */                             
-                       #define ENDPOINT_DOUBLEBANK_SUPPORTED(n)      _ENDPOINT_GET_DOUBLEBANK(n)
+                        *  \param[in] EPIndex  Endpoint number, a value between 0 and (ENDPOINT_TOTAL_ENDPOINTS - 1)
+                        */
+                       #define ENDPOINT_BANKS_SUPPORTED(EPIndex)       _ENDPOINT_GET_BANKS(EPIndex)
 
 
-                       #if !defined(CONTROL_ONLY_DEVICE)
-                               #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__)
-                                       /** Total number of endpoints (including the default control endpoint at address 0) which may
-                                        *  be used in the device. Different USB AVR models support different amounts of endpoints,
-                                        *  this value reflects the maximum number of endpoints for the currently selected AVR model.
-                                        */
-                                       #define ENDPOINT_TOTAL_ENDPOINTS      7
-                               #else
-                                       #define ENDPOINT_TOTAL_ENDPOINTS      5
-                               #endif
+                       #if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__)
+                               /** Total number of endpoints (including the default control endpoint at address 0) which may
+                                *  be used in the device. Different USB AVR models support different amounts of endpoints,
+                                *  this value reflects the maximum number of endpoints for the currently selected AVR model.
+                                */
+                               #define ENDPOINT_TOTAL_ENDPOINTS            ENDPOINT_DETAILS_MAXEP
                        #else
                        #else
-                               #define ENDPOINT_TOTAL_ENDPOINTS          1
+                               #define ENDPOINT_TOTAL_ENDPOINTS            1
                        #endif
 
                /* Enums: */
                        #endif
 
                /* Enums: */
                                                                                 */
                        };
 
                                                                                 */
                        };
 
-               /* Inline Functions: */                 
+               /* Inline Functions: */
                        /** Configures the specified endpoint number with the given endpoint type, direction, bank size
                        /** Configures the specified endpoint number with the given endpoint type, direction, bank size
-                        *  and banking mode. Endpoints should be allocated in ascending order by their address in the
-                        *  device (i.e. endpoint 1 should be configured before endpoint 2 and so on) to prevent fragmentation
-                        *  of the USB FIFO memory.
+                        *  and banking mode. Once configured, the endpoint may be read from or written to, depending
+                        *  on its direction.
+                        *
+                        *  \param[in] Number     Endpoint number to configure. This must be more than 0 and less than
+                        *                        \ref ENDPOINT_TOTAL_ENDPOINTS.
+                        *
+                        *  \param[in] Type       Type of endpoint to configure, a EP_TYPE_* mask. Not all endpoint types
+                        *                        are available on Low Speed USB devices - refer to the USB 2.0 specification.
+                        *
+                        *  \param[in] Direction  Endpoint data direction, either \ref ENDPOINT_DIR_OUT or \ref ENDPOINT_DIR_IN.
+                        *                        All endpoints (except Control type) are unidirectional - data may only be read
+                        *                        from or written to the endpoint bank based on its direction, not both.
+                        *
+                        *  \param[in] Size       Size of the endpoint's bank, where packets are stored before they are transmitted
+                        *                        to the USB host, or after they have been received from the USB host (depending on
+                        *                        the endpoint's data direction). The bank size must indicate the maximum packet size
+                        *                        that the endpoint can handle.
                         *
                         *
-                        *  The endpoint type may be one of the EP_TYPE_* macros listed in LowLevel.h and the direction
-                        *  may be either \ref ENDPOINT_DIR_OUT or \ref ENDPOINT_DIR_IN.
+                        *  \param[in] Banks      Number of banks to use for the endpoint being configured, an ENDPOINT_BANK_* mask.
+                        *                        More banks uses more USB DPRAM, but offers better performance. Isochronous type
+                        *                        endpoints <b>must</b> have at least two banks.
                         *
                         *
-                        *  The bank size must indicate the maximum packet size that the endpoint can handle. Different
-                        *  endpoint numbers can handle different maximum packet sizes - refer to the chosen USB AVR's
-                        *  datasheet to determine the maximum bank size for each endpoint.
+                        *  \note Endpoints <b>must</b> be configured in ascending order, or bank corruption will occur.
+                        *        \n\n
                         *
                         *
-                        *  The banking mode may be either \ref ENDPOINT_BANK_SINGLE or \ref ENDPOINT_BANK_DOUBLE.
+                        *  \note Certain models of USB AVR's endpoints may have different maximum packet sizes based on the endpoint's
+                        *        index - refer to the chosen USB AVR's datasheet to determine the maximum bank size for each endpoint.
+                        *        \n\n
                         *
                         *
-                        *  \note The default control endpoint should not be manually configured by the user application, as 
+                        *  \note The default control endpoint should not be manually configured by the user application, as
                         *        it is automatically configured by the library internally.
                         *        \n\n
                         *
                         *        it is automatically configured by the library internally.
                         *        \n\n
                         *
-                        *  \note This routine will select the specified endpoint, and the endpoint will remain selected
-                        *        once the routine completes regardless of if the endpoint configuration succeeds.
+                        *  \note This routine will automatically select the specified endpoint upon success. Upon failure, the endpoint
+                        *        which failed to reconfigure correctly will be selected.
                         *
                         *  \return Boolean true if the configuration succeeded, false otherwise.
                         */
                         *
                         *  \return Boolean true if the configuration succeeded, false otherwise.
                         */
                                        return UEBCLX;
                                #endif
                        }
                                        return UEBCLX;
                                #endif
                        }
-               
+
                        /** Get the endpoint address of the currently selected endpoint. This is typically used to save
                         *  the currently selected endpoint number so that it can be restored after another endpoint has
                         *  been manipulated.
                        /** Get the endpoint address of the currently selected endpoint. This is typically used to save
                         *  the currently selected endpoint number so that it can be restored after another endpoint has
                         *  been manipulated.
                                        return ENDPOINT_CONTROLEP;
                                #endif
                        }
                                        return ENDPOINT_CONTROLEP;
                                #endif
                        }
-                       
+
                        /** Selects the given endpoint number. If the address from the device descriptors is used, the
                         *  value should be masked with the \ref ENDPOINT_EPNUM_MASK constant to extract only the endpoint
                         *  number (and discarding the endpoint direction bit).
                        /** Selects the given endpoint number. If the address from the device descriptors is used, the
                         *  value should be masked with the \ref ENDPOINT_EPNUM_MASK constant to extract only the endpoint
                         *  number (and discarding the endpoint direction bit).
                        {
                                #if !defined(CONTROL_ONLY_DEVICE)
                                        UENUM = EndpointNumber;
                        {
                                #if !defined(CONTROL_ONLY_DEVICE)
                                        UENUM = EndpointNumber;
-                               #endif                  
+                               #endif
                        }
                        }
-                       
+
                        /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
                         *  In and Out pointers to the bank's contents.
                         *
                        /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
                         *  In and Out pointers to the bank's contents.
                         *
                                UERST = (1 << EndpointNumber);
                                UERST = 0;
                        }
                                UERST = (1 << EndpointNumber);
                                UERST = 0;
                        }
-                       
+
                        /** Enables the currently selected endpoint so that data can be sent and received through it to
                         *  and from a host.
                         *
                        /** Enables the currently selected endpoint so that data can be sent and received through it to
                         *  and from a host.
                         *
                        {
                                UECONX &= ~(1 << EPEN);
                        }
                        {
                                UECONX &= ~(1 << EPEN);
                        }
-                       
+
                        /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
                         *
                         * \return Boolean True if the currently selected endpoint is enabled, false otherwise.
                        /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
                         *
                         * \return Boolean True if the currently selected endpoint is enabled, false otherwise.
                        {
                                return ((UECONX & (1 << EPEN)) ? true : false);
                        }
                        {
                                return ((UECONX & (1 << EPEN)) ? true : false);
                        }
+
+                       /** Aborts all pending IN transactions on the currently selected endpoint, once the bank
+                        *  has been queued for transmission to the host via \ref Endpoint_ClearIN(). This function
+                        *  will terminate all queued transactions, resetting the endpoint banks ready for a new
+                        *  packet.
+                        *
+                        *  \ingroup Group_EndpointPacketManagement
+                        */
+                       static inline void Endpoint_AbortPendingIN(void)
+                       {
+                               while (UESTA0X & (0x03 << NBUSYBK0))
+                               {
+                                       UEINTX |= (1 << RXOUTI);
+                                       while (UEINTX & (1 << RXOUTI));
+                               }
+                       }
                        
                        
+                       /** Retrieves the number of busy banks in the currently selected endpoint, which have been queued for
+                        *  transmission via the \ref Endpoint_ClearIN() command, or are awaiting acknowledgement via the
+                        *  \ref Endpoint_ClearOUT() command.
+                        *
+                        *  \ingroup Group_EndpointPacketManagement
+                        *
+                        *  \return Total number of busy banks in the selected endpoint.
+                        */
+                       static inline uint8_t Endpoint_GetBusyBanks(void)
+                       {
+                               return (UESTA0X & (0x03 << NBUSYBK0));
+                       }
+
                        /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint
                         *  bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN
                         *  direction). This function will return false if an error has occurred in the endpoint, if the endpoint
                        /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint
                         *  bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN
                         *  direction). This function will return false if an error has occurred in the endpoint, if the endpoint
                        {
                                return ((UEINTX & (1 << RWAL)) ? true : false);
                        }
                        {
                                return ((UEINTX & (1 << RWAL)) ? true : false);
                        }
-                       
+
                        /** Determines if the currently selected endpoint is configured.
                         *
                         *  \return Boolean true if the currently selected endpoint has been configured, false otherwise.
                        /** Determines if the currently selected endpoint is configured.
                         *
                         *  \return Boolean true if the currently selected endpoint has been configured, false otherwise.
                        {
                                return ((UESTA0X & (1 << CFGOK)) ? true : false);
                        }
                        {
                                return ((UESTA0X & (1 << CFGOK)) ? true : false);
                        }
-                       
+
                        /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
                         *  interrupt duration has elapsed. Which endpoints have interrupted can be determined by
                         *  masking the return value against (1 << {Endpoint Number}).
                        /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
                         *  interrupt duration has elapsed. Which endpoints have interrupted can be determined by
                         *  masking the return value against (1 << {Endpoint Number}).
                        {
                                return UEINT;
                        }
                        {
                                return UEINT;
                        }
-                       
+
                        /** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type
                         *  endpoints).
                         *
                        /** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type
                         *  endpoints).
                         *
                        {
                                return ((UEINT & (1 << EndpointNumber)) ? true : false);
                        }
                        {
                                return ((UEINT & (1 << EndpointNumber)) ? true : false);
                        }
-                       
-                       /** Determines if the selected IN endpoint is ready for a new packet.
+
+                       /** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                         *
                         *
                         *  \ingroup Group_EndpointPacketManagement
                         *
                        static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsINReady(void)
                        {
                        static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsINReady(void)
                        {
-                               return ((UEINTX & (1 << TXINI))  ? true : false);
+                               return ((UEINTX & (1 << TXINI)) ? true : false);
                        }
                        }
-                       
-                       /** Determines if the selected OUT endpoint has received new packet.
+
+                       /** Determines if the selected OUT endpoint has received new packet from the host.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                         *
                         *
                         *  \ingroup Group_EndpointPacketManagement
                         *
                        {
                                return ((UEINTX & (1 << RXOUTI)) ? true : false);
                        }
                        {
                                return ((UEINTX & (1 << RXOUTI)) ? true : false);
                        }
-                       
+
                        /** Determines if the current CONTROL type endpoint has received a SETUP packet.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                        /** Determines if the current CONTROL type endpoint has received a SETUP packet.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                        {
                                return ((UEINTX & (1 << RXSTPI)) ? true : false);
                        }
                        {
                                return ((UEINTX & (1 << RXSTPI)) ? true : false);
                        }
-                       
+
                        /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
                         *  endpoint for the next packet.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                         *
                        /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
                         *  endpoint for the next packet.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                         *
-                        *  \note This is not applicable for non CONTROL type endpoints. 
+                        *  \note This is not applicable for non CONTROL type endpoints.
                         */
                        static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearSETUP(void)
                        {
                                UEINTX &= ~(1 << RXSTPI);
                        }
                         */
                        static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearSETUP(void)
                        {
                                UEINTX &= ~(1 << RXSTPI);
                        }
-                       
+
                        /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
                         *  next packet and switching to the alternative endpoint bank if double banked.
                         *
                        /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
                         *  next packet and switching to the alternative endpoint bank if double banked.
                         *
                                        UEINTX &= ~(1 << TXINI);
                                #endif
                        }
                                        UEINTX &= ~(1 << TXINI);
                                #endif
                        }
-                       
+
                        /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
                         *  for the next packet and switching to the alternative endpoint bank if double banked.
                         *
                        /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
                         *  for the next packet and switching to the alternative endpoint bank if double banked.
                         *
                                #if !defined(CONTROL_ONLY_DEVICE)
                                        UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON));
                                #else
                                #if !defined(CONTROL_ONLY_DEVICE)
                                        UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON));
                                #else
-                                       UEINTX &= ~(1 << RXOUTI);       
+                                       UEINTX &= ~(1 << RXOUTI);
                                #endif
                        }
                                #endif
                        }
-                       
+
                        /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
                         *  indicated endpoint and that the current transfer sequence should be aborted. This provides a
                         *  way for devices to indicate invalid commands to the host so that the current transfer can be
                        /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
                         *  indicated endpoint and that the current transfer sequence should be aborted. This provides a
                         *  way for devices to indicate invalid commands to the host so that the current transfer can be
                        {
                                UECONX |= (1 << STALLRQ);
                        }
                        {
                                UECONX |= (1 << STALLRQ);
                        }
-                       
+
                        /** Clears the STALL condition on the currently selected endpoint.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                        /** Clears the STALL condition on the currently selected endpoint.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                        {
                                UECONX |= (1 << STALLRQC);
                        }
                        {
                                UECONX |= (1 << STALLRQC);
                        }
-                       
+
                        /** Determines if the currently selected endpoint is stalled, false otherwise.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                        /** Determines if the currently selected endpoint is stalled, false otherwise.
                         *
                         *  \ingroup Group_EndpointPacketManagement
                        {
                                return ((UECONX & (1 << STALLRQ)) ? true : false);
                        }
                        {
                                return ((UECONX & (1 << STALLRQ)) ? true : false);
                        }
-                       
+
                        /** Resets the data toggle of the currently selected endpoint. */
                        static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ResetDataToggle(void)
                        {
                                UECONX |= (1 << RSTDT);
                        }
                        /** Resets the data toggle of the currently selected endpoint. */
                        static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ResetDataToggle(void)
                        {
                                UECONX |= (1 << RSTDT);
                        }
-                       
+
                        /** Determines the currently selected endpoint's direction.
                         *
                         *  \return The currently selected endpoint's direction, as a ENDPOINT_DIR_* mask.
                        /** Determines the currently selected endpoint's direction.
                         *
                         *  \return The currently selected endpoint's direction, as a ENDPOINT_DIR_* mask.
                        static inline void Endpoint_Discard_Byte(void)
                        {
                                uint8_t Dummy;
                        static inline void Endpoint_Discard_Byte(void)
                        {
                                uint8_t Dummy;
-                               
+
                                Dummy = UEDATX;
                        }
                                Dummy = UEDATX;
                        }
-                       
+
                        /** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
                         *  direction endpoints.
                         *
                        /** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
                         *  direction endpoints.
                         *
                                        uint16_t Word;
                                        uint8_t  Bytes[2];
                                } Data;
                                        uint16_t Word;
                                        uint8_t  Bytes[2];
                                } Data;
-                               
+
                                Data.Bytes[0] = UEDATX;
                                Data.Bytes[1] = UEDATX;
                                Data.Bytes[0] = UEDATX;
                                Data.Bytes[1] = UEDATX;
-                       
+
                                return Data.Word;
                        }
 
                                return Data.Word;
                        }
 
                                        uint16_t Word;
                                        uint8_t  Bytes[2];
                                } Data;
                                        uint16_t Word;
                                        uint8_t  Bytes[2];
                                } Data;
-                               
+
                                Data.Bytes[1] = UEDATX;
                                Data.Bytes[0] = UEDATX;
                                Data.Bytes[1] = UEDATX;
                                Data.Bytes[0] = UEDATX;
-                       
+
                                return Data.Word;
                        }
 
                                return Data.Word;
                        }
 
                                UEDATX = (Word & 0xFF);
                                UEDATX = (Word >> 8);
                        }
                                UEDATX = (Word & 0xFF);
                                UEDATX = (Word >> 8);
                        }
-                       
+
                        /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
                         *  direction endpoints.
                         *
                        /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
                         *  direction endpoints.
                         *
                        static inline void Endpoint_Discard_Word(void)
                        {
                                uint8_t Dummy;
                        static inline void Endpoint_Discard_Word(void)
                        {
                                uint8_t Dummy;
-                               
+
                                Dummy = UEDATX;
                                Dummy = UEDATX;
                        }
                                Dummy = UEDATX;
                                Dummy = UEDATX;
                        }
                                        uint32_t DWord;
                                        uint8_t  Bytes[4];
                                } Data;
                                        uint32_t DWord;
                                        uint8_t  Bytes[4];
                                } Data;
-                               
+
                                Data.Bytes[0] = UEDATX;
                                Data.Bytes[1] = UEDATX;
                                Data.Bytes[2] = UEDATX;
                                Data.Bytes[3] = UEDATX;
                                Data.Bytes[0] = UEDATX;
                                Data.Bytes[1] = UEDATX;
                                Data.Bytes[2] = UEDATX;
                                Data.Bytes[3] = UEDATX;
-                       
+
                                return Data.DWord;
                        }
 
                                return Data.DWord;
                        }
 
                                        uint32_t DWord;
                                        uint8_t  Bytes[4];
                                } Data;
                                        uint32_t DWord;
                                        uint8_t  Bytes[4];
                                } Data;
-                               
+
                                Data.Bytes[3] = UEDATX;
                                Data.Bytes[2] = UEDATX;
                                Data.Bytes[1] = UEDATX;
                                Data.Bytes[0] = UEDATX;
                                Data.Bytes[3] = UEDATX;
                                Data.Bytes[2] = UEDATX;
                                Data.Bytes[1] = UEDATX;
                                Data.Bytes[0] = UEDATX;
-                       
+
                                return Data.DWord;
                        }
 
                                return Data.DWord;
                        }
 
                                UEDATX = (DWord >> 16);
                                UEDATX = (DWord >> 24);
                        }
                                UEDATX = (DWord >> 16);
                                UEDATX = (DWord >> 24);
                        }
-                       
+
                        /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
                         *  direction endpoints.
                         *
                        /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
                         *  direction endpoints.
                         *
                                UEDATX = (DWord &  0xFF);
                        }
 
                                UEDATX = (DWord &  0xFF);
                        }
 
-                       /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.       
+                       /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.
                         *
                         *  \ingroup Group_EndpointPrimitiveRW
                         */
                         *
                         *  \ingroup Group_EndpointPrimitiveRW
                         */
                        static inline void Endpoint_Discard_DWord(void)
                        {
                                uint8_t Dummy;
                        static inline void Endpoint_Discard_DWord(void)
                        {
                                uint8_t Dummy;
-                               
+
                                Dummy = UEDATX;
                                Dummy = UEDATX;
                                Dummy = UEDATX;
                                Dummy = UEDATX;
                                Dummy = UEDATX;
                                Dummy = UEDATX;
                #if defined(__cplusplus)
                        }
                #endif
                #if defined(__cplusplus)
                        }
                #endif
-               
+
 #endif
 
 /** @} */
 #endif
 
 /** @} */
+