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-S2: cannot lightsleep again after a wakeup from ULP (IDFGH-4396) #6229

Closed
yannpom opened this issue Dec 8, 2020 · 4 comments
Closed
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@yannpom
Copy link
Contributor

yannpom commented Dec 8, 2020

Environment

  • Development Kit: none
  • Module or chip used: ESP32-S2-WROOM
  • IDF version: v4.3-dev-1901-g178b122c1
  • Build System: idf.py
  • Compiler version: xtensa-esp32-elf-gcc (crosstool-NG esp-2020r3) 8.4.0
  • Operating System: macOS
  • Using an IDE?: No
  • Power Supply: external 3.3V

Problem Description

On the ESP32-S2, I start the ULP RISC-V with an infinite loop calling ulp_riscv_wakeup_main_processor() at around 1 Hz.

On the main CPU I configure the ULP as the only wakeup source then I enter lightsleep.

Around 1 second after, the main CPU is awoken as expected.

Then I re-enter lightsleep, but this time the lightsleep exits instantly. (Before any wakeup call from the ULP).

Expected Behavior

The ESP32-S2 should enter lightsleep a second time, and exit a second time ~1 second later (when the ULP sends the wakeup signal).

Actual Behavior

After a first successful lightsleep / resume, every subsequent lightsleep exits instantly.

Steps to reproduce

Compile, flash and run the following code:

Code to reproduce this issue

main.c

#include <stdio.h>
#include <esp_sleep.h>
#include <esp32s2/ulp_riscv.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_rom_uart.h>

#include "ulp_main.h"

extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[]   asm("_binary_ulp_main_bin_end");

void app_main(void)
{
    ESP_ERROR_CHECK(ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start)));
    ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());
    ESP_ERROR_CHECK(ulp_riscv_run());
    
    while (true) {
        printf("ulp_n = %u ulp_n_wakeup = %u\n", ulp_n, ulp_n_wakeup);
        printf("Entering lightsleep\n");

        uint64_t t1 = esp_timer_get_time();
        esp_rom_uart_tx_wait_idle(0);
        esp_light_sleep_start();

        uint64_t t2 = esp_timer_get_time();
        esp_sleep_wakeup_cause_t reason = esp_sleep_get_wakeup_cause();
        printf("\nLightsleep exited, reason=%d, sleep_duration=%llu\n", reason, t2-t1);
        vTaskDelay(10);
    }
}

ulp/ulp.c

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "ulp_riscv/ulp_riscv.h"
#include "ulp_riscv/ulp_riscv_utils.h"

volatile int n = 0;
volatile int n_wakeup = 0;

int main(void)
{
    bool on = false;
    while (true) {
        n++;

        if (n % 100000 == 0) {
            n_wakeup++;
            ulp_riscv_wakeup_main_processor();
        }
    }
    return 0;
}

CMakeLists.txt

set(COMPONENT_SRCS "main.c")
set(COMPONENT_ADD_INCLUDEDIRS "")
set(COMPONENT_REQUIRES soc nvs_flash ulp driver)

register_component()

set(ulp_app_name ulp_${COMPONENT_NAME})
set(ulp_riscv_sources "ulp/ulp.c")
set(ulp_exp_dep_srcs "main.c")
ulp_embed_binary(${ulp_app_name} "${ulp_riscv_sources}" "${ulp_exp_dep_srcs}")

sdkconfig.defaults

# Enable ULP
CONFIG_ESP32S2_ULP_COPROC_ENABLED=y
CONFIG_ESP32S2_ULP_COPROC_RISCV=y
CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=4096

