Nanosecond delay

User avatar
SREG_SFR
Posts: 3
Joined: Fri Apr 12, 2024 12:27 pm

Nanosecond delay

Postby SREG_SFR » Fri Apr 12, 2024 12:58 pm

Hi there. I'm new to working with ESP controllers.

I'm converting a project from Raspberry Pi Pico to ESP32-S3. And from what I can tell this microcontroller should be more than capable.

There were a couple of time-critical functions and I'm trying to figure out how to implement them on ESP.

The most important one is a sub-microsecond delay. On RPi Pico I did it like this:

Code: Select all

// the clock is set to 125 MHz => 1 tick == 8 ns
// init SysTick timer
systick_hw->csr = 0x05; // enable systick at 1 cycle resolution (8ns)
systick_hw->rvr = 0xffff; // 16 bit

// delay 13 ticks or 102 nanoseconds
uint16_t ticks = 13; // 13*8 = 102 nanos
uint16_t start = systick_hw->cvr;
while((uint16_t)(start-systick_hw->cvr) < ticks); 
How would I achieve the same result on ESP? I tried searching for systick but I can't find it.

For less time-sensitive delays I used "busy_wait_us", but the best I found for ESP is "esp_rom_delay_us" which is marked as "Internal and Unstable". Of course, if I can manage to make a delay in 10s on ns, then this won't be a problem either.

Sidenote: I won't have any wireless connectivity. And in this case, if I understood correctly, I don't need RTOS.

MicroController
Posts: 1706
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Nanosecond delay

Postby MicroController » Fri Apr 12, 2024 3:54 pm

SREG_SFR wrote:
Fri Apr 12, 2024 12:58 pm
How would I achieve the same result on ESP? I tried searching for systick but I can't find it.
Not saying you should do it, or that it will perform the way you need, but esp_cpu_get_cycle_count() ticks away at one count per CPU clock cycle, i.e. up to 240MHz.

If you intend to generate IO signals based on this timing, you'll likely have to use the Dedicated GPIO. To generate or receive (fast) IO signals,
I recommend to use the on-chip peripherals whenever feasible though.
For less time-sensitive delays I used "busy_wait_us", but the best I found for ESP is "esp_rom_delay_us" which is marked as "Internal and Unstable". Of course, if I can manage to make a delay in 10s on ns, then this won't be a problem either.
For short delays, you can use esp_rom_delay_us(). A context switch on the ESP takes about 10-15us, so that's the lower bound of what's achievable for a task by waiting for a notification from a (timer) ISR; if you can accept the jitter, I'd say you should go for blocking waits instead of busy waiting for things above 100us or so, or move stuff into a timer ISR.
Sidenote: I won't have any wireless connectivity. And in this case, if I understood correctly, I don't need RTOS.
Yes, you do need the RTOS. Almost every IDF component/driver depends on FreeRTOS, it is kind-of 'hardwired' into interrupt handling, and without the RTOS you couldn't even have code run on the other CPU core.
However, you do not need to do anything special to have FreeRTOS running; it's included automatically in every IDF project build and also starts running automatically. In fact, your application's entry point, app_main(), is called from an already running FreeRTOS task.

User avatar
SREG_SFR
Posts: 3
Joined: Fri Apr 12, 2024 12:27 pm

Re: Nanosecond delay

Postby SREG_SFR » Sat Apr 13, 2024 3:00 pm

MicroController wrote: Not saying you should do it, or that it will perform the way you need, but esp_cpu_get_cycle_count() ticks away at one count per CPU clock cycle, i.e. up to 240MHz.
This looks promising!

MicroController wrote: If you intend to generate IO signals based on this timing, you'll likely have to use the Dedicated GPIO. To generate or receive (fast) IO signals,
Thanks for the advice! I think I'll need Dedicated GPIO. My LED pulses must be 8 microseconds long, and it seems this might be the only way to achieve that.

MicroController wrote: Almost every IDF component/driver depends on FreeRTOS, it is kind-of 'hardwired' into interrupt handling, and without the RTOS you couldn't even have code run on the other CPU core.
That's a bit sad. RTOS is great but timings can be a bit garbage for high-speed applications. It just adds a bit too much overhead for my liking. Thanks for the heads-up though! I guess I'll have to structure my code around GPTimers

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Nanosecond delay

Postby ESP_Sprite » Sun Apr 14, 2024 1:21 am

Can I ask what you're trying to achieve here? On the ESP32 series, you're usually better off using one of the peripherals rather than trying to bitbang something. For instance, you may want to look at the RMT peripheral if you need to generate 'weird' signals.

DrMickeyLauer
Posts: 168
Joined: Sun May 22, 2022 2:42 pm

Re: Nanosecond delay

Postby DrMickeyLauer » Sun Apr 14, 2024 9:15 pm

There‘s also this https://github.com/FL0WL0W/esp-idf/tree/AMP exciting (3rdparty) project here that allows scheduling one core for FreeRTOS and the other for bare metal. Perhaps that would be of help.

User avatar
SREG_SFR
Posts: 3
Joined: Fri Apr 12, 2024 12:27 pm

Re: Nanosecond delay

Postby SREG_SFR » Mon Apr 15, 2024 1:04 pm

ESP_Sprite wrote:
Sun Apr 14, 2024 1:21 am
Can I ask what you're trying to achieve here?
I need to turn on the LED and then read the strength of the reflection. The LED turns on fully within 8 microseconds, so in order to save energy, I turn it off once I get my data. To do all of this, I need precise control of when the LED is turned on and when the external ADC's sample-and-hold is triggered.

From what I've read so far, it seems RTOS might be not such a big issue. If I run my time-critical task on the second core, and make it the only task on the second core, then the RTOS should do nothing (disabling interrupts for the time-critical task on that core is probably a good idea too).

BTW, I saw "cpu_hal_get_cycle_count()" function mentioned in the docs, but I couldn't find it there. Is there some resource that lists all HAL functions and their usage?

MicroController
Posts: 1706
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Nanosecond delay

Postby MicroController » Tue Apr 16, 2024 8:20 am

SREG_SFR wrote:
Mon Apr 15, 2024 1:04 pm
in order to save energy, I turn it off once I get my data. To do all of this, I need precise control of when the LED is turned on
Doesn't sound like you'd need any kind of precision in the timings. The only 'hard' constraint seems to be the >= 8us between LED on and ADC trigger.
What's the sample rate of the ADC, i.e. for how long do you need the LED to stay on?
Is there some resource that lists all HAL functions and their usage?
Nope. The HAL layer is 'internal' IDF API, not intended for use by applications.

Who is online

Users browsing this forum: Majestic-12 [Bot] and 101 guests