More USB XMEGA porting for Endpoint control.
authorDean Camera <dean@fourwalledcubicle.com>
Mon, 18 Jul 2011 07:03:47 +0000 (07:03 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Mon, 18 Jul 2011 07:03:47 +0000 (07:03 +0000)
LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h

index 3eb156c..6e198d3 100644 (file)
 uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
 uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
-bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
-                                    const uint8_t UECFG0XData,
-                                    const uint8_t UECFG1XData)
-{
-       return false; // TODO
-}
+volatile uint8_t   Endpoint_SelectedEndpoint;
+volatile USB_EP_t* Endpoint_SelectedEndpointHandle;
 
 void Endpoint_ClearEndpoints(void)
 {
 
 void Endpoint_ClearEndpoints(void)
 {
-       // TODO
+       for (uint8_t EPNum = 0; EPNum < (ENDPOINT_TOTAL_ENDPOINTS * 2); EPNum++)
+         ((USB_EP_t*)&USB_EndpointTable)[EPNum].CTRL = 0;
 }
 
 void Endpoint_ClearStatusStage(void)
 {
 }
 
 void Endpoint_ClearStatusStage(void)
 {
-       // TODO
+       while (!(Endpoint_IsOUTReceived()))
+       {
+               if (USB_DeviceState == DEVICE_STATE_Unattached)
+                 return;
+       }
+
+       Endpoint_ClearOUT();
 }
 
 #if !defined(CONTROL_ONLY_DEVICE)
 uint8_t Endpoint_WaitUntilReady(void)
 {
 }
 
 #if !defined(CONTROL_ONLY_DEVICE)
 uint8_t Endpoint_WaitUntilReady(void)
 {
-       return 0; // TODO
+       #if (USB_STREAM_TIMEOUT_MS < 0xFF)
+       uint8_t  TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
+       #else
+       uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
+       #endif
+
+       uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber();
+
+       for (;;)
+       {
+               if (Endpoint_IsOUTReceived())
+                 return ENDPOINT_READYWAIT_NoError;
+               
+               uint8_t USB_DeviceState_LCL = USB_DeviceState;
+
+               if (USB_DeviceState_LCL == DEVICE_STATE_Unattached)
+                 return ENDPOINT_READYWAIT_DeviceDisconnected;
+               else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended)
+                 return ENDPOINT_READYWAIT_BusSuspended;
+               else if (Endpoint_IsStalled())
+                 return ENDPOINT_READYWAIT_EndpointStalled;
+
+               uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber();
+
+               if (CurrentFrameNumber != PreviousFrameNumber)
+               {
+                       PreviousFrameNumber = CurrentFrameNumber;
+
+                       if (!(TimeoutMSRem--))
+                         return ENDPOINT_READYWAIT_Timeout;
+               }
+       }
 }
 #endif
 
 }
 #endif
 
index 4e7592a..14ebf01 100644 (file)
@@ -76,6 +76,7 @@
                #include "../../../../Common/Common.h"
                #include "../USBTask.h"
                #include "../USBInterrupt.h"
                #include "../../../../Common/Common.h"
                #include "../USBTask.h"
                #include "../USBInterrupt.h"
+               #include "../USBController.h"
 
        /* Enable C linkage for C++ Compilers: */
                #if defined(__cplusplus)
 
        /* Enable C linkage for C++ Compilers: */
                #if defined(__cplusplus)
 
                        #define ENDPOINT_DETAILS_MAXEP                 16
 
 
                        #define ENDPOINT_DETAILS_MAXEP                 16
 
+               /* External Variables: */
+                       extern volatile uint8_t   Endpoint_SelectedEndpoint;
+                       extern volatile USB_EP_t* Endpoint_SelectedEndpointHandle;
+
                /* Inline Functions: */
                        static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
                                                                                               ATTR_ALWAYS_INLINE;
                /* Inline Functions: */
                        static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
                                                                                               ATTR_ALWAYS_INLINE;
 
                /* Function Prototypes: */
                        void Endpoint_ClearEndpoints(void);
 
                /* Function Prototypes: */
                        void Endpoint_ClearEndpoints(void);
