Microchip® Advanced Software Framework

Quick Start Guide for Power Driver

List of supported boards:

  • SAM L21 Xplained Pro
  • SAM L22 Xplained Pro
  • SAM L22 Xplained Pro B

This example demonstrates how to use the power driver. BUTTON0 is used to wake up the system from the standby sleep mode and as an external wakeup pin to wake up the system from the backup sleep mode. The wakeup pin level is low. The I/O pins PB22/PB23 are used as GCLK0/GCLK1 outputs so that an oscilloscope can be used to monitor the clock frequencies.

After power-on-reset (POR), GCLK0 and GCLK1 runs at 4MHz and LED0 is turned on. After one second, LED0 is turned off and the system enters standby sleep mode. BUTTON0 can then be used to wake up the system. After the system wakeup, LED0 is turned on, the performance level is switched to PL2, and the GCLK0 is increased to 48MHz. Further LED0 toggles two times and is turned off before the system enters BACKUP.

When BUTTON0 pushes, it connects to low level, system wakes up from the backup sleep mode, LED0 toggles four times. GCLK0/GCLK1 are running at 4MHz.

Quick Start

Prerequisites

There are no prerequisites for this use case.

Code

Copy-paste the following setup code to your user application:

static void performance_level_switch_test(void)
{
struct system_gclk_gen_config gclk_conf;
/* Switch to PL2 */
/* Switch GCLK0 to 48MHz */
gclk_conf.source_clock = SYSTEM_CLOCK_SOURCE_DFLL;
gclk_conf.division_factor = 1;
gclk_conf.run_in_standby = false;
gclk_conf.output_enable = true;
}
static void config_clock_output_and_extwake_pin(void)
{
struct system_pinmux_config pin_conf;
pin_conf.mux_position = CONF_GCLK0_OUTPUT_PINMUX;
pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
system_pinmux_pin_set_config(CONF_GCLK0_OUTPUT_PIN, &pin_conf);
pin_conf.mux_position = CONF_GCLK1_OUTPUT_PINMUX;
system_pinmux_pin_set_config(CONF_GCLK1_OUTPUT_PIN, &pin_conf);
#if SAML21 || SAMR30
pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_UP;
pin_conf.mux_position = CONF_EXT_WAKEUP_PINMUX;
system_pinmux_pin_set_config(CONF_EXT_WAKEUP_PIN, &pin_conf);
#endif
}
static void configure_extint_channel(void)
{
struct extint_chan_conf config_extint_chan;
extint_chan_get_config_defaults(&config_extint_chan);
config_extint_chan.gpio_pin = BUTTON_0_EIC_PIN;
config_extint_chan.gpio_pin_mux = BUTTON_0_EIC_MUX;
config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
config_extint_chan.detection_criteria = EXTINT_DETECT_BOTH;
extint_chan_set_config(BUTTON_0_EIC_LINE, &config_extint_chan);
while (extint_chan_is_detected(BUTTON_0_EIC_LINE)) {
extint_chan_clear_detected(BUTTON_0_EIC_LINE);
}
}
static void led_toggle_indication(uint32_t count)
{
for (uint32_t i = 0; i < count; i++) {
port_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE);
delay_ms(200);
port_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE);
delay_ms(200);
}
}

Workflow

  1. Switch performance level to PL2.
    static void performance_level_switch_test(void)
    {
    struct system_gclk_gen_config gclk_conf;
    /* Switch to PL2 */
    /* Switch GCLK0 to 48MHz */
    gclk_conf.source_clock = SYSTEM_CLOCK_SOURCE_DFLL;
    gclk_conf.division_factor = 1;
    gclk_conf.run_in_standby = false;
    gclk_conf.output_enable = true;
    }
  2. Configure GCLK0/GCLK1 output pin and extwakeup pin.
    static void config_clock_output_and_extwake_pin(void)
    {
    struct system_pinmux_config pin_conf;
    pin_conf.mux_position = CONF_GCLK0_OUTPUT_PINMUX;
    pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
    system_pinmux_pin_set_config(CONF_GCLK0_OUTPUT_PIN, &pin_conf);
    pin_conf.mux_position = CONF_GCLK1_OUTPUT_PINMUX;
    system_pinmux_pin_set_config(CONF_GCLK1_OUTPUT_PIN, &pin_conf);
    #if SAML21 || SAMR30
    pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
    pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_UP;
    pin_conf.mux_position = CONF_EXT_WAKEUP_PINMUX;
    system_pinmux_pin_set_config(CONF_EXT_WAKEUP_PIN, &pin_conf);
    #endif
    }
  3. Config external interrupt.
    static void configure_extint_channel(void)
    {
    struct extint_chan_conf config_extint_chan;
    extint_chan_get_config_defaults(&config_extint_chan);
    config_extint_chan.gpio_pin = BUTTON_0_EIC_PIN;
    config_extint_chan.gpio_pin_mux = BUTTON_0_EIC_MUX;
    config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
    config_extint_chan.detection_criteria = EXTINT_DETECT_BOTH;
    extint_chan_set_config(BUTTON_0_EIC_LINE, &config_extint_chan);
    while (extint_chan_is_detected(BUTTON_0_EIC_LINE)) {
    extint_chan_clear_detected(BUTTON_0_EIC_LINE);
    }
    }

