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.

MSP430FR2476: Using LPM3.5 waking up with RTC and then using TIMER A0 for a timeout

Part Number: MSP430FR2476

Hello!

I am working with a MSP430FR2476 in LPM3.5 and waking up with RTC. Once the micro is up from LPM3.5 I to use Timer A0 in UP-DOWN mode to have a timeout inside a function so that I can get out in case I take too long, but I am not getting inside the TIMER0_A1_ISR. 

I haven't seen any examples where a timer is used as a timer (not for waking up from LPM3.5) alongside RTC for waking up from LPM3.5. 

I wanted to know if i am missing some configuration on the RTC side or the LPM3.5 side.

When I was using LPM4 and a port interruption to wake up from LPM4 mode the timer A timeout was working fine. 

I am using the driver libraries RTC.h and timer_a.h from the SDK from MSP430FR2476

This is my RTC initialization:

void initRTC(bool irqEnable,bool minsOrSec, uint16_t t)
{
    WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer
    uint16_t modulo;

    uint32_t mod;
    if(minsOrSec)
    {
       mod = t * 32 * 60; // Dado que al hacer 32 * t_tick = 1s * 60 = 1m
    }
    else
    {
        mod = t * 32;
    }

    //Testing
    //modulo = 32; //-->IRQs cada 1seg

    modulo = 57600; // --> IRQs cada 30mins
    if(mod < modulo)
    {
        modulo = (uint16_t)mod;
    }
    else
    {
        cantIRQs = (uint16_t)(mod/modulo); // A priori nos va a dar un numero entero. (seconds = 21600 --> 6h)
    }

    *(unsigned int*)(BKMEM_BASE) = (unsigned int)cantIRQs;
    *(unsigned int*)(BKMEM_BASE+2) = (unsigned int)countIRQs;
    P2SEL0 |= BIT0 | BIT1;                  // set XT1 pin as second function

    do
    {
        CSCTL7 &= ~(XT1OFFG | DCOFFG);      // Clear XT1 and DCO fault flag
        SFRIFG1 &= ~OFIFG;
    } while (SFRIFG1 & OFIFG);              // Test oscillator fault flag

    // Initialize RTC
    // Source = 32kHz crystal, divided by 1024
    RTC_clearInterrupt(RTC_BASE,RTC_OVERFLOW_INTERRUPT_FLAG);
    
    __bis_SR_register(GIE); //Enable interrupts
    
    RTC_init(RTC_BASE, modulo - 1, RTC_CLOCKPREDIVIDER_1024);
    RTC_enableInterrupt(RTC_BASE, RTC_OVERFLOW_INTERRUPT);
    RTC_clearInterrupt(RTC_BASE,RTC_OVERFLOW_INTERRUPT_FLAG);
    RTC_start(RTC_BASE,RTC_CLOCKSOURCE_XT1CLK);//RTC_CLOCKSOURCE_XT1VLOCLK

 }

This is how I enter LPM3.5 mode

    PMMCTL0_H = PMMPW_H;                    // Open PMM Registers for write
    PMMCTL0_L |= PMMREGOFF;                 // and set PMMREGOFF

    __bis_SR_register(LPM3_bits | GIE);     // Enter LPM3.5 and Enable Interruptions

This is how i init the timer A instance 0

    //Initialize Timer0_A3 --> Up-Down Mode
    Timer_A_initUpDownModeParam upDownCtr;
    upDownCtr.clockSource = TIMER_A_CLOCKSOURCE_ACLK;
    upDownCtr.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
    upDownCtr.timerPeriod = 65535;  //From 0h to 0FFFFh  --> ~ 4 seg (updown)
    upDownCtr.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
    upDownCtr.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
    upDownCtr.timerClear = TIMER_A_DO_CLEAR;
    upDownCtr.startTimer = false;

    Timer_A_initUpDownMode(TIMER_A0_BASE ,&upDownCtr);

