-
Notifications
You must be signed in to change notification settings - Fork 7.2k
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
Add an example of going to deep sleep from wake stub (IDFGH-6564) #8208
Comments
I will be ready for testing and providing feedback, my stub works for the first wakeup, on the second wakeup the C3 boots and does not call the sub entry. |
Same here |
My stub also is not executed second time. I had to revert to older version for this to work. I hope for a solution soon otherwise I am stuck with older version of IDF |
@baamiis Can you name the lastest esp-idf version where it still works? |
4.22 release it works |
I did some further testing. In short, it boils down to the fact that the WDT resets the chip after deep sleep has been re-initiated by the wake up stub. |
In my testing, the wakeup is done without a reset, I believe that the WDT does a reset @tsVestor |
ESP32S3 has code that looks like
with SOC_PM_SUPPORT_DEEPSLEEP_VERIFY_STUB_ONLY set to 1, so I'm not sure that writing to RTC_ENTRY_ADDR_REG has the desired effect. |
Hi @helmut64 @tsVestor @baamiis , about the issue that ESP32-C3 wake stub works for the first wakeup, on second wakeup the C3 boots and does not call the sub entry. Please call ROM function
|
Does anyone have equivalent instructions for an ESP32S3? |
My understanding is that S2/S2 also needs the set_rtc_memory_crc() |
@andrew-elder @helmut64, ESP32-S3 support |
Some codes like
|
Thank you for the advise. |
@gm-jiang - thank you! That works on my ESP32S3. I also see that ESP32S3 uses
so no need to spin/wait for the RTC reading to be populated in the registers. |
Hi @andrew-elder, is there any problem found in function |
@gm-jiang - no problem at all that I am aware of. The code is just a little different than that used by an ESP32 in other related postings. It took me a while to figure out that ESP32S3 required a different sequence, so I posted here for others to use. |
@andrew-elder Thanks for your question, I think it's an improvement in hardware design, but needs to be double-checked. |
Hi @andrew-elder, It's been confirmed that this is a hardware improvement. |
I'm new to the ESP32-C3. All the above examples are fantastic for me to get started, but what's the easiest way to transmit and receive on the UART in the rtc wake stub? Any example code or pointers will be greatly appreciated. Thanks. |
Hi @jasaw , before enter deep-sleep wake stub, BootROM will do some initialization work on uart0. The |
Thank you for the response and pointing me to the right direction. |
Hi @jasaw, Yeah,we do provide an option to choose whether to use the |
@gm-jiang My RTC wake-up stub needs to receive sensor data, write to flash, and go back to deep sleep. It will only bring up wifi if it has collected enough samples. What's the best way to read and write data from/to SPI flash? |
@jasaw the wakeup stub should be used only for very little code blocks, it has tons of restrictions and every line code must be done with care, no C runtime code can be called (e.g. 64bit multiply, etc. because this code is in the flash) |
I suggest that wake-up stub receive sensor data and save this data to RTC_RAM, then write the data to flash when boot chip. |
@jasaw For read and write data from/to SPI flash, I think you can refer to https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/spi_flash.html#spi-flash-access-api |
Yes, the easy way out is to use the left over RTC memory as a buffer for my sensor samples, but this buffer is way too small. @gm-jiang I still would like to explore writing to flash from my RTC wake-up stub. Are the SPI flash functions that you linked above suitable to be called from RTC wake-up stub? Here's my code that reads the SPI flash: // initialize the spi flash
esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false);
// read data
uint32_t data[10];
esp_rom_spiflash_result_t result = esp_rom_spiflash_read(0x300000, &data, sizeof(data));
// result is ESP_ROM_SPIFLASH_RESULT_ERR but reading address 0x000004 works fine Why would the spi flash read fail at 0x300000 address? |
@jasaw, I think you need call ROM function |
@gm-jiang Thanks. Calling
|
@jasaw You can find this |
I'm having troubles going back to sleep in the stub, either it continues to boot or it bootloops. target = ESP32c3 To start deepsleep:
Then the stub is simply (as a test):
in sdkconfig I have
(not much documentation in the two different sizes, I already tried increasing both but the outcome is the same) The above does a bootloop like this:
If I leave out the RTC_CNTL_STATE0_REG lines it proceeds to the bootloader after deepsleep wakeup Adding in case it matters: this project is using a secure bootloader Added if I only try to wake up with GPIO 3 the stub isn't run, rst:0x1, with the timer it did run the stub (could even increment a variable) |
@peturdainn Could you test your wake up stub code without secure boot? |
This does not seem to change anything I created a stripped down project to run on a devboard, first test is wake from timer. Next test is wake from GPIO sdkconfig.defaults.txt UPDATE: So: do I need to set a new timeout (and how), or somehow clear something? None of the examples of other users makes this clear. UPDATE 2 There's something wrong with RTC_CNTL_WAKEUP_STATE_REG definition in rtc_cntl_reg.h:
Datasheet says lower 16 bits but as you see above the whole mask is shifted 15, so upper bits! When using the REG_SET_FIELD() macro this certainly sets and clears wrong bits? |
First conclusion for GPIO deep sleep wakeup: Ran same code with or without secure bootloader (two different boards, yes) IMPORTANT question: is this by design? |
|
|
Everything OK now, managed to create some code that uses wake stub for GPIO and Timer wakeup. The bootloop was fixed by clearing RTC_CNTL_INT_CLR_REG (well, clearing the INTs by writing 0xFFFF) Have created a test/demo app for ESP32-c3: There is both a secure and non-secure sdkconfig.defaults included, bring your own signing key ;) Remarks welcome. |
@peturdainn I also tested that the RTC wakeup stub works with secure boot (using flash encryption).
|
@gm-jiang a yes, rtc_hal_set_wakeup_timer() is what I need(ed), it takes care of setting RTC_CNTL_MAIN_TIMER_ALARM_EN looking back, these were probably the two issues that I had:
Any API is better than having to scrape bits and pieces together ;) |
Turns out that when starting deep sleep, the function esp_deep_sleep_wakeup_prepare() will modify some GPIO settings, something I would have expected would be done in esp_deep_sleep_enable_gpio_wakeup() This includes switching pull-up/down based on configured level and HOLD. IMHO this functionality could be split better, and pin config could be left to the caller (or print an error if configured incorrect)? EDIT: just discovered this is actually the root cause for some issue on our hardware :( |
Thanks for reporting and sharing the updates, fix is available at a6f7035, feel free to reopen. Thanks. |
@Alvin1Zhang any comment on my last remark about the GPIO settings changed in esp_deep_sleep_wakeup_prepare()? As I wrote, it would make more sense to have this in esp_deep_sleep_enable_gpio_wakeup() so for specific hardware setups it is still possible to override the PU/PD config Or do I need to create a new issue for this since this remark is not the topic of this issue? |
Hi, @peturdainn In |
Hi, |
@jasaw This is not feasible, in wake_stub, radio is not initialized yet, and the size of RTC_RAM is not enough to store the initialization code |
@esp-wzh Is the radio initialization code in ROM? I can map the ROM radio init code and call it from RTC_RAM? |
No, the initialization process is very complicated and it is placed in Flash, and the radio will rely on some pll clock and power initialization in the bootloader, so if you needs to use the radio, it is worth running the bootloader |
Is your feature request related to a problem? Please describe.
Deep sleep wake stubs allow small pieces of code to be executed quickly after deep sleep. For example, deep sleep wake stub may check GPIOs or read some sensor. The deep sleep stub code may need to put the chip back into deep sleep if some condition isn't met.
Describe the solution you'd like
Describe alternatives you've considered
Additional context
Originally the feature for the ESP32 was requested in https://www.esp32.com/viewtopic.php?t=2369, and an ESP32 specific example is available at https://gist.github.com/igrr/54f7fbe0513ac14e1aea3fd7fbecfeab. In comments to that gist, users have requested this feature to be provided for ESP32-C3
The text was updated successfully, but these errors were encountered: