ESP32 ULP minimum wakeup time

dmarcos
Posts: 5
Joined: Thu Sep 06, 2018 10:48 am

ESP32 ULP minimum wakeup time

Postby dmarcos » Thu Sep 06, 2018 11:16 am

Hi,

I'm trying to check the minimum wakeup period for the ULP. For that I did a small sample code for the ULP which just turns ON and OFF RTC_GPIO17 (GPIO27) and halts. In the main app I just configure GPIO direction and set the wakeup period for the ESP32 using the IDF provided function for that. The main CPU then goes deep sleep and it never wakes up. Only ULP keeps running.

The code for ULP is as follows:

Code: Select all

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


	.bss
	/* Code goes into .text section */
	.text
	.global entry
entry:
	/* Disable hold of RTC_GPIO17 output */
	WRITE_RTC_REG(RTC_IO_TOUCH_PAD7_REG,RTC_IO_TOUCH_PAD7_HOLD_S,1,0)
	/* Set the RTC_GPIO17 output HIGH */
	WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG,RTC_GPIO_OUT_DATA_W1TS_S+17,1,1)	
	/* Set the RTC_GPIO17 output LOW */
	WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG,RTC_GPIO_OUT_DATA_W1TC_S+17,1,1)
	/* Enable hold of RTC_GPIO17 output */
	WRITE_RTC_REG(RTC_IO_TOUCH_PAD7_REG,RTC_IO_TOUCH_PAD7_HOLD_S,1,1)
	/*halt and wait for next ULP timer wakeup*/
	halt
And the code for the main processor just sets GPIO direction, configures ULP and sets it off calling ULP run. The configuration function contains basically this code:

Code: Select all

    rtc_gpio_init(ulp_toggle_num);
    rtc_gpio_set_direction(ulp_toggle_num, RTC_GPIO_MODE_OUTPUT_ONLY);
    
    /* Set ULP wake up period to XXus */
    ulp_set_wakeup_period(0, XX);

For what I understand, ULP wakeup period is configurable in 6.67us steps (uses 150 kHz clock) and the ulp_set_wakeup_period helper function takes microseconds as argument.

For example, doing ulp_set_wakeup_period(0, 300) should generate a periodic signal consisting of a very narrow pulse every 300us.

The problem is that it doesn't. Every period I set yields a periodic signal with approx 160us extra period. I mean,

This:
ulp_set_wakeup_period(0, 300)
generates a periodic signal with ~460us period, while this:
ulp_set_wakeup_period(0, 7)
generates a ~167us periodic signal.

Pulse width of the signal is about 1.2us in all cases (ULP execution time).

I can't find anything about these extra 160us in the documentation. Do you have any extra info about it?

User avatar
ESP_krzychb
Posts: 400
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: ESP32 ULP minimum wakeup time

Postby ESP_krzychb » Fri Sep 07, 2018 6:15 am

Hi @dmarcos,

Good find! I see identical result. My assumption is that 160us you identified, is the time required by ULP to wake up by the timer and start running the code. I will investigate more and post here if have some new updates.

dmarcos
Posts: 5
Joined: Thu Sep 06, 2018 10:48 am

Re: ESP32 ULP minimum wakeup time

Postby dmarcos » Mon Sep 10, 2018 9:01 am

krzychb wrote:Hi @dmarcos,

Good find! I see identical result. My assumption is that 160us you identified, is the time required by ULP to wake up by the timer and start running the code. I will investigate more and post here if have some new updates.

Hi,

Any update on this?

I've measured wakeup time more precisely and the extra time es 156us. If you do ulp_set_wakeup_period(0, 0) you get a period of 156.0 us. Any clue?

User avatar
ESP_krzychb
Posts: 400
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: ESP32 ULP minimum wakeup time

Postby ESP_krzychb » Mon Sep 10, 2018 9:09 pm

Hi David,

Indeed the minimum wakeup time is lower. My previous measurements were incorrect and included the program execution time. Sorry for that! I did separate check with the hardware design team and obtained more specific information.

The minimum wakeup time represents clock cycles spend by ULP's FSM on internal tasks:
1. Time to wakeup - 2 clock cycles
2. Waiting until the 8M clock is stable - 16 clock cycles
3. Preparation to go to sleep - 2 clock cycles

This makes the total of 20 clock cycles or 20 / 150 MHz = ~133us
Item 2 is defined by setting of RTC_CNTL_ULPCP_TOUCH_START_WAIT field in RTC_CNTL_TIMER2_REG register.
This field is set to 16 by default and this is also the recommended setting.

The ulp_set_wakeup_period() API will be updated to account for the clock cycles spent on internal tasks.

Who is online

Users browsing this forum: Google [Bot] and 177 guests