-                       bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
-                                                           const uint8_t UECFG0XData,
-                                                           const uint8_t UECFG1XData);
-
        #endif
 
        /* Public Interface - May be used in end-application: */
        #endif
 
        /* Public Interface - May be used in end-application: */
                        /** 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                        false
+                       #define ENDPOINT_DIR_OUT                        ENDPOINT_DESCRIPTOR_DIR_OUT
 
                        /** 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                         true
+                       #define ENDPOINT_DIR_IN                         ENDPOINT_DESCRIPTOR_DIR_IN
                        //@}
                        
                        /** \name Endpoint Bank Mode Masks */
                        //@}
                        
                        /** \name Endpoint Bank Mode Masks */
                         *  in faster transfers as one USB device (the AVR or the host) can access one bank while the other
                         *  accesses the second bank.
                         */
                         *  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                    USB_EP_BANK_bm
+                       #define ENDPOINT_BANK_DOUBLE                    USB_EP_PINGPONG_bm
                        //@}
 
                        #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
                        //@}
 
                        #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
                        };
 
                /* Inline Functions: */
                        };
 
                /* Inline Functions: */
+                       /** 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).
+                        *
+                        *  Any endpoint operations which do not require the endpoint number to be indicated will operate on
+                        *  the currently selected endpoint.
+                        *
+                        *  \param[in] EndpointNumber Endpoint number to select.
+                        */
+                       static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
+                       static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber)
+                       {
+                               uint8_t EPTableIndex = ((EndpointNumber & ENDPOINT_EPNUM_MASK) << 1) | ((EndpointNumber & ENDPOINT_DESCRIPTOR_DIR_IN) ? 0x01 : 0);
+
+                               Endpoint_SelectedEndpoint       = EndpointNumber;
+                               Endpoint_SelectedEndpointHandle = &((USB_EP_t*)&USB_EndpointTable)[EPTableIndex];
+                       }
+
                        /** Configures the specified endpoint number with the given endpoint type, direction, bank size
                         *  and banking mode. Once configured, the endpoint may be read from or written to, depending
                         *  on its direction.
                        /** Configures the specified endpoint number with the given endpoint type, direction, bank size
                         *  and banking mode. Once configured, the endpoint may be read from or written to, depending
                         *  on its direction.
                                                                      const uint16_t Size,
                                                                      const uint8_t Banks)
                        {
                                                                      const uint16_t Size,
                                                                      const uint8_t Banks)
                        {
-                               return 0; // TODO
+                               Endpoint_SelectEndpoint(Number | Direction);
+                               Endpoint_SelectedEndpointHandle->CTRL = (Type | Banks | Endpoint_BytesToEPSizeMask(Size));
+                               return true;
                        }
 
                        /** Indicates the number of bytes currently stored in the current endpoint's selected bank.
                        }
 
                        /** Indicates the number of bytes currently stored in the current endpoint's selected bank.
                        static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint16_t Endpoint_BytesInEndpoint(void)
                        {
                        static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint16_t Endpoint_BytesInEndpoint(void)
                        {
-                               return 0; // TODO
+                               return (((uint16_t)(Endpoint_SelectedEndpointHandle->CNTH & ~USB_EP_ZLP_bm) << 8) | Endpoint_SelectedEndpointHandle->CNTL);
                        }
 
                        /** Get the endpoint address of the currently selected endpoint. This is typically used to save
                        }
 
                        /** Get the endpoint address of the currently selected endpoint. This is typically used to save
                        static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint8_t Endpoint_GetCurrentEndpoint(void)
                        {
                        static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint8_t Endpoint_GetCurrentEndpoint(void)
                        {
-                               return 0; // TODO
-                       }
-
-                       /** 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).
-                        *
-                        *  Any endpoint operations which do not require the endpoint number to be indicated will operate on
-                        *  the currently selected endpoint.
-                        *
-                        *  \param[in] EndpointNumber Endpoint number to select.
-                        */
-                       static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
-                       static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber)
-                       {
-                               // TODO
+                               return Endpoint_SelectedEndpoint;
                        }
 
                        /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
                        }
 
                        /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
                        {
                                // TODO
                        }
                        {
                                // TODO
                        }
-
+#if 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.
                         *
                        {
                                // TODO
                        }
                        {
                                // TODO
                        }
