Teensy 4, Set interrupt priority on given pins

Status
Not open for further replies.

PDOS

Well-known member
I would like to increase the interrupt priority for pins 2, 3 and 16 on a Teensy 4.0. This is where I have fuel flow and wheel sensors generating time sensitive interrupts.

I have been puzzling through cores/teensy4 to see what is possible.
So far I have discovered that the following functions are available to me:

NVIC_DISABLE_IRQ(IRQ_number);
NVIC_ENABLE_IRQ(IRQ_number);
NVIC_SET_PRIORITY(IRQ_number, priority);

from startup.c:

72: for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
where NVIC_NUM_INTERRUPTS == 160 (imxrt.h)

So the default priority is 128 and there are 160 IRQ numbers available. But how do these relate to pin numbers?

From imxrt.h I get the following definitions for the available 160 interrupts:
Code:
enum IRQ_NUMBER_t {
        IRQ_DMA_CH0 =           0,
        IRQ_DMA_CH1 =           1,
        IRQ_DMA_CH2 =           2,
        IRQ_DMA_CH3 =           3,
        IRQ_DMA_CH4 =           4,
        IRQ_DMA_CH5 =           5,
        IRQ_DMA_CH6 =           6,
        IRQ_DMA_CH7 =           7,
        IRQ_DMA_CH8 =           8,
        IRQ_DMA_CH9 =           9,
        IRQ_DMA_CH10 =          10,
        IRQ_DMA_CH11 =          11,
        IRQ_DMA_CH12 =          12,
        IRQ_DMA_CH13 =          13,
        IRQ_DMA_CH14 =          14,
        IRQ_DMA_CH15 =          15,
        IRQ_DMA_ERROR =         16,
        IRQ_CTI0 =              17,
        IRQ_CTI1 =              18,
        IRQ_CORE_ERROR =        19, // TODO - name?
        IRQ_LPUART1 =           20,
        IRQ_LPUART2 =           21,
        IRQ_LPUART3 =           22,
        IRQ_LPUART4 =           23,
        IRQ_LPUART5 =           24,
        IRQ_LPUART6 =           25,
        IRQ_LPUART7 =           26,
        IRQ_LPUART8 =           27,
        IRQ_LPI2C1 =            28,
        IRQ_LPI2C2 =            29,
        IRQ_LPI2C3 =            30,
        IRQ_LPI2C4 =            31,
        IRQ_LPSPI1 =            32,
        IRQ_LPSPI2 =            33,
        IRQ_LPSPI3 =            34,
        IRQ_LPSPI4 =            35,
        IRQ_CAN1 =              36,
        IRQ_CAN2 =              37,
        IRQ_ADDR_ERR =          38, // TODO: name?
        IRQ_KPP =               39,
        IRQ_TSC_DIG =           40,
        IRQ_GPR_IRQ =           41,
        IRQ_LCDIF =             42,
        IRQ_CSI =               43,
        IRQ_PXP =               44,
        IRQ_WDOG2 =             45,
        IRQ_SNVS_IRQ =          46,
        IRQ_SNVS_SECURITY =     47,
        IRQ_SNVS_ONOFF =        48,
        IRQ_CSU =               49,
        IRQ_DCP0 =              50, // TODO: ???
        IRQ_DCP1 =              51, // TODO: ???
        IRQ_DCP2 =              52, // TODO: ???
        IRQ_TRNG =              53,
        IRQ_SJC_IRQ =           54,
        IRQ_BEE =               55,
        IRQ_SAI1 =              56,
        IRQ_SAI2 =              57,
        IRQ_SAI3_RX =           58,
        IRQ_SAI3_TX =           59,
        IRQ_SPDIF =             60,
        IRQ_BROWNOUT0 =         61,
        IRQ_Reserved1 =         62,
        IRQ_TEMPERATURE =       63,
        IRQ_TEMPERATURE_PANIC = 64,
        IRQ_USBPHY0 =           65,
        IRQ_USBPHY1 =           66,
        IRQ_ADC1 =              67,
        IRQ_ADC2 =              68,
        IRQ_DCDC =              69,
        IRQ_SOFTWARE =          70,
        IRQ_Reserved2 =         71,
        IRQ_GPIO1_INT0 =        72,
        IRQ_GPIO1_INT1 =        73,
        IRQ_GPIO1_INT2 =        74,
        IRQ_GPIO1_INT3 =        75,
        IRQ_GPIO1_INT4 =        76,
        IRQ_GPIO1_INT5 =        77,
        IRQ_GPIO1_INT6 =        78,
        IRQ_GPIO1_INT7 =        79,
        IRQ_GPIO1_0_15 =        80,
        IRQ_GPIO1_16_31 =       81,
        IRQ_GPIO2_0_15 =        82,
        IRQ_GPIO2_16_31 =       83,
        IRQ_GPIO3_0_15 =        84,
        IRQ_GPIO3_16_31 =       85,
        IRQ_GPIO4_0_15 =        86,
        IRQ_GPIO4_16_31 =       87,
        IRQ_GPIO5_0_15 =        88,
        IRQ_GPIO5_16_31 =       89,
        IRQ_FLEXIO1 =           90,
        IRQ_FLEXIO2 =           91,
        IRQ_WDOG1 =             92,
        IRQ_RTWDOG =            93,
        IRQ_EWM =               94,
        IRQ_CCM1 =              95,
        IRQ_CCM2 =              96,
        IRQ_GPC =               97,
        IRQ_SRC =               98,
        IRQ_Reserved3 =         99,
        IRQ_GPT1 =              100,
        IRQ_GPT2 =              101,
        IRQ_FLEXPWM1_0 =        102,
        IRQ_FLEXPWM1_1 =        103,
        IRQ_FLEXPWM1_2 =        104,
        IRQ_FLEXPWM1_3 =        105,
        IRQ_FLEXPWM1_FAULT =    106,
        IRQ_FLEXSPI2 =          107, // RT1060 only
        IRQ_FLEXSPI =           108,
        IRQ_SEMC =              109,
        IRQ_SDHC1 =             110,
        IRQ_SDHC2 =             111,
        IRQ_USB2 =              112,
        IRQ_USB1 =              113,
        IRQ_ENET =              114,
        IRQ_ENET_TIMER =        115,
        IRQ_XBAR1_01 =          116,
        IRQ_XBAR1_23 =          117,
        IRQ_ADC_ETC0 =          118,
        IRQ_ADC_ETC1 =          119,
        IRQ_ADC_ETC2 =          120,
        IRQ_ADC_ETC_ERR =       121,
        IRQ_PIT =               122,
        IRQ_ACMP1 =             123,
        IRQ_ACMP2 =             124,
        IRQ_ACMP3 =             125,
        IRQ_ACMP4 =             126,
        IRQ_Reserved4 =         127,
        IRQ_Reserved5 =         128,
        IRQ_ENC1 =              129,
        IRQ_ENC2 =              130,
        IRQ_ENC3 =              131,
        IRQ_ENC4 =              132,
        IRQ_QTIMER1 =           133,
        IRQ_QTIMER2 =           134,
        IRQ_QTIMER3 =           135,
        IRQ_QTIMER4 =           136,
        IRQ_FLEXPWM2_0 =        137,
        IRQ_FLEXPWM2_1 =        138,
        IRQ_FLEXPWM2_2 =        139,
        IRQ_FLEXPWM2_3 =        140,
        IRQ_FLEXPWM2_FAULT =    141,
        IRQ_FLEXPWM3_0 =        142,
        IRQ_FLEXPWM3_1 =        143,
        IRQ_FLEXPWM3_2 =        144,
        IRQ_FLEXPWM3_3 =        145,
        IRQ_FLEXPWM3_FAULT =    146,
        IRQ_FLEXPWM4_0 =        147,
        IRQ_FLEXPWM4_1 =        148,
        IRQ_FLEXPWM4_2 =        149,
        IRQ_FLEXPWM4_3 =        150,
        IRQ_FLEXPWM4_FAULT =    151,
        IRQ_ENET2 =             152, // RT1060 only
        IRQ_ENET2_TIMER =       153, // RT1060 only
        IRQ_CAN3 =              154, // RT1060 only
        IRQ_Reserved6 =         155,
        IRQ_FLEXIO3 =           156, // RT1060 only
        IRQ_GPIO6789 =          157, // RT1060 only
        IRQ_SJC_DEBUG =         158,
        IRQ_NMI_WAKEUP =        159
};

