Quantcast
Channel: MSP430 Technical Forums
Viewing all articles
Browse latest Browse all 2077

Can WDT interrupt and NMI interrupt be armed simultaneously?

$
0
0

Colleagues,

 

The circuit that I'm working on is based on an 8-pin MSP430G2210.  The RST#/NMI serves as a soft on/off switch.  While the device is on, it will use the WDT in the interval mode for cyclic sleep (at least, that's my intent).  I was able to make the NMI# interrupt work to wake up from LPM4.  Separately, I was able to make the WDT interrupt work to wake up from LPM3.  But I wasn't able to make them work together.

// PURPOSE: Keep track of button presses
#pragma vector=NMI_VECTOR
__interrupt void nmi_isr(void) {
    g_nmiFlag = true;                           // set a flag, which will be examined in the main() loop
    for (volatile unsigned int i = 20000;  i != 0;  --i);   // allow some time for contact bouncing to settle
    IFG1 &= ~NMIIFG;                            // re-clear NMI flag if there was bouncing
    IE1 |= NMIIE;                               // enable NMI
    __bic_SR_register_on_exit(LPM4_bits);       // exit the LPM on return from the ISR
}

// PURPOSE: Allow cyclic wake up.
#pragma vector=WDT_VECTOR
__interrupt void wdt_isr(void) {
    __bic_SR_register_on_exit(LPM3_bits);       // exit the LPM on return from the ISR
}


int main(void) {
    // Initialize the MSP430
    P1DIR |=  0x04;                 // LED. Set P1.2 to output direction
    P1OUT |=  0x04;                 // LED off
    P1OUT &= ~0x20;                 // Make sure that sensors are powered down
    P1DIR |=  0x20;

    while (1) {
        // Enter the Dormant state
        WDTCTL = WDTPW
            | WDTHOLD       // WDT off
            | WDTNMI        // NMI (instead of reset).  See section 10.3.1 in [1] and fig. 2-1 in [1].
            | WDTNMIES;     // NMI on falling edge
        IFG1 &= ~NMIIFG;    // make sure that the interrupt flag is not set
        IE1 |=  NMIIE;      // Enable NMI
        __bis_SR_register(LPM4_bits | GIE);     // Enter LPM4 w/interrupt
        // Button will cause the interrupt, which will end the dormant state.  See NMI ISR.
        g_nmiFlag = false;


        // WDT is used for cyclic sleep. Set WDT to interval mode.
    BCSCTL1 |= DIVA_1;  // ACLK/2
    BCSCTL3 |= LFXT1S_2;    // ACLK = VLO
        WDTCTL = WDTPW
            | WDTTMSEL  // WDT in interval mode
        | WDTCNTCL  // clear counter
        | WDTSSEL   // clock WDT from ACLK
            | WDTNMI;   // NMI (instead of reset).  See section 10.3.1 in [1] and fig. 2-1 in [1].
        IE1 |= WDTIE;   // Enable WDT interrupt

        volatile bool remainAware = true;
        while (remainAware) {
            __bis_SR_register(LPM3_bits | GIE); // nap
            // awoken by the WDT interrupt
            // <bring-up>
            P1OUT &= ~0x04;                         // Set P1.0 LED on
            for (volatile int i = 5000; i>0; i--);   // Delay
            P1OUT |=  0x04;                         // Reset P1.0 LED off
            // </bring-up>

            // Did user press the button to deactivate the unit?
            if (g_nmiFlag == true) {
                remainAware = false;
            }
        }
    }

    return 0;
}

The LED blinks only once after the NMI is created with a button.  I expected that the WDT timer would make the LED blink repeatedly.  What am I missing?

 

Any suggestion, insight or reference is really appreciated!

 

Cheers,
- Nick


Viewing all articles
Browse latest Browse all 2077

Trending Articles