Add software FIFOs to the UC3B pipe control interfaces, to match the endpoint control...
authorDean Camera <dean@fourwalledcubicle.com>
Sat, 5 Mar 2011 12:13:35 +0000 (12:13 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Sat, 5 Mar 2011 12:13:35 +0000 (12:13 +0000)
LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h
LUFA/Drivers/USB/Core/DeviceStandardReq.c
LUFA/Drivers/USB/Core/UC3B/Endpoint_UC3B.c
LUFA/Drivers/USB/Core/UC3B/Endpoint_UC3B.h
LUFA/Drivers/USB/Core/UC3B/Pipe_UC3B.c
LUFA/Drivers/USB/Core/UC3B/Pipe_UC3B.h

index 30979af..6933a89 100644 (file)
                         *
                         *  \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset.
                         */
                         *
                         *  \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset.
                         */
-                       static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
-                       static inline void Endpoint_ResetFIFO(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)
                        {
                                UERST = (1 << EndpointNumber);
                                UERST = 0;
                        {
                                UERST = (1 << EndpointNumber);
                                UERST = 0;
index e43543d..4ee2fce 100644 (file)
@@ -50,9 +50,9 @@ void USB_Device_ProcessControlRequest(void)
 {
        USB_ControlRequest.bmRequestType = Endpoint_Read_Byte();
        USB_ControlRequest.bRequest      = Endpoint_Read_Byte();
 {
        USB_ControlRequest.bmRequestType = Endpoint_Read_Byte();
        USB_ControlRequest.bRequest      = Endpoint_Read_Byte();
-       USB_ControlRequest.wValue        = le16_to_cpu(Endpoint_Read_Word_LE());
-       USB_ControlRequest.wIndex        = le16_to_cpu(Endpoint_Read_Word_LE());
-       USB_ControlRequest.wLength       = le16_to_cpu(Endpoint_Read_Word_LE());
+       USB_ControlRequest.wValue        = Endpoint_Read_Word_LE();
+       USB_ControlRequest.wIndex        = Endpoint_Read_Word_LE();
+       USB_ControlRequest.wLength       = Endpoint_Read_Word_LE();
 
        EVENT_USB_Device_ControlRequest();
 
 
        EVENT_USB_Device_ControlRequest();
 
@@ -339,7 +339,7 @@ static void USB_Device_ClearSetFeature(void)
                                        else
                                        {
                                                Endpoint_ClearStall();
                                        else
                                        {
                                                Endpoint_ClearStall();
-                                               Endpoint_ResetFIFO(EndpointIndex);
+                                               Endpoint_ResetEndpoint(EndpointIndex);
                                                Endpoint_ResetDataToggle();
                                        }
                                }
                                                Endpoint_ResetDataToggle();
                                        }
                                }
index ee9d35f..1775e98 100644 (file)
@@ -50,7 +50,7 @@ bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
 \r
        (&AVR32_USBB.uecfg0)[Number] = 0;\r
        (&AVR32_USBB.uecfg0)[Number] = UECFG0Data;\r
 \r
        (&AVR32_USBB.uecfg0)[Number] = 0;\r
        (&AVR32_USBB.uecfg0)[Number] = UECFG0Data;\r
-       USB_EndpointFIFOPos[Number] = &AVR32_USBB_SLAVE[Number * 0x10000];\r
+       USB_EndpointFIFOPos[Number]  = &AVR32_USBB_SLAVE[Number * 0x10000];\r
 \r
        return Endpoint_IsConfigured();\r
 }\r
 \r
        return Endpoint_IsConfigured();\r
 }\r
@@ -62,7 +62,7 @@ void Endpoint_ClearEndpoints(void)
                Endpoint_SelectEndpoint(EPNum);\r
                (&AVR32_USBB.uecfg0)[EPNum]    = 0;\r
                (&AVR32_USBB.uecon0clr)[EPNum] = 0xFFFFFFFF;\r
                Endpoint_SelectEndpoint(EPNum);\r
                (&AVR32_USBB.uecfg0)[EPNum]    = 0;\r
                (&AVR32_USBB.uecon0clr)[EPNum] = 0xFFFFFFFF;\r
-               USB_EndpointFIFOPos[EPNum] = &AVR32_USBB_SLAVE[EPNum * 0x10000];\r
+               USB_EndpointFIFOPos[EPNum]     = &AVR32_USBB_SLAVE[EPNum * 0x10000];\r
                Endpoint_DisableEndpoint();\r
        }\r
 }\r
                Endpoint_DisableEndpoint();\r
        }\r
 }\r
