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.

The Eleventh I/O Pin for LaunchPad G2xx1

The LaunchPad and many other demo/experimental boards all have a push-button switch connected to the nRST/NMI pin. Can this switch be used as input during execution of Application firmware?

I made an attempt to do so and demonstrate it by turning on/off an LED controlled by P1.0 (another common feature of LaunchPand other demo/experimental boards). I would like to hear from you guys if I made any mistake or had any blind spot in this example code.

Please note that because nRST/NMI pin is also the SBWTDIO pin. Thus you should not press this push-button while you are using SBW.

/*******************************************************************************
*                     Demo Program for LaunchPad Board                         *
*             Using S1 at nRST/NMI Pin as Input for Application                *
*                                OCY Oct 2010                                  *
*******************************************************************************/
#include <msp430.h>
#define FLIP_HOLD (0x3300 | WDTHOLD) /* flip HOLD while preserving other bits */
//
#define S1_MAKE P1OUT |= BIT0 /* turn on LED1 for demo */
#define S1_BREAK P1OUT &= ~BIT0 /* turn off LED1 for demo */
//
void main (void)
{
  // We use the red LED1 at P1.0 to demostrate that we can detect
  //    the switch s1 at nRST/NMI pin as an input
  P1OUT &= ~BIT0;
  P1DIR |= BIT0;
  // The WDT will be used exclusively to debounce s1
  WDTCTL = WDTPW | WDTHOLD | WDTNMIES | WDTNMI;
  IFG1 &= ~(WDTIFG | NMIIFG);
  IE1 |= WDTIE | NMIIE;
  // The CPU is free to do other tasks, or go to sleep
  __bis_SR_register(CPUOFF | GIE);
}
//==============================================================================
// isr to detect make/break of s1 at the nRST/NMI pin
#pragma vector = NMI_VECTOR
__interrupt void nmi_isr(void)
{
  if (IFG1 & NMIIFG) // nmi caused by nRST/NMI pin
  {
    IFG1 &= ~NMIIFG;
    if (WDTCTL & WDTNMIES) // falling edge detected
    {
      S1_MAKE; // tell the rest of the world that s1 is depressed
      WDTCTL = WDT_MDLY_32 | WDTNMI; // debounce and detect rising edge
    }
    else // rising edge detected
    {
      S1_BREAK; // tell the rest of the world that s1 is released
      WDTCTL = WDT_MDLY_32 | WDTNMIES | WDTNMI; // debounce and detect falling edge
    }
  } // Note that NMIIE is cleared; wdt_isr will set NMIIE 32msec later
  else {/* add code here to handle other kinds of nmi, if any */}
}
//==============================================================================
// WDT is used exclusively to debounce s1 and re-enable NMIIE
#pragma vector = WDT_VECTOR
__interrupt void wdt_isr(void)
{
  WDTCTL ^= FLIP_HOLD; // Flip the HOLD bit only, others remain unchanged
  IFG1 &= NMIIFG; // It may have been set by switch bouncing, clear it
  IE1 |= NMIIE; // Now we can enable nmi to detect the next edge
}
//==============================================================================

  • Hi OKY,

    I'm still waiting for my Launchpads to arrive, so I'm currently unable to test your code in 'the real world'.

    NMI can for shure be used as an interrupt by one's application. I'm also sometimes (o.k. most of the times) miss-using the WDT as interval timer for debouncing or other short timing things, so nothing to comment on this.

    On first view your code looks o.k.. Maybe you should think about shortening the WDT interval time because many tactile switches were rated with 5ms bouncing time.

    Rgds
    aBUGSworstnightmare

  • Hello Nightmare;

    Thank you for your comments. My main concern is that both the NMI and the WDT interrupt disable themselves and enable the other guy. They both depend on the other guy to enable them again. I think it should work but I am a little nervous.

    As for the de-bouncing duration, it can be changed by selecting a different clock source or WDT setting. I just picked SMCLK with 15-bit WDT setting out of a hat. With the default DCO as SMCLK, that setting actually will be shorter than 32msec. The quality of the switch used determines the lower limit of the de-bouncing duration, user reaction time determines the upper limit. (I know I cannot press the button faster than 100msec and a woodpecker can do it in 50msec ;-)

**Attention** This is a public forum