ULP timer API doesn't work in deep sleep.

wevets
Posts: 112
Joined: Sat Mar 09, 2019 2:56 am

ULP timer API doesn't work in deep sleep.

Postby wevets » Mon May 25, 2020 8:04 am

I'm trying to build an app in which I want the ULP to wait a period of 5 seconds (sometimes more, sometimes less, configurable by the user) between checks of a peripheral by the ULP. I wrote a minimal ULP driver and ULP module, attached, to test things out. It appears that ulp_set_wakeup_period() does not work as advertised. In the example, the wait wait period (the 2nd parameter) is set to wait only 20 mS, which would be un-noticeable in testing the example. I set it to 5,000,000 µS, which should give a delay between ULP runs of about 5 seconds, and it doesn't. I'm making the calls to set up and run the ULP in exactly the same order as they are used in the examples. It should be irrelevant, but I'm using the CMake build system with esp-idf v4.0
Is this a bug, or is there some secret sauce I'm missing. I've attached the files to illustrate this problem.
Any help is appreciated.

Note: I attached the assembly file, but this message system won't accept files with a .S extension, the file extension used for ULP files in the esp-idf. I renamed it with a .S.c extension. Simply rename it back to a .S file to run.
Attachments
ULPinitialTimer.S.c
ULP file in assembly. Rename removing the .c extension to run
(690 Bytes) Downloaded 350 times
ULPinitialTimer.c
app_main file that initializes and runs the ULP code in deep sleep
(1.27 KiB) Downloaded 341 times

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

Re: ULP timer API doesn't work in deep sleep.

Postby boarchuz » Mon May 25, 2020 10:04 am

It starts immediately, and then every 5s thereafter. Maybe there's a way to tweak the registers for delayed start? I don't know.
For now you might need to work around it. eg.
[*] Simple: Create a variable to act as a 'first run' flag that is set on first run.
[*] Slightly cleaner?: have a 'mini' program at offset 0 that sets the entry of the actual program (eg. 2) and then halts. Every subsequent run will load directly into the actual program.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: ULP timer API doesn't work in deep sleep.

Postby WiFive » Mon May 25, 2020 11:41 am

You have to call halt

wevets
Posts: 112
Joined: Sat Mar 09, 2019 2:56 am

Re: ULP timer API doesn't work in deep sleep.

Postby wevets » Mon May 25, 2020 7:45 pm

Boarchuz and WeFive,

Thanks for your replies. My mistake was not putting a "halt" instruction in my code following the "jump TestAbleToWake, eq" instruction at line 24. With that I get the delay I want. In my testing, I'm going for 5 million µS, but the SENS_ULP_CP_SLEEP_CYC0_REG is 32 bits. If even 31 bits work, I'll have well more delay than I can use, but if all 32 bits work, one can delay for a bit more than 70 minutes. Cool.

Boarchuz, you're right that the ULP starts immediately on calling ulp_run() from system code, contrary to the ESP32 Tech Rev v4.0, bottom of page 613 and the following page.

Thanks again Boarchuz and WeFive for your input.

wevets
Posts: 112
Joined: Sat Mar 09, 2019 2:56 am

Re: ULP timer API doesn't work in deep sleep.

Postby wevets » Tue May 26, 2020 12:11 am

I needed to go out for what turned out to be a convenient amount of time, so I set up an experiment, which was easy with my sample code. I can now verify that the 32-bits of SENS_ULP_CP_SLEEP_CYC0_REG will allow a maximum delay time of a bit over 71 minutes with a bit of uncertainty due to how close the internal 150 kHz RC oscillator is to it's target frequency. On my test board, the timing was off by about 15 seconds after 71 minutes. Not bad for an RC oscillator.

Who is online

Users browsing this forum: No registered users and 138 guests