XMEGA port improvements; connection and disconnection are now detected correctly...
authorDean Camera <dean@fourwalledcubicle.com>
Sun, 30 Oct 2011 07:09:20 +0000 (07:09 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Sun, 30 Oct 2011 07:09:20 +0000 (07:09 +0000)
LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h
LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c
LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h
LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.c
LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.h

index 8764ea1..df6823a 100644 (file)
                        static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
                        static inline uint16_t USB_Device_GetFrameNumber(void)
                        {
                        static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
                        static inline uint16_t USB_Device_GetFrameNumber(void)
                        {
-                               return (((uint16_t)USB_EndpointTable.FRAMENUMH << 8) | USB_EndpointTable.FRAMENUML);
+                               return USB_EndpointTable.FrameNum;
                        }
 
                        #if !defined(NO_SOF_EVENTS)
                        }
 
                        #if !defined(NO_SOF_EVENTS)
index 6e198d3..6542217 100644 (file)
 uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
 uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
-volatile uint8_t   Endpoint_SelectedEndpoint;
-volatile USB_EP_t* Endpoint_SelectedEndpointHandle;
+Endpoint_AuxData_t           Endpoint_AuxData[ENDPOINT_DETAILS_MAXEP * 2];
+
+volatile uint8_t             Endpoint_SelectedEndpoint;
+volatile USB_EP_t*           Endpoint_SelectedEndpointHandle;
+volatile Endpoint_AuxData_t* Endpoint_SelectedEndpointAux;
+
+bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
+                                    const uint8_t Direction,
+                                    const uint8_t Config,
+                                    const uint8_t Size)
+{
+       Endpoint_SelectEndpoint(Number | Direction);
+       
+       Endpoint_SelectedEndpointHandle->CTRL      = 0;
+       Endpoint_SelectedEndpointHandle->STATUS    = (Direction == ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0;
+       Endpoint_SelectedEndpointHandle->CTRL      = Config;
+       Endpoint_SelectedEndpointHandle->CNT       = 0;
+       Endpoint_SelectedEndpointHandle->DATAPTR   = (intptr_t)&Endpoint_SelectedEndpointAux->Data;
+       
+       Endpoint_SelectedEndpointAux->BankSize     = Size;
+       Endpoint_SelectedEndpointAux->FIFOLength   = (Direction == ENDPOINT_DIR_IN) ? Size : 0;
+       Endpoint_SelectedEndpointAux->FIFOPosition = 0;
+
+       return true;
+}
 
 void Endpoint_ClearEndpoints(void)
 {
 
 void Endpoint_ClearEndpoints(void)
 {
index 77fb7f7..3fbd3ff 100644 (file)
 
                        #define ENDPOINT_DETAILS_MAXEP                 16
 
 
                        #define ENDPOINT_DETAILS_MAXEP                 16
 
+               /* Type Defines: */
+                       typedef struct
+                       {
+                               uint8_t   Data[64];
+                               uint8_t   BankSize;
+                               uint8_t   FIFOLength;
+                               uint8_t   FIFOPosition;
+                       } Endpoint_AuxData_t;
+
                /* External Variables: */
                /* External Variables: */
-                       extern volatile uint8_t   Endpoint_SelectedEndpoint;
-                       extern volatile USB_EP_t* Endpoint_SelectedEndpointHandle;
+                       extern Endpoint_AuxData_t           Endpoint_AuxData[ENDPOINT_DETAILS_MAXEP * 2];
+                       extern volatile uint8_t             Endpoint_SelectedEndpoint;
+                       extern volatile USB_EP_t*           Endpoint_SelectedEndpointHandle;
+                       extern volatile Endpoint_AuxData_t* Endpoint_SelectedEndpointAux;
 
                /* Inline Functions: */
                        static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
 
                /* Inline Functions: */
                        static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
                        }
 
                /* Function Prototypes: */
                        }
 
                /* Function Prototypes: */
+                       bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
+                                                           const uint8_t Direction,
+                                                           const uint8_t Config,
+                                                           const uint8_t Size);
                        void Endpoint_ClearEndpoints(void);
        #endif
 
                        void Endpoint_ClearEndpoints(void);
        #endif
 
                                                        ((EndpointNumber & ENDPOINT_DIR_IN) ? 0x01 : 0);
 
                                Endpoint_SelectedEndpoint       = EndpointNumber;
                                                        ((EndpointNumber & ENDPOINT_DIR_IN) ? 0x01 : 0);
 
                                Endpoint_SelectedEndpoint       = EndpointNumber;
