Does the ULP have a fixed execution frequency?

istokm
Posts: 27
Joined: Thu Jun 25, 2020 12:11 pm

Does the ULP have a fixed execution frequency?

Postby istokm » Fri Jan 15, 2021 9:06 pm

From my testing it seems that when you setup the ULP via ulp_set_wakeup_period, and run the ULPs program, it essentially works like a loop with a delay with the length being the period you set. This means that if you, for example, set a period of 100ms, the actual execution time for each loop will be 100.13ms (130us is roughly the execution time I measured for my ULP code). Section 31.5 of the ESP32 Technical reference seems to also describe this the same way.
Of course the reason you don't want this, is that over 100s or 1000s of cycles, you accumulate quite a large delay - severity depending on the clock cycle. 10ms wakeup cycles giving me roughly 1.8% or 18000ppm drift.
On the MCU, you'd use vTaskDelayUntil instead of vTaskDelay to solve this.. I guess the ULP just can't be this simple.

Essentially my questions are:
- are my observations correct?
- is there something I can do about this?

For example, is there a way to read the RTC_TIME registers at the very beginning, then reading them at the very end of the program, and using the difference to alter the ULPs sleep timer? - and also accounting for the fixed number of cycles we spend doing this of course.
According to the documentation, and technical reference, you can only
select one of theSENS_ULP_CP_SLEEP_CYCn_REG registers that contain the expiration period
So I'm a bit sceptical about the feasibility of this - this is why I came here to ask, instead of spending hours digging through the documentation, dumping and writing to registers, etc.

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

Re: Does the ULP have a fixed execution frequency?

Postby WiFive » Sat Jan 16, 2021 4:45 am

You can change the period register value but you can't select a different period register afaik

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

Re: Does the ULP have a fixed execution frequency?

Postby boarchuz » Sat Jan 16, 2021 8:11 am

Cycles for all instructions are included here:
https://docs.espressif.com/projects/esp ... n_set.html
read the RTC_TIME registers at the very beginning, then reading them at the very end of the program, and using the difference to alter the ULPs sleep timer?
It's possible to select a different one (that you could have preconfigured to, for example, 99.8ms, 100ms, 100.2ms) but it's not realistic to alter their values with the ULP.

You will need to keep RTC peripherals on for the ULP to be able to select a different wakeup period: esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)
(bearing in mind the note here: https://docs.espressif.com/projects/esp ... sor-wakeup)

Another option is to wake early (eg. set timer to 99ms) and then wait until the exact point the RTC time hits the next 100ms interval before continuing.

The easiest thing to do would be to determine your average ULP execution time (eg. 130us) and subtract it from the sleep interval (eg. sleep 99.87ms instead of 100).

Also, remember that RTC slow clock is used for the ULP sleep timer, with 5% error...

istokm
Posts: 27
Joined: Thu Jun 25, 2020 12:11 pm

Re: Does the ULP have a fixed execution frequency?

Postby istokm » Sun Jan 17, 2021 1:16 am

Well, that's a bit unfortunate, but it's fine as I've had some other ideas to mitigate the issues I'm encountering from this drift (in the future, I could store the current RTC time along with the data the ULP is generating, to take the cycle duration out of the equation).
Also, remember that RTC slow clock is used for the ULP sleep timer, with 5% error...
Oh I thought that ESP32_RTC_CLK_SRC also applies to the ULP.. is this not the case? If you can't use an external crystal for the ULP then I'm not even going to bother. 5% is way more than any on the drift I get from the execution time.

Btw. looking back at my methodology, the 130us I arrived at was likely very incorrect, and it is more in the 1000us range, but I don't actually have the hardware to measure this properly.

Edit: I've now got better tools to measure the actualy execution time of the ULP code, so I decided to give it a shot. My methology is just setting the ULP period to a known value, and every few hundred cycles toggle a GPIO output; so don't expect great accuracy, as it doesn't take into account the ESP32's clock (which is an external 10ppm cystal), gates & other logic to actually toggle the GPIO, etc. But the number that I've arrived at was ~40us with a few hundred lines of code in the ULP, so it's of a good size for this kind of testing. It also uses 3 READ_RTC_FIELD operations per cycle. The raw results I got were as follows:
1st is the total time drifted, 2nd is the number of cycles performed to achieve that drift. All of these measurements were taken over 3 seconds, so I can definitely prove, that the drift increases with the number of cycles per second. The fact that the scaling is linear also means that the drift is caused by the execution time, which is close to fixed.
6.996ms/150 cycles = 0.04664 ms/cycle
20.7ms/600 cycles = 0.03449 ms/cycle
66.496/1500 cycles = 0.04433 ms/cycle
112.26ms/3000 cycles = 0.03742 ms/cycle

by 'cycle' I mean the whole period from start to halt of the ULP, so essentially a wake up cycle
Last edited by istokm on Tue Jun 22, 2021 2:20 pm, edited 5 times in total.

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

Re: Does the ULP have a fixed execution frequency?

Postby boarchuz » Sun Jan 17, 2021 8:54 am

istokm wrote:
Sun Jan 17, 2021 1:16 am
Oh I thought that ESP32_RTC_CLK_SRC also applies to the ULP..
You're right, it does. I assumed you were using 150khz internal. Ignore that part.

Who is online

Users browsing this forum: No registered users and 236 guests