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.

MSP430G2202: different IFG2 behaviour depending on package

Part Number: MSP430G2202
Other Parts Discussed in Thread: TPS61221

Hello all

I have the interesting case where a MSP430G2202 behaves differently, depending on the package.

In a first THT design, I used a IN20 variant. A PIR sensor's signal is conditioned and converted to digital H/L. The micro is in LPM4 and wakes up on the rising edge on P2.7. The sensor circuitry works fine and I verified that there are no false-positives. The FW does the following.

BIT_CLEAR(P2IFG, GPIO_IR_DETECT_PIN);
BIT_SET(P2IE, GPIO_IR_DETECT_PIN);
__bis_SR_register(LPM4_bits);
// Zzz...
nextState = StateCheckUndervoltageLockout;

With:

void GpioInit() {
  // Make GPIOs input with pull down
  P1OUT = 0x00;
  P1REN = 0xff;
  P1DIR = 0x00;

  P2OUT = 0x00;
  P2REN = 0xff;
  P2DIR = 0x00;

  // Disable pull resistors on actively driven pins
  BIT_CLEAR(P2REN, GPIO_IR_DETECT_PIN);
  BIT_CLEAR(P1REN, GPIO_DAYLIGHT_DETECT_PIN);
 
...

  // Rising edge for IR detect signal
  BIT_CLEAR(P2IES, GPIO_IR_DETECT_PIN);
  BIT_CLEAR(P2SEL2, GPIO_IR_DETECT_PIN);
  BIT_CLEAR(P2SEL, GPIO_IR_DETECT_PIN);
}

and


#pragma vector=PORT2_VECTOR
__interrupt void Port2Isr(void) {

  switch (P2IFG) {

    case GPIO_IR_DETECT_PIN: {
      // Avoid getting stuck here
      GPIO_EDGE_INTERRUPT_DISABLE();
      BIT_CLEAR(P2IFG, GPIO_IR_DETECT_PIN);
      __bic_SR_register_on_exit(LPM4_bits);
      break;
    }

    default: {
      break;
    }
  }
}


The micro runs on DCO (1 MHz), WDT is turned off. No other interrupt sources are enabled.

And this works perfectly fine. It has been running on three prototypes during weeks.

On a second batch, an IRSA16 package was used. The sensor circuitry works as desired, which I verified. But the micro wakes up immediately after being put into LPM4. Even if the sensor is turned towards a wall with no thermal movement at all, it keeps turning on. My first guess was a different behaviour of XIN/XOUT, as they look a bit messy in the datasheet. With the debugger (MSP430G2 launchpad) attached, I stepped through the above lines. And it worked! No false interrupt was detected, the micro would stay asleep until I put my hand in front of the sensor. As soon as I let it run freely, the micro forgets about LPM4 and keeps waking up again.


CCS: 12.4.0.00007
OS: Linux Mint 20.3 Cinnamon
Compiler: TI v21.6.1.LTS  

Does anybody have an idea, where this might come from? Obviously it must be linked to the debugger.

Schematics:
 
