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.

LAUNCHXL-F28P55X: Triggering NMI with External GPIO

Part Number: LAUNCHXL-F28P55X

Tool/software:

Hi experts,

Is it possible to trigger NMI with external GPIO (rising/falling edge)? Mayve ERAD can do it but I can't find an example.

Customer wants this feature to algin with previous design.  

Regards,

Hang

  • Hi,

    It is possible to generate interrupt based on external GPIO input using XINT module.

    Although generating NMI isnt straightforward, like you said ERAD can be used.

    Alternately you can trigger interrupt using XINT module and software triggers NMI through NMIFRCFLG (NMI Flag Force) in System control chapter Manual.

    Thanks

  • Hi Bhatt,

    They need NMI as it can interrupts normal interrupt, therefore they can't use XINT to trigger NMI.

    If ERAD can do it, could you provide an example configuration of external GPIO triggering NMI?

    Regards,

    Hang 

  • //#############################################################################
    //
    // FILE:   erad_ex2_bus_monitor.c
    //
    // TITLE:  ERAD Monotoring instruction and data address buses.
    //
    //! \addtogroup driver_example_list
    //! <h1>ERAD HWBP Monitor Program Counter</h1>
    //!
    //!  In this example, the function delayFunction is called multiple times.
    //!  The function does read and writes to the global variables startCount and
    //!  endCount.
    //!
    //!  The BUSCOMP1 and COUNTER1 is used to count the number of times the function
    //!  delayFunction was invoked. BUSCOMP2 is used to generate an interrupt when
    //!  there is read access to the startCount variable and BUSCOMP3 is used to
    //!  generate an interrupt when there is a write access to the endCount variable
    //!
    //!  \b Watch \b Variables \n
    //!  - funcCount - number of times the function delayFunction was invoked
    //!  - isrCount  - number of times the ISR was invoked
    //!
    //! \b External \b Connections \n
    //!  - None
    //
    //#############################################################################
    
    //
    //Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    //
    // Globals
    //
    uint32_t isrCount = 0;
    uint32_t funcCount = 0;
    volatile uint32_t startCount, endCount;
    #define myGPIO0_GPIO_PIN_CONFIG GPIO_5_GPIO5
    #define myGPIO0 5
    #define myINPUTXBARINPUT0_SOURCE 5
    #define myINPUTXBARINPUT0_INPUT XBAR_INPUT1
    
    //
    // Main
    //
    void main(void)
    {
        ERAD_Counter_Config sec_params;
    
        //
        // Initializes device clock and peripherals
        //
        Device_init();
    
        //
        // Configures the GPIO pin as a push-pull output
        //
        Device_initGPIO();
    
        // GPIO5 -> myGPIO0 Pinmux
    
    	GPIO_setPinConfig(GPIO_5_GPIO5);
        GPIO_writePin(myGPIO0, 0);
    	GPIO_setPadConfig(myGPIO0, GPIO_PIN_TYPE_STD);
    	GPIO_setQualificationMode(myGPIO0, GPIO_QUAL_SYNC);
    	GPIO_setDirectionMode(myGPIO0, GPIO_DIR_MODE_OUT);
    	GPIO_setControllerCore(myGPIO0, GPIO_CORE_CPU1);
    
        XBAR_setInputPin(INPUTXBAR_BASE, myINPUTXBARINPUT0_INPUT, myINPUTXBARINPUT0_SOURCE);
    
        //
        // Initialise the ERAD module with the APPLICATION as the owner
        //
        ERAD_initModule(ERAD_OWNER_APPLICATION);
    
        //
        // Initializes PIE and clears PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initializes the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Enable RTOS Interrupt
        //
        Interrupt_enable(INT_RTOS);
        sec_params.event = ERAD_EVENT_INPUTXBAR0;
        sec_params.event_mode = ERAD_COUNTER_MODE_RISING_EDGE;
        sec_params.reference = 0x2;
        sec_params.rst_on_match = true;
    
        ERAD_configCounterInCountingMode(ERAD_COUNTER1_BASE, sec_params);
        ERAD_enableNMI(ERAD_INST_COUNTER1);
        ERAD_enableModules(ERAD_INST_COUNTER1);
    
        EINT;
        ERTM;
    
    
        while(1)
        {
            // Once
            DEVICE_DELAY_US(100);
            GPIO_writePin(myGPIO0, 1);
            DEVICE_DELAY_US(100);
            GPIO_writePin(myGPIO0, 0);
            DEVICE_DELAY_US(100);
            ESTOP0;
            // Twice
            GPIO_writePin(myGPIO0, 1);
            DEVICE_DELAY_US(100);
            GPIO_writePin(myGPIO0, 0);
            DEVICE_DELAY_US(100);
            ESTOP0;
        };
    }
    

    Hi Hang,

    This is using GPIO5 -> INPUTXBAR -> ERAD -> NMI Generation 

    For this example I am simply setting ERAD to count for when two GPIO rising edges occurs and generating a NMI.

    Best,

    Ryan Ma

  • Hi,

    Could you please share the interrupt function that handles this event? Or share the entire demo. Thank you!

  • Hi Zengzeng,

    That will be up to the customer on how to configure the NMI handler. I have provided the main functionality for the GPIO + ERAD + NMI trigger.

    Best,

    Ryan Ma

  • Hi,
    I have tested this demo can trigger the NMI interrupt, but when test GPIO5 output use the oscilloscope, it showed a waveform like this:

    I have deleted ESTOP0 before testing, It is not the waveform designed in the software. 
    I wonder what's going on inside? Or am I missing something?

  • Hi Zengzeng,

    What are you doing in the NMI Handler?

    I wonder if the device is going to an unknown state or being held in bootROM.

    Seems like the GPIO goes to a high impedance state.

    Best,

    Ryan Ma

  • Hi Ryan,

    I don't do anything in __interrupt void Interrupt_nmiHandler(void), it's empty.
    Is there anything I need to write to keep this demo running?

    BR

    Zengzeng

  • Hi Ryan,


    We found that the exception was caused by the reset caused by the NMI watchdog. Added SysCtl_clearAllNMIFlags(); to Interrupt_nmiHandler to stop NMI watchdog counting in time. But at the same time, a new problem was discovered. As the program cycled again, NMI could not be triggered again. Do you know what the reason is? Looking forward to your reply. 

    BR

    Zengzeng

  • We found that the exception was caused by the reset caused by the NMI watchdog. Added SysCtl_clearAllNMIFlags(); to Interrupt_nmiHandler to stop NMI watchdog counting in time. But at the same time, a new problem was discovered. As the program cycled again, NMI could not be triggered again. Do you know what the reason is? Looking forward to your reply. 

    You'll need to clear the ERAD events since it was triggered and the event was fired. To have it trigger again, you'll need to clear it.

  • Got it, It looks like OK now. Thank you Ryan!

  • Hi Zengzeng,

    Please mark the request as resolved. Thank you!

    Best,

    Ryan Ma

  • Hi Ryan,

    How I can mark the request? 
    I can't seem to do that.

    BR

    Zengzeng

  • Hi Zengzeng,

    There should be a button that you can press like: "This solved my issue". It should be in green.

    Best,

    Ryan Ma