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.

Naughty Nested ISR

Other Parts Discussed in Thread: MSP430G2553

The G2 LaunchPad has two LEDs and two push buttons. This thing below tests them. But the ISR is naughty.

#include <msp430.h>

void main(void)
{
  WDTCTL = WDTPW | WDTHOLD;

  P1OUT = BIT3;              // S2 push button
  P1DIR = BIT6 | BIT0;       // green LED, red LED
  P1REN = BIT3;              // pull-up with internal resistor

  P1IE = BIT3;               // S2
  P1IFG = 0;

  _BIS_SR (GIE);
  while (1);
}

#pragma vector = PORT1_VECTOR
__interrupt void naughty (void)
{
  P1IFG <<= 1;
  P1IE <<= 1;
  __delay_cycles (100000);
  P1OUT |= BIT0;             // red LED on  
  __delay_cycles (400000);
  P1OUT &= ~BIT0;            // red LED off
  _BIS_SR (GIE);
  __delay_cycles (100000);
  P1OUT |= BIT6;             // green LED on
  __delay_cycles (400000);
  P1OUT &= ~BIT6;            // green LED off
}

  • Lol nice one! What are you smoking to think of shifting IFG?

  • old_cow_yellow said:
    But the ISR is naughty.

    Yes, it is. Once the ISR is called, it will 'fake' and interrupt on the next pin by shifting P1IFG (and P1IE). So if you press the button on P1.3, the ISR will be called 5 times in a row, until P1IFG and P1IE contents have been shifted out into the void. After this, the ISR won't be called ever again, as P1IE is clear then.

    Also, never do busy-waiting loops inside an ISR. It's a death sin. ISR's are there to immediately react on a n event, and then exit as fast as possible. NO busy-waiting of any kind. Never.

  • Jens-Michael Gross said:
    NO busy-waiting of any kind. Never.

    Never say never :) Obviously I kind of agree but let me clarify where I see using delay/poll cycles in the ISR.

    If ISR serve some external logic I/O and you know that interrupt exit/entry time takes longer than to wait or poll flag for couple of CPU cycles needed - then why not. Especially if timing is critical and using ISR reentry approach could be "too late - does not work" approach.

  • O Lord, forgive me for my transgression!

    #include <msp430g2553.h>
    volatile int software_flag;

    void main(void)
    {
      WDTCTL = WDTPW | WDTHOLD;

      P1OUT = BIT3;              // S2 push button
      P1DIR = BIT6 | BIT0;       // green LED, red LED
      P1REN = BIT3;              // pull-up with internal resistor

      P1IE = BIT3;               // S2
      P1IFG = 0;

      _BIS_SR (GIE);
      while (1)
      {
        if (software_flag)
        {
          software_flag <<= 1;
          __delay_cycles (100000);
          P1OUT |= BIT0;             // red LED on  
          __delay_cycles (400000);
          P1OUT &= ~BIT0;            // red LED off
          P1IFG = software_flag;
          P1IE = software_flag;
          __delay_cycles (100000);
          P1OUT |= BIT6;             // green LED on
          __delay_cycles (400000);
          P1OUT &= ~BIT6;            // green LED off
        }
      }
    }

    #pragma vector = PORT1_VECTOR
    __interrupt void repent (void)
    {
      software_flag = P1IFG;
      P1IFG = 0;
    }

  • old_cow_yellow said:
    O Lord, forgive me for my transgression!

    You may call me Jens-Michael :)

    Well, we gurus should give good example(s), as people tend to take our output more serious than others'.

    @Ilmars: I agree that under this specific condition, a delay inside the ISR is an optimization of the 'correct' implementation and may(!) be okay. Just like the while(1) inside an ISR when the loop covers a switch of an IV register that contains an exit on case 0, so multiple interrupts are handled without exiting the ISR.
    However, even in this case, it should be considered that other interrupts are blocked while you spend extra time in this ISR. It should be pondered whether this is acceptable. And not carelessly done.

**Attention** This is a public forum