Notes: 1. ONLY the reset (watchdog reset included) disables this function. The Watchdog System
Reset Flag (WDRF bit of MCUSR register) can be used to monitor the reset cause.
2. ONLY clock frequencies ≥ (4 * WatchDog Clock frequency) can be monitored.
Here is a “light” C-code of a clock switching function using automatic clock monitoring.
C Code Example
void ClockSwiching (unsigned char clk_number, unsigned char sut) {
#define CLOCK_RECOVER
#define CLOCK_ENABLE
#define CLOCK_SWITCH
#define CLOCK_DISABLE
#define WD_ARL_ENABLE
0x05
0x02
0x04
0x01
0x06
#define WD_2048CYCLES 0x07
unsigned char previous_clk, temp;
// Disable interrupts
temp = SREG; asm ("cli");
// Save the current system clock source
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK_RECOVER;
previous_clk = CLKSELR & 0x0F;
// Enable the new clock source
CLKSELR = ((sut << 4 ) & 0x30) | (clk_number & 0x0F);
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK_ENABLE;
// Wait for clock validity
while ((CLKCSR & (1 << CLKRDY)) == 0);
// Enable the watchdog in automatic reload mode
WDTCSR = (1 << WDCE) | (1 << WDE);
WDTCSR = (1 << WDE ) | WD_2048CYCLES;
CLKCSR = 1 << CLKCCE;
CLKCSR = WD_ARL_ENABLE;
// Switch clock source
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK_SWITCH;
// Wait for effective switching
while (1){
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK_RECOVER;
if ((CLKSELR & 0x0F) == (clk_number & 0x0F)) break;
}
// Shut down unneeded clock source
if (previous_clk != (clk_number & 0x0F)) {
CLKSELR = previous_clk;
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK_DISABLE;
}
// Re-enable interrupts
SREG = temp;
}
60 Atmel ATA6616/ATA6617
9132D–AUTO–12/10