-
+#endif
                        /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
                         *
                         * \return Boolean \c true if the currently selected endpoint is enabled, \c false otherwise.
                        /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
                         *
                         * \return Boolean \c true if the currently selected endpoint is enabled, \c false otherwise.
                        static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsEnabled(void)
                        {
                        static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsEnabled(void)
                        {
-                               return 0; // TODO
+                               return true;
                        }
 
                        /** Retrieves the number of busy banks in the currently selected endpoint, which have been queued for
                        }
 
                        /** Retrieves the number of busy banks in the currently selected endpoint, which have been queued for
                        static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsConfigured(void)
                        {
                        static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsConfigured(void)
                        {
-                               return 0; // TODO
+                               return ((Endpoint_SelectedEndpointHandle->CTRL & USB_EP_TYPE_gm) ? true : false);
                        }
 
                        /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
                        }
 
                        /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
                        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 0; // TODO
+                               return (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm);
                        }
 
                        /** Determines if the selected OUT endpoint has received new packet from the host.
                        }
 
                        /** Determines if the selected OUT endpoint has received new packet from the host.
                        static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsOUTReceived(void)
                        {
                        static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsOUTReceived(void)
                        {
-                               return 0; // TODO
+                               return (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm);
                        }
 
                        /** Determines if the current CONTROL type endpoint has received a SETUP packet.
                        }
 
                        /** Determines if the current CONTROL type endpoint has received a SETUP packet.
                        static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsSETUPReceived(void)
                        {
                        static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsSETUPReceived(void)
                        {
-                               return 0; // TODO
+                               return (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_SETUP_bm);
                        }
 
                        /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
                        }
 
                        /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
                        static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_StallTransaction(void)
                        {
                        static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_StallTransaction(void)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointHandle->CTRL |=  USB_EP_STALL_bm;
                        }
 
                        /** Clears the STALL condition on the currently selected endpoint.
                        }
 
                        /** Clears the STALL condition on the currently selected endpoint.
                        static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearStall(void)
                        {
                        static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearStall(void)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointHandle->CTRL &= ~USB_EP_STALL_bm;
                        }
 
                        /** Determines if the currently selected endpoint is stalled, false otherwise.
                        }
 
                        /** Determines if the currently selected endpoint is stalled, false otherwise.
                        static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsStalled(void)
                        {
                        static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsStalled(void)
                        {
-                               return 0; // TODO
+                               return (Endpoint_SelectedEndpointHandle->CTRL & USB_EP_STALL_bm);
                        }
 
                        /** Resets the data toggle of the currently selected endpoint. */
                        static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ResetDataToggle(void)
                        {
                        }
 
                        /** Resets the data toggle of the currently selected endpoint. */
                        static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ResetDataToggle(void)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointHandle->STATUS &= ~USB_EP_TOGGLE_bm;
                        }
 
                        /** Determines the currently selected endpoint's direction.
                        }
 
                        /** Determines the currently selected endpoint's direction.
index 6b6c39a..ca9f0f8 100644 (file)
                        #define USB_OPT_BUSEVENT_PRIHIGH          ((1 << 1) | (0 << 1))
                        //@}
 
                        #define USB_OPT_BUSEVENT_PRIHIGH          ((1 << 1) | (0 << 1))
                        //@}
 
-                       /** \name Endpoint/Pipe Type Masks */
+                       /** \name Endpoint Type Masks */
                        //@{
                        /** Mask for a CONTROL type endpoint or pipe.
                         *
                        //@{
                        /** Mask for a CONTROL type endpoint or pipe.
                         *
-                        *  \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.
+                        *  \note See \ref Group_EndpointManagement for endpoint functions.
                         */
                         */
-                       #define EP_TYPE_CONTROL                 0x00
+                       #define EP_TYPE_CONTROL                 USB_EP_TYPE_CONTROL_gc
 
                        /** Mask for an ISOCHRONOUS type endpoint or pipe.
                         *
 
                        /** Mask for an ISOCHRONOUS type endpoint or pipe.
                         *
-                        *  \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.
+                        *  \note See \ref Group_EndpointManagement for endpoint functions.
                         */
                         */
-                       #define EP_TYPE_ISOCHRONOUS             0x01
+                       #define EP_TYPE_ISOCHRONOUS             USB_EP_TYPE_ISOCHRONOUS_gc
 
                        /** Mask for a BULK type endpoint or pipe.
                         *
 
                        /** Mask for a BULK type endpoint or pipe.
                         *
-                        *  \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.
+                        *  \note See \ref Group_EndpointManagement for endpoint functions.
                         */
                         */
-                       #define EP_TYPE_BULK                    0x02
+                       #define EP_TYPE_BULK                    USB_EP_TYPE_BULK_gc
 
                        /** Mask for an INTERRUPT type endpoint or pipe.
                         *
 
                        /** Mask for an INTERRUPT type endpoint or pipe.
                         *
-                        *  \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.
+                        *  \note See \ref Group_EndpointManagement for endpoint functions.
                         */
                         */
-                       #define EP_TYPE_INTERRUPT               0x03
+                       #define EP_TYPE_INTERRUPT              USB_EP_TYPE_BULK_gc
                        //@}
 
                        #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__)
                        //@}
 
                        #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__)