Nachtlicht_Schema_Rev_2.00.pdf

  • To avoid some lingering doubts, I suggest you start by adding these to GpioInit():

    > P2SEL = 0;   // P2.6/7 as GPIO, not LFXT1

    > BCSCTL3 |= LFXT1S_2;  // ACLK=VLOCLK to really disable LFXT1

    XIN/XOUT are linked in odd ways, so if you disable the LFXT function on P2.7, you should do the same on P2.6.

    The second line is just extra insurance, inspired by the (new?) Note at the beginning of user guide (SLAU144K) Sec 8.1.

    ----

    You mention that the LPM4 wakes up immediately. Is the Port2 ISR called in that case?

  • Hi Bruce, thank you for the quick reply. I tried your solution, but it didn't change anything. I'll try to strip down the FW to as few lines as possible and come back with it.

  • to completely answer your question, yes it is P2 ISR.

    4643.main.c
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include "App.h"
    #include "Gpio.h"
    #include "System.h"
    
    int main(void) {
    
      // Stop watchdog
      WDTCTL = WDTPW + WDTHOLD;
    
      // Select lowest DCOx and MODx settings
      DCOCTL = 0;
      // Set range
      BCSCTL1 = CALBC1_1MHZ;
      // Set DCO step + modulation
      DCOCTL = CALDCO_1MHZ;
    
      BCSCTL3 |= LFXT1S_2;
      P2SEL = 0;
      P2SEL2 = 0;
    
      // Make GPIOs input with pull down
      P1OUT = 0x00;
      P1REN = 0xff;
      P1DIR = 0x00;
    
      P2OUT = 0x00;
      P2REN = 0xff;
      P2DIR = 0x00;
    
      // P2.6 LED, low active
      BIT_SET(P2OUT, BIT6);
      BIT_CLEAR(P2REN, BIT6);
      BIT_SET(P2DIR, BIT6);
    
      // P1.2 INFO LED, high active
      BIT_CLEAR(P1OUT, BIT2);
      BIT_CLEAR(P1REN, BIT2);
      BIT_SET(P1DIR, BIT2);
    
      // Rising edge for IR detect signal (P2.7)
      BIT_CLEAR(P2IES, GPIO_IR_DETECT_PIN);
      BIT_CLEAR(P2SEL2, GPIO_IR_DETECT_PIN);
      BIT_CLEAR(P2SEL, GPIO_IR_DETECT_PIN);
    
      __bis_SR_register(GIE);
    
      while(1) {
        BIT_CLEAR(P2IES, GPIO_IR_DETECT_PIN);
        BIT_CLEAR(P2IFG, GPIO_IR_DETECT_PIN);
        BIT_SET(P2IE, GPIO_IR_DETECT_PIN);
        __bis_SR_register(LPM4_bits);
    
        // Interrupt has been detected, turn on LED for a second
        BIT_SET(P1OUT, BIT2);
        _delay_cycles(1000000);
        BIT_CLEAR(P1OUT, BIT2);
    //    BIT_CLEAR(P2OUT, BIT6);
    //    _delay_cycles(1000000);
    //    BIT_SET(P2OUT, BIT6);
      }
    }
    
    #pragma vector=PORT2_VECTOR
    __interrupt void Port2Isr(void) {
    
      switch (P2IFG) {
    
        case GPIO_IR_DETECT_PIN: {
          // Avoid getting stuck in here
          BIT_CLEAR(P2IE, GPIO_IR_DETECT_PIN);
          BIT_CLEAR(P2IFG, GPIO_IR_DETECT_PIN);
          __bic_SR_register_on_exit(LPM4_bits);
          break;
        }
    
        default: {
          break;
        }
      }
    }
    


    I condensed it down to one small main function and the ISR.

    • When running the coded appended, it works all good. The P1.2 LED illuminates shortly, as soon as you move in front of the sensor. This works repeatedly.
    • When reactivating lines 60-62, the two LEDs illimunate one after another, but just once. I flashed the code using the launchpad and disconnected it. Also after a power cycle, the functionality stays one-shot.

    So if you see anything I do wrong, I'd be glad to know.

    But assuming my code is correct, it leaves the following causes:

    • ESD damage on launchpad/debugger
    • turn-off of P2.6 LED (55mA) causes some funny oscillation on supply voltage, leading to this behaviour of MCU
    • some internal misbehaviour of P2.6/7 we are not aware of.
  • The 55mA LED caught my eye. Your schematic shows it being powered by a battery (via TPS61221), but you mentioned a Launchpad. Is that how you're powering it?

    I ask since as I recall the (old) G2 Launchpads were only good for about 50mA for everything. The (newer) G2ET Launchpad has a TPS73533 which claims to be capable of 400mA (though I've never pushed one that far).

  • turn-off of P2.6 LED (55mA) causes some funny oscillation on supply voltage, leading to this behaviour of MCU

    This seems unlikely given Figure 15 (load transient response) in the TPS61221 data sheet.

  • >  switch (P2IFG) {

    Switching P2OUT.6 (to turn on/off the LED) will set P2IFG.6, so this switch() won't do what you expect. Try instead:

    >  switch (P2IFG & GPIO_IR_DETECT_PIN) {

  • The 55mA LED caught my eye. Your schematic shows it being powered by a battery (via TPS61221), but you mentioned a Launchpad. Is that how you're powering it?

    No, it's battery powered. The connection to the launchpad consists of GND + SBW.

    This seems unlikely given Figure 15 (load transient response) in the TPS61221 data sheet.

    Yes. The supply should be ok. But I haven't measured it with the oscilloscope yet.

    >  switch (P2IFG) {

    Switching P2OUT.6 (to turn on/off the LED) will set P2IFG.6, so this switch() won't do what you expect. Try instead:

    >  switch (P2IFG & GPIO_IR_DETECT_PIN) {

    The complex trivialities. More than one flags can be set at a time. Thank you, I fixed it.

    As I only set the PIR GPIO pin P2.7 in the P2IE, P2.6 shouldn't be able to trigger an interrupt. Correct?


    After your code review I would exclude the FW as a cause for now. I will check the supply and the sensor circuitry to see what waveforms are actually present using an oscilloscope, as soon as I get back to work.

  • P2IFG.6=1 wouldn't trigger an interrupt, but it would cause the switch() not to "see" the P2IFG.7 interrupt (starting the second time through). This would result in the symptom you described.

    I see the same mistake in your original code fragment, but perhaps the (visible) symptom is different there.

  • The use of switch() is the mistake, not the argument.

    >  if (P2IFG & GPIO_IR_DETECT_PIN) {

    Use of a switch() makes sense on those parts that have a PxIV register.

  • I found the time to conduct the measurements I had promised earlier.

    First of all, the ISR was changed to

    #pragma vector=PORT2_VECTOR
    __interrupt void Port2Isr(void) {
    
      if(BIT_READ(P2IFG, GPIO_IR_DETECT_PIN) != 0) {
        // Avoid getting stuck here
        GPIO_EDGE_INTERRUPT_DISABLE();
        BIT_CLEAR(P2IFG, GPIO_IR_DETECT_PIN);
        SystemWakeup();
      }
    }


    Exchanging the Debugger (EXP-MSP430FR4133 --> EXP-MSP430G2) did not help.

    Furthermore I conducted measurements using our SDS6104A.
    U_Bat was 2.7 V. Environment was laboratory / office.

    To measure the PIR signals, connections were made as shown.
    Yes the ground (loop) wires flapping in the breeze are not optimal.
     
    Then the signals according to their label (schematics in first post).
    I moved my hand twice with a pause in between. Looks all good.
    And of course what you should always do first, the supply measurement.
    A SAP2500 active probe was used.
    3.3 V, C10 next to MSP430
    3.3VA, C22 which is part of LC filter.
    3.3VA, C38 next to the PIR opamp. Not too good, not too bad.
    On the left side we can see the ripple while one LED is illuminated.
    After the LED has been turned off, more ripple is observable.

    I realised that I should also measure the ripple while the micro is in LPM4. Maybe there is an ugly ripple caused by the low current consumption and discontinuous mode...

  • What is your symptom now? Before, it was a spin in the ISR since the IFG wasn't being cleared, but I expect your code change fixed that.

**Attention** This is a public forum