When waking up from RTC I run the initialization of everything i needed again and then I start the timer A with Timer_A_startCounter(TIMER_A0_BASE,TIMER_A_UPDOWN_MODE); but I never reached the timer interruption:

// Timer0_A3 CC1-2, TA Interrupt Handler
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) TIMER0_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(TA0IV,TA0IV_TAIFG))
    {
        case TA0IV_NONE:                            // No interrupt
            break;
        case TA0IV_TACCR1:                          // CCR1 not used
            break;
        case TA0IV_TACCR2:                          // CCR2 not used
            break;
        case TA0IV_TAIFG:                           // overflow
            counterTimer--;
            if(counterTimer <= 0)
            {
                timeOut = true;
            }
            break;
        default:
            break;
    }
}

Also, the Code Composer Studio compiler does not allow me to place a breakpoint inside the interruption (line 23), therefore I assume there is a problem with the configuration of the LPM3.5 mode or the RTC mode. 

Just in case I will include the code form the RTC interrupt vector:

 // RTC interrupt service routine
 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
 #pragma vector=RTC_VECTOR
 __interrupt void RTC_ISR(void)
 #elif defined(__GNUC__)
 void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void)
 #else
 #error Compiler not supported!
 #endif
 {
     cantIRQs = *(unsigned int*)BKMEM_BASE;
     countIRQs = *(unsigned int*)(BKMEM_BASE+2) + 1;
     switch(__even_in_range(RTCIV,RTCIV_RTCIF))
     {
         case  RTCIV_NONE:   break;          // No interrupt
         case  RTCIV_RTCIF:         // RTC Overflow
         {
             RTC_clearInterrupt(RTC_BASE,RTC_OVERFLOW_INTERRUPT_FLAG);
             if(countIRQs == cantIRQs)
             {
                 cbStatus = true;
                 countIRQs=0;
             }
             else
             {
                 cbStatus = false;
             }
             *(unsigned int*)(BKMEM_BASE+2) = 0;
             *(unsigned int*)(BKMEM_BASE+2) = countIRQs;
         }
             break;
         default: break;
     }
 }

Thank you and any tip or example where LPM3.5 + RTC to wake up + Timers are used will be greatly appreciated.

  • I must add that I think a solution could be just polling the TA0CTL register bit TAIFG to check if the timer has ended the updown cycle but I am not sure if the TAIFG is set as 1 until it is read or it goes automatically down to 0 afer a time, as it indicates in this diagram from the MSP430FR4xcxxFamilyUsersGuide.pdf

    For example, in my case I just want the time out to get out of this function where I read the UART port

        //Poll for flag
        if (!(HWREG16(EUSCI_A1_BASE + OFS_UCAxIE) & UCRXIE)){
            //Poll for receive interrupt flag and exit if timeout
            while ((!(HWREG16(EUSCI_A1_BASE + OFS_UCAxIFG) & UCRXIFG)) && (HWREG16(TIMER_A0_BASE + OFS_TAxCCTL0) & TAIFG));
        }
    
        uint8_t word = 0;
        if(HWREG16(TIMER_A0_BASE + OFS_TAxCCTL0) & TAIFG)
            HWREG16(TIMER_A0_BASE + OFS_TAxCCTL0) &= ~TAIFG;          --> Clear interrupt?
        else
            word = HWREG16(EUSCI_A1_BASE + OFS_UCAxRXBUF);
    

  • Hi Maria Ines Quihillalt

    Please check msp430fr267x_LPM3_5_01.c on https://www.ti.com/tool/download/SLAC781

    during MCU wakeup, SYSRSTIV == SYSRSTIV_LPM5WU check is needed.

    both MCU Device powered up from a cold start and from LPM3.5, all used register Initialize is needed.

    on document, please check 1.4.3 Low-Power Modes LPM3.5 and LPM4.5 (LPMx.5) of MSP430FR4xx and MSP430FR2xx Family User's Guide (Rev. I)

    Thanks!



**Attention** This is a public forum