ULP Sleep timer clock

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

ULP Sleep timer clock

Postby wevets » Fri Sep 27, 2019 3:01 am

Hi,
I built a minimal ESP32 program that involved the ULP so that I could test by experiment a number of features that are not clearly documented in the ESP docs.

One question that has arisen the clock frequency with which the ULP timer clock is driven. The docs claim that the ULP timer is driven by a 150 kHz clock, and that clock source appears to be changeable in sdkconfig via make menuconfig. An app I’m developing will need to use long ULP delays, so I did some testing. I built minimal TestBed.c and TestBed.S programs to do the testing, which appear below. These programs build without error (I’m using GNU make at this time). When the C program invokes
ulp_set_wakeup_period( 0, 15000000 ); (15,000,000). If the ULP timer RTC_SLOW clock is driving the ULP timer clock at 150 kHz, I would expect to get a delay of about 100 seconds. Instead I get a delay of approximately 15 seconds. (Timings are between seeing “Yooo Hooo” printed on the terminal – see TestBed.c below.) Either of these delays are so long compared to other sources of “friction” that that “friction” is negligible. It seems that the clock driving the timer can’t possibly be 150 kHz. My calculations indicate that it’s closer to 1 MHz.

Am I misinterpreting this? I’ve supplied my .c and .S programs so you can see how I’m measuring. The programs are pretty minimal, stripping as much “friction” out of the processing as possible, leaving only essential stuff that should account for well less than a second. The code builds without error in a conventional GNU make directory structure within the ESP IDF, with the .S program in a ulp directory below the main directory. The makefile and component makefiles are vanilla. I invite you to verify.

What am I missing? Is there another clock driving the ULP timer? I’d like to understand so that I can set up sleep times more-or-less formulaically and dynamically in my final app.
  1. // TestBed.c
  2.  
  3. #include <stdio.h>
  4. #include <freertos/FreeRTOS.h>
  5. #include <freertos/portmacro.h>
  6. #include <esp32/ulp.h>
  7. #include "esp_sleep.h"
  8. #include "ulp_main.h"
  9.  
  10. extern const uint8_t bin_start[] asm("_binary_ulp_main_bin_start");
  11. extern const uint8_t bin_end[]   asm("_binary_ulp_main_bin_end");
  12.  
  13. void InitializeULP()
  14. {
  15.     // Set ULP RTC_SLOW_CLOCK tick count for ULP sleep.  Set SENS_UOP_CP_CYC0_REG...
  16.     // to 15,000,000, which should yield a sleep time of ~100 seconds if the clock...
  17.     // driving the sleep timer is 150 kHz.
  18.     ulp_set_wakeup_period( 0, 15000000 );   //Set ULP wake up for ~100 seconds
  19.     ulp_load_binary(0, bin_start, (bin_end - bin_start) / sizeof(uint32_t));
  20. }
  21.  
  22. void app_main()
  23. {
  24.     if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_ULP)  
  25.         InitializeULP();
  26.     else
  27.         printf("Yooo Hooo\n\n\n");
  28.    
  29.     // Start ULP and go to sleep
  30.     ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t));
  31.     esp_sleep_enable_ulp_wakeup();
  32.     esp_deep_sleep_start();
  33. }  
------------------------------------------------------------------------------------------------------------------------------
  1. // TestBed.S
  2.  
  3. // These includes define stuff in ULP macros and rtc_gpio
  4. //#include "soc/rtc_cntl_reg.h"
  5. //#include "soc/rtc_io_reg.h"
  6. //#include "soc/sens_reg.h"
  7. //#include "soc/soc_ulp.h"
  8.  
  9.     .bss
  10.  
  11.     .text
  12.    
  13.     .global entry
  14. entry:
  15.  
  16.     sleep 0     // use SENS_ULP_CP_CYC1_REG to set sleep time
  17.  
  18.     .global exitULP
  19. exitULP:
  20.     wake
  21.     // disable the timer (effectively preventing the ULP program from running again),
  22.     // clear the RTC_CNTL_ULP_CP_SLP_TIMER_EN bit in the RTC_CNTL_STATE0_REG register.
  23.     // This can be done both from ULP code and from the main program.
  24.     // WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
  25.     Halt

And as long as I’m here, is there any way to eliminate or at least shorten all the info that comes out on the terminal every time the main processors reboots on reset when awakened by the ULP?
Thanks.

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

Re: ULP Sleep timer clock

Postby WiFive » Fri Sep 27, 2019 5:14 am

ulp_set_wakeup_period argument is in microseconds, then converted to cycles by the function

https://github.com/espressif/esp-idf/bl ... ulp.c#L114

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

Re: ULP Sleep timer clock

Postby wevets » Fri Sep 27, 2019 6:05 am

Thanks. That explains my result perfectly, and that's more convenient. Is there an upper limit on number of µS the ULP can sleep with this API? Is that Upper limit a function of writing 32 bits of 1's into a SENS_ULP_CP_SLEEP_CYCn_REG?

And is there a way to limit the amount of stuff reported to a terminal output when the main processors reboot on reset when awakened by the ULP?

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

Re: ULP Sleep timer clock

Postby WiFive » Fri Sep 27, 2019 6:48 am

Yes I think so.

You can change bootloader log level but that will affect any reboot reason.

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot], igormoo and 139 guests