From 29ba88cffd4198b02e8ca04c31aed2c175c5502e Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Sun, 27 Feb 2011 22:06:31 +0000
Subject: [PATCH] Add code to start the USBB Generic Clock from the
 user-specified master clock source (OSCx or PLLx) in the AVR32 UC3B core USB
 driver.

---
 .../USB/Core/UC3B/USBController_UC3B.c        |  8 +++++++
 .../USB/Core/UC3B/USBController_UC3B.h        | 24 +++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.c b/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.c
index 88dbcdaeb..ee25de755 100644
--- a/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.c
+++ b/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.c
@@ -92,6 +92,8 @@ void USB_Disable(void)
 	USB_CurrentMode = USB_MODE_None;
 	#endif
 
+	AVR32_PM.GCCTRL[3].cen = false;
+
 	USB_IsInitialized = false;
 }
 
@@ -105,6 +107,12 @@ void USB_ResetInterface(void)
 	USB_INT_ClearAllInterrupts();
 
 	USB_Controller_Reset();
+	
+	AVR32_PM.GCCTRL[USB_GCLK_USBB_INDEX].pllsel = !(USB_Options & USB_OPT_GCLK_SRC_OSC);
+	AVR32_PM.GCCTRL[USB_GCLK_USBB_INDEX].oscsel = !(USB_Options & USB_OPT_GCLK_CHANNEL_0);
+	AVR32_PM.GCCTRL[USB_GCLK_USBB_INDEX].diven  = (F_CLOCK != 48000000UL);
+	AVR32_PM.GCCTRL[USB_GCLK_USBB_INDEX].div    = ((F_CLOCK / 2) / 48000000UL);
+	AVR32_PM.GCCTRL[USB_GCLK_USBB_INDEX].cen    = true;
 
 	#if defined(USB_CAN_BE_BOTH)
 	if (UIDModeSelectEnabled)
diff --git a/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.h b/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.h
index 56ee252d5..5bfcb5bff 100644
--- a/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.h
+++ b/LUFA/Drivers/USB/Core/UC3B/USBController_UC3B.h
@@ -82,6 +82,27 @@
 
 	/* Public Interface - May be used in end-application: */
 		/* Macros: */
+			/** \name USB Controller Option Masks */
+			//@{
+			/** Selects one of the system's main clock oscillators as the input clock to the USB Generic Clock source
+			 *  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)
+
+			/** 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)
+
+			/** Selects PLL or External Oscillator 0 as the USB Generic Clock source module input clock. */
+			#define USB_OPT_GCLK_CHANNEL_0             (1 << 2)
+
+			/** Selects PLL or External Oscillator 1 as the USB Generic Clock source module input clock. */
+			#define USB_OPT_GCLK_CHANNEL_1             (0 << 2)
+			//@}
+
 			/** \name Endpoint/Pipe Type Masks */
 			//@{
 			/** Mask for a CONTROL type endpoint or pipe.
@@ -272,6 +293,9 @@
 
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
+		/* Macros: */
+			#define USB_GCLK_USBB_INDEX          3
+	
 		/* Function Prototypes: */
 			#if defined(__INCLUDE_FROM_USB_CONTROLLER_C)
 				#if defined(USB_CAN_BE_DEVICE)
-- 
GitLab