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.

MSP430F5438A: Port interrupt

Part Number: MSP430F5438A

Hi,

We have a problem with spurious GPIO interrupts on a custom board running MSP430F5438A.
Most Port 1 & 2 pins have PxIE enabled and different PxIES depending on connected peripherals.
Toggling pin P1.2 at ~1KHz accelerates/causes the issue where multiple IFG's on both ports has been set.

By testing/logging the system we've found the following pseudo code sequence when the issue happen.

//////////////////////////////////////////////////////////////////////////////////////////////

volatile unsigned int g_cnt = 0;
volatile unsigned char g_save_1 = 0;
volatile unsigned char g_save_2 = 0;

// 1. Main enters low power mode here
__bis_SR_register( LPM3_bits + GIE );

// 2. Port 1 IRQ
__interrupt void Port1( void )
{
  if (P1IFG & 0x04)
  {
    g_cnt++;
    P1IFG &= ~0x04;
  }
  else
  {
    // P1 registry at this point:
    // IN=0x32, OUT=0x32, DIR=0x00, SEL=0x00, REN=0x7A, IES=0x10, IE=0x3E, IFG=0x11

    g_save_1 = (P1IFG & P1IE);
    P1IFG = 0;
    __low_power_mode_off_on_exit();
}
}

// 3. Port 2 IRQ
__interrupt void Port2( void )
{
  // P2 registry at this point:
  // IN=0xAA OUT=0xAA DIR=0x40 SEL=0x00 REN=0xBF IES=0xAA IE=0xBF IFG=0xAA

  g_save_2 = (P2IFG & P2IE);

  P2IFG = 0;
  __low_power_mode_off_on_exit();
}

// 4. Main is back from low power mode here ... both Port 1 & 2 interrupt routines has been executed
if (g_save_1 || g_save_2)
{
  // Take action ...
}

///////////////////////////////////////////////////

By measurement we cannot see any real level transitions on pins that would explain the multiple PxIFGs
Does anyone have a suggestion on what could cause this problem?

We have two hardware designs that are schematically identical (to 99%) but mostly differs in layout.
The problem has only been visible on one board design so far ...

Kind regards, TMA

  • Hello,

    Are you enabling interrupts on pins that you use for interrupts? Also, are you clearing the interrupt flags immediately after enabling the interrupts for each IO pin and are you clearing the interrupt flags in the ISRs? According to the user's guide, writing to P1OUT, P1DIR, P1REN, P2OUT, P2DIR, or P2REN can result in setting the corresponding P1IFG or P2IFG flags.

    /* --COPYRIGHT--,BSD_EX
     * Copyright (c) 2012, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *******************************************************************************
     * 
     *                       MSP430 CODE EXAMPLE DISCLAIMER
     *
     * MSP430 code examples are self-contained low-level programs that typically
     * demonstrate a single peripheral function or device feature in a highly
     * concise manner. For this the code may rely on the device's power-on default
     * register values and settings such as the clock configuration and care must
     * be taken when combining code from several examples to avoid potential side
     * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
     * for an API functional library-approach to peripheral configuration.
     *
     * --/COPYRIGHT--*/
    //******************************************************************************
    //  MSP430F543xA Demo - Software Port Interrupt Service on P1.4 from LPM4 with
    //                    Internal Pull-up Resistance Enabled
    //
    //  Description: A hi "TO" low transition on P1.4 will trigger P1_ISR which,
    //  toggles P1.0. P1.4 is internally enabled to pull-up. Normal mode is
    //  LPM4 ~ 0.1uA. LPM4 current can be measured with the LED removed, all
    //  unused Px.x configured as output or inputs pulled high or low.
    //  ACLK = n/a, MCLK = SMCLK = default DCO
    //
    //               MSP430F5438A
    //            -----------------
    //        /|\|              XIN|-
    //         | |                 |
    //         --|RST          XOUT|-
    //     /|\   |                 |
    //      --o--|P1.4         P1.0|-->LED
    //     \|/
    //
    //   M. Morales
    //   Texas Instruments Inc.
    //   June 2009
    //   Built with CCE Version: 3.2.2 and IAR Embedded Workbench Version: 4.11B
    //******************************************************************************
    
    #include <msp430.h>
    
    int main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
      P1DIR |= 0x01;                            // Set P1.0 to output direction
      P1REN |= 0x10;                            // Enable P1.4 internal resistance
      P1OUT |= 0x10;                            // Set P1.4 as pull-Up resistance
      P1IE |= 0x10;                             // P1.4 interrupt enabled
      P1IES |= 0x10;                            // P1.4 Hi/Lo edge
      P1IFG &= ~0x10;                           // P1.4 IFG cleared
    
      __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4 w/interrupt
      __no_operation();                         // For debugger
    }
    
    // Port 1 interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
    #else
    #error Compiler not supported!
    #endif
    {
      P1OUT ^= 0x01;                            // P1.0 = toggle
      P1IFG &= ~0x010;                          // P1.4 IFG cleared
    }