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.

CCS/MSP430FR5994: Interrupts not firing when the buttons are pressed

Part Number: MSP430FR5994
Other Parts Discussed in Thread: MSP430WARE,

Tool/software: Code Composer Studio

Hello, 

I am very new to the MSP430 mcu family as well as serious embedded programming/design (I come from an arduino/rpi backround).

I have been looking at this code for the second consecutive day and still can't figure out what the problem could possibly be or where to start looking for it.

The concept of the code is to light a different on-board LED depending on which of the on-board buttons is pressed, but no matter what I try the interrupt doesn't seem to fire at all.

Appreciate any help, and be nice I bruise easy!

Here is my code:

#include <msp430.h>
#include <driverlib.h>
#include <gpio.h>
#include <stdio.h>
#include <string.h>

int main(void) {

    WDT_A_hold(WDT_A_BASE);        // Stop watchdog timer

        GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);         // Set Red LED output
        GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);      // Red LED off
        GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN1);         // Set Green LED output
        GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN1);      // Green LED off

        GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN6);                      // S1 P5.6: PxDIR, PxOUT and PxREN registers
        GPIO_selectInterruptEdge(GPIO_PORT_P5, GPIO_PIN6,GPIO_LOW_TO_HIGH_TRANSITION);      // S1 P5.6: PxIES register

        GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN5);                      // S2 P5.5: PxDIR, PxOUT and PxREN registers
        GPIO_selectInterruptEdge(GPIO_PORT_P5, GPIO_PIN5,GPIO_LOW_TO_HIGH_TRANSITION);      // S2 P5.5: PxIES register

    // Disable the GPIO power-on default high-impedance mode to activate previously configured port settings

        PMM_unlockLPM5();

    // Set all P5IFG to zero

        P5IFG = 0x00;

        GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN6);                                      // S1 P5.6: PxIE register
        GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN5);                                      // S2 P5.5: PxIE register

        __bis_SR_register(GIE);  // Enable all interrupts

        while(1) {;}
    }

    #pragma vector=PORT5_VECTOR
    __interrupt void Port_5(void)
    {

        switch (P5IFG)
        {
            case 0b01000000: // S1 P5.6 = 64: toggle red LED
            {
                P1OUT ^= BIT0;          // Toggle P1.0
                P5IFG &= ~BIT6;         // P5.6 clear interrupt flag
                break;
            }

            case 0b00100000: // S2 P5.5 = 32: toggle green LED
            {
                P1OUT ^= BIT1;          // Toggle P1.1
                P5IFG &= ~BIT5;         // P5.5 clear interrupt flag
                break;
            }

            default: // should not be here!
            {
                break;

            }
    }
}

  • switch (P5IFG)

    It's routine for P5IFG to have bits set which you aren't interested in, so you need to mask them with something like (P5IFG&(BIT5|BIT6)).

    But I'm going to suggest instead that you not use switch, but instead check the bits individually, something like:

    > if (P5IFG & BIT5)

    That way it will work correctly if you push both buttons.

    Unsolicited:

    Using GPIO_LOW_TO_HIGH_TRANSITION means you'll get an indication when the button is released, not when it is pushed.

    Eventually you'll have to deal with de-bouncing. This will show up as a brief blink when you push (release) the button.

  • First of all thanks for being on the watch Bruce, I noticed that you answered basically any other post I looked through before posting myself, you're doing honest work.

    I don't know why I didn't think of a masked interrupt but unfortunately, it wasn't the issue since I changed the ISR to this 

    #pragma vector=PORT5_VECTOR
        __interrupt void Port_5(void)
        {
    
            if (P5IFG & BIT6)
            {
                P1OUT ^= BIT0;          // Toggle P1.0
                P5IFG &= ~BIT6;         // P5.6 clear interrupt flag
            }
            else if (P5IFG & BIT5)
            {
                P1OUT ^= BIT1;          // Toggle P1.1
                P5IFG &= ~BIT5;         // P5.5 clear interrupt flag
            }
        }

    And still I get no change in the IFG of P5. 

    I run the code continuously and none of the button presses (or releases) triggers the ISR or changes anything in the P5 registers.

    I was starting to think of some sort of HW failure but I tried the same code on a spare msp430 and still got the same behaviour...

    Any other thoughts ? (Thanks again for your support)

  • Hello,

    Are you not getting any lights to turn on at all or is it an issue with consecutive presses?

    Also, have you tried to set print statements or debug breakpoints inside of your switch statement to see if it gets to the correct case?

    Luke 

  • I don't see anything obviously wrong, and I don't have my equipment here. 

    How can you tell it isn't working? (a) breakpoint in the ISR? (b) watching the LEDs? (c) other?

  • Hi Luke, thanks for replying.

    Yes the LEDs do not turn on at all not even a fade or anything.

    I haven't properly setup the code for debugging yet, but I expected it to be simple enough that I wouldn't have to...

    I will add breakpoints tomorrow.

  • Nothing looks wrong, so far I used method (b) but i obviously have to start properly debugging this because there is something clearly weird about it...

    I will revisit this in the morning, and answer on this thread asap.

  • I just tried this code on my Launchpad and it performed as expected -- LEDs toggle when each button is released. I see a bit of switch bounce -- sometimes the LED blinks very briefly or stays on (when it should go out) -- but it's generally right.

    One thing I'll mention, since I just tripped over it (again): When you disconnect the debugger, it may leave the MCU halted. If so, just push the RST button up at the top-left.

    How are you loading your code? If you're using CCS, you start out in the debugger, so you can step and set breakpoints immediately. For a first step, you probably don't need to "set up" the code at all.

  • Ok i tried debugging a bit this morning, but I think I'm doing something wrong.

    I watched all the registers in P5 during execution and the flag didn't change when the button is released...

    I am not really sure where I need to set the breakpoints to properly debug (full disclosure I was never taught how to properly debug so I am always eyballing it)

    But the fact that in your launchpad it runs fine makes me think I might be doing something wrong in the CCS side of things...

    Any ideas ?

  • IF my debugging is done properly and I'm looking at the right things, when 

     GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN6);  

    is executed i see no change in the P5IE register, shouldn't this value change when I enable interrupts for a pin ?

  • Yes, I would expect P5IE (specifically the 0x40 bit) to change. 

    As I recall, you would see this effect if the LOCKLPM5 bit were still set. But we can see that call to PMM_unlockLPM5 right there. All the same, it might be worth a look at the PM5CTL0 register (I think it's the 0x01 bit).

    Then I'd start scrounging: What is the origin of this project? Did you create it (using "File->New->CCS Project") or import it from someplace? Did you see any Warnings (you can ignore the Advice) when you built it? In my case, I created a "new driverlib with source" project and pasted your code in.

  • I tried multiple ways of production.

    The one you are looking at was an imported example from ti's website (it was just a blink example) to which I added the rest of the code.

    I imported it from their official zip and just started working on it.

    For good measure I tried your way just in case but the same thing happens...interrupts are not firing...I am 90% sure that CCS is somehow the culprit in this situation...could it be that I have the latest version ???

  • This is a good mystery. Did you see anything odd about the PM5CTL0 register? You might try using the debugger to set P5IE and seeing if the change "sticks" .(You may have to do a single-step to see the change).

    Are you checking both buttons? (I ask this since there's a jumper controlling the P1.0, but not the P1.1 LED.)

    I'm using CCS v8.2.0 with MSP430Ware v3.80.04.05. This is pretty basic stuff, though, so I wouldn't expect big changes between versions.

  • Ok get ready because this is kind of infuriating...at least to me...

    So I am currently doing my MSc on embedded and I am learning this platform for my dissertation project...so as you can expect I also contacted my supervisor after I posted on this forum...

    He suggested that it is highly possible that there is something broken about the "API" for msp430fr5994 that includes command bundles like "GPIO_enableInterrupt()" etc that essentially wrap the code parts that you need nicely and make the whole programming process a bit like arduino programming.

    So I sat down and rewrote the whole thing using raw register programming and tadaaaa it works exactly as expected in a matter of minutes...

    I am currently not sure which of the commands broke the sequence but it is 100% sure now that the interrupts were not firing at all since I literally tried every possible version of code for that task...

    I attach the working code below and I'll let it to your imagination to figure out what the heck was wrong with the old version...

    #include <msp430.h>
    #include <driverlib.h>
    #include <gpio.h>
    #include <stdio.h>
    #include <string.h>
    
    unsigned int i = 0;
    
    int main(void) {
    
        WDT_A_hold(WDT_A_BASE);        // Stop watchdog timer
    
            //GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);         // Set Red LED output
            P1DIR |= BIT0;
            //GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);      // Red LED off
            P1OUT &= ~BIT0; // Set P1.0 LOW
    
            //GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN6);                      // S1 P5.6: PxDIR, PxOUT and PxREN registers
            P5DIR &= ~BIT6; //Config P5.6 as input
            P5REN = BIT6; //Enable Pullup/down for P5.6
            P5OUT = BIT6; //Select Pullup resistor for P5.6
    
            //GPIO_selectInterruptEdge(GPIO_PORT_P5, GPIO_PIN6,GPIO_LOW_TO_HIGH_TRANSITION);      // S1 P5.6: PxIES register
            P5IE |= BIT6;//interrupt enabled for P5.6
            P5IES |= BIT6;//LOW->HIGH transition
            P5IFG = 0;//P5.6 IFG cleared
    
            // Disable the GPIO power-on default high-impedance mode to activate previously configured port settings
            PMM_unlockLPM5();
    
    //        GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN6);                                      // S1 P5.6: PxIE register
    //        GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN5);                                      // S2 P5.5: PxIE register
    
            __bis_SR_register(GIE);  // Enable all interrupts
            __no_operation();
            while(1) {i++;}
        }
    
        #pragma vector=PORT5_VECTOR
        __interrupt void Port_5(void)
        {
    
            if (P5IFG & BIT6)
            {
                P1OUT ^= BIT0;          // Toggle P1.0
                P5IFG &= ~BIT6;         // P5.6 clear interrupt flag
            }
    
        }

    P.S. I left the old commands as comments as a reminder of the original version to make the comparison easier...

  • I'm glad you got it working. I don't use Driverlib myself, but I also don't try to talk people out of using it. It's still a bit of a mystery, since this is pretty basic stuff. 

    Be a little careful about setting P5IE before clearing LOCKLPM5 (PMM_unlockLPM5). At least on some devices, the setting either doesn't "stick" or is inoperative somehow (I forget) when you do this. [Ref User Guide (SLAU367P) Sec 12.3.1]. It sounds like it's working in your case though.

    [Edit: Unsolicited:

    >        P5IES |= BIT6;//LOW->HIGH transition
    This actually selects a high->low transition [Ref UG Sec 12.2.6.2], so it will trigger on a press rather than a release. This is actually what most people expect, so I'm not suggesting you change it.] 
  • I'm glad you were able to find a workaround for your issue. I don't have a MSP430FR5994 board with me but I will try to get someone to figure out if the issue was with the DriverLib just for reference for the future. 

  • We've looked into this and by creating an empty project through resource explorer found at this link we were able to just copy and paste your original code into the main and it worked. The issue might've been with the creation of the project and the linking with DriverLib.

**Attention** This is a public forum