Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 11 of 11

Thread: Need table of Teensy4 interrupt mask names

  1. #1

    Need table of Teensy4 interrupt mask names

    I need a table for interrupt mask names like the one on this page only for Teensy4.
    https://www.pjrc.com/teensy/interrupts.html

    Any help?

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,190
    AFAIK that page still relates to Teensy AVR not ARM - posted recently to ask for that to be updated.

    On ARM - like the T_4 - interrupts are handled differently - For T_4 unique available vectors are at the top of : ...\hardware\teensy\avr\cores\teensy4\imxrt.h

    Desired usage of interrupts not indicated - perhaps pin interrupts? See : arduino.cc/en/pmwiki.php?n=Reference/AttachInterrupt

    If that misses it may help with forum search? Better answer if needed given more details.

  3. #3
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,422
    I believe the page you are referring to is specific to AVR based boards (T2.x)

    There are a ton of pages that would be great to be updated. Also there is an unofficial WIKI, which some members are trying to maintain and enhance:
    https://github.com/TeensyUser/doc/wiki

    But no real information in your post to know what you are looking for.

    With most of these boards there are 2 or 3 different levels of types of interrupts and APIS to setup to access them.
    As with most Arduino boards, you can setup to do interrupts on some IO pins. And as the Cards for the T4 and T4.1 mention: All digital pins have interrupt capability.
    For the normal things like this you use the standard Arduino API: attachInterrupt
    https://www.arduino.cc/reference/en/...tachinterrupt/
    Note: this API will setup an actual Interrupt vector for the IO port that pin is on, and then figure out which pin or pins were triggered and call your registered interrupt function.

    To setup an interrupt handler at the low level, you can use the function:

    As with most things with T4.x I look in avr\cores\teensy4\imxrt.h

    You will see most of the Interrupts defined near the top:
    Code:
    #ifdef __cplusplus
    extern "C" void (* _VectorsRam[NVIC_NUM_INTERRUPTS+16])(void);
    static inline void attachInterruptVector(IRQ_NUMBER_t irq, void (*function)(void)) __attribute__((always_inline, unused));
    static inline void attachInterruptVector(IRQ_NUMBER_t irq, void (*function)(void)) { _VectorsRam[irq + 16] = function; asm volatile("": : :"memory"); }
    #else
    extern void (* _VectorsRam[NVIC_NUM_INTERRUPTS+16])(void);
    static inline void attachInterruptVector(enum IRQ_NUMBER_t irq, void (*function)(void)) __attribute__((always_inline, unused));
    static inline void attachInterruptVector(enum IRQ_NUMBER_t irq, void (*function)(void)) { _VectorsRam[irq + 16] = function; asm volatile("": : :"memory"); }
    #endif
    
    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
    };
    Full list of interrupts is in reference manual (Chapter 3.3)

    As for what each of these interrupts do, you need to look at the section in the Reference Manual that discusses that interrupt. Example suppose you wish to setup an interrupt associated with a Quad Timer: You might look at section 54.6 and see all of the interrupts that can be generated and flags and the like: You will see I marked the quad timer interrupts in RED above.
    Each of these Interrupts handles multiple things that can trigger tham. In this case 5 different interrupts, which is controlled by the SCTRLn of the that system, which we have defines for by both structure and #defines, like:
    Code:
    #define TMR1_SCTRL0			(IMXRT_TMR1.CH[0].SCTRL)
    Which matchs section 53.6.8

    Which in imxrt.h we will mostly have defines that match the logical register name and field name, like:
    Code:
    #define TMR_SCTRL_TCF				((uint16_t)(1<<15))
    #define TMR_SCTRL_TCFIE				((uint16_t)(1<<14))
    #define TMR_SCTRL_TOF				((uint16_t)(1<<13))
    #define TMR_SCTRL_TOFIE				((uint16_t)(1<<12))
    #define TMR_SCTRL_IEF				((uint16_t)(1<<11))
    #define TMR_SCTRL_IEFIE				((uint16_t)(1<<10))
    #define TMR_SCTRL_IPS				((uint16_t)(1<<9))
    #define TMR_SCTRL_INPUT				((uint16_t)(1<<8))
    #define TMR_SCTRL_CAPTURE_MODE(n)		((uint16_t)(((n) & 0x03) << 6))
    #define TMR_SCTRL_MSTR				((uint16_t)(1<<5))
    #define TMR_SCTRL_EEOF				((uint16_t)(1<<4))
    #define TMR_SCTRL_VAL				((uint16_t)(1<<3))
    #define TMR_SCTRL_FORCE				((uint16_t)(1<<2))
    #define TMR_SCTRL_OPS				((uint16_t)(1<<1))
    #define TMR_SCTRL_OEN				((uint16_t)(1<<0))
    Now assuming you set an interrupt vector and you set the approriate value to cause the interrupt to trigger.

    In many case you need to make sure that your ISR function will remove the cause of the interrupt before it returns, otherwise it will get triggered again and again.

    Note: There is also things you can/should do to enable and disable interrupts, set priority...
    Looks for NVIC_...
    functions both in the above header file as well as in system code and libraries, to see their usage.

    But again not sure if this is what you are looking for?

  4. #4
    I need to set an interrupt on FlexPWM compare and overflow for a particular pin. Pretty simple, just need to know the vector names.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,190
    Sounds like it would be one of these perhaps in the indicated file:
    Code:
            IRQ_FLEXPWM1_0 =        102,
            IRQ_FLEXPWM1_1 =        103,
            IRQ_FLEXPWM1_2 =        104,
            IRQ_FLEXPWM1_3 =        105,
    Any alternate FLEX channels or related info should follow the manual naming conventions in that same file

  6. #6
    I saw that, but I need to the vector names to implement the ISR unless there's a way to do it with just the IRQ.
    Also, am I too conclude that compare and overflow both use the same IRQ? Obviously there's something I'm not getting.

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,190
    If there isn't a forum example search the CORES ... otheriwse the manual ...

    Not sure if this is a good start :: ...\hardware\teensy\avr\libraries\FreqMeasure\util \FreqMeasureCapture.h
    It doesn't actually do anything in the _isr ??? - but it demonstrates IRQ and uses other elements of that timer that might help in searching ...

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,467
    Quote Originally Posted by kdharbert View Post
    but I need to the vector names to implement the ISR unless there's a way to do it with just the IRQ.
    There is indeed a way to do it with just the IRQ number, and on Teensy 4.x that's the *only* supported way.

    Code:
      attachInterruptVector(IRQnumber, function);
    So for your interrupt function, just make up any name you like. The only requirement is it must take no inputs and return nothing, and of course it can't be a C++ class member. You can even make the function static, so it isn't visible and can't conflict with names from any other files in your project.

    If you look in imxrt.h for the definition of attachInterruptVector(), you'll see it just writes your function's address into the RAM-based vector table. This is why we're not pre-defining function names, as was done on Teensy 3.x and is common on many other chips where the interrupt vector table is stored in flash. The table is in RAM on Teensy 4.x, so you just call attachInterruptVector(), or if you really want to write directly to the table you could do that too.

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,422
    Also the library FreqMeasureMulti sets up and uses that interrupt.

    It is more ore less table driven, sort of brute foce set of statis ISRs for each possible interrupt.
    But it does attachInterruptVector to them, plus set priority and enable the interrupt.

  10. #10
    Hmmm. If I read the FlexPWM timer documentation correctly, I believe there are three output compare registers per timer. How do I capture an interrupt for each of them? The above makes it look like a single interrupt per timer.

  11. #11
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,422
    You have one interrupt index and interrupt vector, you control what is called for by configuring it in INTEN register, and when the isr is called you figure out for what by looking at STS registers...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •