/*
              LUFA Library
-     Copyright (C) Dean Camera, 2011.
+     Copyright (C) Dean Camera, 2014.
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
-  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2014  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
   advertising or publicity pertaining to distribution of the
   software without specific, written prior permission.
 
-  The author disclaim all warranties with regard to this
+  The author disclaims all warranties with regard to this
   software, including all implied warranties of merchantability
   and fitness.  In no event shall the author be liable for any
   special, indirect or consequential damages or any damages
 #define  __INCLUDE_FROM_DEVICESTDREQ_C
 #include "DeviceStandardReq.h"
 
-uint8_t USB_ConfigurationNumber;
+uint8_t USB_Device_ConfigurationNumber;
 
 #if !defined(NO_DEVICE_SELF_POWER)
-bool    USB_CurrentlySelfPowered;
+bool    USB_Device_CurrentlySelfPowered;
 #endif
 
 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
-bool    USB_RemoteWakeupEnabled;
+bool    USB_Device_RemoteWakeupEnabled;
 #endif
 
 void USB_Device_ProcessControlRequest(void)
 {
-       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());
+       #if defined(ARCH_BIG_ENDIAN)
+       USB_ControlRequest.bmRequestType = Endpoint_Read_8();
+       USB_ControlRequest.bRequest      = Endpoint_Read_8();
+       USB_ControlRequest.wValue        = Endpoint_Read_16_LE();
+       USB_ControlRequest.wIndex        = Endpoint_Read_16_LE();
+       USB_ControlRequest.wLength       = Endpoint_Read_16_LE();
+       #else
+       uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;
+
+       for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
+         *(RequestHeader++) = Endpoint_Read_8();
+       #endif
 
        EVENT_USB_Device_ControlRequest();
 
                                  USB_Device_SetConfiguration();
 
                                break;
+
+                       default:
+                               break;
                }
        }
 
        if (Endpoint_IsSETUPReceived())
        {
-               Endpoint_StallTransaction();
                Endpoint_ClearSETUP();
+               Endpoint_StallTransaction();
        }
 }
 
 {
        uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
 
-       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
-       {
-               Endpoint_ClearSETUP();
+       USB_Device_SetDeviceAddress(DeviceAddress);
+
+       Endpoint_ClearSETUP();
 
-               Endpoint_ClearStatusStage();
+       Endpoint_ClearStatusStage();
 
-               while (!(Endpoint_IsINReady()));
+       while (!(Endpoint_IsINReady()));
+
+       USB_Device_EnableDeviceAddress(DeviceAddress);
 
-               USB_Device_SetDeviceAddress(DeviceAddress);
-       }
-       
        USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
 }
 
        #else
        USB_Descriptor_Device_t* DevDescriptorPtr;
 
-       #if defined(USE_FLASH_DESCRIPTORS)
-               #define MemoryAddressSpace  MEMSPACE_FLASH
-       #elif defined(USE_EEPROM_DESCRIPTORS)
-               #define MemoryAddressSpace  MEMSPACE_EEPROM
-       #elif defined(USE_SRAM_DESCRIPTORS)
-               #define MemoryAddressSpace  MEMSPACE_SRAM
-       #else
-               uint8_t MemoryAddressSpace;
+       #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
+               #if defined(USE_FLASH_DESCRIPTORS)
+                       #define MemoryAddressSpace  MEMSPACE_FLASH
+               #elif defined(USE_EEPROM_DESCRIPTORS)
+                       #define MemoryAddressSpace  MEMSPACE_EEPROM
+               #elif defined(USE_SRAM_DESCRIPTORS)
+                       #define MemoryAddressSpace  MEMSPACE_SRAM
+               #else
+                       uint8_t MemoryAddressSpace;
+               #endif
        #endif
 
        if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
-       #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
+       #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
+           !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
                                       , &MemoryAddressSpace
        #endif
                                       ) == NO_DESCRIPTOR)
                return;
        }
 
+       #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
        if (MemoryAddressSpace == MEMSPACE_FLASH)
        {
                if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
                if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
                  return;
        }
+       #else
+       if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
+         return;
+       #endif
        #endif
 
        Endpoint_ClearSETUP();
 
-       USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
+       USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
 
        Endpoint_ClearStatusStage();
 
-       if (USB_ConfigurationNumber)
+       if (USB_Device_ConfigurationNumber)
          USB_DeviceState = DEVICE_STATE_Configured;
        else
          USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
 {
        Endpoint_ClearSETUP();
 
-       Endpoint_Write_Byte(USB_ConfigurationNumber);
+       Endpoint_Write_8(USB_Device_ConfigurationNumber);
        Endpoint_ClearIN();
 
        Endpoint_ClearStatusStage();
        struct
        {
                USB_Descriptor_Header_t Header;
-               wchar_t                 UnicodeString[20];
+               uint16_t                UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
        } SignatureDescriptor;
 
        SignatureDescriptor.Header.Type = DTYPE_String;
-       SignatureDescriptor.Header.Size = USB_Device_GetSerialString(SignatureDescriptor.UnicodeString,
-                                                                    sizeof(SignatureDescriptor.UnicodeString));
+       SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);
+
+       USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);
 
        Endpoint_ClearSETUP();
 
        const void* DescriptorPointer;
        uint16_t    DescriptorSize;
 
-       #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
+       #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
+           !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
        uint8_t DescriptorAddressSpace;
        #endif
 
 
        if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
                                                         &DescriptorPointer
-       #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
+       #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
+           !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
                                                         , &DescriptorAddressSpace
        #endif
                                                                                                         )) == NO_DESCRIPTOR)
 
        Endpoint_ClearSETUP();
 
-       #if defined(USE_RAM_DESCRIPTORS)
+       #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
        Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
        #elif defined(USE_EEPROM_DESCRIPTORS)
        Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
 
        switch (USB_ControlRequest.bmRequestType)
        {
-               #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
                case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
                        #if !defined(NO_DEVICE_SELF_POWER)
-                       if (USB_CurrentlySelfPowered)
+                       if (USB_Device_CurrentlySelfPowered)
                          CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
                        #endif
 
                        #if !defined(NO_DEVICE_REMOTE_WAKEUP)
-                       if (USB_RemoteWakeupEnabled)
+                       if (USB_Device_RemoteWakeupEnabled)
                          CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
                        #endif
                        break;
-               #endif
-               #if !defined(CONTROL_ONLY_DEVICE)
                case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
+                       #if !defined(CONTROL_ONLY_DEVICE)
                        Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
 
                        CurrentStatus = Endpoint_IsStalled();
 
                        Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
+                       #endif
 
                        break;
-               #endif
                default:
                        return;
        }
 
        Endpoint_ClearSETUP();
 
-       Endpoint_Write_Word_LE(CurrentStatus);
+       Endpoint_Write_16_LE(CurrentStatus);
        Endpoint_ClearIN();
 
        Endpoint_ClearStatusStage();
                #if !defined(NO_DEVICE_REMOTE_WAKEUP)
                case REQREC_DEVICE:
                        if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
-                         USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
+                         USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
                        else
                          return;
 
                                        else
                                        {
                                                Endpoint_ClearStall();
-                                               Endpoint_ResetFIFO(EndpointIndex);
+                                               Endpoint_ResetEndpoint(EndpointIndex);
                                                Endpoint_ResetDataToggle();
                                        }
                                }