-                               Endpoint_SelectedEndpointHandle = &((USB_EP_t*)&USB_EndpointTable)[EPTableIndex];
+                               Endpoint_SelectedEndpointHandle = &((USB_EP_t*)&USB_EndpointTable.Endpoints)[EPTableIndex];
+                               Endpoint_SelectedEndpointAux    = &Endpoint_AuxData[EPTableIndex];
                        }
 
                        /** 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
                                                                      const uint16_t Size,
                                                                      const uint8_t Banks)
                        {
                                                                      const uint16_t Size,
                                                                      const uint8_t Banks)
                        {
-                               Endpoint_SelectEndpoint(Number | Direction);
+                               uint8_t EPConfigMask = (Banks | Endpoint_BytesToEPSizeMask(Size));
 
 
-                               uint8_t EPTypeMask = 0;
                                switch (Type)
                                {
                                        case EP_TYPE_CONTROL:
                                switch (Type)
                                {
                                        case EP_TYPE_CONTROL:
-                                               EPTypeMask = USB_EP_TYPE_CONTROL_gc;
+                                               EPConfigMask |= USB_EP_TYPE_CONTROL_gc;
                                                break;
                                        case EP_TYPE_ISOCHRONOUS:
                                                break;
                                        case EP_TYPE_ISOCHRONOUS:
-                                               EPTypeMask = USB_EP_TYPE_ISOCHRONOUS_gc;
+                                               EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc;
                                                break;
                                        default:
                                                break;
                                        default:
-                                               EPTypeMask = USB_EP_TYPE_BULK_gc;
+                                               EPConfigMask |= USB_EP_TYPE_BULK_gc;
                                                break;
                                }
                                                break;
                                }
-       
-                               Endpoint_SelectedEndpointHandle->CTRL   = 0;
-                               Endpoint_SelectedEndpointHandle->STATUS = (USB_EP_BUSNACK0_bm | USB_EP_BUSNACK1_bm);
-                               Endpoint_SelectedEndpointHandle->CTRL   = (EPTypeMask | Banks | Endpoint_BytesToEPSizeMask(Size));
-                               return true;
+                               
+                               if (Type == EP_TYPE_CONTROL)
+                                 Endpoint_ConfigureEndpoint_PRV(Number, Direction ^ ENDPOINT_DIR_IN, EPConfigMask, Size);
+                                 
+                               return Endpoint_ConfigureEndpoint_PRV(Number, Direction, EPConfigMask, Size);
                        }
 
                        /** 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 (((uint16_t)(Endpoint_SelectedEndpointHandle->CNTH & ~USB_EP_ZLP_bm) << 8) | Endpoint_SelectedEndpointHandle->CNTL);
+                               return Endpoint_SelectedEndpointAux->FIFOPosition;
                        }
 
                        /** 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 void Endpoint_ResetEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber)
                        {
                        static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointAux->FIFOPosition = 0;
                        }
 
                        /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
                        }
 
                        /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
                        static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsReadWriteAllowed(void)
                        {
                        static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsReadWriteAllowed(void)
                        {
-                               return 0; // TODO
+                               return (Endpoint_SelectedEndpointAux->FIFOPosition < Endpoint_SelectedEndpointAux->FIFOLength);
                        }
 
                        /** Determines if the currently selected endpoint is configured.
                        }
 
                        /** Determines if the currently selected endpoint is configured.
                        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 (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm);
+                               return ((Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm) ? true : false);
                        }
 
                        /** 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 (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm);
+                               if (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm)
+                               {
+                                       Endpoint_SelectedEndpointAux->FIFOLength = Endpoint_SelectedEndpointHandle->CNT;
+                                       return true;
+                               }
+                               
+                               return false;
                        }
 
                        /** 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 (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_SETUP_bm);
+                               return ((Endpoint_SelectedEndpointHandle->STATUS & USB_EP_SETUP_bm) ? true : false);
                        }
 
                        /** 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_ClearSETUP(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearSETUP(void)
                        {
                        static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearSETUP(void)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm);
+
+                               Endpoint_SelectedEndpointAux->FIFOPosition    = 0;
                        }
 
                        /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
                        }
 
                        /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
                        static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearIN(void)
                        {
                        static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearIN(void)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointHandle->CNT     = Endpoint_SelectedEndpointAux->FIFOPosition;
+                               Endpoint_SelectedEndpointHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm);
+
+                               Endpoint_SelectedEndpointAux->FIFOPosition    = 0;
                        }
 
                        /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
                        }
 
                        /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
                         */
                        static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearOUT(void)
                         */
                        static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearOUT(void)
