Page 1 of 1

Very accurate hardware timer & FreeRTOS

Posted: Mon Apr 29, 2019 12:08 pm
by zamek42@gmail.com
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

Re: Very accurate hardware timer & FreeRTOS

Posted: Tue Apr 30, 2019 12:03 am
by ESP_Angus
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?

Re: Very accurate hardware timer & FreeRTOS

Posted: Fri May 03, 2019 5:40 am
by zamek42@gmail.com
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

Re: Very accurate hardware timer & FreeRTOS

Posted: Fri May 03, 2019 6:43 am
by ESP_Angus
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.

Re: Very accurate hardware timer & FreeRTOS

Posted: Fri May 03, 2019 7:03 am
by WiFive
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.

Re: Very accurate hardware timer & FreeRTOS

Posted: Thu Dec 12, 2019 9:39 pm
by fervenceslau
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 ).

Re: Very accurate hardware timer & FreeRTOS

Posted: Fri Dec 13, 2019 2:58 am
by ESP_Sprite
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.

Re: Very accurate hardware timer & FreeRTOS

Posted: Fri Dec 13, 2019 10:32 pm
by fervenceslau
Nevermind, wanted to delete de post as soon as I hit send...

Re: Very accurate hardware timer & FreeRTOS

Posted: Sat Dec 14, 2019 3:32 am
by ESP_Sprite
Suggest you start a new thread with those questions, if you still have them; we're now kinda hijacking someone elses thread here.