Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32: deep sleep modes #13365

Closed
nicoHarel opened this issue Feb 13, 2020 · 36 comments
Closed

ESP32: deep sleep modes #13365

nicoHarel opened this issue Feb 13, 2020 · 36 comments
Assignees
Labels
Area: pm Area: (Low) power management Platform: ESP Platform: This PR/issue effects ESP-based platforms State: stale State: The issue / PR has no activity for >185 days Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Comments

@nicoHarel
Copy link

Description

I've noticed RIOT OS is not yet compatible with deep sleep modes on ESP32 and more generally on all ESPs. Unless I'm wrong, the only "energy saving" mechanism available consists in reducing the MCU frequency to 80MHz (which is the default clock on RIOT OS if I'm not mistaken).

At that frequency, most ESP boards current consumption is still around at least 30mA, which is unacceptable for most low energy applications. This is a decisive flaw for me as I need my ESP to draw less than a mA most of the time.

I've tried in a hurry to implement it myself, adding the right files (sleep_modes.c...) containing the functions definition needed (esp_deep_sleep_start...) but without success. It seems the ESP-IDF version used by RIOT OS is too old and still uses the ancient C way of defining a function without arguments (no void inside the parenthesis). GCC doesn't like that any more.

So the ESP-IDF need updating but doing so would have repercussions on the ESPs implementation in RIOT OS.

Proposition

  • Evaluate the impact of updating to a more recent version of the ESP-IDF.

  • If it doesn't seem to break absolutely everything about the ESP implementation, change the ESP-IDF tagged version in a branch and work from there.

  • Then implement the deep sleep functions inside RIOT OS.

@kaspar030
Copy link
Contributor

@gschorcht I guess you've seen this. 😉 Can /should we update ESP-IDF?

It seems the ESP-IDF version used by RIOT OS is too old and still uses the ancient C way of defining a function without arguments (no void inside the parenthesis).

That can probably be worked around by adding -Wno-old-style-definition to CFLAGS.

@kaspar030 kaspar030 added Area: pm Area: (Low) power management Platform: ESP Platform: This PR/issue effects ESP-based platforms labels Feb 13, 2020
@gschorcht
Copy link
Contributor

You mentioned two problems:

  1. The outdated version of the ESP-IDF.
  2. The missing deep-sleep mode.

Let me give some explanations to both problems.

1. Outdated version of the ESP-IDF.

When I started with porting RIOT for the ESP32, ESP-IDF version 3.0 beta was available, the version that is still in use. Although I had an update to version 3.1 or later on my ToDo list, I haven't done for the following reasons:

  • Updating to a new ESP-IDF version is a very extensive task, as it requires the rework of some parts in cpu/esp3'.
  • The RIOT port is quite stable. Updating to a new version of the ESP-IDF is error-prone and will probably break this stability.

The biggest problem with the ESP-IDF is that it can't be used as a standalone SDK as with other platforms for the following reasons:

  • It is inseparably linked to FreeRTOS. RIOT can't be implemented on top of FreeRTOS.
  • It uses functions from binary library blobs, e.g., for WiFi and SoC handling, which in turn reference functions that are provided by ESP-IDF.

Therefore, the only way to port RIOT for the ESP32 was to pick only that parts from ESP-IDF that are absolutely necessary to get RIOT running on ESP32. These are the system clock handling and SoC startup.

BTW, updating to the newest offical ESP-IDF release v4.0 wouldn't help to solve the problem with old style function definitions. It is still a problem in release v4.0, fore example here.

That was the reason why we couldn't use all header files directly from ESP-IDF but had to copy some to the vendor part of the code only to be able to fix these old style function declarations.

For all these reasons I haven't yet started an update. And to be honest, I will not start an update until ESP-IDF allows the use of newlib-nano.

2. Deep-sleep mode

I'm pretty sure that deep-sleep mode was already working with this old ESP-IDF version. But I didn't implement it since I'm not sure whether the deep-sleep mode is compatible with the concept of power management in RIOT.

The deep-sleep mode requires a warm-restart of the CPU to leave this mode so that RIOT will restart. That is, RIOT's system state and all data in kernel, drivers, ... are lost. Data that have to be preserved would have to be stored in RTC memory by the application.

The only sleep mode that would allow to preserve RIOT's system state is the light-sleep mode. But even if the CPU then consumes only 800 uA, together with other board components a power consumption of less than 1 mA would not be feasible.

@kaspar030
Copy link
Contributor

Thanks for the detailed explanation! I agree on everything.

The only sleep mode that would allow to preserve RIOT's system state is the light-sleep mode. But even if the CPU then consumes only 800 uA, together with other board components a power consumption of less than 1 mA would not be feasible.

Reading this, I thought "1mA is 30 times lower than 30mA".

@gschorcht
Copy link
Contributor

While reading the tests/periph_pm/README.md, I wondered if it would be compliant with RIOT's power management to enter a power mode that requires a system reboot to exit the mode?

@nicoHarel
Copy link
Author

nicoHarel commented Feb 13, 2020

1. Outdated version of the ESP-IDF.

Ok thanks a lot for the clarifications. I was wondering why some of the ESP-IDF files were actually inside the riot project. In fact I started to copy some of those files (esp_timer_impl.h, ...) inside the Riot ESP folder myself.

I was afraid that updating the ESP-IDF would also mean reworking the cpu implementation of the ESP.

Updating the ESP-IDF seems out of the question then.

2. Deep-sleep mode

It should be working yes with the older version, except for the GCC compiler error about the old style function definition. But as kaspar030 mentioned, adding CFLAG options should be okay as a work around.

I understand what you're implying about the loss of data when going into deep mode. And what it means for RIOT, although I don't think that would be a problem for my application, I can imagine how that would be problematic as this "deep sleep behaviour" would be different from other MCU implemented ( yes ? ).

Light sleep might be okayish for me I guess but not great of course.

3. tests/periph_pm/README.md

Yes there is a mention about resetting the CPU there. Although I don't think this has got any real value ?

4. Why I needed this

If I'm being honest I was trying to add RIOT support for the lopy4 from Pycom. Because its got everything I need (Lora Chip + mesh + big flash + cheap...). But if using an ESP has too many drawbacks I might just as well use some other board (with an NRF52 MCU for example) and some Lora chip on the side.

@benemorius
Copy link
Member

benemorius commented Feb 13, 2020

Reading this, I thought "1mA is 30 times lower than 30mA".

Generally anything more than about 10uA is not considered "low-power" anymore. Even 100uA will break a great many applications.

While reading the tests/periph_pm/README.md, I wondered if it would be compliant with RIOT's power management to enter a power mode that requires a system reboot to exit the mode?

It would not be consistent with the intended functionality of pm_layered to do that. Riot expects to return from pm_set() with full ram retention and doing it any other way doesn't make sense given the context of what the modern mcus are able to do. Technically it's compliant in that pm_layered only deals with how power states are entered, not left, but normally only the lowest power state requires a reset to wake from and normally this is only necessary if you need to achieve better than 0.5uA.

Anyway, I'm really hopefully? sure that it shouldn't be necessary to do that even for esp32. The defining difference between whether the system reboot is necessary is whether the mcu can retain ram at a low-power state. Any modern low-power mcu can retain ram for less than 1uA so the only time we should need to deal with a full reset is with mcus that don't have good low-power support.

@gschorcht
Copy link
Contributor

Any modern low-power mcu can retain ram for less than 1uA so the only time we should need to deal with a full reset is with mcus that don't have good low-power support.

Ok, then ESP32 has a very poor low-power support:

  • Hibernation mode at 4.5 uA with RTC memory powered off, only RTC timer is working for wakeup.
  • Deep-Sleep mode at 6.5 uA and RTC memory can be retained
  • Light-Sleep mode at 800 uA and memory can be retained, only the CPU cores are stalled
  • Modem-Sleep mode at 30 mA where WiFi/Bluetooth are powered down

This means that even the mode with the lowest power consumption needs 4.5 uA and requires a reset.

@benemorius
Copy link
Member

  • Deep-Sleep mode at 6.5 uA and RTC memory can be retained

I'm suffering from not being familiar with esp32 but if it can resume from this state with good (aka most) ram retention then this is completely adequate. However if it's true that this ~5uA state only retains RTC ram then yes this means unfortunately that esp32 has very poor low-power support if it requires 800uA just to retain ram. That's an unmitigated disaster.

This has probably prompted me to investigate esp32 low-power support in the near future.

@nicoHarel
Copy link
Author

nicoHarel commented Feb 13, 2020

However if it's true that this ~5uA state only retains RTC ram then yes this means unfortunately that esp32 has very poor low-power support if it requires 800uA just to retain ram.

I can confirm only the ligh-sleep mode allows to retain the RAM content therefore needing at least 800µA to do so.

Edit: Wouldn't it be possible to consider one of the deep-sleep mode (6.5µA for example) as the lowest power state in pm_layered in RIOT and the light-sleep mode (800µA) as a "higher" deep-sleep mode ? I know it's not clean, but it's at least kind of a "power mode" support.

@gschorcht
Copy link
Contributor

  • Deep-Sleep mode at 6.5 uA and RTC memory can be retained

I'm suffering from not being familiar with esp32 but if it can resume from this state with good (aka most) ram retention then this is completely adequate. However if it's true that this ~5uA state only retains RTC ram then yes this means unfortunately that esp32 has very poor low-power support if it requires 800uA just to retain ram. That's an unmitigated disaster.

This has probably prompted me to investigate esp32 low-power support in the near future.

Deep-Sleep mode only retains RTC memory, the so called digital core including the SRAM is powered down in this mode. Detailed information can be found in ESP32 Technical Reference Manual, page 646.

@benemorius
Copy link
Member

I can confirm only the ligh-sleep mode allows to retain the RAM content therefore needing at least 800µA to do so.

That is horribly unfortunate. It reminds me of mcus from 8+ years ago. Although since esp32 is primarily a wifi chip, and wifi is not low-power, perhaps it shouldn't be surprising.

However, it's not incompatible with pm_layered and if you can sustain 800uA then you could still use pm_layered to control when this sleep state is entered. For that matter, you can also use pm_layered to enter the lower states too, just with the understanding that the next WFI will reset the mcu.

Wouldn't it be possible to consider one of the deep-sleep mode (6.5µA for example) as the lowest power state in pm_layered in RIOT and the light-sleep mode (800µA) as a "higher" deep-sleep mode ? I know it's not clean, but it's at least kind of a "power mode" support.

Yes that's what I'd recommend doing. The difference between 6.5uA and 4.5uA won't be noticed by any practical application.

@gschorcht
Copy link
Contributor

OK, I will have a look what is needed to implement these both power modes and what their impact on the platform code would be.

One further remark. There is a PR #12955 with extensive code deduplication, which has a major impact on the code in cpu/esp32. I would prefer to merge this PR before making further changes in cpu/esp32. Otherwise, a subsequent merge could become difficult.

@gschorcht gschorcht self-assigned this Feb 16, 2020
@gschorcht
Copy link
Contributor

gschorcht commented Feb 16, 2020

Just for information, I have small test with deep sleep and RTC timer wakeup already running. At the moment, I'm thinking about how to use it as platform implementation for pm_layered. ESP32 can also be woken up by several GPIOs. [Update] Deep sleep works also with GPIOs. As next step, I will see how to get light sleep working.

@Citrullin
Copy link
Contributor

@gschorcht I have to agree. I currently port a library to the ESP32 for Arduino and it is the most annoying platform I ever worked with. I cannot recommend anybody to work with this platform. For prototyping it is kind of fine, but I wouldn't use it for real life products.

@nicoHarel If you need to use Lora, I would use the STM32F1/STM32F4 and a Lora module. Or maybe the STM32L series is more interesting for you. Depending on the requirements. It is not that complicated to create your own board. There are several ready to use modules out there. So, you basically just need to connect the STM32 module and Lora modul on one SBC together. But if the range of BLE is good enough, you can use the nRF52832/nRF52840 for your use-case. This would be even cheaper, since the nrf52 already has the radio on the IC.

@nicoHarel
Copy link
Author

nicoHarel commented Feb 20, 2020

@nicoHarel If you need to use Lora, I would use the STM32F1/STM32F4 and a Lora module. Or maybe the STM32L series is more interesting for you. Depending on the requirements. It is not that complicated to create your own board. There are several ready to use modules out there. So, you basically just need to connect the STM32 module and Lora modul on one SBC together. But if the range of BLE is good enough, you can use the nRF52832/nRF52840 for your use-case. This would be even cheaper, since the nrf52 already has the radio on the IC.

Yes, I'm trying to do something with a particle board (NRF52X). But by the looks of it, pm_layered isn't implemented either for those MCUs. The only function available is pm_off() which puts the MCU in "SYSTEM_OFF" mode, which is perfectly fine except I can't, for the life of me, wake up the NRF52840 after that (I tried to do so with a GPIO interrupt which normally should do the trick ?).

@kaspar030
Copy link
Contributor

Yes, I'm trying to do something with a particle board (NRF52X). But by the looks of it, pm_layered isn't implemented either for those MCUs.

The NRF are special and do most of pm_layered automatically. This is not as optimized as it could be, but usable. Someone stated the particle is using ~500uA in idle, with examples/hello-world. Enabling the internal DC-DC would make it go down another 100-150uA. It should be far below 100uA, but that's missing the mentioned optimization.

@gschorcht
Copy link
Contributor

PR #13416 fixes the issue for ESP32 MCU. It implements the light-sleep as well as the deep-sleep mode. Since CPU including peripherals are stalled in these modes and can't be woken up by internal interrupts such as timers they can't be used as idle power mode. Therefore, they are blocked and have to be set explicitly using pm_set.

But putting ESP32 into the light-sleep or deep-sleep mode is only one part of the problem. All ESP32 boards I know usually have a base load of more than 10 mA. You can measure this base load when you press the RESET button. Pressing the RESET button does nothing else than pulling down the CHIP_EN pin so that ESP32 is powered off completely. The reason are the components around the ESP32 like the USB2UART bridge or the voltage regulator.

There are some battery powered ESP32 boards. Maybe the base load for such board is much better.

@nicoHarel
Copy link
Author

nicoHarel commented Feb 21, 2020

The NRF are special and do most of pm_layered automatically. This is not as optimized as it could be, but usable. Someone stated the particle is using ~500uA in idle, with examples/hello-world. Enabling the internal DC-DC would make it go down another 100-150uA. It should be far below 100uA, but that's missing the mentioned optimization.

That's what I also get here (~600µA in idle) with the hello-world project. With more "heavy" projects (gnrc, spi...) I get around 1.7mA in Idle. Not great. As you mentioned it should be way lower than this. People are measuring around 50µA with the System.sleep() function (not the deep sleep one) from Particle .

I've actually managed to wake up the NRF from SYSTEMOFF with a GPIO interrupt by setting the "sense" register of the pin myself. But it's pointless. The MCU reboots while waking up (meaning that, so does RIOT). So the current implementation is correct. It makes more sense to reset the board with the reset pin in that case...

PR #13416 fixes the issue for ESP32 MCU. It implements the light-sleep as well as the deep-sleep mode. Since CPU including peripherals are stalled in these modes and can't be woken up by internal interrupts such as timers they can't be used as idle power mode. Therefore, they are blocked and have to be set explicitly using pm_set.

Awesome 👍 thank you for your work ! Does that mean it can't be a awoken by a GPIO interrupt either ?

But putting ESP32 into the light-sleep or deep-sleep mode is only one part of the problem. All ESP32 boards I know usually have a base load of more than 10 mA. You can measure this base load when you press the RESET button. Pressing the RESET button does nothing else than pulling down the CHIP_EN pin so that ESP32 is powered off completely. The reason are the components around the ESP32 like the USB2UART bridge or the voltage regulator.

There are some battery powered ESP32 boards. Maybe the base load for such board is much better.

Yes. I've noticed that too. The lopy4 is one of the battery powered board though. Every "non-essential" components are on a "programming shield". So that's fine with me.

@gschorcht
Copy link
Contributor

Awesome thank you for your work ! Does that mean it can't be a awoken by a GPIO interrupt either ?

Yes and no. No, because GPIOs or better RTC GPIOs[*] can be used as wake-up source. Yes, because it's not a GPIO interrupt in the strict sense, where you could attach an ISR which is executed as soon as the MCU is woken up. Rather, you just define a list of GPIOs that can wake up the MCU when either all of them go LOW or one of them goes HIGH.

The GPIOs and the level that are used for the wake-up logic are defined by the environment variables ESP_PM_WUP_PINS and ESP_PM_WUP_LEVEL.

[*] RTC GPIOs are the GPIOs that are realized by the RTC module. In fact, these are all GPIOs that might be also used as ADC channels.

@gschorcht
Copy link
Contributor

Yes. I've noticed that too. The lopy4 is one of the battery powered board though. Every "non-essential" components are on a "programming shield". So that's fine with me.

The board seems to be quite interesting. Do you have this board? If yes, may I ask you to measure the base load?

@nicoHarel
Copy link
Author

Yes. I've noticed that too. The lopy4 is one of the battery powered board though. Every "non-essential" components are on a "programming shield". So that's fine with me.

The board seems to be quite interesting. Do you have this board? If yes, may I ask you to measure the base load?

No problem, but what do you mean base load exactly ? With, for example, the hello-world project from RIOT OS ? If that is what you're looking for: 23mA with a LiPO batt (+3.8V) and the ESP32 frequency at 80MHz.

I know it seems like a lot, but compared to other ESP boards, it's actually quite low.

@gschorcht
Copy link
Contributor

gschorcht commented Feb 24, 2020

No problem, but what do you mean base load exactly ? With, for example, the hello-world project from RIOT OS ? If that is what you're looking for: 23mA with a LiPO batt (+3.8V) and the ESP32 frequency at 80MHz.

No, by base load I meant the current consumption when the ESP32 is not operating or disabled at all. That means the current consumption while you press the RESET button.

When you press the RESET button, ESP32's CHIP_PU pin is pulled down and the current consumption of the EPS32 drops down to 0.1uA. The current consumption reduced by the current that flows over the pull-up resistor at the RESET button should give the current consumption of the board itself (the base load).

@nicoHarel
Copy link
Author

nicoHarel commented Feb 24, 2020

When you press the RESET button, ESP32's CHIP_PU pin is pulled down and the current consumption of the EPS32 drops down to 0.1uA. The current consumption reduced by the current that flows over the pull-up resistor at the RESET button should give the current consumption of the board itself (the base load).

Ok. I measure 0.1mA-0.2mA overall on the board. My current meter is a bit rubbish (can't measure anything lower than 0.1mA)... So maybe about 0.150mA, maybe lower, I don't know, it's hard to say. But it doesn't look like it's high at all.

@gschorcht
Copy link
Contributor

Ok. I measure 0.1mA-0.2mA overall on the board. My current meter is a bit rubbish (can't measure anything lower than 0.1mA)... So maybe about 0.150mA, I don't know, it's hard to say. But it doesn't look like it's high at all.

That sounds really great. All boards I have here consume at least 11 mA.

May I ask you to try PR #13416 to see if you measure about the same in deep sleep and not more than 1 mA in light sleep mode? It would be really interesting whether it would work for you.

@nicoHarel
Copy link
Author

Ok. I measure 0.1mA-0.2mA overall on the board. My current meter is a bit rubbish (can't measure anything lower than 0.1mA)... So maybe about 0.150mA, I don't know, it's hard to say. But it doesn't look like it's high at all.

That sounds really great. All boards I have here consume at least 11 mA.

May I ask you to try PR #13416 to see if you measure about the same in deep sleep and not more than 1 mA in light sleep mode? It would be really interesting whether it would work for you.

No problem. I will try it this afternoon. I'm also very interested in the results anyway. The merge seems to blocked on your PR, but RIOT will still build, right ?

@gschorcht
Copy link
Contributor

gschorcht commented Feb 24, 2020

No problem. I will try it this afternoon. I'm also very interested in the results anyway. The merge seems to blocked on your PR, but RIOT will still build, right ?

Thanks. The merge is blocked because the PR first requires a review. RIOT will still build.

@nicoHarel
Copy link
Author

nicoHarel commented Feb 24, 2020

Ok, I've got a weird behaviour with your PR but maybe it's me or my board, I don't know.

I've tried a simple program (based on hello-world):

#include <stdio.h>
#include "periph/pm.h"
#include "xtimer.h"

int main(void)
{
    puts("hello World!");

    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);

    xtimer_sleep(5);

    pm_set(ESP_PM_DEEP_SLEEP);

    xtimer_sleep(5);

    while(1);

    return 0;
}

And this gives me the following output (with DEBUG flags turned on in the ESP32's and pm_layered's pm):

2020-02-24 15:21:21,076 # main(): This is RIOT! (Version: 2020.04-devel-661-g02ad1e-cpu/esp32/pm_layered)
2020-02-24 15:21:21,076 # hello World!
2020-02-24 15:21:21,084 # You are running RIOT on a(n) esp32-lopy4 board.
2020-02-24 15:21:21,085 # This board features a(n) esp32 MCU.
2020-02-24 15:21:21,086 # pm: setting mode 2
2020-02-24 15:21:21,088 # pm_set_lowest_normal enter.................. to normal sleep @8498
2020-02-24 15:21:23,077 # pm_set_lowest_normal exit from normal sleep @2006928
2020-02-24 15:21:23,078 # pm: setting mode 2
2020-02-24 15:21:23,084 # pm_set_lowest_normal enter.................. to normal sleep @2007035
2020-02-24 15:21:25,097 # pm_set_lowest_normal exit from normal sleep @4006933
2020-02-24 15:21:25,098 # pm: setting mode 2
2020-02-24 15:21:25,099 # pm_set_lowest_normal enter.................. to normal sleep @4007036

So I see all the "automatic" calls to "pm_set_lowest_normal" from pm_layered. But what I don't see, is the call to pm_set in the log. The program gets stuck here. Even if I change "ESP_PM_DEEP_SLEEP" with "ESP_PM_LIGHT_SLEEP".

Am I missing something ? Is my "pm_set()" calling incorrect ? pm_set() calls the function definition inside ESP32 pm module right ?

Edit: nevermind ! A simple delay fixes this. Turns out the cpu enter its sleep mode when calling "pm_set" before printing anything on the terminal. I'm measuring the currents right now.

@nicoHarel
Copy link
Author

Ok, the measurements:
IDLE: 24mA
ESP_PM_LIGHT_SLEEP: 4.5mA, a bit more than we anticipated I think. Something must still be on somewhere (board design maybe ?)
ESP_PM_DEEP_SLEEP: can't measure anything more than the board (only displaying 0.1mA), pretty good !

@Citrullin
Copy link
Contributor

Citrullin commented Feb 24, 2020

The NRF are special and do most of pm_layered automatically. This is not as optimized as it could be, but usable. Someone stated the particle is using ~500uA in idle, with examples/hello-world. Enabling the internal DC-DC would make it go down another 100-150uA. It should be far below 100uA, but that's missing the mentioned optimization.

If you want to optimize in these areas, it probably makes more sense to have an external RTC with alarms. It should be possible to reach the 20uA. Maybe there are even more efficient RTCs, I don't know.

@nicoHarel
Copy link
Author

nicoHarel commented Mar 3, 2020

If you want to optimize in these areas, it probably makes more sense to have an external RTC with alarms. It should be possible to reach the 20uA. Maybe there are even more efficient RTCs, I don't know.

In my case the MCU will be woken up by an external LORA chip so no need for for an external RTC. But this means that, after all, the NRF52X has the same behaviour as the ESP32 (it needs a reset to exit deep sleep). The only difference being that I can choose the "wake up" pin on the ESP 32 with the PR #13416 which is not the case with the NRFs.

I don't know, I haven't made my mind yet. The NRF boards seems to be less power hungry. But the lopy 4 has an embedded SX1276 LORA chips (there's a RIOT OS driver for that one).

@nicoHarel
Copy link
Author

nicoHarel commented Mar 5, 2020

Ok @gschorcht I've got a question. You made the following statement:

PR #13416 fixes the issue for ESP32 MCU. It implements the light-sleep as well as the deep-sleep mode. Since CPU including peripherals are stalled in these modes and can't be woken up by internal interrupts such as timers they can't be used as idle power mode.

Now I have trouble understanding why is that. The ESP32 has an internal RTC which seems to remain active no matter what sleep modes the MCU enters. See this link (just an example):
https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/

I've also seen a function available inside the esp32 vendor folder (esp32/vendor/esp-idf/esp32/sleep_modes.c):
"esp_deep_sleep(uint64_t time_in_us)"
This functions calls "esp_deep_sleep_start()" (the one you call in pm.c I think) just after setting up a wake up timer.

I'm pretty sure that would mean it is possible to wake up from timer. Am i forgetting something ?

Have a good day.

@gschorcht
Copy link
Contributor

You must not mix up timers and the RTC timer. Timers (module periph_timer) are part of the peripherals that are only active if the digital core is active (active or modem sleep). The RTC timer (module periph_rtc) is part of the RTC module which is also active in light or deep sleep and in hinbernation mode.

So the answer is: It is not possible to wake up the ESP32 by a peripheral timer (module periph_timer), but it is possible to wake it up by the RTC timer (module periph_rtc).

I know it is a bit more complicated to first set an RTC alarm with rtc_set_alarm and then call pm_set than to simply use esp_deep_sleep(10000). But this is the API used in RIOT.

Just for information: It's a bit confusing for ESP32 that the timer in the RTC module is called RTC timer. In fact, it's rather a RTT than a RTC. At the moment, the periph_rtc module is an emulated RTC based on that RTT. However, I will soon provide an RTT implementation periph_rtt soon so that the wake up time need not be set as an RTC alarm, but can be set as a simple counter offset

@nicoHarel
Copy link
Author

Alright, it seems that I misunderstood your original statement and thought you were talking about the RTC timers.

I know it is a bit more complicated to first set an RTC alarm with rtc_set_alarm and then call pm_set than to simply use esp_deep_sleep(10000). But this is the API used in RIOT.

I have absolutely no problem doing that. I just didn't know it was possible as I wasn't aware of the RTC module existence. Thanks for the tip.

Just for information: It's a bit confusing for ESP32 that the timer in the RTC module is called RTC timer. In fact, it's rather a RTT than a RTC

Agreed.

@nicoHarel
Copy link
Author

I have seen that the PR related to this issue has been merged, many thanks to everyone.

Also I thought I'd had bit more precision to the measurements I posted about the LOPY4 as @gschorcht seemed interested. With a lot more accurate current meter, a 3.9V charged LiPo battery, and nothing else except a capacitor in parallel with the battery to allow changing the caliber on the current meter:

Sleep modes Current
IDLE 27.4mA
Light sleep 4.21mA
Deep sleep 19.8µA

So, it's still weirdly high for the light sleep. This doesn't really bother but i thought I'd share the results.

@danirebollo
Copy link

Try to force shut down on all peripherals (WiFi, Bluetooth, RTC RAM, RTC pins...), maybe something is running

@miri64 miri64 added the Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation label Jul 6, 2020
@stale
Copy link

stale bot commented Jan 9, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Jan 9, 2021
@stale stale bot closed this as completed Feb 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: pm Area: (Low) power management Platform: ESP Platform: This PR/issue effects ESP-based platforms State: stale State: The issue / PR has no activity for >185 days Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

No branches or pull requests

7 participants