Power Manager Debugging and Error Handling#

Comprehensive Troubleshooting Guide#

Power Consumption Issues#

Problem: Higher than expected power consumption

Diagnosis Steps:

  1. Check active requirements:

    // Enable debug and check requirements
    #define SL_POWER_MANAGER_DEBUG 1
    sl_power_manager_debug_print_em_requirements();
  2. Verify energy mode transitions:

    // Add transition callback to monitor mode changes
    void power_transition_callback(sl_power_manager_em_t from, sl_power_manager_em_t to) {
      printf("Power transition: EM%d -> EM%d\n", from, to);
    }
  3. Check peripheral states:

    • UART/SPI drivers may prevent deep sleep

    • GPIO configurations can cause leakage current

    • Unused peripherals should be disabled

Common Causes and Solutions:

Cause

Symptoms

Solution

Persistent EM1 requirement

Never enters EM2/EM3

Use debug print to identify module

UART preventing sleep

High consumption, no deep sleep

Use low-power UART or disable when idle

GPIO leakage

Baseline consumption too high

Configure unused pins appropriately

Peripheral clocks enabled

Higher EM2/EM3 consumption

Disable unused peripheral clocks

Voltage scaling disabled

Higher EM0/EM1 consumption

Enable voltage scaling in config

Using "No Deep Sleep" component

Never enters EM2/EM3

Switch to "Deep Sleep" component variant

Problem: System not entering deep sleep

Diagnosis Steps:

// Comprehensive requirement analysis
void diagnose_sleep_issues(void) {
  // Print detailed requirement information
  sl_power_manager_debug_print_em_requirements();
}

Systematic Investigation:

  1. Module-by-module analysis: Disable modules one-by-one to identify culprit

  2. Timing analysis: Use Energy Profiler to correlate requirements with energy modes

  3. Configuration review: Verify Power Manager configuration matches application needs

EM4 Specific Issues#

Problem: EM4 entry failing

Diagnosis Steps:

// Check EM4 blocking conditions
void diagnose_em4_issues(void) {
  // Check watchdog configuration
  if (WDOG0->CFG & WDOG_CFG_EM4BLOCK) {
    printf("ERROR: Watchdog blocking EM4 entry\n");
    printf("Solution: Disable WDOG_CFG_EM4BLOCK or stop watchdog\n");
  }
}

Problem: EM4 wake-up issues

Diagnosis Steps:

// Check EM4 wake-up configuration
void diagnose_em4_wakeup(void) {
  // Check reset cause
  uint32_t reset_cause = sl_hal_emu_get_reset_cause();
  sl_hal_emu_clear_reset_cause();
  if (reset_cause & EMU_RSTCAUSE_EM4) {
    printf("EM4 wake-up detected\n");
  } else {
    printf("Not an EM4 wake-up\n");
    printf("Reset cause: 0x%08lx\n", reset_cause);
  }
  // Check wake-up source
  if (EMU->EM4CAUSE & EMU_EM4CAUSE_EM4WUPIN) {
    printf("Wake-up source: GPIO pin\n");
  }
  if (EMU->EM4CAUSE & EMU_EM4CAUSE_EM4WUBURTC) {
    printf("Wake-up source: BURTC\n");
  }
}

Common EM4 Issues:

Issue

Cause

Solution

Entry blocked

Watchdog EM4BLOCK set

Clear WDOG_CFG_EM4BLOCK

No wake-up

Wake-up sources not configured

Configure GPIO/BURTC wake-up

Pin states lost

Pin retention not configured

Set EM4CTRL_EM4IORETMODE

Data lost

BURAM not used

Use BURAM for data persistence

Schedule Wake-up Timing Issues#

Problem: Suboptimal wake-up timing

Diagnosis and Tuning:

// Measure and optimize wake-up timing
void tune_wakeup_timing(void) {
  // Get current settings
  int32_t restore_overhead = sl_power_manager_schedule_wakeup_get_restore_overhead_tick();
  uint32_t min_offtime = sl_power_manager_schedule_wakeup_get_minimum_offtime_tick();
  
  printf("Current restore overhead: %ld ticks\n", restore_overhead);
  printf("Current minimum off-time: %lu ticks\n", min_offtime);
  
  // Measure actual timing with oscilloscope/profiler
  // Adjust based on measurements:
  
  // For power optimization (longer sleep cycles)
  sl_power_manager_schedule_wakeup_set_minimum_offtime_tick(min_offtime + 10);
  
  // For timing accuracy (earlier wake-up)
  sl_power_manager_schedule_wakeup_set_restore_overhead_tick(restore_overhead - 5);
}

Debug Configuration#

// Enable debug features during development
#define SL_POWER_MANAGER_DEBUG 1
#define SL_POWER_MANAGER_DEBUG_POOL_SIZE 20
#define CURRENT_MODULE_NAME "MY_MODULE"

void debug_power_requirements(void)
{
  // Print current requirement table
  sl_power_manager_debug_print_em_requirements();
  
  // Output shows which modules have active requirements
}

Energy Profiler Integration#

Using Simplicity Studio Energy Profiler:

  1. Enable Power Manager debug: Set SL_POWER_MANAGER_DEBUG = 1

  2. Add debug prints: Use requirement tracking and transition callbacks

  3. Correlate events: Match Energy Profiler traces with debug output

  4. Identify patterns: Look for unexpected EM1 requirements or wake-up events

Performance Analysis and Optimization#

Power Consumption Measurement#

Baseline Measurement Process:

  1. Disable all debug features in production builds

  2. Measure each energy mode individually

  3. Profile application patterns with Energy Profiler

  4. Compare against datasheet values for validation

// In sl_power_manager_config.h, disable debug features
#define SL_POWER_MANAGER_DEBUG 0
#define SL_POWER_MANAGER_INIT_EMU_EM2_DEBUG_ENABLE 0
// Measurement-friendly configuration
void configure_for_measurement(void) {
  // Minimize external influences
  // Disable unnecessary peripherals, LEDs, etc.

  // Enter EM2 for 2s
  sl_sleeptimer_start_timer_ms(&timer, 2000,  NULL, NULL, 0, 0);
  sl_power_manager_sleep();

  // Enter EM1 for 2s
  sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
  sl_sleeptimer_start_timer_ms(&timer, 2000, NULL, NULL, 0, 0);
  sl_power_manager_sleep();

  // Wait in EM0 for 2s
  sl_sleeptimer_delay_millisecond(2000);

  // Enter EM4, the device will not wake up by itself, and will need to be reset
  // from an external source.
  sl_power_manager_enter_em4();
}

Optimization Strategies#

Iterative Optimization Process:

  1. Baseline measurement: Establish current power consumption

  2. Profile analysis: Identify high-consumption periods

  3. Targeted optimization: Focus on highest-impact areas

  4. Measurement validation: Verify improvements

// Optimization validation
void validate_power_optimization(void) {
  uint32_t start_time = sl_sleeptimer_get_tick_count();
  
  // Run application for measurement period
  run_application_cycle();
  
  uint32_t end_time = sl_sleeptimer_get_tick_count();
  uint32_t duration = end_time - start_time;
  
  printf("Application cycle duration: %lu ticks\n", duration);
  // Correlate with Energy Profiler data for power analysis
}