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.

NESTED INTERRUPTS

Other Parts Discussed in Thread: MSP430G2553

HELLO,

I HAVE A QUERY REGARDING NESTED INTERRUPTS IN MSP430G2553. I HAVE WRITTEN A SIMPLE CODE, AND IT IS NOT WORKING THAT ACCURATELY. SOMETIMES IT PRODUCES WRONG OUTPUT. THE CODE IS AS FOLLOWS:

/*test: HERE WE NEST UP THE INTERRUPTS. THAT IS ONE INTERRUPT WITHIN OTHER.*/
/*LET P1.1 TO P1.4 BE INPUTS, AND P1.0,P1.5 TO P1.7 BE OUTPUTS.*/
#include<msp430g2553.h>
void main(void)
{
WDTCTL= WDTPW+WDTHOLD;
P1DIR&=~(BIT1+BIT2+BIT3+BIT4);
P1SEL&=~(BIT1+BIT2+BIT3+BIT4);
P1IN|=(BIT1+BIT2+BIT3+BIT4);
P1REN|=(BIT1+BIT2+BIT3+BIT4);
P1DIR|=(BIT0+BIT5+BIT6+BIT7);
P1OUT&=~(BIT0+BIT5+BIT6+BIT7);
P1IE|=(BIT1+BIT2+BIT3+BIT4);
P1IFG&=~(BIT1+BIT2+BIT3+BIT4);
_BIS_SR(GIE);
}
#pragma vector=PORT1_VECTOR
__interrupt void port1(void)
{
if((P1IN & BIT1)==0)
{
_BIS_SR(GIE);
P1IFG&=~BIT1;
for(;;){
P1OUT^=BIT0;
__delay_cycles(100000);
}
}
if((P1IN & BIT2)==0)
{
_BIS_SR(GIE);
int i=0;
P1IFG&=~BIT2;
for(i=0;i<=100;i++){
P1OUT^=BIT5;
__delay_cycles(100000);
}
}
if((P1IN & BIT3)==0)
{
_BIS_SR(GIE);
int j=0;
P1IFG&=~BIT3;
for(j=0;j<=50;j++){
P1OUT^=BIT6;
__delay_cycles(100000);
}
}
if((P1IN & BIT4)==0)
{
_BIS_SR(GIE);
int k=0;
P1IFG&=~BIT4;
for(k=0;k<=50;k++){
P1OUT^=BIT7;
__delay_cycles(100000);
}
}
}

