The Xmega has made some major advances in clock management, likely as a conceptual follow-on to the picoPower AVR. While clock selection used to be both limited to a few options and mostly configured via fuses (at programming time), the Xmega has a very wide range of clocking choices that are entirely run-time configured.
The Xmega has the following clock sources available:
– 2MHz internal RC
– 32MHz internal ring oscillator
– 32.768 internal precision RC
– 400kHz – 20MHz external crystal
– 32.768 external crystal
– External (square wave) clock
In addition there are not only the usual clock dividers, but a PLL capable of anywhere from 2x to 31x multiplication.
All chips power up off the 2MHz internal RC at all times, because it’s the first to come up and is guaranteed to be available. All user code that wishes to use something else must configure it before continuing.
Each clock source has both an enable bit and a ready flag, since various clocks take different (and sometimes relatively long) periods of time to stabilize. The external crystal drivers also have failure detectors with dedicated interrupts that fire after the clock is switched back to the 2MHz fallback.
Several of the key registers are covered by the Configuration Change Protection (CCP) mechanism, which is nearly identical to the mechanism used to change or disable the watchdog timer on conventional AVRs. To write the protected register one must first write the CCP register, then the desired register within some short number of cycles (typically 4). This is to protect mostly from rogue memory pointers drifting into critical registers.
There are a total of 3 dividers, which allow the clock to be dropped by as much as 4096(?)x from the base frequency, in powers of 2. However, the first two have more specific purpose: they allow higher peripheral clocks to specific modules. CLKper4 and CLKper2 drive the high-res timer and External Bus Interface modules, respectively.
To make use of these higher frequencies, the (???) register can be set to predivide the input clock in order to bring it down to the range in which the actual CPU can operate. For instance: 8MHz crystal with 16x PLL gives 128MHz, which when divided /2,/2, gives 32MHz to the CPU, 64MHz to the EBI, and 128MHz to the highres timer extention.
Additionally for those who need the lower parts count you get from running off one of the internal oscillators, the Xmega theoretically offers two DFLL’s (Digital Frequency-Locked Loop) that are supposed to adjust the timings (a la OSCCAL) relative to a 32.768kHz reference, either internal or external. However, this module appears to be particularly buggy, and for the most part can be treated as if it doesn’t exist, at least in current silicon.
I will be posting a form of my clock routines sometime tomorrow to help get people boot-strapped on something other than ~2MHz…