Can not start ULP after DEEPSLEEP_RESET

themadsens
Posts: 17
Joined: Wed Sep 05, 2018 6:49 pm

Can not start ULP after DEEPSLEEP_RESET

Postby themadsens » Fri Jun 21, 2019 10:49 am

I have a setup where we use the ULP to poll the power supply every 1ms in order to get an early warning for taking the ESP32 into deepsleep. This works just fine with code along the lines of:

Code: Select all

    ulp_set_wakeup_period(0, 1000); // Set ULP wake up period to 1ms
    ulp_threshold = ref * 95 / 100;
    adc1_ulp_enable(); // Give it back to the ULP
    ulp_run(&ulp_entry - RTC_SLOW_MEM);
When this condition is detected we wait for the GPIO to go below logical "1" and goes to deepsleep, guarded by the GPIO:

Code: Select all

  ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(LG_GPIO_PSDOWN, 1));
  esp_deep_sleep_start();
The problem is that I can not repeat this after the wakeup (cause: DEEPSLEEP_RESET). The ULP simply never statrts, no matter how many times I run the code above. Also, it exhibits the same behaviour after a short deepsleep via esp_deep_sleep();

I have to do a hardware reset on CHIP_PU, and then it works again until the next DEEPSLEEP_RESET

Any clues to bits / registers / whatever to rummage through?

/Flemming

boarchuz
Posts: 606
Joined: Tue Aug 21, 2018 5:28 am

Re: Can not start ULP after DEEPSLEEP_RESET

Postby boarchuz » Fri Jun 21, 2019 11:44 am

To be clear, is your ULP program ending immediately after it reports the power supply down state? Or does it continue to run while in deep sleep?

Are you confident that the problem is that the ULP program isn't running, or is it possible that it's running but there is some other problem (eg. pin not configured, unable to interrupt, etc)? Suggest implementing a simple counter that the ULP increments each loop so you can check for a heartbeat from the main program.

Does the ULP use the same pin as ext0 wakeup - LG_GPIO_PSDOWN - for the analog read? There are a couple points to note here: https://docs.espressif.com/projects/esp ... akeup-ext0
-Ext0 is incompatible with ULP wakeup source. I assume this means incompatible with ULP interrrupts while the SoC is awake too, which might be how you're having the ULP report the detected state. I don't think that's the problem here though, they don't seem to be enabled simultaneously.
-"After wake up from sleep, IO pad used for wakeup will be configured as RTC IO. Before using this pad as digital GPIO, reconfigure it using rtc_gpio_deinit(gpio_num) function." Maybe try reconfiguring the pin for ULP ADC on wakeup?

themadsens
Posts: 17
Joined: Wed Sep 05, 2018 6:49 pm

Re: Can not start ULP after DEEPSLEEP_RESET

Postby themadsens » Fri Jun 21, 2019 12:24 pm

boarchuz wrote: To be clear, is your ULP program ending immediately after it reports the power supply down state? Or does it continue to run while in deep sleep?
Wow! Good point :D :D
It works now, after i inserted the stop code below from the example (duh!)

Code: Select all

WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0) // Stop!
Thanks!! /Flemming

I guess the rest of the reply is now irrelevant. Anyway for posterity's sake
Does the ULP use the same pin as ext0 wakeup - LG_GPIO_PSDOWN - for the analog read? There are a couple points to note here: https://docs.espressif.com/projects/esp ... akeup-ext0
-Ext0 is incompatible with ULP wakeup source. I assume this means incompatible with ULP interrrupts while the SoC is awake too, which might be how you're having the ULP report the detected state. I don't think that's the problem here though, they don't seem to be enabled simultaneously.
Yes it does .. My point exactly. The esp_sleep_enable_ext0_wakeup(LG_GPIO_PSDOWN, 1) is only done after the ULP has done it's 'wake' and stopped polling.
-"After wake up from sleep, IO pad used for wakeup will be configured as RTC IO. Before using this pad as digital GPIO, reconfigure it using rtc_gpio_deinit(gpio_num) function." Maybe try reconfiguring the pin for ULP ADC on wakeup?
I do that no matter the wakeup reason. The following init snippet should take care of everything

Code: Select all

int ref = adc1_get_raw((adc1_channel_t)chan); // Does any required pin init in here. Actually we poll 16 times to establish 'ref'
adc1_ulp_enable(); // Give it back to the ULP

Who is online

Users browsing this forum: No registered users and 40 guests