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.
Part Number: MSP432P401R
I am trying to write some simple code to turn an on-board LED on and off using the two switches on the Launchpad. However, as soon as I enable interrupts on Port 1 Pin 4, the interrupt flag is raised. This pin is connected to Switch 2 on the Launchpad which is normally open and connects the pin to GND when it is closed. I started doing some experimenting and this also happens when I enable interrupts on Port 1 Pin 5 which is not connected to any button. I've played around with several different configurations and I simply cannot figure out why the interrupt is occurring as soon as I enable it. Port 1 Pin 1 has the exact same register and switch configuration and does not behave in this way.
I initially wrote the code using TI's driverlib for the MSP432 and then wrote it a second time by just setting the register value. Both pieces of code had the same problem.
I have tried both rising edge triggering with the pin configured as input with pulldown and falling edge interrupt triggering with the pin configured as input with a pullup and both have the same issue. I know on MSP430s, you have to clear the interrupt as the register initializes to the flag being set. However, the P1IFG register initializes to all the flags not asserted.
Here is the code:
void main(void) { WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer /* S1 */ GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); /* S2 */ GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4); /* Red LED */ GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION); // Upper 3 bits control hardware priority, lower 7 bits control sub-priority Interrupt_setPriority(INT_PORT1, 0xC0); GPIO_registerInterrupt(GPIO_PORT_P1, inputIRQHandler); interrupts = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4); /* Register Level Code P1->SEL0 &= ~BIT4; P1->SEL1 &= ~BIT4; P1->DIR &= ~BIT4; P1->OUT |= BIT4; P1->REN |= BIT4; P1->IES |= BIT4; P1->IE |= BIT4; */ Interrupt_enableMaster(); while(1); } void inputIRQHandler(void) { uint_fast16_t interrupts; interrupts = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); if (interrupts & GPIO_PIN1) { GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); } if (interrupts & GPIO_PIN4) { GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4); GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0); } }
Any thoughts?
Here is my code now:
#include <stdint.h> /* MSP432 driverlib includes */ #include <ti/devices/msp432p4xx/driverlib/gpio.h> #include <ti/devices/msp432p4xx/driverlib/interrupt.h> void inputIRQHandler(void) { uint_fast16_t interrupts; interrupts = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); if (interrupts & GPIO_PIN1) { GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); } if (interrupts & GPIO_PIN4) { GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4); GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0); } } void main(void) { uint_fast16_t interrupts; WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer Interrupt_disableMaster(); /* S1 */ GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); /* S2 */ GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4); /* Red LED */ GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION); // Upper 3 bits control hardware priority, lower 7 bits control sub-priority //Interrupt_setPriority(INT_PORT1, 0xC0); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4); GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4); GPIO_registerInterrupt(GPIO_PORT_P1, inputIRQHandler); interrupts = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); Interrupt_enableMaster(); interrupts = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); while(1); }
I found out the master interrupt is enabled by default so I disabled it before doing all the setup and reenabled it at the end of setup. I check the GPIO Interrupt Status both before and after enabling master interrupts. Both times shows no interrupts flags asserted, however the ISR is still entered once. However, because the ISR logic checks the GPIO Interrupt flags (which are still all unasserted), the ISR does nothing.
When I comment out the code that clears the GPIO interrupt flags, the function which returns their status shows that the interrupt associated with P1.4 is asserted. It seems like the interrupt is somehow latched in the NVIC as soon as I enable it. Is this even possible? I'm 99% sure this isn't some sort of problem with the button as P1.1 has exactly the same configuration and does not exhibit this problem. I tried setting up all the pins on port 1 the same way as P1.1 and P1.4 and only P1.5 (which is a floating pin) also exhibited this strange behavior of asserting the interrupt as soon as it was enabled.
Any thoughts?
I used the CMSIS function NVIC_GetPendingIRQ(PORT1_IRQn) to check the status of the Port 1 interrupt in the NVIC. Before I enabled the P1.4 interrupt, the function returns 0. Afterwards, it returns 1. Therefore, enabling the interrupt is somehow causing the NVIC Port 1 interrupt to be asserted. How could this happen?
This code seems to fix it, but I shouldn't have to clear a specific pin interrupt in order to have it behave properly. I would like to understand exactly what is going on to cause this specific pin interrupt to be automatically asserted when I enable it.
#include <stdint.h> /* MSP432 driverlib includes */ #include <ti/devices/msp432p4xx/driverlib/gpio.h> #include <ti/devices/msp432p4xx/driverlib/interrupt.h> void inputIRQHandler(void) { uint_fast16_t interrupts; interrupts = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); if (interrupts & GPIO_PIN1) { GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); } if (interrupts & GPIO_PIN4) { GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4); GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0); } } void main(void) { uint_fast16_t interrupts; WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer Interrupt_disableMaster(); /* S1 */ GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); /* S2 */ GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4); /* Red LED */ GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION); // Upper 3 bits control hardware priority, lower 7 bits control sub-priority //Interrupt_setPriority(INT_PORT1, 0xC0); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4); GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4); NVIC_ClearPendingIRQ(PORT1_IRQn); GPIO_registerInterrupt(GPIO_PORT_P1, inputIRQHandler); Interrupt_enableMaster(); while(1); }
Hi Nicholas,
can you please tell me which Launchpad version you used (maybe send a picture). Also please let me know the marking of the chip so I know what DIE revision you have assembled.
I will set up a launch pad v1.9 with a RevC device and will try the MSP432 SDK - v:1.40.01.00 example "gpio_input_interrupt" example utalizing the DriverLib.
Once I have results I will come back to you.
Best regards,
Dietmar
Try setting a breakpoint in the ISR and see if it enters it. The code I posted functionally works but unexpectedly enters the ISR for no apparent reason.
Nicholas,
for sure I also tried it with breakpoints as well but once I let the program run via the debugger it will not enter the ISR.
First time it enters the ISR is when I press one of the 2 buttons.
Again can you please tell me which version of the launchpad you use and which device? Maybe there is a difference.
Best regards,
Dietmar
I figured it out. I was clearing the interrupt flag directly after enabling the interrupt instead of directly before it. I changed
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4); GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4);
to
GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4);
and it worked...Just goes to show you cant necessarily trust the register's default values. Sorry for the non-issue. I know you suggested this earlier but I didn't realize that my flag clear was happening after the interrupt enable which essentially defeats the purpose of clearing the flag. I'm still not sure why only GPIO interrupts on pins 4 and 5 were being asserted automatically, but I guess that's besides the point...Thanks for the help!
**Attention** This is a public forum