Page 1 of 1

ESP32 ULP can't wake up SOC from deep sleep

Posted: Wed Jan 20, 2021 3:16 pm
by timmbo
Hey there,

I don't know why, but I can't wake up the SOC (pico D4) from deep sleep by the ULP Coprocessor. The ULP code is running correctly, incrementing a variable that I can successfully read out when waking the SOC by the timer. Code is simple:

Code: Select all

static void init_ulp_program(void) {
    ulp_x = 0;
    ESP_ERROR_CHECK( ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t)) ); // load binary into rtc
    ESP_ERROR_CHECK( ulp_set_wakeup_period(0, 2000*1000) ); // run every 2 seconds
    ESP_ERROR_CHECK( ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t)));
}

extern "C" void app_main() {
    while(1) {
        if(firstStart) {
            firstStart = false;
            init_ulp_program();
        }
        printf("X = %d\n", ulp_x & UINT16_MAX);

        ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
        esp_deep_sleep_start(); 
    }
}
And the ULP code:

Code: Select all

#include "soc/rtc_cntl_reg.h"
#include "soc/soc_ulp.h"
#include "soc/rtc_io_reg.h"

	.bss

	.global x
x:	.long 0

	.text
	.global entry
entry:
	move r1, x    // Get adress of x
	ld r0, r1, 0  // Read x in r0
	add r0, r0, 1 // Increment x
	st r0, r1, 0  // Save the x in memory

	wake
	halt
The ULP code is running, but somehow totally ignores the "wake".

Anybody has an idea?

Thanks in advance.

Re: ESP32 ULP can't wake up SOC from deep sleep

Posted: Wed Jan 20, 2021 11:19 pm
by felmue
Hello @timmbo

your code is actually working and the SoC is woken up by the 'wake' command. You can easily test that by removing the 'wake' command - the SoC stays in deep sleep forever.
Some remarks:
- you don't need a while loop in your main code - when the SoC wakes from deep sleep the code is run from the top again anyhow
- ulp_set_wakeup_period(0, 2000*1000) causes the ULP code to start to run 2 seconds after the SoC goes into deep sleep - that is why the SoC is in deep sleep for about 2 seconds, then woken up again by the 'wake' command
- using esp_sleep_get_wakeup_cause() gives you the wake up reason - reset or ulp or ...
Here is a revised main code:

Code: Select all

void app_main() {
    esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
    if (cause != ESP_SLEEP_WAKEUP_ULP) {
        printf("Not ULP wakeup, initializing ULP\n");
        init_ulp_program();
    } else {
        printf("ULP wakeup\n");
        printf("X = %d\n", ulp_x & UINT16_MAX);
    }

    ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
    esp_deep_sleep_start();
}
Thanks
Felix

Re: ESP32 ULP can't wake up SOC from deep sleep

Posted: Sun Jan 24, 2021 8:10 pm
by timmbo
Hi Felix,

thanks for your answer. My problem was that the SOC did not wake up at all. I found the reason though: I'm using PlatformIO where all compilers and tools were up to date except the ULP compiler. After updating the framework it now works.

Best, Timm