Debug Logs

ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x8
load:0x3ffe6108,len:0x1818
load:0x4004c000,len:0x9d8
load:0x40050000,len:0x2e34
entry 0x4004c1ec
I (46) boot: ESP-IDF v4.3-dev-1901-g178b122c1 2nd stage bootloader
I (46) boot: compile time 16:18:47
I (46) boot: chip revision: 0
I (49) boot.esp32s2: SPI Speed      : 80MHz
I (54) boot.esp32s2: SPI Mode       : DIO
I (59) boot.esp32s2: SPI Flash Size : 2MB
I (63) boot: Enabling RNG early entropy source...
I (69) boot: Partition Table:
I (72) boot: ## Label            Usage          Type ST Offset   Length
I (80) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (87) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (94) boot:  2 factory          factory app      00 00 00010000 00100000
I (102) boot: End of partition table
I (106) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f000020 size=0x06080 ( 24704) map
I (120) esp_image: segment 1: paddr=0x000160a8 vaddr=0x3ffbd480 size=0x025c8 (  9672) load
I (126) esp_image: segment 2: paddr=0x00018678 vaddr=0x40022000 size=0x00404 (  1028) load
I (133) esp_image: segment 3: paddr=0x00018a84 vaddr=0x40022404 size=0x07594 ( 30100) load
I (150) esp_image: segment 4: paddr=0x00020020 vaddr=0x40080020 size=0x112f4 ( 70388) map
I (165) esp_image: segment 5: paddr=0x0003131c vaddr=0x40029998 size=0x03adc ( 15068) load
I (176) boot: Loaded app from partition at offset 0x10000
I (176) boot: Disabling RNG early entropy source...
I (188) cache: Instruction cache 	: size 8KB, 4Ways, cache line size 32Byte
I (188) cpu_start: Pro cpu up.
I (242) cpu_start: Pro cpu start user code
I (242) cpu_start: cpu freq: 160000000
I (242) cpu_start: Application information:
I (245) cpu_start: Project name:     ulp-test
I (250) cpu_start: App version:      1
I (254) cpu_start: Compile time:     Dec  8 2020 16:18:42
I (260) cpu_start: ELF file SHA256:  fdcd4fb193f8d17d...
I (266) cpu_start: ESP-IDF:          v4.3-dev-1901-g178b122c1
I (273) heap_init: Initializing. RAM available for dynamic allocation:
I (280) heap_init: At 3FF9E000 len 00002000 (8 KiB): RTCRAM
I (286) heap_init: At 3FFC01D8 len 0003BE28 (239 KiB): DRAM
I (292) heap_init: At 3FFFC000 len 00003A10 (14 KiB): DRAM
I (299) spi_flash: detected chip: generic
I (303) spi_flash: flash io: dio
W (307) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (321) cpu_start: Starting scheduler on PRO CPU.
ulp_n = 0 ulp_n_wakeup = 0
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=998509
ulp_n = 109574 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6038
ulp_n = 119702 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6040
ulp_n = 129830 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6038
ulp_n = 139958 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6040
ulp_n = 150087 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6039
ulp_n = 160215 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6052
ulp_n = 170344 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6039
ulp_n = 180470 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6040
ulp_n = 190598 ulp_n_wakeup = 1
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6039
ulp_n = 200725 ulp_n_wakeup = 2
Entering lightsleep

Lightsleep exited, reason=6, sleep_duration=6041
ulp_n = 210852 ulp_n_wakeup = 2
Entering lightsleep
@github-actions github-actions bot changed the title ESP32-S2: cannot lightsleep again after a wakeup from ULP ESP32-S2: cannot lightsleep again after a wakeup from ULP (IDFGH-4396) Dec 8, 2020
@Alvin1Zhang
Copy link
Collaborator

Thanks for the report and sharing the details and sorry for the inconvenience, we will look into.

@igrr
Copy link
Member

igrr commented Dec 9, 2020

@yannpom Could you try acknowledging and clearing the wakeup state from the main program? You can do this using REG_CLR_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR).

@yannpom
Copy link
Contributor Author

yannpom commented Dec 9, 2020

I edited main.c to add your call before and/or after the call to esp_light_sleep_start():

REG_CLR_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR);
esp_light_sleep_start();
REG_CLR_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR);

But I get the same behaviour.

@AshIzat
Copy link

AshIzat commented Aug 27, 2021

I was having this exact same problem, reading this issue lead me to the solution:

esp_light_sleep_start(); 
REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR);

(Just need to set rather than clear the bit)

@espressif-bot espressif-bot added Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Resolution: NA Issue resolution is unavailable labels May 13, 2022
espressif-bot pushed a commit that referenced this issue May 26, 2022
…om ULP

Since ulp wakeup signal are connected to ulp int raw(except esp32), we
need to clear ulp int raw before sleep when ulp wakeup enabled. Otherwise,
if the ulp int raw is already set, chip will not sleep properly.

Closes #6229
espressif-bot pushed a commit that referenced this issue Jun 10, 2022
… ULP

Since ulp wakeup signal are connected to ulp int raw(except esp32), we
need to clear ulp int raw before sleep when ulp wakeup enabled. Otherwise,
if the ulp int raw is already set, chip will not sleep properly.

Closes #6229
espressif-bot pushed a commit that referenced this issue Jun 10, 2022
…om ULP

Since ulp wakeup signal are connected to ulp int raw(except esp32), we
need to clear ulp int raw before sleep when ulp wakeup enabled. Otherwise,
if the ulp int raw is already set, chip will not sleep properly.

Closes #6229
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

5 participants