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.

MSP430FR2355: P1IN not capturing???

Part Number: MSP430FR2355

Hello.

I am trying to capture every 1/10 second P2IN and PI1N....TIMER2 runs in the background and collects pin history.  In the event a keystroke PORT1 VECTOR is hit a 2 second timer (TIMER0 ISR) is started.  After the 2 second timer expires I immediately disable TIMER2 ISR and look at history array.  It NEVER shows change in the P1IN status...P1IN is configured as an input with pulldowns.  In the event I put a breakpoint in TIMER2 ISR where I reset the pointer to the beginning of history for rollover I can see changes in history showing it has read P1IN....please can someone explain to me why when I break after disabling TIMER2 in TIMER0 that the history array reverts back to 00???  I am using an MSP430FR2355EVM board.  One more quick blurb....If I hold 3.3V to one of P1 pins for the duration of 2 seconds all history shows it captured...I however would like to know why >1/10s and < 2s I cannot see any captures?

#pragma vector=TIMER2_B0_VECTOR  //CCIE every tenth of a second
__interrupt void m100SecondTimerB2(void)
//rolling counter...resets after 20 hits or at 2 sec. timer going off
{
    TB2CCR0 += TENTHSEC;
    *pHistory = ((unsigned)((P2IN << 8)|(P1IN)));
    *pHistory &= ~(0xF701); //mask unused pins
    pHistory++;
    if (pHistory > history + 19)
        pHistory = history;
}

/*#pragma vector=TIMER0_B0_VECTOR  //CCIE every tenth of a second
__interrupt void m100SecondTimer(void)
{
    TB0CCR0 += TENTHSEC;
    *pHistory = ((unsigned)((P2IN << 8)|(P1IN)));
    *pHistory &= ~(0xF701); //mask unused pins
    pHistory++;
}*/

#pragma vector=TIMER0_B1_VECTOR  //TBIE overflow every 2 seconds
__interrupt void twoSecondTimer(void)
{
    switch(__even_in_range(TB0IV,TB0IV_TBIFG))
    {
      case TB0IV_NONE:   break;               // No interrupt
      case TB0IV_TBCCR1: break;               // CCR1 not used
      case TB0IV_TBCCR2: break;               // CCR2 not used
      case TB0IV_TBIFG:                       // overflow
          remote = T;
          TB2CCTL0 &= ~CCIE;
          pHistory = history;
          __bic_SR_register_on_exit(LPM3_bits); //exit ISR and wake up, process in main
          break;
      default: break;
    }
}

//ISR for on/off buttons
#pragma vector=PORT1_VECTOR
__interrupt void indicatorButtons(void)
{
    launchTimerSeq();
    switch (__even_in_range(P1IV, 16))
    {
        case 4: //P1.1
            indicator ^= SW1;
            P1IFG &= ~BIT1;
            break;
        case 6: //P1.2
            indicator ^= SW2;
            P1IFG &= ~BIT2;
            break;
        case 8: //P1.3
            indicator ^= SW3;
            P1IFG &= ~BIT3;
            break;
        case 10: //P1.4
            indicator ^= SW4;
            P1IFG &= ~BIT4;
            break;
        case 12: //P1.5
            indicator ^= SW5;
            P1IFG &= ~BIT5;
            break;
        case 14: //P1.6
            indicator ^= SW6;
            P1IFG &= ~BIT6;
            break;
        case 16: //P1.7
            indicator ^= ALL;
            P1IFG &= ~BIT7;
            break;
        default:
            break;
    }
}

Any ideas....

Thank you