Use Case

Code

Copy-paste the following code to your user application:

#if SAML21 || SAMR30
/* Check if the RESET is caused by external wakeup pin */
&& system_get_backup_exit_source() == SYSTEM_RESET_BACKKUP_EXIT_EXTWAKE
&& (system_get_pin_wakeup_cause() & (1 << CONF_EXT_WAKEUP_PIN))
) {
delay_init();
config_clock_output_and_extwake_pin();
/* Now GCLK0/GCLK1 are running at 4MHz , using LED0 ON/OFF as an indication */
led_toggle_indication(4);
port_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE);
while(1);
}
#endif
/* Disable I/O retention*/
delay_init();
port_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE);
/* Config GCLK0/GCLK1 output pin and extwakeup pin */
config_clock_output_and_extwake_pin();
/* Config external interrupt for wakeup system from standby mode*/
configure_extint_channel();
delay_s(1);
/* Turn off LED0 before enter standby mode */
port_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE);
/* Set and enter standby mode, using default stanby config */
/* Detect BUTTON pressed and system wakeup from standby mode,
turn on led */
port_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE);
/* Disable external interrupt to avoid any impact */
extint_chan_disable_callback(BUTTON_0_EIC_LINE,
extint_chan_clear_detected(BUTTON_0_EIC_LINE);
/* Switch GCLK0 to 48MHz */
performance_level_switch_test();
/* GCLK0 is runing at 48MHz and GCLK1 is running at 4MHz ,
use led ON/OFF as an indication */
led_toggle_indication(2);
#if SAML21 || SAMR30
/* Set external wakeup pin polarity */
system_set_pin_wakeup_polarity_low(1<<CONF_EXT_WAKEUP_PIN);
/* Set external wakeup detector */
system_enable_pin_wakeup(1<<CONF_EXT_WAKEUP_PIN);
system_set_pin_wakeup_debounce_counter(SYSTEM_WAKEUP_DEBOUNCE_2CK32);
/* Enter BACKUP mode */
/* Now system is in BACKUP mode and wait for extwakeup pin to low */
#endif

Workflow

  1. Check if the RESET is caused by external wakeup pin.
    #if SAML21 || SAMR30
    /* Check if the RESET is caused by external wakeup pin */
    && system_get_backup_exit_source() == SYSTEM_RESET_BACKKUP_EXIT_EXTWAKE
    && (system_get_pin_wakeup_cause() & (1 << CONF_EXT_WAKEUP_PIN))
    ) {
    delay_init();
    config_clock_output_and_extwake_pin();
    /* Now GCLK0/GCLK1 are running at 4MHz , using LED0 ON/OFF as an indication */
    led_toggle_indication(4);
    port_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE);
    while(1);
    }
    #endif
  2. Check the standby mode and the backup sleep mode.
    /* Disable I/O retention*/
    delay_init();
    port_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE);
    /* Config GCLK0/GCLK1 output pin and extwakeup pin */
    config_clock_output_and_extwake_pin();
    /* Config external interrupt for wakeup system from standby mode*/
    configure_extint_channel();
    delay_s(1);
    /* Turn off LED0 before enter standby mode */
    port_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE);
    /* Set and enter standby mode, using default stanby config */
    /* Detect BUTTON pressed and system wakeup from standby mode,
    turn on led */
    port_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE);
    /* Disable external interrupt to avoid any impact */
    extint_chan_disable_callback(BUTTON_0_EIC_LINE,
    extint_chan_clear_detected(BUTTON_0_EIC_LINE);
    /* Switch GCLK0 to 48MHz */
    performance_level_switch_test();
    /* GCLK0 is runing at 48MHz and GCLK1 is running at 4MHz ,
    use led ON/OFF as an indication */
    led_toggle_indication(2);
    #if SAML21 || SAMR30
    /* Set external wakeup pin polarity */
    system_set_pin_wakeup_polarity_low(1<<CONF_EXT_WAKEUP_PIN);
    /* Set external wakeup detector */
    system_enable_pin_wakeup(1<<CONF_EXT_WAKEUP_PIN);
    system_set_pin_wakeup_debounce_counter(SYSTEM_WAKEUP_DEBOUNCE_2CK32);
    /* Enter BACKUP mode */
    /* Now system is in BACKUP mode and wait for extwakeup pin to low */
    #endif