Hi Guys,
We need your help.
Our customer is using an MSP430FR2433 with the development board from TI and want to use its low power mode 3.5 so that they can wake it up from a GPIO pin or the RTC. They are using one of the LPM3.5 example codes in the resource explorer in Code Composer studio as a reference.
Kindly check the attached file for the full inquiry.
I am using an MSP430FR2433 with the development board from TI and want to use its low power mode 3.5 so that I can wake it up from a GPIO pin or the RTC. I am using one of the LPM3.5 example codes in the resource explorer in CodeComposer studio as a reference. My goal is: 1. To keep the microcontroller in a low power mode until a button is pushed or the RTC wakes it up (GPIO or RTC interrupt). 2. To activate the associated interrupt service routing (ISR) 3. Set a variable "interrupt_type" to "1" or "2" depending on which ISR is activated 4. Return to main() after the ISR and perform specific functions depending on the value of "interrupt_type". I am able to do 1,2, and 3, but I am not able to change the value of "interrupt_type" in the PORT interrupt ISR. I am able to do it in the RTC ISR. In the port ISR, it is always the initialized value that was declared before main(). I have read that declaring it as a global (volatile) variable should make it work but it doesnt. Here is the relatively simple code in question: #include <msp430.h> void initGpio(void); void initCrystalclk(void); void GPIOfunction(void); void RTCfunction(void); volatile int interrupt_type = 0; void main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer initGpio(); // Configure GPIO initCrystalclk(); // Initialize XT1 32kHz crystal P1OUT |= BIT1; if (SYSRSTIV == SYSRSTIV_LPM5WU) // If MCU wakes up from LPM3.5. { __enable_interrupt(); // The RTC interrupt should trigger now... __no_operation(); if(interrupt_type==1){ GPIOfunction(); } if(interrupt_type==2){ RTCfunction(); } } else { //waking up from cold start static int const Offtime=30; //time in seconds to stay in LPM RTCMOD = 32*Offtime-1; //forcing LPM3.5 (i.e. run RTC module) RTCCTL = RTCSS__XT1CLK | RTCSR |RTCPS__1024| RTCIE; //clock control bits } P2IES |= BIT3; // P2.3 low/high interrupt edge select for button P2IE |= BIT3; // P2.2 Interrupt enable P1IE |= BIT6; for MP P2IFG &=~BIT3; // in case PxIES set the interrupt flag PMMCTL0_H = PMMPW_H; // Open PMM Registers for write PMMCTL0_L |= PMMREGOFF; // and set PMMREGOFF __bis_SR_register(LPM3_bits | GIE); // enter LPM 3.5 with interrupts enabled __no_operation(); } #pragma vector=PORT2_VECTOR //Interrupt routine when switch closes __interrupt void Port_2() { __disable_interrupt(); //this is to prevent RTC from interrupting (not tested) interrupt_type=1; //DOESNT WORK P2IFG &=~BIT3; } #pragma vector = RTC_VECTOR __interrupt void RTC_ISR(void) { switch(__even_in_range(RTCIV, RTCIV_RTCIF)) { case RTCIV_NONE : break; // No interrupt pending case RTCIV_RTCIF: // RTC Overflow interrupt_type=2; //WORKS break; default: break; } } void GPIOfunction(void) { //do something eg. blink led } void RTCfunction() { //do something else } void initGpio(void) //initialize ports { P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF; P2DIR &= ~BIT3; //Set P2.3 as input P2REN |= BIT3; //Enable Resistor P2OUT |= BIT3; //Configure P2.3 as pulled-up for debug purpose using button PM5CTL0 &= ~LOCKLPM5; //Turn ON digital I/O } void initCrystalclk(void) //note: crystal clock needs to be connected on Dev board { P2SEL0 |= BIT0 | BIT1; // set XT1 pin as second function (for crystal as clock) do { CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag } If I put the GPIOfunction() or RTCfunction() inside the ISR, it works, but they are quite lengthy and have their own interrupts, which apparently is not good practice. Please let me know if there is a way to modify the variable value inside the ISR and have it readable by the main() after the ISR. Essentially I am hoping to set a flag inside the ISR that indicates which ISR was called so that I can run a specific subroutine in main(). Thanks in advance! I can read the P2IFG vector at the beginning of main() to set the variable in main() instead of the ISR, but not sure this is a recommended way.
Thank you in advance for the support.
Best regards,
Jonathan