Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 245 of 9363. Microcontroller Fundamentals and Bare-Metal CFree lesson

Implementing Low-Power Sleep and Wakeup Modes

Configure clock tree behavior during deep sleep states to ensure rapid system recovery and correct peripheral state restoration upon wake-up events.

In this lesson, you will learn how to configure the clock tree for deep sleep states to ensure your system recovers instantly and reliably when a wake-up event occurs.

The Challenge of Deep Sleep

When you put a microcontroller into a deep sleep state to save power, the system typically shuts down high-speed clocks (like the PLL or external crystal) to minimize current draw. The challenge is that these high-speed clocks take significant time to stabilize—often measured in milliseconds. If your system wakes up and immediately tries to execute code or access high-speed peripherals before the clock is ready, the CPU will likely crash or experience data corruption.

Configuring Clock Tree Behavior

To manage this transition, you must configure the clock tree to use a "fast-start" source during the wake-up sequence. Most modern microcontrollers allow you to define which clock source the system reverts to the moment a wake-up interrupt triggers.

The common strategy is:

  1. Prepare for Sleep: Before entering deep sleep, ensure the system is configured to switch to a stable, low-frequency internal oscillator (like an internal RC oscillator) as the primary system clock.
  2. Deep Sleep Entry: Enter the sleep mode, allowing the power management unit to gate off the high-frequency PLL.
  3. Wake-up Trigger: Upon an interrupt (e.g., a GPIO toggle), the hardware automatically restores the previously configured internal clock, allowing the CPU to start executing instructions immediately.
  4. Restore State: Within your wake-up ISR or the code immediately following the sleep command, you must trigger the re-locking of the PLL and then switch the system clock mux back to the high-speed source once the hardware indicates the PLL is stable.
// Example: Preparing the clock tree for rapid wake-up
void enter_deep_sleep(void) {
    // 1. Switch system clock to stable Internal RC Oscillator
    set_system_clock_source(INTERNAL_RC_OSC);
    
    // 2. Disable PLL to save power
    disable_pll();
    
    // 3. Enter Deep Sleep
    enter_low_power_mode();
    
    // --- WE ARE NOW AWAKE ---
    
    // 4. Restart PLL and wait for lock
    enable_pll();
    while(!is_pll_stable());
    
    // 5. Switch back to high-speed clock
    set_system_clock_source(PLL_OUTPUT);
}

Key Takeaway: To ensure rapid, stable recovery from deep sleep, always switch to a fast-starting internal clock before entering sleep and manage the transition back to high-frequency oscillators only after the clock source is verified as stable.