From f4528c4aefcadd3342e9de2360d4c48196394fde Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Thu, 14 Jul 2011 02:58:07 +0000 Subject: [PATCH] Add high speed USB support for the UC3 devices containing a high speed USB controller. Add device support preprocessor checks and use symbolic bit names in the UC3 platform clock management driver. --- LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h | 45 ++++++------- LUFA/Drivers/USB/Core/UC3/Device_UC3.h | 66 ++++++++++++------- LUFA/Drivers/USB/Core/UC3/USBController_UC3.c | 15 ++++- LUFA/Drivers/USB/Core/UC3/USBController_UC3.h | 8 +-- LUFA/Platform/UC3/ClockManagement.h | 20 ++++-- 5 files changed, 96 insertions(+), 58 deletions(-) diff --git a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h index 39b4cf7d2d..08604ac1e7 100644 --- a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h @@ -50,6 +50,7 @@ /* Includes: */ #include "../../../../Common/Common.h" + #include "../USBController.h" #include "../StdDescriptors.h" #include "../USBInterrupt.h" #include "../Endpoint.h" @@ -155,34 +156,34 @@ } #if !defined(NO_SOF_EVENTS) - /** Enables the device mode Start Of Frame events. When enabled, this causes the - * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, - * at the start of each USB frame when enumerated in device mode. - * - * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. - */ - static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; - static inline void USB_Device_EnableSOFEvents(void) - { - USB_INT_Enable(USB_INT_SOFI); - } + /** Enables the device mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when enumerated in device mode. + * + * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableSOFEvents(void) + { + USB_INT_Enable(USB_INT_SOFI); + } - /** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the - * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. - * - * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. - */ - static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; - static inline void USB_Device_DisableSOFEvents(void) - { - USB_INT_Disable(USB_INT_SOFI); - } + /** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. + * + * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_DisableSOFEvents(void) + { + USB_INT_Disable(USB_INT_SOFI); + } #endif /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) /* Inline Functions: */ - #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + #if defined(USB_DEVICE_OPT_LOWSPEED) static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE; static inline void USB_Device_SetLowSpeed(void) { diff --git a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h index 55e4b0cf75..9b324ab69c 100644 --- a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h @@ -50,6 +50,7 @@ /* Includes: */ #include "../../../../Common/Common.h" + #include "../USBController.h" #include "../StdDescriptors.h" #include "../USBInterrupt.h" #include "../Endpoint.h" @@ -80,6 +81,13 @@ * USB interface should be initialized in full speed (12Mb/s) mode. */ #define USB_DEVICE_OPT_FULLSPEED (0 << 0) + + #if defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) || defined(__DOXYGEN__) + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in high speed (480Mb/s) mode. + */ + #define USB_DEVICE_OPT_HIGHSPEED (1 << 1) + #endif //@} #if (!defined(NO_INTERNAL_SERIAL) && \ @@ -145,28 +153,28 @@ } #if !defined(NO_SOF_EVENTS) - /** Enables the device mode Start Of Frame events. When enabled, this causes the - * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, - * at the start of each USB frame when enumerated in device mode. - * - * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. - */ - static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; - static inline void USB_Device_EnableSOFEvents(void) - { - USB_INT_Enable(USB_INT_SOFI); - } + /** Enables the device mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when enumerated in device mode. + * + * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableSOFEvents(void) + { + USB_INT_Enable(USB_INT_SOFI); + } - /** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the - * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. - * - * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. - */ - static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; - static inline void USB_Device_DisableSOFEvents(void) - { - USB_INT_Disable(USB_INT_SOFI); - } + /** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. + * + * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_DisableSOFEvents(void) + { + USB_INT_Disable(USB_INT_SOFI); + } #endif /* Private Interface - For use in library only: */ @@ -175,15 +183,27 @@ static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE; static inline void USB_Device_SetLowSpeed(void) { - AVR32_USBB.UDCON.ls = true; + AVR32_USBB.UDCON.ls = true; } static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; static inline void USB_Device_SetFullSpeed(void) { - AVR32_USBB.UDCON.ls = false; + AVR32_USBB.UDCON.ls = false; + #if defined(USB_DEVICE_OPT_HIGHSPEED) + AVR32_USBB.UDCON.spdconf = 3; + #endif } + #if defined(USB_DEVICE_OPT_HIGHSPEED) + static inline void USB_Device_SetHighSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetHighSpeed(void) + { + AVR32_USBB.UDCON.ls = false; + AVR32_USBB.UDCON.spdconf = 0; + } + #endif + static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; static inline void USB_Device_SetDeviceAddress(const uint8_t Address) { diff --git a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c index 7cfa28eded..1472dd6a86 100644 --- a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c @@ -166,9 +166,20 @@ static void USB_Init_Device(void) #endif if (USB_Options & USB_DEVICE_OPT_LOWSPEED) - USB_Device_SetLowSpeed(); + { + USB_Device_SetLowSpeed(); + } else - USB_Device_SetFullSpeed(); + { + #if defined(USB_DEVICE_OPT_HIGHSPEED) + if (USB_Options & USB_DEVICE_OPT_HIGHSPEED) + USB_Device_SetHighSpeed(); + else + USB_Device_SetFullSpeed(); + #else + USB_Device_SetFullSpeed(); + #endif + } USB_INT_Enable(USB_INT_VBUSTI); diff --git a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h index eaff22278c..0bad549ca3 100644 --- a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h @@ -92,19 +92,19 @@ * generation module. This indicates that an external oscillator should be used directly instead of an * internal PLL clock source. */ - #define USB_OPT_GCLK_SRC_OSC (1 << 1) + #define USB_OPT_GCLK_SRC_OSC (1 << 2) /** Selects one of the system's PLL oscillators as the input clock to the USB Generic Clock source * generation module. This indicates that one of the device's PLL outputs should be used instead of an * external oscillator source. */ - #define USB_OPT_GCLK_SRC_PLL (0 << 1) + #define USB_OPT_GCLK_SRC_PLL (0 << 2) /** Selects PLL or External Oscillator 0 as the USB Generic Clock source module input clock. */ - #define USB_OPT_GCLK_CHANNEL_0 (1 << 2) + #define USB_OPT_GCLK_CHANNEL_0 (1 << 3) /** Selects PLL or External Oscillator 1 as the USB Generic Clock source module input clock. */ - #define USB_OPT_GCLK_CHANNEL_1 (0 << 2) + #define USB_OPT_GCLK_CHANNEL_1 (0 << 3) //@} /** \name Endpoint/Pipe Type Masks */ diff --git a/LUFA/Platform/UC3/ClockManagement.h b/LUFA/Platform/UC3/ClockManagement.h index 60a3d18f4c..6087020690 100644 --- a/LUFA/Platform/UC3/ClockManagement.h +++ b/LUFA/Platform/UC3/ClockManagement.h @@ -233,19 +233,19 @@ switch (Source) { case CLOCK_SRC_OSC0: - AVR32_PM.GCCTRL[Channel].pllsel = 0; + AVR32_PM.GCCTRL[Channel].pllsel = false; AVR32_PM.GCCTRL[Channel].oscsel = 0; break; case CLOCK_SRC_OSC1: - AVR32_PM.GCCTRL[Channel].pllsel = 0; + AVR32_PM.GCCTRL[Channel].pllsel = false; AVR32_PM.GCCTRL[Channel].oscsel = 1; break; case CLOCK_SRC_PLL0: - AVR32_PM.GCCTRL[Channel].pllsel = 1; + AVR32_PM.GCCTRL[Channel].pllsel = true; AVR32_PM.GCCTRL[Channel].oscsel = 0; break; case CLOCK_SRC_PLL1: - AVR32_PM.GCCTRL[Channel].pllsel = 1; + AVR32_PM.GCCTRL[Channel].pllsel = true; AVR32_PM.GCCTRL[Channel].oscsel = 1; break; default: @@ -291,15 +291,21 @@ switch (Source) { + #if defined(AVR32_PM_MCCTRL_MCSEL_SLOW) case CLOCK_SRC_SLOW_CLK: - AVR32_PM.MCCTRL.mcsel = 0; + AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_SLOW; break; + #endif + #if defined(AVR32_PM_MCCTRL_MCSEL_OSC0) case CLOCK_SRC_OSC0: - AVR32_PM.MCCTRL.mcsel = 1; + AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_OSC0; break; + #endif + #if defined(AVR32_PM_MCCTRL_MCSEL_PLL0) case CLOCK_SRC_PLL0: - AVR32_PM.MCCTRL.mcsel = 2; + AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_PLL0; break; + #endif default: return false; }