aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Platform
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2012-04-14 14:41:17 +0000
committerDean Camera <dean@fourwalledcubicle.com>2012-04-14 14:41:17 +0000
commit47f6a35013b2c6a370e5dce29aa6da3a96844695 (patch)
tree3f5842347a696c92beb74bc255c9489e6c38f49d /LUFA/Platform
parente8570c4a37e41117e3fd1e989e0b41f1e9608f3c (diff)
downloadlufa-47f6a35013b2c6a370e5dce29aa6da3a96844695.tar.gz
lufa-47f6a35013b2c6a370e5dce29aa6da3a96844695.tar.bz2
lufa-47f6a35013b2c6a370e5dce29aa6da3a96844695.zip
Reintegrate the FullEPAddresses development branch into trunk.
Diffstat (limited to 'LUFA/Platform')
-rw-r--r--LUFA/Platform/XMEGA/ClockManagement.h36
1 files changed, 29 insertions, 7 deletions
diff --git a/LUFA/Platform/XMEGA/ClockManagement.h b/LUFA/Platform/XMEGA/ClockManagement.h
index dcde7dcdb..9b3b56244 100644
--- a/LUFA/Platform/XMEGA/ClockManagement.h
+++ b/LUFA/Platform/XMEGA/ClockManagement.h
@@ -53,13 +53,13 @@
*
* void main(void)
* {
- * // Start the PLL to multiply the 2MHz RC oscillator to 32MHz and switch the CPU core to run from it
- * XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, 32000000);
- * XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL, F_CPU);
+ * // Start the PLL to multiply the 2MHz RC oscillator to F_CPU and switch the CPU core to run from it
+ * XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU);
+ * XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL);
*
- * // Start the 32MHz internal RC oscillator and start the DFLL to increase it to 48MHz using the USB SOF as a reference
+ * // Start the 32MHz internal RC oscillator and start the DFLL to increase it to F_USB using the USB SOF as a reference
* XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ);
- * XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, 48000000);
+ * XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB);
* }
* \endcode
*
@@ -117,6 +117,26 @@
};
/* Inline Functions: */
+ /** Write a value to a location protected by the XMEGA CCP protection mechanism. This function uses inline assembly to ensure that
+ * the protected address is written to within four clock cycles of the CCP key being written.
+ *
+ * \param[in] Address Address to write to, a memory address protected by the CCP mechanism
+ * \param[in] Value Value to write to the protected location
+ */
+ static inline void XMEGACLK_CCP_Write(volatile void* Address, const uint8_t Value) ATTR_ALWAYS_INLINE;
+ static inline void XMEGACLK_CCP_Write(volatile void* Address, const uint8_t Value)
+ {
+ __asm__ __volatile__ (
+ "out %0, __zero_reg__" "\n\t" /* Zero RAMPZ using fixed zero value register */
+ "movw r30, %1" "\n\t" /* Copy address to Z register pair */
+ "out %2, %3" "\n\t" /* Write key to CCP register */
+ "st Z, %4" "\n\t" /* Indirectly write value to address */
+ : /* No output operands */
+ : /* Input operands: */ "m" (RAMPZ), "e" (Address), "m" (CCP), "r" (CCP_IOREG_gc), "r" (Value)
+ : /* Clobbered registers: */ "r30", "r31"
+ );
+ }
+
/** Starts the external oscillator of the XMEGA microcontroller, with the given options. This routine blocks until
* the oscillator is ready for use.
*
@@ -219,6 +239,9 @@
if (SourceFreq > Frequency)
return false;
+
+ if (MulFactor > 31)
+ return false;
switch (Source)
{
@@ -355,8 +378,7 @@
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
GlobalInterruptDisable();
- CCP = CCP_IOREG_gc;
- CLK_CTRL = ClockSourceMask;
+ XMEGACLK_CCP_Write(&CLK.CTRL, ClockSourceMask);
SetGlobalInterruptMask(CurrentGlobalInt);