This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to trigger the external interrupt by software?

Other Parts Discussed in Thread: TM4C123GH6PM

 I use an GPIO interrupt in TI-RTOS, the main code is listed below:

    GPIO_setupCallbacks(&EK_TM4C1294XL_gpioPortJCallbacks);

    /* Enable interrupts */
    GPIO_enableInt(Board_BUTTON0, GPIO_INT_RISING);
    GPIO_enableInt(Board_BUTTON1, GPIO_INT_FALLING);

 When I push the button , the interrupt is happened. It is ok.

I want to know how to trigger the interrupt by software? Which function will be used?

Thanks !

  • jian ri li said:
    I want to know how to trigger the interrupt by software? Which function will be used?

     It is not clear what you means with this phrase:

     - arm peripheral interrupt flags to fire interrupts.

    - have a so called Software Interrupts like a call from code (also trap used to interface OS to user code)

     - manage critical exceptions?

  • Thanks for your answer!
    I mean how to set peripheral interrupt flags to fire interrupts.Regards.
    Li Jian Ri
  • Not sure how you could set interrupt flags at the peripheral level, but you can trigger the "main" peripheral interrupts with IntPendSet(). See the TivaWare Driverlib User's Guide to find out if that's what you need.
  • jian ri li said:
    ...how to trigger the interrupt by software? Which function will be used?

    Follows an example we use which meets your requirement:

    // Trigger the waveform update software interrupt.
    //
       HWREG(NVIC_SW_TRIG) = INT_PWM0_1 - 16;

    This code generates a Software Interrupt - we manage the resulting interrupt via a "normal" handler - but no "return" from the "software interrupt" is required.

    To gain true understanding you may wish to review ARM Tech docs - EXTRA Credit for your understanding of that ( - 16) .  (or your Verify Answer tick may motivate my further detail...)

  • cb1_mobile said:
    HWREG(NVIC_SW_TRIG) = INT_PWM0_1 - 16;

    I've used this myself before, and for some reason I remembered that IntPendSet() is internally exactly this, but it isn't. This is definitely the way to go, unless you need to trigger NMI, PENDSV or SYSTICK interrupts that IntPendSet() also handles via writes to other registers.

  • Veikko Immonen said:
    This is (cb1's post) definitely the way to go

    Indeed friend Veikko.   (if only you could award most deserved Verify Answer.)

    You're clever enough to decode (the -16) want to take a shot?

  • Here's my shot:

    Not all interrupts are equal, some are more equal than others... also referred to as faults, which occupy interrupt numbers 0-15.

    That's what I remembered outright, and with a bit of datasheet diving I think the difference is that interrupts from 16 onwards are handled by the NVIC (which wants them to be indexed beginning from zero) whereas the faults take a more direct route to the core. And why the "non-fault" interrupts are indexed beginning from 16 in TivaWare, I think that's because the interrupt number is then a valid index for the interrupt vector table, for faults and interrupts alike... Am I even close?

  • Veikko Immonen said:
    Am I even close?

    Uh - points for trying - not too many for the answer.

    Your resort to "fine datasheet" (but for USB & uDMA sections) makes great sense.

    Look carefully at the interrupt list (one showing all of the interrupts - in sequence - specifically @ PWM0. 

    Then ask - how can we, "fake" an interrupt?   Can we "hook" to a real interrupt - yet not trigger it - simply use it as an interrupt anchor?  (Say what?)

    Safe, controlled experimentation provides great insight - especially when "fine manual" itself, "Does not Work!"   (where have we seen that?...)

    Frayed, dog-eared copy of Joseph Yiu's book may assist - too...

  • Not sure I follow you anymore - you asked specifically about the -16 and that's what I tried to explain - INT_PWM0_1 is defined as 27 in inc/hw_ints.h (it's vector number) but the interrupt number is actually 11 (bit in interrupt registers, tm4c123gh6pm datasheet, table 2-9 on page 104).

    27 - 16 = 11

    Judging from your answer I'm so far off track that I really need to ask you to explain where I took the wrong turn...
  • Believe it very good that you located subject interrupt w/in, "inc/hw_ints.h."   That's most resourceful.

    Now poster asked about "software interrupt" - and when we review hw_ints.h we observe:'

    // The following are defines for the fault assignments.
    //
    //*****************************************************************************
    #define FAULT_NMI               2           // NMI fault
    #define FAULT_HARD            3           // Hard fault
    #define FAULT_MPU             4           // MPU fault
    #define FAULT_BUS              5           // Bus fault
    #define FAULT_USAGE         6           // Usage fault
    #define FAULT_SVCALL     11          // SVCall
    #define FAULT_DEBUG      12          // Debug monitor
    #define FAULT_PENDSV    14          // PendSV
    #define FAULT_SYSTICK   15          // System Tick

    //*****************************************************************************
    //
    // The following are defines for the interrupt assignments.
    //
    //*****************************************************************************
    #define INT_GPIOA               16          // GPIO Port A
    #define INT_GPIOB               17          // GPIO Port B
    #define INT_GPIOC               18          // GPIO Port C
    #define INT_GPIOD               19          // GPIO Port D
    #define INT_GPIOE               20          // GPIO Port E
    #define INT_UART0               21          // UART0 Rx and Tx
    #define INT_UART1               22          // UART1 Rx and Tx
    #define INT_SSI0                  23          // SSI0 Rx and Tx
    #define INT_I2C0                  24          // I2C0 Master and Slave
    #define INT_PWM0_FAULT  25          // PWM0 Fault
    #define INT_PWM0_0           26          // PWM0 Generator 0
    #define INT_PWM0_1           27          // PWM0 Generator 1
    #define INT_PWM0_2           28          // PWM0 Generator 2

    and then continuing up to value 154.

    Might it be "safe" to subtract 16 from PWM0_1 - which has a value of 27?   Such yields 11 - as you noted - and might that be, "FAULT_SVCALL?"  Can that explain the "magic" (if any) of (-16)? 

    But what if we subtract that same 16 from INT_CAN1 (see below)

    #define INT_CAN1                56          // CAN1

    That yields value 40 - and we note:

    #define INT_TIMER2B         40          // Timer 2 subtimer B

    Can that be right?  What might then result?  (one notes that, "FAULT_SVCALL" seems (not available) - this time - to save us...)

  • The numbers listed in inc/hw_ints.h are the interrupt vector numbers. For every non-fault interrupt, ie. interrupts that go through the NVIC, one can get the NVIC interrupt number by subtracting 16 from the interrupt vector number. IntPendSet() "eats" vector numbers, while NVIC_SW_TRIG "eats" interrupt numbers. This is what I've been trying to say all along - is there something else to it? The more I look at this the more clear it seems to me.
  • If it's clear to you - and to poster - my job here est fini...

    Here I repeat my earlier, "Verify Answer" so that this single post is full/complete & properly detailed & documented:

    // Trigger the waveform update software interrupt.
    //
       HWREG(NVIC_SW_TRIG) = INT_PWM0_1 - 16;   //  you may use any of the MCU's "non-fault" interrupts (right-most column, below) - one I illustrated has no special advantage...

    This code generates a Software Interrupt - we manage the resulting interrupt via a "normal" handler - but no "interrupt return" from such, "software interrupt" is required.

    Yet - to provide (proper) clarity - this chart from the MCU manual should prove most useful:

    Note that the "left-most column" reveals (the more usually encountered) "Interrupt Vector Number."  

    Next column reveals the less encountered, "Interrupt Number."   Those MCU Registers which handle interrupts - have "awareness" of these "Interrupt Numbers" - and this is the "why/how" of the earlier described, "subtraction of 16" from the "Interrupt Vector's Number."

    Chart above continues on thru Interrupt Vector Number # 154 - and may be used identically...