PLEASE DISCUSS WHETHER THE CODE IS CORRECT, STACK INFORMATION, STACK SIZE, REASON FOR GARBAGE OUTPUT AT SOMETIME, PRIORITY ASPECTS, PRIORITY OF PINS WITHIN A PORT, HOW TO SET PRIORITY WITHIN SAME PORT FOR DIFFERENT PINS.

  • This code re-enables interrupts (GIE) before clearing the interrupt condition (P1IFG) that triggered the ISR.

    I would expect the first P1 trigger to cause it to loop through the ISR, walking over the stack and anything else in its way. The only reason it appears to work is that the ISR never returns.


    Incidentally, this main() function "falls off the end" and returns. I forget what the CCS library does in this case, but this is at best a poor practice.

  • How do you make P1.1, P1.2, P1.3, or P1.4 go low? If you use things like push buttons, the  contacts will "bounce". Even after you fixed the problems Bruce McKenney pointed out, you will still have other problems.

    The interrupts are caused by "edges", and your ISR tests for "levels". With a "bouncing" signal, your ISR becomes unpredictable.

    The ISR probably needs to push a few register on to the stack. Thus for every yet-to-finish interrupt, the stack will grow by 2+a few words. P1.1 interrupt can never finish (it is an infinity loop), it uses the stack as a one-way-street.

  • Thanks for the reply.

    can u give me a simple perfect example of nested interrupts?, so that i can make corrections in my program.

    please help.

    Thanks and regards:

    Gurumoorthy

  • Hello,

    This is the modified version of the above code. This appears to work fine. But please verify this for me. Switch bouncing issue has been solved with a low level strategy. Please discuss the bug in the code if any.

    /*test: HERE WE NEST UP THE INTERRUPTS. THAT IS ONE INTERRUPT WITHIN OTHER.*/
    /*LET P1.1 TO P1.4 BE INPUTS, AND P1.0,P1.5 TO P1.7 BE OUTPUTS.*/
    #include<msp430g2553.h>
    void main(void)
    {
    WDTCTL= WDTPW+WDTHOLD;
    P1DIR&=~(BIT1+BIT2+BIT3+BIT4);
    P1SEL&=~(BIT1+BIT2+BIT3+BIT4);
    P1IN|=(BIT1+BIT2+BIT3+BIT4);
    P1REN|=(BIT1+BIT2+BIT3+BIT4);
    P1DIR|=(BIT0+BIT5+BIT6+BIT7);
    P1OUT&=~(BIT0+BIT5+BIT6+BIT7);
    P1IE|=(BIT1+BIT2+BIT3+BIT4);
    P1IFG&=~(BIT1+BIT2+BIT3+BIT4);
    _BIS_SR(GIE);
    }
    #pragma vector=PORT1_VECTOR
    __interrupt void port1(void)
    {
    if((P1IN & BIT1)==0)
    {
    int h=0;
    __delay_cycles(3000000);
    _BIS_SR(GIE);
    P1IFG&=~BIT1;
    for(h=0;h<20;h++){
    P1OUT^=BIT0;
    __delay_cycles(1000000);
    }
    }
    if((P1IN & BIT2)==0)
    {
    __delay_cycles(3000000);
    _BIS_SR(GIE);
    int i=0;
    P1IFG&=~BIT2;
    for(i=0;i<20;i++){
    P1OUT^=BIT5;
    __delay_cycles(1000000);
    }
    }
    if((P1IN & BIT3)==0)
    {
    __delay_cycles(3000000);
    _BIS_SR(GIE);
    int j=0;
    P1IFG&=~BIT3;
    for(j=0;j<20;j++){
    P1OUT^=BIT6;
    __delay_cycles(1000000);
    }
    }
    if((P1IN & BIT4)==0)
    {
    __delay_cycles(3000000);
    _BIS_SR(GIE);
    int k=0;
    P1IFG&=~BIT4;
    for(k=0;k<20;k++){
    P1OUT^=BIT7;
    __delay_cycles(1000000);
    }
    }
    }

  • GURU MOORTHY said:
    can u give me a simple perfect example of nested interrupts?, so that i can make corrections in my program.

    Do you need to solve some problem which you think can be done using nested interrupts or your aim is to demonstrate properly working nested, recursive interrupts?

    Usually you don't do recursive nested interrupts of single source - because it is safe way to programming hell which in your case you are walking right now, especially taking in account long delays in your ISR code which is very bad style of coding.

  • This code doesn't fix the original problem (setting GIE before clearing P1IFG), so the ISR (still) just recurses forever (without doing any work) and walking completely over the stack.

    This is separate from the question of switch bounce, which (as O_C_Y points out) will be your next obstacle.

  • GURU MOORTHY said:
    #pragma vector=PORT1_VECTOR
    __interrupt void port1(void)
    [...]
    __delay_cycles(3000000);
    _BIS_SR(GIE);


    [...]

    Two death sins in two lines.

    Never do any busy-waiting inside an ISR. ISRs are fast-in, fast-out. They react on events so the main code doesn't have to check constantly for them and may even go to sleep. But except for setting a few flags or initiating something, ISRs should never do time-consuming things, calculations or (worst!) do any busy-waiting.

    Also, never ever set GIE inside an ISR. NEVER! There is no acceptable reason for doing this. You're calling for problems. (well, and you got them promptly)
    When you have enough expertise to handle nested and reentrant ISRs, you will also have the expertise to see that you don't need it. Until then, simply don't do it.

**Attention** This is a public forum