From 69ab85cbc0504dd0a13346ca547ad13a25d55f71 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 18 Jul 2011 07:03:47 +0000 Subject: [PATCH] More USB XMEGA porting for Endpoint control. --- LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c | 52 ++++++++++--- LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h | 78 ++++++++++--------- .../USB/Core/XMEGA/USBController_XMEGA.h | 18 ++--- 3 files changed, 94 insertions(+), 54 deletions(-) diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c index 3eb156ca63..6e198d3a4d 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c +++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c @@ -39,27 +39,61 @@ 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) { - // TODO + for (uint8_t EPNum = 0; EPNum < (ENDPOINT_TOTAL_ENDPOINTS * 2); EPNum++) + ((USB_EP_t*)&USB_EndpointTable)[EPNum].CTRL = 0; } 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) { - 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 diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h index 4e7592a2f3..14ebf01f29 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h @@ -76,6 +76,7 @@ #include "../../../../Common/Common.h" #include "../USBTask.h" #include "../USBInterrupt.h" + #include "../USBController.h" /* Enable C linkage for C++ Compilers: */ #if defined(__cplusplus) @@ -95,6 +96,10 @@ #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; @@ -114,10 +119,6 @@ /* 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: */ @@ -127,12 +128,12 @@ /** 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. */ - #define ENDPOINT_DIR_IN true + #define ENDPOINT_DIR_IN ENDPOINT_DESCRIPTOR_DIR_IN //@} /** \name Endpoint Bank Mode Masks */ @@ -149,7 +150,7 @@ * 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__)) @@ -212,6 +213,24 @@ }; /* 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. @@ -263,7 +282,9 @@ 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. @@ -278,7 +299,7 @@ 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 @@ -290,22 +311,7 @@ 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 @@ -318,7 +324,7 @@ { // TODO } - +#if 0 /** Enables the currently selected endpoint so that data can be sent and received through it to * and from a host. * @@ -338,7 +344,7 @@ { // 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. @@ -346,7 +352,7 @@ 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 @@ -399,7 +405,7 @@ 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 @@ -436,7 +442,7 @@ 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. @@ -448,7 +454,7 @@ 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. @@ -460,7 +466,7 @@ 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 @@ -512,7 +518,7 @@ 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. @@ -522,7 +528,7 @@ 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. @@ -534,14 +540,14 @@ 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) { - // TODO + Endpoint_SelectedEndpointHandle->STATUS &= ~USB_EP_TOGGLE_bm; } /** Determines the currently selected endpoint's direction. diff --git a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h index 6b6c39a2c1..ca9f0f8f73 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h @@ -103,31 +103,31 @@ #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. * - * \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. * - * \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. * - * \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. * - * \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__)