Deep Sleep

Requirements

In order to run this example, you must have an GAP9_EVK board.

Description

This example shows how to use the Deep Sleep mode in order to save power. It sets up the wakeup source using pi_pmu_wakeup_control as RTC. The RTC is set to trigger after a few seconds. The chips then goes to deep sleep using pi_pmu_domain_state_change. To have more details about these functions you can refer to the PMU API documentation.

When the RTC triggers, the chip wakes up and blinks the LED for 10 times. It then sets up the deep sleep and RTC wakeup again.

The memory banks are not saved during the deep sleep mode. The code needs to be reloaded when the chip wakes up. Hence it needs to be flashed.

To run this example, follow the Flashing guide.

For more information about low-power modes, please refer to the Using low power modes guide.

How to run

  1. Configure CMake

cmake -B build
  1. Flash the code on your board

cmake --build build -t flash

See more details in the Flashing guide.

  1. Run the example

Put a jumper on the boot pins. Press the reset button of your board to execute the code flashed.

Logs will be prompt on the uart console.

Code

#include "pmsis.h"

#define PAD_GPIO_LED2           (PI_PAD_086)
#define BLINK_DELAY_US          (500 * 1000)
#define BLINK_ITERATIONS        (10)
#define TIMER_COUNTER_SECONDS   (5)

static int8_t blink_led()
{
#if defined(BLINK_LED)
    /* set pad to gpio mode */
    pi_pad_function_set(PAD_GPIO_LED2, PI_PAD_FUNC1);

    /* configure gpio output */
    pi_gpio_flags_e flags = PI_GPIO_OUTPUT;
    pi_gpio_pin_configure(PAD_GPIO_LED2, flags);

    /* blink the LED */
    for (uint8_t i = 0; i < BLINK_ITERATIONS; i++)
    {
        pi_gpio_pin_write(PAD_GPIO_LED2, 1);
        pi_time_wait_us(BLINK_DELAY_US);
        pi_gpio_pin_write(PAD_GPIO_LED2, 0);
        pi_time_wait_us(BLINK_DELAY_US);
    }
    /* Due to an EVK known issue, the LED2 must be 1 */
    pi_gpio_pin_write(PAD_GPIO_LED2, 1);
#endif

    return 0;
}

static void go_to_sleep(void)
{
    /* force outputs during sleep to avoid random communications */
    pi_pad_sleep_cfg_force(1);

    /* set wakeup source */
    pi_pmu_wakeup_control(PI_PMU_WAKEUP_RTC, 0);

    /* configure RTC */
    {
        struct pi_rtc_conf conf;
        pi_device_t rtc;
        pi_rtc_conf_init(&conf);
        conf.mode = PI_RTC_MODE_TIMER;
        conf.counter = TIMER_COUNTER_SECONDS;
        pi_open_from_conf(&rtc, &conf);

        if (pi_rtc_open(&rtc))
        {
            pmsis_exit(-1);
        }

        uint32_t repeat = 1;
        pi_rtc_ioctl(&rtc, PI_RTC_TIMER_START, (void*) repeat);
    }

    /* go to deep sleep */
    pi_pmu_domain_state_change(PI_PMU_DOMAIN_CHIP, PI_PMU_DOMAIN_STATE_DEEP_SLEEP, 0);
}

int main(void)
{
    /* Release the outputs that we forced in case we come back from deep sleep */
    pi_pad_sleep_cfg_force(0);

    /* Get boot source */
    switch(pi_pmu_boot_state_get())
    {
        case PI_PMU_DOMAIN_STATE_DEEP_SLEEP:
            {
                blink_led();
            }
            break;
        default:
            break;
    }

    /* enter the deep sleep mode */
    go_to_sleep();

    return 0;
}