-                       {
-                               // TODO
+                       {                               
+                               Endpoint_SelectedEndpointHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm);
+
+                               Endpoint_SelectedEndpointAux->FIFOPosition    = 0;
                        }
 
                        /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
                        }
 
                        /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
                        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 (Endpoint_SelectedEndpointHandle->CTRL & USB_EP_STALL_bm);
+                               return ((Endpoint_SelectedEndpointHandle->CTRL & USB_EP_STALL_bm) ? true : false);
                        }
 
                        /** Resets the data toggle of the currently selected endpoint. */
                        }
 
                        /** Resets the data toggle of the currently selected endpoint. */
                        static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint8_t Endpoint_GetEndpointDirection(void)
                        {
                        static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint8_t Endpoint_GetEndpointDirection(void)
                        {
-                               return 0; // TODO
+                               return ((Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) ? true : false);
                        }
 
                        /** Sets the direction of the currently selected endpoint.
                        }
 
                        /** Sets the direction of the currently selected endpoint.
                        static inline uint8_t Endpoint_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint8_t Endpoint_Read_8(void)
                        {
                        static inline uint8_t Endpoint_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint8_t Endpoint_Read_8(void)
                        {
-                               return 0; // TODO
+                               return Endpoint_SelectedEndpointAux->Data[Endpoint_SelectedEndpointAux->FIFOPosition++];
                        }
 
                        /** Writes one byte to the currently selected endpoint's bank, for IN direction endpoints.
                        }
 
                        /** Writes one byte to the currently selected endpoint's bank, for IN direction endpoints.
                        static inline void Endpoint_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_8(const uint8_t Data)
                        {
                        static inline void Endpoint_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_8(const uint8_t Data)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointAux->Data[Endpoint_SelectedEndpointAux->FIFOPosition++] = Data;
                        }
 
                        /** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints.
                        }
 
                        /** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints.
                        static inline void Endpoint_Discard_8(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Discard_8(void)
                        {
                        static inline void Endpoint_Discard_8(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Discard_8(void)
                        {
-                               // TODO
+                               Endpoint_SelectedEndpointAux->FIFOPosition++;
                        }
 
                        /** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
                        }
 
                        /** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
                        static inline uint16_t Endpoint_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint16_t Endpoint_Read_16_LE(void)
                        {
                        static inline uint16_t Endpoint_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint16_t Endpoint_Read_16_LE(void)
                        {
-                               return 0; // TODO
+                               uint16_t Byte0 = Endpoint_Read_8();
+                               uint16_t Byte1 = Endpoint_Read_8();
+                               
+                               return ((Byte1 << 8) | Byte0);
                        }
 
                        /** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT
                        }
 
                        /** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT
                        static inline uint16_t Endpoint_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint16_t Endpoint_Read_16_BE(void)
                        {
                        static inline uint16_t Endpoint_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint16_t Endpoint_Read_16_BE(void)
                        {
-                               return 0; // TODO
+                               uint16_t Byte0 = Endpoint_Read_8();
+                               uint16_t Byte1 = Endpoint_Read_8();
+                               
+                               return ((Byte0 << 8) | Byte1);
                        }
 
                        /** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN
                        }
 
                        /** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN
                        static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_16_LE(const uint16_t Data)
                        {
                        static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_16_LE(const uint16_t Data)
                        {
-                               // TODO
+                               Endpoint_Write_8(Data & 0xFF);
+                               Endpoint_Write_8(Data >> 8);
                        }
 
                        /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
                        }
 
                        /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
                        static inline void Endpoint_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_16_BE(const uint16_t Data)
                        {
                        static inline void Endpoint_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_16_BE(const uint16_t Data)
                        {
-                               // TODO
+                               Endpoint_Write_8(Data >> 8);
+                               Endpoint_Write_8(Data & 0xFF);
                        }
 
                        /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.
                        }
 
                        /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.
                        static inline void Endpoint_Discard_16(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Discard_16(void)
                        {
                        static inline void Endpoint_Discard_16(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Discard_16(void)
                        {
-                               // TODO
+                               Endpoint_Discard_8();
+                               Endpoint_Discard_8();
                        }
 
                        /** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT
                        }
 
                        /** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT
                        static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint32_t Endpoint_Read_32_LE(void)
                        {
                        static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint32_t Endpoint_Read_32_LE(void)
                        {
-                               return 0; // TODO
+                               uint32_t Byte0 = Endpoint_Read_8();
+                               uint32_t Byte1 = Endpoint_Read_8();
+                               uint32_t Byte2 = Endpoint_Read_8();
+                               uint32_t Byte3 = Endpoint_Read_8();
+                               
+                               return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0);
                        }
 
                        /** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT
                        }
 
                        /** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT
                        static inline uint32_t Endpoint_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint32_t Endpoint_Read_32_BE(void)
                        {
                        static inline uint32_t Endpoint_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline uint32_t Endpoint_Read_32_BE(void)
                        {
-                               return 0; // TODO
+                               uint32_t Byte0 = Endpoint_Read_8();
+                               uint32_t Byte1 = Endpoint_Read_8();
+                               uint32_t Byte2 = Endpoint_Read_8();
+                               uint32_t Byte3 = Endpoint_Read_8();
+                               
+                               return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);
                        }
 
                        /** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN
                        }
 
                        /** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN
                        static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_32_LE(const uint32_t Data)
                        {
                        static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_32_LE(const uint32_t Data)
                        {
-                               // TODO
+                               Endpoint_Write_8(Data & 0xFF);
+                               Endpoint_Write_8(Data >> 8);
+                               Endpoint_Write_8(Data >> 16);
+                               Endpoint_Write_8(Data >> 24);
                        }
 
                        /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
                        }
 
                        /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
                        static inline void Endpoint_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_32_BE(const uint32_t Data)
                        {
                        static inline void Endpoint_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Write_32_BE(const uint32_t Data)
                        {
-                               // TODO
+                               Endpoint_Write_8(Data >> 24);
+                               Endpoint_Write_8(Data >> 16);
+                               Endpoint_Write_8(Data >> 8);
+                               Endpoint_Write_8(Data & 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.
                        static inline void Endpoint_Discard_32(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Discard_32(void)
                        {
                        static inline void Endpoint_Discard_32(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_Discard_32(void)
                        {
-                               // TODO
+                               Endpoint_Discard_8();
+                               Endpoint_Discard_8();
+                               Endpoint_Discard_8();
+                               Endpoint_Discard_8();
                        }
 
                /* External Variables: */
                        }
 
                /* External Variables: */
