Jump to content
43oh

Can WDT interrupt and NMI interrupt be armed simultaneously?


Recommended Posts

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

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...