The closest I can find to what might be pin numbers is the following
Code:
 IRQ_GPIO1_INT0 =        72,
        IRQ_GPIO1_INT1 =        73,
        IRQ_GPIO1_INT2 =        74,
        IRQ_GPIO1_INT3 =        75,
        IRQ_GPIO1_INT4 =        76,
        IRQ_GPIO1_INT5 =        77,
        IRQ_GPIO1_INT6 =        78,
        IRQ_GPIO1_INT7 =        79,
        IRQ_GPIO1_0_15 =        80,
        IRQ_GPIO1_16_31 =       81,
        IRQ_GPIO2_0_15 =        82,
        IRQ_GPIO2_16_31 =       83,
        IRQ_GPIO3_0_15 =        84,
        IRQ_GPIO3_16_31 =       85,
        IRQ_GPIO4_0_15 =        86,
        IRQ_GPIO4_16_31 =       87,
        IRQ_GPIO5_0_15 =        88,
        IRQ_GPIO5_16_31 =       89,

Is this the case? And if so, how do I map them to my pins of interest(pins 2, 3 and 16).
Have I missed something obvious? I have searched the schematic for clues but can find nothing obvious.
 
Unfortunately all the pin interrupts use IRQ_GPIO6789. That is a consequence that comes with configuring the chip for fast GPIO.

On possibility, which I'm not 100% sure will work, might involve writing to IOMUXC_GPR_GPR26 - IOMUXC_GPR_GPR29 to put certain pins back into regular (slow) GPIO mode. Then you could configure them with the GPIO1 to GPIO4 registers, and write your own functions and use attachInterruptVector() to connect them to the interrupt vectors you want. Inside your interrupt function, you *must* clear the interrupt status bit before returning, so the function doesn't keep interrupting in an infinite loop.
 
Thanks Paul. Perhaps a reverse strategy might work.
What if I reduced the priority for all interrupts from 128 to, say 130. Then I increased the interrupt priority of IRQ_GPIO6789 to, say, 120?
 
Sure, but the hardware implements priorities in steps of 16. So the next lower priority step from 128 is 140.

Normally you would just change the priority of the interrupt you use. That's why they all default to 128 (except the ones that have different defaults, 64 for serial ports, 32 for systick, etc...) so you can raise your interrupt above them if needed.
 
I have a similar project. I am reading two frequencies on different pins with FreqCount. I get decent results by the Teensy frequency differs from what the scope connected to the same signal shows. I would like to try setting the priority to the lowest (highest priority) and see if I get different results. If I did NVIC_SET_PRIORITY(IRQ_GPIO6789,0) is having every pin at max priority going to do bad things to the Teensy?
 
Status
Not open for further replies.
Back
Top