index df45f74..8c6f46c 100644 (file)
@@ -40,7 +40,7 @@ volatile uint8_t USB_CurrentMode = USB_MODE_None;
 volatile uint8_t USB_Options;
 #endif
 
 volatile uint8_t USB_Options;
 #endif
 
-USB_EP_TABLE_t USB_EndpointTable ATTR_ALIGNED(4);
+USB_EndpointTable_t USB_EndpointTable ATTR_ALIGNED(4);
 
 void USB_Init(
                #if defined(USB_CAN_BE_BOTH)
 
 void USB_Init(
                #if defined(USB_CAN_BE_BOTH)
@@ -73,6 +73,7 @@ void USB_Init(
        USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1));
        
        USB.EPPTR = (intptr_t)&USB_EndpointTable;
        USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1));
        
        USB.EPPTR = (intptr_t)&USB_EndpointTable;
+       USB.CTRLA = (USB_STFRNUM_bm | USB_MAXEP_gm);
 
        if ((USB_Options & USB_OPT_BUSEVENT_PRIHIGH) == USB_OPT_BUSEVENT_PRIHIGH)
          USB.INTCTRLA = (3 << USB_INTLVL_gp);
 
        if ((USB_Options & USB_OPT_BUSEVENT_PRIHIGH) == USB_OPT_BUSEVENT_PRIHIGH)
          USB.INTCTRLA = (3 << USB_INTLVL_gp);
index 79e2438..abaf057 100644 (file)
 
        /* Private Interface - For use in library only: */
        #if !defined(__DOXYGEN__)
 
        /* Private Interface - For use in library only: */
        #if !defined(__DOXYGEN__)
+               /* Type Defines: */
+                       typedef struct
+                       {
+                               uint16_t FrameNum;
+                               struct
+                               {
+                                       USB_EP_t OUT;
+                                       USB_EP_t IN;
+                               } Endpoints[16];
+                       } ATTR_PACKED USB_EndpointTable_t;
+       
                /* External Variables: */
                /* External Variables: */
-                       extern USB_EP_TABLE_t USB_EndpointTable;
+                       extern USB_EndpointTable_t USB_EndpointTable;
+               
        #endif
        
        /* Includes: */
        #endif
        
        /* Includes: */
                        /** Sets the USB bus interrupt priority level to be low priority. The USB bus interrupt is used for Start of Frame events, bus suspend
                         *  and resume events, bus reset events and other events related to the management of the USB bus.
                         */
                        /** Sets the USB bus interrupt priority level to be low priority. The USB bus interrupt is used for Start of Frame events, bus suspend
                         *  and resume events, bus reset events and other events related to the management of the USB bus.
                         */
