Very accurate hardware timer & FreeRTOS

zamek42@gmail.com
Posts: 34
Joined: Sat Dec 02, 2017 7:27 pm

Very accurate hardware timer & FreeRTOS

Postby zamek42@gmail.com » Mon Apr 29, 2019 12:08 pm

Hi All,
I need to drive and addressable LED chain which contains 64 addressable LEDs. The timing needs very accurate, 1X430uS and 2X430uS (0 or 1 bits). AFAIK freertos uses timer0 as a hardware timer which is the highest priority timer. I found a config flag in make menuconfig to assign hardware timer 1 to freertos, and I can use timer0. Its working well, but if I see it in an oscilloscope, there is a hard jittering.
My question is that, how can I make a high precision timer?
I tried this:
in config:
- clock frequency: 240Mhz
- run Freertos only first core
- XTensa timer to use as the freertos tick source (Timer 1(int 15 level 3))
in my code:

Code: Select all

timer_config_t config = {
		  .alarm_en=true,
		  .counter_en=false,
		  .intr_type = TIMER_INTR_LEVEL,
		  .counter_dir = TIMER_COUNT_UP,
		  .auto_reload = true,
		  .divider = TIMER_PRE_DIVIDER  // 5
  };

  timer_init(TIMER_GROUP_0, TIMER_0, &config);
  timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
  timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_RELOAD_US);
  timer_enable_intr(TIMER_GROUP_0, TIMER_0);
  timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer_proc_isr, NULL, 0, &timer_handle);
 
timer it:

Code: Select all

static void timer_proc_isr(void* arg)
{
	 static int io_state = 0;
         TIMERG0.int_clr_timers.t0 = 1;
         TIMERG0.hw_timer[0].config.alarm_en = 1;
 	 gpio_set_level(PLANE_0_PIN, 0);
	 gpio_set_level(PLANE_0_PIN, 1);
}
If I don't create a freertos task it works well, but when I create only one simple task it has jittering.

thx,
Zamek

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Very accurate hardware timer & FreeRTOS

Postby ESP_Angus » Tue Apr 30, 2019 12:03 am

You can use the timer group driver or the High Resolution Timer library to get accurate timer ISRs.

Regarding jitter, there are three things which are likely to cause short delays:
  • A higher priority interrupt is preempting the one you've registered. You have configured a level 3 interrupt as the FreeRTOS tick timer source, but the code is passing zero as the interrupt flags argument when registering the timer interrupt so it will choose "default" priority which could be an interrupt with priority of 1, 2 or 3. This means the FreeRTOS tick interrupt will probably preempt the timer, or (at best) defer it sometimes if they are both priority 3. Read about the flags argument here. It should be possible to set the system up so that the FreeRTOS tick is on timer 0 with priority 1 (the default), and you can register your timer in a way that it has priority 2 or 3 and preempts the tick.
  • Reading executable code into the flash cache due to a cache miss. To work around this, move the entire timer ISR into IRAM by adding the IRAM_ATTR attribute to the ISR function(s). You may need to implement the gpio_set_level() calls as direct register writes rather than function calls to have these in IRAM, but removing the function call will also make it faster.
  • Flash writes (due to NVS or something else) will disable all non-IRAM interrupts while writing to the flash chip. Moving your timer interrupt to IRAM (see above item) and then registering it as IRAM-safe with the ESP_INTR_FLAG_IRAM flag will prevent this.
All this aside, for what you need I would strongly recommend not using a timer at all and looking at the RMT peripheral and the RMT driver. This is a more accurate way to bit-bang a single pin without tying up the CPU. If the IDF RMT driver is not suitable for the throughput you need, there are some examples out in the community of addressable LED drivers using the RMT peripheral registers directly that you may want to take a look at.

PS Is there a reason you're only using one core?

zamek42@gmail.com
Posts: 34
Joined: Sat Dec 02, 2017 7:27 pm

Re: Very accurate hardware timer & FreeRTOS

Postby zamek42@gmail.com » Fri May 03, 2019 5:40 am

Hi ESP_Angus,

Thx for the idea this library seems good.

> PS Is there a reason you're only using one core?
I just want to dedicate a core for all non freertos components including hardware timer, but - I lready know - it is not the best idea.

thx,
Zamek

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Very accurate hardware timer & FreeRTOS

Postby ESP_Angus » Fri May 03, 2019 6:43 am

zamek42@gmail.com wrote:
Fri May 03, 2019 5:40 am
> PS Is there a reason you're only using one core?
I just want to dedicate a core for all non freertos components including hardware timer, but - I lready know - it is not the best idea.
This is not a bad idea (although not as good as RMT, in my opinion), but it's quite hard to do in IDF at the moment - you essentially have to build all the Core 1 code yourself as there's no driver support, and run all code from IRAM.

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

Re: Very accurate hardware timer & FreeRTOS

Postby WiFive » Fri May 03, 2019 7:03 am

ESP_Angus wrote:
Fri May 03, 2019 6:43 am

This is not a bad idea (although not as good as RMT, in my opinion), but it's quite hard to do in IDF at the moment - you essentially have to build all the Core 1 code yourself as there's no driver support, and run all code from IRAM.
There would be some overlap with a wake stub sdk so they could be developed together.

fervenceslau
Posts: 2
Joined: Thu Dec 12, 2019 9:32 pm

Re: Very accurate hardware timer & FreeRTOS

Postby fervenceslau » Thu Dec 12, 2019 9:39 pm

I have a similar problem, but I'm still learning about ESP32 and I have no idea how to solve it. I was hoping someone would please point me to the right direction.

I want to use bluetooth/wifi in core 0 and do adc sampling in core 1 with timer interrupt (high-ish frequency). The idea is to sample some data, do some quick calculations, put the data into a buffer which will be accessed by core 0 and sent over bluetooth/wifi (low frequency) to firebase. However, I have no experience with freeRTOS, so I don't know if this is even possible right now.

I have found a great example of adc sampling with timer but I don't think this will be enough to solve this problem (https://www.toptal.com/embedded/esp32-audio-sampling ).

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

Re: Very accurate hardware timer & FreeRTOS

Postby ESP_Sprite » Fri Dec 13, 2019 2:58 am

You are aware that you can use I2S and its associated DMA infrastructure to do ADC sampling? No timer needed then. There's an example under examples/peripherals/i2s_adc_dac if you need it.

fervenceslau
Posts: 2
Joined: Thu Dec 12, 2019 9:32 pm

Re: Very accurate hardware timer & FreeRTOS

Postby fervenceslau » Fri Dec 13, 2019 10:32 pm

Nevermind, wanted to delete de post as soon as I hit send...
Last edited by fervenceslau on Sat Dec 14, 2019 5:48 am, edited 1 time in total.

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

Re: Very accurate hardware timer & FreeRTOS

Postby ESP_Sprite » Sat Dec 14, 2019 3:32 am

Suggest you start a new thread with those questions, if you still have them; we're now kinda hijacking someone elses thread here.

Who is online

Users browsing this forum: Bing [Bot] and 119 guests