index 4860d26..b74b5da 100644 (file)
                         *\r
                         *  \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset.\r
                         */\r
                         *\r
                         *  \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset.\r
                         */\r
-                       static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;\r
-                       static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber)\r
+                       static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;\r
+                       static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber)\r
                        {\r
                                AVR32_USBB.uerst |=  (AVR32_USBB_EPRST0_MASK << EndpointNumber);\r
                                AVR32_USBB.uerst &= ~(AVR32_USBB_EPRST0_MASK << EndpointNumber);\r
                        {\r
                                AVR32_USBB.uerst |=  (AVR32_USBB_EPRST0_MASK << EndpointNumber);\r
                                AVR32_USBB.uerst &= ~(AVR32_USBB_EPRST0_MASK << EndpointNumber);\r
                                        (&AVR32_USBB.UECON0SET)[USB_SelectedEndpoint].killbks = true;\r
                                        while ((&AVR32_USBB.UECON0)[USB_SelectedEndpoint].killbk);\r
                                }\r
                                        (&AVR32_USBB.UECON0SET)[USB_SelectedEndpoint].killbks = true;\r
                                        while ((&AVR32_USBB.UECON0)[USB_SelectedEndpoint].killbk);\r
                                }\r
-\r
-                               USB_EndpointFIFOPos[USB_SelectedEndpoint] = &AVR32_USBB_SLAVE[USB_SelectedEndpoint * 0x10000];\r
                        }\r
                        \r
                        /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint\r
                        }\r
                        \r
                        /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint\r
                                uint16_t Byte1 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint16_t Byte0 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
                                uint16_t Byte1 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint16_t Byte0 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
