Skip to content

Commit

Permalink
fixup! fixup! cpu/esp32: add pm_layered support
Browse files Browse the repository at this point in the history
  • Loading branch information
gschorcht committed Mar 20, 2020
1 parent d4fc4f0 commit 0ccf4d3
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 37 deletions.
4 changes: 2 additions & 2 deletions cpu/esp32/include/gpio_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ int gpio_set_drive_capability(gpio_t pin, gpio_drive_strength_t drive);

/**
* @brief Called before the power management enters a light or deep sleep mode
*
* @param mode sleep mode that is entered
*/
void gpio_pm_sleep_enter(unsigned mode);

/**
* @brief Called after the power management left light sleep mode
* @param cause wake-up cause
*/
void gpio_pm_sleep_exit(void);
void gpio_pm_sleep_exit(uint32_t cause);

#ifdef __cplusplus
}
Expand Down
7 changes: 5 additions & 2 deletions cpu/esp32/include/rtc_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ extern "C" {

/**
* @brief Called before the power management enters a light or deep sleep mode
* @param mode sleep mode that is entered
* @return time to sleep in us
*/
void rtc_pm_sleep_enter(void);
uint64_t rtc_pm_sleep_enter(unsigned mode);

/**
* @brief Called after the power management left light sleep mode
* @param cause wake-up cause
*/
void rtc_pm_sleep_exit(void);
void rtc_pm_sleep_exit(uint32_t cause);

#ifdef __cplusplus
}
Expand Down
3 changes: 2 additions & 1 deletion cpu/esp32/periph/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,8 +636,9 @@ void gpio_pm_sleep_enter(unsigned mode)
}
}

void gpio_pm_sleep_exit(void)
void gpio_pm_sleep_exit(uint32_t cause)
{
(void)cause;
#if MODULE_PERIPH_GPIO_IRQ
DEBUG("%s\n", __func__);
for (unsigned i = 0; i < GPIO_PIN_NUMOF; i++) {
Expand Down
59 changes: 32 additions & 27 deletions cpu/esp32/periph/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,29 @@
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"

static inline esp_sleep_wakeup_cause_t pm_get_wakeup_cause(void)
{
return esp_sleep_get_wakeup_cause();
}

/* function that is required by pm_set if esp_now and esp_wifi are not used */
esp_err_t __attribute__((weak)) esp_wifi_start(void)
{
return ESP_OK;
}

/* function that is required by pm_set if esp_now and esp_wifi are not used */
esp_err_t __attribute__((weak)) esp_wifi_stop(void)
{
return ESP_OK;
}

static inline void pm_set_lowest_normal(void)
{
#if !defined(QEMU)
/* reset system watchdog timer */
system_wdt_feed();

#ifndef MODULE_ESP_QEMU
/* passive wait for interrupt to leave lowest power mode */
__asm__ volatile ("waiti 0");

Expand Down Expand Up @@ -80,18 +100,6 @@ void pm_set_lowest(void)

#else /* MODULE_PM_LAYERED */

/* function that is required by pm_set if esp_now and esp_wifi are not used */
esp_err_t __attribute__((weak)) esp_wifi_start(void)
{
return ESP_OK;
}

/* function that is required by pm_set if esp_now and esp_wifi are not used */
esp_err_t __attribute__((weak)) esp_wifi_stop(void)
{
return ESP_OK;
}

void pm_set(unsigned mode)
{
if (mode == ESP_PM_MODEM_SLEEP) {
Expand All @@ -101,8 +109,8 @@ void pm_set(unsigned mode)

DEBUG ("%s enter to power mode %d @%u\n", __func__, mode, system_get_time());

/* wait until UART is idle to avoid losing output */
uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM);
/* flush stdout */
fflush(stdout);

/* Labels for RTC slow memory that are defined in the linker script */
extern int _rtc_bss_rtc_start;
Expand All @@ -118,11 +126,8 @@ void pm_set(unsigned mode)
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
}

/* stop WiFi if necessary */
esp_wifi_stop();

/* Prepare the RTC timer if an RTC alarm is set to wake up. */
rtc_pm_sleep_enter();
rtc_pm_sleep_enter(mode);

/* Prepare GPIOs as wakeup source */
gpio_pm_sleep_enter(mode);
Expand All @@ -133,17 +138,17 @@ void pm_set(unsigned mode)
UNREACHABLE();
}
else if (mode == ESP_PM_LIGHT_SLEEP) {
/* stop WiFi if necessary */
esp_wifi_stop();

esp_light_sleep_start();
gpio_pm_sleep_exit();

uint32_t wakeup_cause = esp_sleep_get_wakeup_cause();
DEBUG ("%s exit from power mode %d because of %d @%u\n", __func__,
mode, wakeup_cause, system_get_time());
esp_sleep_wakeup_cause_t pm_wakeup_reason = pm_get_wakeup_cause();
gpio_pm_sleep_exit(pm_wakeup_reason);
rtc_pm_sleep_exit(pm_wakeup_reason);

if (wakeup_cause == ESP_SLEEP_WAKEUP_TIMER) {
/* call the RTC alarm handler if an RTC alarm was set */
rtc_pm_sleep_exit();
}
DEBUG ("%s exit from power mode %d @%u with reason %d\n", __func__,
mode, system_get_time(), pm_wakeup_reason);

/* restart WiFi if necessary */
if (esp_wifi_start() != ESP_OK) {
Expand Down
14 changes: 9 additions & 5 deletions cpu/esp32/periph/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,17 +346,21 @@ static void IRAM_ATTR _rtc_timer_handler(void* arg)
irq_isr_exit();
}

void rtc_pm_sleep_enter(void)
uint64_t rtc_pm_sleep_enter(unsigned mode)
{
(void)mode;
if (_rtc_alarm_cb) {
uint32_t sleep = _sys_alarm_time - _sys_get_time();
esp_sleep_enable_timer_wakeup((uint64_t)sleep * US_PER_SEC);
uint64_t sleep = (_sys_alarm_time - _sys_get_time()) * US_PER_SEC;
esp_sleep_enable_timer_wakeup(sleep);
return sleep;
}
return 0;
}

void rtc_pm_sleep_exit(void)
void rtc_pm_sleep_exit(uint32_t cause)
{
if (_rtc_alarm_cb) {
/* call the RTC time was the wakeup source and an RTC alarm was set */
if (cause == ESP_SLEEP_WAKEUP_TIMER && _rtc_alarm_cb) {
_rtc_alarm_cb(_rtc_alarm_arg);
_rtc_alarm_cb = 0;
}
Expand Down

0 comments on commit 0ccf4d3

Please sign in to comment.