-                       #define USB_OPT_BUSEVENT_PRILOW           ((0 << 1) | (0 << 1))
+                       #define USB_OPT_BUSEVENT_PRILOW           ((0 << 2) | (0 << 1))
 
                        /** Sets the USB bus interrupt priority level to be medium priority. The USB bus interrupt is used for Start of Frame events, bus suspend
                         *  and resume events, bus reset events and other events related to the management of the USB bus.
                         */
 
                        /** Sets the USB bus interrupt priority level to be medium priority. The USB bus interrupt is used for Start of Frame events, bus suspend
                         *  and resume events, bus reset events and other events related to the management of the USB bus.
                         */
-                       #define USB_OPT_BUSEVENT_PRIMED           ((0 << 1) | (1 << 1))
+                       #define USB_OPT_BUSEVENT_PRIMED           ((0 << 2) | (1 << 1))
 
                        /** Sets the USB bus interrupt priority level to be high priority. The USB bus interrupt is used for Start of Frame events, bus suspend
                         *  and resume events, bus reset events and other events related to the management of the USB bus.
                         */
 
                        /** Sets the USB bus interrupt priority level to be high priority. The USB bus interrupt is used for Start of Frame events, bus suspend
                         *  and resume events, bus reset events and other events related to the management of the USB bus.
                         */
-                       #define USB_OPT_BUSEVENT_PRIHIGH          ((1 << 1) | (0 << 1))
+                       #define USB_OPT_BUSEVENT_PRIHIGH          ((1 << 2) | (0 << 1))
                        //@}
 
                        #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__)
                        //@}
 
                        #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__)
                        static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE;
                        static inline void USB_Controller_Enable(void)
                        {
                        static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE;
                        static inline void USB_Controller_Enable(void)
                        {
-                               USB.CTRLA |= (USB_ENABLE_bm | USB_STFRNUM_bm | USB_MAXEP_gm);
+                               USB.CTRLA |=  USB_ENABLE_bm;
                        }
 
                        static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE;
                        }
 
                        static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE;
index dccdf2e..62fbf2d 100644 (file)
@@ -33,7 +33,7 @@
 
 void USB_INT_DisableAllInterrupts(void)
 {
 
 void USB_INT_DisableAllInterrupts(void)
 {
-       USB.INTCTRLA     = 0;
+       USB.INTCTRLA    &= USB_INTLVL_gm;
        USB.INTCTRLB     = 0;
 }
 
        USB.INTCTRLB     = 0;
 }
 
index c25c5c8..f27ea60 100644 (file)
                                switch (Interrupt)
                                {
                                        case USB_INT_BUSEVENTI:
                                switch (Interrupt)
                                {
                                        case USB_INT_BUSEVENTI:
-                                               return (USB.INTCTRLA & USB_BUSEVIE_bm);
+                                               return ((USB.INTCTRLA & USB_BUSEVIE_bm) ? true : false);
                                        case USB_INT_SOFI:
                                        case USB_INT_SOFI:
-                                               return (USB.INTCTRLA & USB_SOFIE_bm);
+                                               return ((USB.INTCTRLA & USB_SOFIE_bm) ? true : false);
                                }
                                
                                return false;
                                }
                                
                                return false;
                                switch (Interrupt)
                                {
                                        case USB_INT_BUSEVENTI_Suspend:
                                switch (Interrupt)
                                {
                                        case USB_INT_BUSEVENTI_Suspend:
-                                               return (USB.INTFLAGSACLR & USB_SUSPENDIF_bm);
+                                               return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false);
                                        case USB_INT_BUSEVENTI_Resume:
                                        case USB_INT_BUSEVENTI_Resume:
-                                               return (USB.INTFLAGSACLR & USB_RESUMEIF_bm);
+                                               return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false);
                                        case USB_INT_BUSEVENTI_Reset:
                                        case USB_INT_BUSEVENTI_Reset:
-                                               return (USB.INTFLAGSACLR & USB_RSTIF_bm);
+                                               return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false);
                                        case USB_INT_SOFI:
                                        case USB_INT_SOFI:
-                                               return (USB.INTFLAGSACLR & USB_SOFIF_bm);
+                                               return ((USB.INTFLAGSACLR & USB_SOFIF_bm) ? true : false);
                                }
                                
                                return false;
                                }
                                
                                return false;