-                               return ((Byte1 << 8) | Byte0);\r
+                               return ((Byte0 << 8) | Byte1);\r
                        }\r
 \r
                        /** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT\r
                        }\r
 \r
                        /** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT\r
                                uint16_t Byte0 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint16_t Byte1 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
                                uint16_t Byte0 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint16_t Byte1 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
-                               return ((Byte1 << 8) | Byte0);\r
+                               return ((Byte0 << 8) | Byte1);\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN\r
                        static inline void Endpoint_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_Word_LE(const uint16_t Word)\r
                        {\r
                        static inline void Endpoint_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_Word_LE(const uint16_t Word)\r
                        {\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word & 0xFF);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word >> 8);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word >> 8);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word & 0xFF);\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN\r
                        static inline void Endpoint_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_Word_BE(const uint16_t Word)\r
                        {\r
                        static inline void Endpoint_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_Word_BE(const uint16_t Word)\r
                        {\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word >> 8);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word & 0xFF);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word & 0xFF);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (Word >> 8);\r
                        }\r
 \r
                        /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.\r
                        }\r
 \r
                        /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.\r
                                uint32_t Byte1 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint32_t Byte0 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
                                uint32_t Byte1 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint32_t Byte0 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
-                               return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0);\r
+                               return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);\r
                        }\r
 \r
                        /** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT\r
                        }\r
 \r
                        /** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT\r
                                uint32_t Byte2 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint32_t Byte3 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
                                uint32_t Byte2 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
                                uint32_t Byte3 = *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++);\r
 \r
-                               return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0);\r
+                               return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN\r
                        static inline void Endpoint_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_DWord_LE(const uint32_t DWord)\r
                        {\r
                        static inline void Endpoint_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_DWord_LE(const uint32_t DWord)\r
                        {\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord &  0xFF);\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 8);\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 16);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 24);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 24);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 16);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 8);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord &  0xFF);\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN\r
                        static inline void Endpoint_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_DWord_BE(const uint32_t DWord)\r
                        {\r
                        static inline void Endpoint_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Endpoint_Write_DWord_BE(const uint32_t DWord)\r
                        {\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 24);\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 16);\r
-                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 8);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord &  0xFF);\r
                                *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord &  0xFF);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 8);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 16);\r
+                               *(((volatile uint8_t** volatile)USB_EndpointFIFOPos)[USB_SelectedEndpoint]++) = (DWord >> 24);\r
                        }\r
 \r
                        /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.\r
                        }\r
 \r
                        /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.\r
index eb41143..51f4d5e 100644 (file)
@@ -36,7 +36,9 @@
 #include "../Pipe.h"\r
 \r
 uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;\r
 #include "../Pipe.h"\r
 \r
 uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;\r
+\r
 volatile uint8_t USB_SelectedPipe = PIPE_CONTROLPIPE;\r
 volatile uint8_t USB_SelectedPipe = PIPE_CONTROLPIPE;\r
+volatile void*   USB_PipeFIFOPos[PIPE_TOTAL_PIPES];\r
 \r
 bool Pipe_ConfigurePipe(const uint8_t Number,\r
                         const uint8_t Type,\r
 \r
 bool Pipe_ConfigurePipe(const uint8_t Number,\r
                         const uint8_t Type,\r
@@ -50,10 +52,11 @@ bool Pipe_ConfigurePipe(const uint8_t Number,
 \r
        (&AVR32_USBB.upcfg0)[Number] = 0;\r
        (&AVR32_USBB.upcfg0)[Number] = (AVR32_USBB_ALLOC_MASK |\r
 \r
        (&AVR32_USBB.upcfg0)[Number] = 0;\r
        (&AVR32_USBB.upcfg0)[Number] = (AVR32_USBB_ALLOC_MASK |\r
-                                                          ((uint32_t)Type  << AVR32_USBB_PTYPE_OFFSET)  |\r
-                                                          ((uint32_t)Token << AVR32_USBB_PTOKEN_OFFSET) |\r
-                                                          ((uint32_t)Banks << AVR32_USBB_PBK_OFFSET)    |\r
-                                                          ((EndpointNumber & PIPE_EPNUM_MASK) << AVR32_USBB_PEPNUM_OFFSET));\r
+                                       ((uint32_t)Type  << AVR32_USBB_PTYPE_OFFSET)  |\r
+                                       ((uint32_t)Token << AVR32_USBB_PTOKEN_OFFSET) |\r
+                                       ((uint32_t)Banks << AVR32_USBB_PBK_OFFSET)    |\r
+                                       ((EndpointNumber & PIPE_EPNUM_MASK) << AVR32_USBB_PEPNUM_OFFSET));\r
+       USB_PipeFIFOPos[PNum]        = &AVR32_USBB_SLAVE[PNum * 0x10000];\r
 \r
        Pipe_SetInfiniteINRequests();\r
 \r
 \r
        Pipe_SetInfiniteINRequests();\r
 \r
@@ -67,6 +70,7 @@ void Pipe_ClearPipes(void)
                Pipe_SelectPipe(PNum);\r
                (&AVR32_USBB.upcfg0)[PNum]    = 0;\r
                (&AVR32_USBB.upcon0clr)[PNum] = 0xFFFFFFFF;\r
                Pipe_SelectPipe(PNum);\r
                (&AVR32_USBB.upcfg0)[PNum]    = 0;\r
                (&AVR32_USBB.upcon0clr)[PNum] = 0xFFFFFFFF;\r
+               USB_PipeFIFOPos[PNum]         = &AVR32_USBB_SLAVE[EPNum * 0x10000];\r
                Pipe_DisablePipe();\r
        }\r
 }\r
                Pipe_DisablePipe();\r
        }\r
 }\r
index 033dd01..183975a 100644 (file)
                        {\r
                                AVR32_USBB.uprst |=  (AVR32_USBB_PRST0_MASK << PipeNumber);\r
                                AVR32_USBB.uprst &= ~(AVR32_USBB_PRST0_MASK << PipeNumber);\r
                        {\r
                                AVR32_USBB.uprst |=  (AVR32_USBB_PRST0_MASK << PipeNumber);\r
                                AVR32_USBB.uprst &= ~(AVR32_USBB_PRST0_MASK << PipeNumber);\r
+                               USB_PipeFIFOPos[Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[Pipe_SelectedPipe * 0x10000];\r
                        }\r
 \r
                        /** Enables the currently selected pipe so that data can be sent and received through it to and from\r
                        }\r
 \r
                        /** Enables the currently selected pipe so that data can be sent and received through it to and from\r
                        static inline void Pipe_ClearSETUP(void)\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].txstpic = true;\r
                        static inline void Pipe_ClearSETUP(void)\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].txstpic = true;\r
+                               USB_PipeFIFOPos[Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[Pipe_SelectedPipe * 0x10000];\r
                        }\r
 \r
                        /** Acknowledges the reception of a setup IN request from the attached device on the currently selected\r
                        }\r
 \r
                        /** Acknowledges the reception of a setup IN request from the attached device on the currently selected\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].rxinic   = true;\r
                                (&AVR32_USBB.UPCON0CLR)[USB_SelectedPipe].fifoconc = true;\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].rxinic   = true;\r
                                (&AVR32_USBB.UPCON0CLR)[USB_SelectedPipe].fifoconc = true;\r
+                               USB_PipeFIFOPos[Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[Pipe_SelectedPipe * 0x10000];\r
                        }\r
 \r
                        /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing\r
                        }\r
 \r
                        /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].txoutic  = true;\r
                                (&AVR32_USBB.UPCON0CLR)[USB_SelectedPipe].fifoconc = true;\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].txoutic  = true;\r
                                (&AVR32_USBB.UPCON0CLR)[USB_SelectedPipe].fifoconc = true;\r
+                               USB_PipeFIFOPos[Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[Pipe_SelectedPipe * 0x10000];\r
                        }\r
 \r
                        /** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on\r
                        }\r
 \r
                        /** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on\r
                        static inline void Pipe_ClearStall(void)\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].rxstalldic = true;\r
                        static inline void Pipe_ClearStall(void)\r
                        {\r
                                (&AVR32_USBB.UPSTA0CLR)[USB_SelectedPipe].rxstalldic = true;\r
+                               USB_PipeFIFOPos[Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[Pipe_SelectedPipe * 0x10000];\r
                        }\r
 \r
                        /** Reads one byte from the currently selected pipe's bank, for OUT direction pipes.\r
                        }\r
 \r
                        /** Reads one byte from the currently selected pipe's bank, for OUT direction pipes.\r
                        static inline uint8_t Pipe_Read_Byte(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint8_t Pipe_Read_Byte(void)\r
                        {\r
                        static inline uint8_t Pipe_Read_Byte(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint8_t Pipe_Read_Byte(void)\r
                        {\r
-                               return *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               return *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
                        }\r
 \r
                        /** Writes one byte from the currently selected pipe's bank, for IN direction pipes.\r
                        }\r
 \r
                        /** Writes one byte from the currently selected pipe's bank, for IN direction pipes.\r
                        static inline void Pipe_Write_Byte(const uint8_t Byte) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_Byte(const uint8_t Byte)\r
                        {\r
                        static inline void Pipe_Write_Byte(const uint8_t Byte) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_Byte(const uint8_t Byte)\r
                        {\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = Byte;\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = Byte;\r
                        }\r
 \r
                        /** Discards one byte from the currently selected pipe's bank, for OUT direction pipes.\r
                        }\r
 \r
                        /** Discards one byte from the currently selected pipe's bank, for OUT direction pipes.\r
                        {\r
                                uint8_t Dummy;\r
 \r
                        {\r
                                uint8_t Dummy;\r
 \r
-                               Dummy = *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               Dummy = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
                        }\r
 \r
                        /** Reads two bytes from the currently selected pipe's bank in little endian format, for OUT\r
                        }\r
 \r
                        /** Reads two bytes from the currently selected pipe's bank in little endian format, for OUT\r
                        static inline uint16_t Pipe_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint16_t Pipe_Read_Word_LE(void)\r
                        {\r
                        static inline uint16_t Pipe_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint16_t Pipe_Read_Word_LE(void)\r
                        {\r
-                               union\r
-                               {\r
-                                       uint16_t Word;\r
-                                       uint8_t  Bytes[2];\r
-                               } Data;\r
-\r
-                               Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               uint16_t Byte1 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint16_t Byte0 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
 \r
 \r
-                               return Data.Word;\r
+                               return ((Byte0 << 8) | Byte1);\r
                        }\r
 \r
                        /** Reads two bytes from the currently selected pipe's bank in big endian format, for OUT\r
                        }\r
 \r
                        /** Reads two bytes from the currently selected pipe's bank in big endian format, for OUT\r
                        static inline uint16_t Pipe_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint16_t Pipe_Read_Word_BE(void)\r
                        {\r
                        static inline uint16_t Pipe_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint16_t Pipe_Read_Word_BE(void)\r
                        {\r
-                               union\r
-                               {\r
-                                       uint16_t Word;\r
-                                       uint8_t  Bytes[2];\r
-                               } Data;\r
-\r
-                               Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               uint16_t Byte0 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint16_t Byte1 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
 \r
 \r
-                               return Data.Word;\r
+                               return ((Byte0 << 8) | Byte1);\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected pipe's bank in little endian format, for IN\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected pipe's bank in little endian format, for IN\r
                        static inline void Pipe_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_Word_LE(const uint16_t Word)\r
                        {\r
                        static inline void Pipe_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_Word_LE(const uint16_t Word)\r
                        {\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (Word & 0xFF);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (Word >> 8);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (Word >> 8);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (Word & 0xFF);\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected pipe's bank in big endian format, for IN\r
                        }\r
 \r
                        /** Writes two bytes to the currently selected pipe's bank in big endian format, for IN\r
                        static inline void Pipe_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_Word_BE(const uint16_t Word)\r
                        {\r
                        static inline void Pipe_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_Word_BE(const uint16_t Word)\r
                        {\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (Word >> 8);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (Word & 0xFF);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (Word & 0xFF);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (Word >> 8);\r
                        }\r
 \r
                        /** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes.\r
                        }\r
 \r
                        /** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes.\r
                        {\r
                                uint8_t Dummy;\r
 \r
                        {\r
                                uint8_t Dummy;\r
 \r
-                               Dummy = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Dummy = *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               Dummy = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               Dummy = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
                        }\r
 \r
                        /** Reads four bytes from the currently selected pipe's bank in little endian format, for OUT\r
                        }\r
 \r
                        /** Reads four bytes from the currently selected pipe's bank in little endian format, for OUT\r
                        static inline uint32_t Pipe_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint32_t Pipe_Read_DWord_LE(void)\r
                        {\r
                        static inline uint32_t Pipe_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint32_t Pipe_Read_DWord_LE(void)\r
                        {\r
-                               union\r
-                               {\r
-                                       uint32_t DWord;\r
-                                       uint8_t  Bytes[4];\r
-                               } Data;\r
-\r
-                               Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[2] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[3] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               uint32_t Byte3 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint32_t Byte2 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint32_t Byte1 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint32_t Byte0 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
 \r
 \r
-                               return Data.DWord;\r
+                               return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);\r
                        }\r
 \r
                        /** Reads four bytes from the currently selected pipe's bank in big endian format, for OUT\r
                        }\r
 \r
                        /** Reads four bytes from the currently selected pipe's bank in big endian format, for OUT\r
                        static inline uint32_t Pipe_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint32_t Pipe_Read_DWord_BE(void)\r
                        {\r
                        static inline uint32_t Pipe_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
                        static inline uint32_t Pipe_Read_DWord_BE(void)\r
                        {\r
-                               union\r
-                               {\r
-                                       uint32_t DWord;\r
-                                       uint8_t  Bytes[4];\r
-                               } Data;\r
-\r
-                               Data.Bytes[3] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[2] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               uint32_t Byte0 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint32_t Byte1 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint32_t Byte2 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               uint32_t Byte3 = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
 \r
 \r
-                               return Data.DWord;\r
+                               return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected pipe's bank in little endian format, for IN\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected pipe's bank in little endian format, for IN\r
                        static inline void Pipe_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_DWord_LE(const uint32_t DWord)\r
                        {\r
                        static inline void Pipe_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_DWord_LE(const uint32_t DWord)\r
                        {\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord &  0xFF);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 8);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 16);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 24);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord >> 24);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord >> 16);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord >> 8);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord &  0xFF);\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected pipe's bank in big endian format, for IN\r
                        }\r
 \r
                        /** Writes four bytes to the currently selected pipe's bank in big endian format, for IN\r
                        static inline void Pipe_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_DWord_BE(const uint32_t DWord)\r
                        {\r
                        static inline void Pipe_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE;\r
                        static inline void Pipe_Write_DWord_BE(const uint32_t DWord)\r
                        {\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 24);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 16);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 8);\r
-                               *((uint8_t*)AVR32_USBB_EP_DATA) = (DWord &  0xFF);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord &  0xFF);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord >> 8);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord >> 16);\r
+                               *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++) = (DWord >> 24);\r
                        }\r
 \r
                        /** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes.\r
                        }\r
 \r
                        /** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes.\r
                        {\r
                                uint8_t Dummy;\r
 \r
                        {\r
                                uint8_t Dummy;\r
 \r
-                               Dummy = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Dummy = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Dummy = *((uint8_t*)AVR32_USBB_EP_DATA);\r
-                               Dummy = *((uint8_t*)AVR32_USBB_EP_DATA);\r
+                               Dummy = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               Dummy = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               Dummy = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
+                               Dummy = *(((volatile uint8_t** volatile)USB_PipeFIFOPos)[USB_SelectedPipe]++);\r
                        }\r
 \r
                /* External Variables: */\r
                        }\r
 \r
                /* External Variables: */\r