I am reading conflicting information on what valid values are for NVIC interrupt priorities. Some resources say only 4 bits (0-15), others say 0-256. I am using the K64 processor.
Example usage: NVIC_SetPriority(PORTB_IRQn, 16);
I am using values: 0, 8, 16, 32, 64, and 128 for different interrupts. I am not getting errors, but I also cannot tell if the priorities are actually working correctly either.
Any insight would be helpful.
Thanks,
John Baker
AVG
Solved! Go to Solution.
Hi
void NVIC_SetPriority(int iInterruptID, unsigned char ucPriority)
{
unsigned char *ptrPriority = IRQ0_3_PRIORITY_REGISTER_ADD;
ptrPriority += iInterruptID;
*ptrPriority = (ucPriority << __NVIC_PRIORITY_SHIFT);
}
ucPriority 0..15 for K devices - #define __NVIC_PRIORITY_SHIFT 4
ucPriority 0..6 for KL and KE devices #define __NVIC_PRIORITY_SHIFT 6
Regards
Mark
Kinetis: µTasker Kinetis support
K64: µTasker Kinetis FRDM-K64F support / µTasker Kinetis TWR-K64F120M support / µTasker Kinetis TWR-K65F180M support
For the complete "out-of-the-box" Kinetis experience and faster time to market
I find the supplied 'arm_cm4.h' contains the a proper #define for the device-in-use. For the MK20 I see:
#define ARM_INTERRUPT_LEVEL_BITS | 4 |
The code in arm_cm4.c that uses it to take an integer (0-15 in this case) into the 'proper' place:
*prio_reg = ( (prio&((1<<ARM_INTERRUPT_LEVEL_BITS)-1)) << (8 - ARM_INTERRUPT_LEVEL_BITS) ); |
As long as we are talking about arm_cm4.c, I will reiterate here that the original enable_irq (and disable_irq) code from Freescale contained |= operations into NVICICPRx, which is blatently INAPPROPRIATE, and MUST just be '=' to avoid killing other pending interrupts.
Hello John,
ARM has designed the NVIC controller to allow up to 256 levels of priority in the interrupts. Is up to the chip manufacturer to implement the whole 256 levels or to reduce it to save silicon space.
In the case of K64 devices, they support 16 levels of interrupts. You have all the details in the chapter 3.2.2 of the Reference Manual of the device.
Regards,
Santiago
John,
What Santiago tries to tell you is that for each IRQn vector, there are 4 bits reserved to set the priority (0000 - 1111 value for each IRQ), so it is easier to set them as 0 to 15 instead of all decimal value (0,16,32,48, ..., etc), for example, for first 4 IRQ vectors, it would be easier to set their priority as follows:
As you can see, the first value indicates the priority level and it is easier to understand which priority level you are setting instead of using 32, 64, 128, ... values.
Regards,
Isaac
Hi
void NVIC_SetPriority(int iInterruptID, unsigned char ucPriority)
{
unsigned char *ptrPriority = IRQ0_3_PRIORITY_REGISTER_ADD;
ptrPriority += iInterruptID;
*ptrPriority = (ucPriority << __NVIC_PRIORITY_SHIFT);
}
ucPriority 0..15 for K devices - #define __NVIC_PRIORITY_SHIFT 4
ucPriority 0..6 for KL and KE devices #define __NVIC_PRIORITY_SHIFT 6
Regards
Mark
Kinetis: µTasker Kinetis support
K64: µTasker Kinetis FRDM-K64F support / µTasker Kinetis TWR-K64F120M support / µTasker Kinetis TWR-K65F180M support
For the complete "out-of-the-box" Kinetis experience and faster time to market
Hello John,
It depends how you rotate them, of course. Values 0-15 will need to be rotated 4 bits more than values 0-16,32,etc...The interrupt priority is given by a 4 bit field register. For me it would be more intuitive to write values 0-15 and then rotate them as needed by each register.
Regards,
Santiago