relative interrupt priorities (Timer0 vs UART) - Teensy3.1

Status
Not open for further replies.

jimlux

Active member
I've got an application using Timer0 to fire an ISR that does an analogRead() at 50kHz. The Serial1,Serial2,Serial3 all use interrupts to service their FIFOs. Which one is higher in priority.. in my case, I'd rather the Timer0 be higher priority (and that there be minimal time spent with interrupts disabled in the Serial port code).

In any case the interrupts web page has a list of interrupts as do a few forum posts, but the ordering is different, and nowhere does it say they're in priority order.

Where can I find this info (MK20DX manual?)
 
Isn't this what the ADC library is for? It can ask for readings and services them when data is ready - it can sample at high rates - but is done using hardware resources. The serial(1 or 2) should take care of itself given the size of the buffered data available to the hardware on T_3.1.
 
Most ARM ADCs can have the ADC store via DMA. And have a timer automatically cause the ADC to take a sample - in hardware. No interrupt per sample.
CPU interrupt only when sample DMA buffer is 1/2 or 3/4 full. Much lower interrupt rate.
 
an ISR that runs 50,000/sec to do ADC? Better to do use DMA and a DMA circular buffer.

need to sample both A0 and A1, and DMA library (as of a year ago, when we coded this up) only runs one ADC.
The ISR, including the arithmetic operations for a 2 stage CIC decimator, consumes about 50% of the CPU cycles, so that's fine.
 
Have to look at ADC library..

Our two inputs are on A0 and A1, doing 16 bit conversions.. Originally, the software was coded for the Teensy 3.0, and the timing skew between the two was around 2 microseconds, which is fine for our application (that is, we don't need synchronous sampling, although that *would* be nice).

I'll look into it, but there's a non-zero cost to recoding things and verifying all the timing: it works now with the 20 microsecond ISR and it's pretty simple:

a1 = analogRead(A0);
b1 = analogRead(A1);
asum = asum + (a1 - 32768);
bsum = bsum + (b1 - 32768);

etc.
 
Hi,

you got no answer regarding the priorities :)
In short : There is a makro, NVIC_SET_PRIORITY(irqnum, priority)
You need to know the irqnumber. Please look at kinetis.h, it's very helpful.
Code:
// 0 = highest priority
// Cortex-M4: 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240
I would try to begin with 48 (i forgot which priority is the systick, its relativley high).

You can find the prioritys for serial in the source, it's 64 for all hardware-serials.
 
Don't know that this is a 100% solution but these two lines from ADC link above suggest this work is ready to use - except you'd do your math in batches outside the ISR.
I've have finally updated the ADC library and now it supports the Teensy 3.1 two ADC
Update: RingBufferDMA works correctly with Teensy 3.x, not LC yet

With this possible bonus: readSynchronizedContinuous(...)
 
Yep.. looks like IRQ_PIT_CH0 is interrupt #68 (assuming that timer0 uses PIT 0)

the UART IRQ #s are 44-50 (IRQ_UART0_LON)

then in mk20dx128.c it looks like:
// default all interrupts to medium priority level
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);

As you note, in serial1,2,3.c
#define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest
...
NVIC_SET_PRIORITY(IRQ_UART0_STATUS, IRQ_PRIORITY);
NVIC_ENABLE_IRQ(IRQ_UART0_STATUS);

However, intervaltimer.cpp doesn't change it from the original 128.

So by default the serial ports are higher priority than the interval timer.
 
Yes, indeed, it looks like it might work. I'll have to dig into it some more.
Doing the math outside in batches is fine (actually, preferred).
 
Cool. If can use Pedvide's good work. Looking forward to see how it works. Especially if the collection can run fast synchronously with low DMA overhead.
 
However, intervaltimer.cpp doesn't change it from the original 128.

IntervalTimer has a priority() function, which you can use to change the priority.

Details here:

http://www.pjrc.com/teensy/td_timing_IntervalTimer.html

You can also try to use NVIC_SET_PRIORITY(), but if you are using the IntervalTimer object, it's best to use its priority() function to make sure you're changing the correct timer.

The serial ports default to 64, so you'd want to set the timer to 48 or less to make sure it's able to interrupt the serial interrupt.
 
Status
Not open for further replies.
Back
Top