Steve

  • In what sense does the history "revert" to 0? Are there non-0 entries, but when you breakpoint they've all been cleared? Try setting a breakpoint at the second line of main() just in case there's a surprise reset.

    What sort of switches are attached to P1.x? Are they two-position or momentary? The PORT interrupts recognize changes, not levels, in switch state, Also, most physical switches require some form of debouncing.

  • Hi Bruce...

    I will do my best to answer....I have scaled down the project to understand this and attached the complete code (minus function details)..I'd be more than happy to send them as well.

    1.  History is zeroed out at the beginning per definition.....In this test code I do a memset after TIMERB0 goes off.  

    2.  If I break within TIMER2 at pHistory = history I see P1 changes.  But if I remove this breakpoint and place one within TIMER0 at pHistory = History all changes are gone and I see 0x00 (essentially the pulldowns from IOConfig macro)...If I change to pullups I would get them instead, that is 0xFE (bit 0 is an output).

    3. I reverted out of main and into TIMER0 because problem existed in main, so I'm backing up to the source here

    4.  Ok I'm using an EVAL board and I have no switches (yes I am aware of debounce).  I am just taking a jumper and tapping it along P1 pins to see them register the change every tenth of a second (ie record history).  I am aware that PORT1 VECTOR is purely Interrupt driven.

    5.  Basically what I am trying to do is have a running background (ie TIMER2) constantly surveying pins.  When a P1 IRQ goes off. I want to start the two second timer to validate if any of the pins have been asserted for 2 seconds.  Within main I will look at the history and either pass or fail on any pins that have had a 2 second hold.  I also don't want to lose the other pin status that I've captured that may be under 2 seconds as that has value also....Also once I wake in main and do this task I want to re-enable the switch settings..In this code you do not see me disable the P1 but in TIMER0 most likely I will to freeze the edges captured.

    Hope this helps....I'm really struggling with these PxIN....They are not that friendly to use....If I was only concerned with them TIMER2 works fine, but trying to grab edges off of P1 seems to blow everything up

    Thanks

    Steve

    #include <msp430.h>
    #include <string.h>
    #include <stdint.h>
    #include "rc.h"
    #include "LPRSradio.h"
    
    volatile unsigned int history[20] = {0}, *pHistory;
    volatile char indicator = 0xFE;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
        pHistory = &history[0];
        IOconfig;
        initClockTo16MHz();
        initTimerB0();
        initTimerB2();
        __bis_SR_register(LPM3_bits + GIE);
    }
    
    #pragma vector=TIMER2_B0_VECTOR  //CCIE every tenth of a second
    __interrupt void m100SecondTimerB2(void)
    //rolling counter...resets after 20 hits or at 2 sec. timer going off
    {
        TB2CCR0 += TENTHSEC;
        *pHistory = (unsigned)(P1IN);
        *pHistory &= ~(0x01); //mask unused pins
        pHistory++;
        if (pHistory > history + 19)
            pHistory = history;
    }
    
    #pragma vector=TIMER0_B1_VECTOR  //TBIE overflow every 2 seconds
    __interrupt void twoSecondTimer(void)
    {
        switch(__even_in_range(TB0IV,TB0IV_TBIFG))
        {
          case TB0IV_NONE:   break;               // No interrupt
          case TB0IV_TBCCR1: break;               // CCR1 not used
          case TB0IV_TBCCR2: break;               // CCR2 not used
          case TB0IV_TBIFG:                       // overflow
              pHistory = history;
              memset(history, 0, 20*sizeof(history));
              break;
          default: break;
        }
    }
    
    //ISR for on/off buttons
    #pragma vector=PORT1_VECTOR
    __interrupt void indicatorButtons(void)
    {
        TB2CCTL0 |= CCIE;
        launchTimerSeq();
        switch (__even_in_range(P1IV, 16))
        {
            case 4: //P1.1
                indicator ^= SW1;
                P1IFG &= ~BIT1;
                break;
            case 6: //P1.2
                indicator ^= SW2;
                P1IFG &= ~BIT2;
                break;
            case 8: //P1.3
                indicator ^= SW3;
                P1IFG &= ~BIT3;
                break;
            case 10: //P1.4
                indicator ^= SW4;
                P1IFG &= ~BIT4;
                break;
            case 12: //P1.5
                indicator ^= SW5;
                P1IFG &= ~BIT5;
                break;
            case 14: //P1.6
                indicator ^= SW6;
                P1IFG &= ~BIT6;
                break;
            case 16: //P1.7
                indicator ^= ALL;
                P1IFG &= ~BIT7;
                break;
            default:
                break;
        }
    }
    

  •  >         memset(history, 0, 20*sizeof(history));

    This looks suspicious. sizeof(history)==(20*2), so this runs far off the end. That may or may not bear on your symptom, but it's a good way to produce random results.

  • No sir....checked this as I initially had 20 down....turns out memset wants a byte in that field and history is an integer....When I placed a 20 there only half the array gets cleared out.

  • I recommend:

    >         memset(history, 0, sizeof(history));

  • Fair enough...I will give it a try but it still doesn't solve my problem....That line was put in the code late as an attempt to try things.....Any ideas about the PxIN?

  • I suggest you try it before you decide it doesn't fix anything. One possibility is that it is writing over pHistory, and you're logging down at location 0. This might cause a reset (which would trigger the breakpoint you set at main[2]) but in any case it will never count back up to &history[0].

    You mentioned that you were testing by touching a (3V3) wire to one of the P1.x pins. Keep in mind that you'll see bounce both when you touch the pin and when you remove the wire. You didn't show launchTimerSeq, but my guess is that it resets the timer (so you get the full 2 seconds). This will happen every time the pin bounces, so in general all of your history[] entries will be the same; if you remove the wire within 2 seconds all the entries will be 0. Try holding the wire in contact for the full 2 seconds.

    [Edit: Minor wording fix.]

  • Yes I came upon the fact I was coming into the P1 VECTOR multiple times....which I believe is a big issue .....I've since only allow the timer to launch once ......

    thank you for your help.

**Attention** This is a public forum