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.

CCS/MSP430F5529: Nested interrupts

Part Number: MSP430F5529

Tool/software: Code Composer Studio

I am basically trying to make a nested interrupt with this one.  I have the WDT ISR working correctly with the correct timing, but the PORT2_ISR doesn't call right (or at all I think).  I can uncomment line 27 and comment line 26, and the LED will toggle perfectly.  When I try to do it with the nested ISR, however, it does nothing.

#include <msp430.h>

int i = 0;

void main(void)
{
    WDTCTL = WDTPW | WDTSSEL__SMCLK | WDTIS__512 | WDTTMSEL;    // Set WDT 0.5ms interval
    P4DIR |= BIT7;              // Set P1.0 to output direction (LED2)
    P4OUT &= ~BIT7;             // LED2 initially OFF
    SFRIE1 |= WDTIE;            // Enable WDT interrupt
    _BIS_SR(LPM0_bits + GIE);   // Enter LPM0 w/ interrupt
    P2IE |= BIT1;               // enable interrupt at P2.1
    P2IES |= BIT1;              // enable hi->lo edge for interrupt
    P2IFG &= ~BIT1;             // clear any erroneous interrupt flag
}

// Watchdog Timer Interrupt Service Routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
    if(i <1000)
        i++;
    else
    {
        i = 0;
        P2IFG |= BIT1;
        //P4OUT ^= BIT7;
    }
}

#pragma vector = PORT2_VECTOR       //SW1 ISR
__interrupt void PORT2_ISR(void)
{
    P2IFG &= ~BIT1; // Clear the flag
    P4OUT ^= BIT7;  // Toggle LED2
}

  • As part of servicing an interrupt the processor clears GIE so if you want to be able to service another interrupt from within an ISR, you have to set GIE yourself.

  • Does this mean I need to repeat the line (_BIS_SR(LPM0_bits + GIE);   // Enter LPM0 w/ interrupt) inside the WDT ISR?

  • I tried setting it via _EINT(); inside the WDT ISR, but that did not work.

  • Here is my current (non-working) setup:

    #include <msp430.h>
    
    int i = 0;
    
    void main(void)
    {
        WDTCTL = WDTPW | WDTSSEL__SMCLK | WDTIS__512 | WDTTMSEL;    // Set WDT 0.5ms interval
        P4DIR |= BIT7;              // Set P1.0 to output direction (LED2)
        P4OUT &= ~BIT7;             // LED2 initially OFF
        SFRIE1 |= WDTIE;            // Enable WDT interrupt
        _BIS_SR(LPM0_bits + GIE);   // Enter LPM0 w/ interrupt
        P2IE |= BIT1;               // enable interrupt at P2.1
        P2IES |= BIT1;              // enable hi->lo edge for interrupt
        P2IFG &= ~BIT1;             // clear any erroneous interrupt flag
    }
    
    // Watchdog Timer Interrupt Service Routine
    #pragma vector=WDT_VECTOR
    __interrupt void watchdog_timer(void)
    {
        _EINT();    // Reset GIE
        if(i <1000)
            i++;
        else
        {
            i = 0;
            P2IFG |= BIT1;  //Set flag for SW1
        }
    }
    
    #pragma vector = PORT2_VECTOR       //SW1 ISR
    __interrupt void PORT2_ISR(void)
    {
        P2IFG &= ~BIT1; // Clear the flag
        P4OUT ^= BIT7;  // Toggle LED2
    }
    

  • __EINT() is the same as _BIS_SR(GIE)

    Your code configuring the port interrupts is never executed because you enter LPM0 before that and have no means of exiting it. Also, you should do something at the end of main() rather than rely on the startup code to do something reasonable on exit. A simple while(1); would do.

  • I didn't think about LPMO being a problem here.  Simply removing the LPMO setting fixed it.  Thanks a bunch!

**Attention** This is a public forum