TM4C129DNCPDT: NMI intrupt not working properly

Part Number: TM4C129DNCPDT

I am trying to use PD7 as an NMI input on a TM4C129DNCPDT.

Requirement:

  • PD7 should be idle low.
  • When PD7 transitions from low to high (rising edge), the MCU should enter the NMI handler.
  • Inside the NMI handler, I want to execute some application code such as incrementing a counter and driving an output pin.

I followed the NMI configuration discussed here:

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1009876/sw-ek-tm4c1294xl-nmi

My PD7 initialization is:

HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= GPIO_PIN_7;

GPIOPinConfigure(GPIO_PD7_NMI);

GPIOPadConfigSet(GPIO_PORTD_BASE,
                 GPIO_PIN_7,
                 GPIO_STRENGTH_2MA,
                 GPIO_PIN_TYPE_STD_WPD);

GPIODirModeSet(GPIO_PORTD_BASE,
               GPIO_PIN_7,
               GPIO_DIR_MODE_HW);

My NMI handler is:

static void nmiHandler(UArg arg)
{
    SysCtlNMIClear(SysCtlNMIStatus());

    SysCtlDelay(5);

    putsUserNull("\nNMI Detected");

    counnt++;

    GPIOPinWrite(GPIO_PORTM_BASE,
                 GPIO_PIN_3,
                 GPIO_PIN_3);
}

However, the NMI handler is never entered when PD7 transitions from low to high.

My questions are:

  1. Does the TM4C1294 NMI input support rising-edge detection, or is it level-sensitive only?
  2. Is additional NMI configuration required beyond assigning PD7 to GPIO_PD7_NMI?
  3. Does the NMI handler need to be registered in the vector table differently from a normal interrupt?
  4. Is SysCtlNMIClear() sufficient, or are there additional status bits that must be cleared?
  5. Is the weak pull-down configuration (GPIO_PIN_TYPE_STD_WPD) appropriate for an idle-low NMI input?

Any example showing a working PD7-to-NMI configuration would be appreciated.

  • Hello,

    1. It is only able to determine if the pin is high. However you should be able to use this for rising edge detection.

    2.you will also need to use the commit control registers to lock the NMI pin

    3. The NMI would just generate a different type of interrupt instead nothing else needs to be configured.

    4. That should be good

    5. It would be a strong pull down resistor (20.5 ohms) if you're using the internal pull-down resistor.

  • Can you give a example code of initialization of nmi interrupt in PD7 and how to configure nmi_Handler function with 

  • For Us we configured the nmi interrupt. We are giving a high voltage supply to the pin for 5 sec. Due that the nmi handler function triggering continusily and after some time watchdog will reset the IC. We want a situation like The interrupt handler should work one time only and need to jump out of it. We are clearing the interrupt with 

    SysCtlNMIClear(SysCtlNMIStatus());
    
        SysCtlDelay(5); . But the compailer continuously jumping in to the nmihandler function
  • Hi Sarath,

    Sorry for the delays. The best way to go about this would be to configure the NMI handler to remove the pin configuration after the NMI has been triggered. to do this you can read the NMIC register NMI handler.

    Try this code in the NMI handler:

     uint32_t nmiSource = HWREG(SYSCTL_NMIC);
        if (nmiSource & SYSCTL_NMIC_EXTERNAL)
        {
            // 2. Unlock the GPIO commit control for PD7
            HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;  // 0x4C4F434B
            HWREG(GPIO_PORTD_BASE + GPIO_O_CR)  |= 0x80;           // Enable commit for bit 7
    
            // 3. Disable the NMI alternate function on PD7 (revert to GPIO)
            HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) &= ~0x80;
    
            // 4. Clear the PCTL field for PD7 (set mux to 0 = GPIO)
            HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) &= ~0xF0000000;
    
            // 5. Optionally disable digital enable to fully tri-state the pin
            // HWREG(GPIO_PORTD_BASE + GPIO_O_DEN) &= ~0x80;
    
            // 6. Re-lock the commit control
            HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0;
    
            // 7. Clear the NMI source
            SysCtlNMIClear(SYSCTL_NMI_EXTERNAL);
    
            // --- Handle your edge event here ---
        }