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.

Compiler/MSP430FR6989: Real Time Clock interrupt clarification.

Part Number: MSP430FR6989


Tool/software: TI C/C++ Compiler

Following the somewhat abbreviated code examples in MSP430 training chapter 8 (RTC), and the code snippet in the Driverlib documentation I have been able to successfully implement the RTCcalendar alarm on FR6989 launchpad, however there are a couple of things that are confusing to me going forward. Can someone explain:

1.  Is it necessary to enable the read ready interrupt, time event interrupt as well as the clock alarm interrupt if I only want an interrupt on the alarm? If so why didnt driverlib wrap them into one predefined constant since that would imply that they all three would be used any time an alarm is set.

and related to that

2. When following the examples mentioned above for caIendar alarm I seem to be getting a prescale interval interrupt (RTCEVIFG) on about a 1 sec period as well as calendar interrupt (RTCAIFG) as intended. I know I can ignore the RTCEVIFG  but I'm wondering if it is supposed to happen, and if so curious as to why. 

I can include my code if needed, however it will take a while to strip out all of the extraneous stuff and the RTC section is essentially a copy of the driverlib example so Im hoping  this description will suffice.

Thanks! 

  • Hi Andy,
    sorry, but it is not perfectly clear, which kind of configuration and code you're applying to your setup. Thus, to avoid unnecessary efforts, could you please strip the code down to the RTC functionality only, and post it?
    If you do not want to disclose the code here, please let me know. There are ways to share it privately through the forum.
    Many thanks in advance.

    Best regards
    Peter
  • Thanks for responding, Peter. I dont have anything proprietary its just that I like to put the 'under the hood' stuff in subroutines in the header file and was a bit lazy about rearranging them in an appropriate format for this forum. No prob though. Note the questions are annotated below. I've done quite a bit of searching but havent found anything to date so am asking you guys. 

    #include "driverlib.h"
    #include "rtc_c.h"

    #define ONE_SECOND 8000000
    #define HALF_SECOND 4000000
    #define LF_CRYSTAL_FREQUENCY_IN_HZ 32768


    /************************************************* prototypes*****************************

    ******************************************************************************************/
    /***** Defines ***************************************************************/

    #define ONE_SECOND 8000000
    #define HALF_SECOND 4000000
    #define LF_CRYSTAL_FREQUENCY_IN_HZ 32768
    #define XT_TIMEOUT 100000
    #define GPIO_ALL GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3| \
    GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7

    /******************************************************************************************/
    /************************************************* Global Variables ************************/

    RTC_C_configureCalendarAlarmParam alarmParam;
    Calendar currentTime;
    bool bReturn = STATUS_FAIL;

    /************************************************* *******************************************/ 

    int main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer


    //init LFXtl********************************************************************
    GPIO_setAsInputPinWithPullDownResistor(GPIO_PORT_PJ, GPIO_ALL);
    PMM_unlockLPM5();
    GPIO_setAsPeripheralModuleFunctionInputPin(
    GPIO_PORT_PJ,
    GPIO_PIN4 + // LFXIN on PJ.4
    GPIO_PIN5 , // LFXOUT on PJ.5
    GPIO_PRIMARY_MODULE_FUNCTION);

    CS_setExternalClockSource (32768,0);
    bReturn = CS_turnOnLFXTWithTimeout(
    CS_LFXT_DRIVE_0,
    XT_TIMEOUT
    );

    if ( bReturn == STATUS_FAIL )
    {
    while( 1 );
    }

    //init Real Time Clock
    currentTime.Seconds = 0x00;
    currentTime.Minutes = 0x26;
    currentTime.Hours = 0x13;
    currentTime.DayOfWeek = 0x03;
    currentTime.DayOfMonth = 0x20;
    currentTime.Month = 0x07;
    currentTime.Year = 0x2011;
    RTC_C_initCalendar(RTC_C_BASE,&currentTime,RTC_C_FORMAT_BCD);

    // set alarm for one minute later to test
    alarmParam.minutesAlarm = 0x27;
    alarmParam.hoursAlarm = 0x13;
    alarmParam.dayOfWeekAlarm = RTC_C_ALARMCONDITION_OFF;
    alarmParam.dayOfMonthAlarm = RTC_C_ALARMCONDITION_OFF;
    RTC_C_configureCalendarAlarm(RTC_C_BASE,&alarmParam);

    //Question: Is this a necessary step if I just want a one time alarm interrupt?
    RTC_C_setCalendarEvent(RTC_C_BASE,RTC_C_CALENDAREVENT_MINUTECHANGE);
    //

    // Clearing interrupts just to be sure

    // Question: is there a better method to do this? Seems redundant.
    RTC_C_clearInterrupt(RTC_C_BASE,
    RTC_C_CLOCK_READ_READY_INTERRUPT +
    RTC_C_TIME_EVENT_INTERRUPT +
    RTC_C_CLOCK_ALARM_INTERRUPT);

    // now enabling

    //Question: Are the Read ready interrupt and time event interrupt enables always necessary?
    // I would think the alarm interrupt would include the read ready (and not sure why the time event is there).

    RTC_C_enableInterrupt(RTC_C_BASE,
    RTC_C_CLOCK_READ_READY_INTERRUPT +
    RTC_C_TIME_EVENT_INTERRUPT +
    RTC_C_CLOCK_ALARM_INTERRUPT);

    RTC_C_startClock(RTC_C_BASE);

    __bis_SR_register(LPM3_bits + GIE);// enable interrupt and go to LPM3

    return 0;
    }


    char i2; // included to give vectors a place to break while debugging

    #pragma vector = RTC_VECTOR
    __interrupt void TimerRTC_ISR(void)
    {
    switch(__even_in_range(RTCIV,16))
    {
    case 0: break; // No interrupts
    case 2: // RTCRDYIFG
    i2=1;
    break;

    // Question: Interrupts here at ~ 1 sec interval. Why wake mpu if not needed - even for a very short time?
    case 4: // RTCEVIFG - interrupt on prescale interval timer
    i2=1;
    break;

    // Interrupts here as expected
    case 6: // RTCAIFG Clock alarm flag. Remains cleared when in counter mode
    i2=1;
    break;

    // Doesnt interrupt here that I have found, as expected.

    case 8: // RT0PSIFG
    i2=1;
    break;


    // Question: Interrupts here if I only enable alarm interrupt but not the other two - why that behavior?
    case 10: // RT1PSIFG
    i2=1;
    break;

    case 12: break; // Reserved
    case 14: break; // Reserved
    case 16: break; // Reserved
    default: break;
    }

    return; // No wakeup

    }
    /*
    * RTCRDYIFG -> interrupt on the rising edge of TRCRd:Y bit you have one second to access reg values
    * RTCEVIFG -> interrupt on prescale interval timer
    * RTCAIFG -> Calender (min,hrs,dayof month, day of week) alarm flag. Remains cleared when in counter mode
    * RT0PSIFG -> genned when prescale returns to 0
    * RT1PS -> genned on preset divide by 2,4,88,16,32,64,128, or 256
    */

  • Hi Andy,
    many thanks for the clarification.
    Let's start with the RTCRDYIFG: No, for a configured alarm and operation without accessing the RTC_C control registers, this interrupt would not be necessary. The important point about the RTCRDYIFG is the following. The RTC_C is usually running asynchronously to the CPU and the rest of the system, as these are clocked usually by other clocks. Thus there could be a collision between the RTC_C logic accessing and updating the RTC_C registers and e.g. the CPU accessing and modifying those. This could lead to erroneous results. Thus it is necessary to avoid such collisions. This is the purpose of the RTCRDYIFG, as it tells the CPU, when it is safe accessing the RTC_C registers. If you have already configured the RTC_C and reached a steady operating state, and not accessing the RTC_C registers at all, you can shut the RTCRDYIFG off.
    For a pure alarm interrupt, also the RTCEVIE is not necessary. This event interrupt flag can be used to obtain triggers from the RTC_C in a regular time frame, e.g. minute, hour, midnight, noon. If you do not need this, you can switch this off.

    //Question: Is this a necessary step if I just want a one time alarm interrupt?
    RTC_C_setCalendarEvent(RTC_C_BASE,RTC_C_CALENDAREVENT_MINUTECHANGE);
    //
    As mentioned, this is not necessary. I think the intention of the author of the driver lib was to showcase "everything" in one code example.

    // Question: Interrupts here at ~ 1 sec interval. Why wake mpu if not needed - even for a very short time?
    No, if not needed, it definitely makes no sense.

    // Question: Interrupts here if I only enable alarm interrupt but not the other two - why that behavior? RT1PSIFG
    Need to check on this, why it occurs in your case. This should only happen when RT1PSIE is enabled.

    Best regards
    Peter
  • Many thanks Peter. This mostly answers my questions. I'll play around with RTC some more.... my code was functioning anyway I just was curious about a few things.

  • Errr.. One more comment (embarrassed). It turns out that the
    RTC_C_clearInterrupt(RTC_C_BASE,
    RTC_C_CLOCK_READ_READY_INTERRUPT +
    RTC_C_TIME_EVENT_INTERRUPT +
    RTC_C_CLOCK_ALARM_INTERRUPT);
    in the driverlib doesnt clear everything (check the documentation). That is why I was getting a 1 sec interrupt.
  • Hi Andy,
    not sure, what you mean. Are you referring to the fact, that there are more interrupt sources than the ones you've cleared
    RTC_C_BASE,
    RTC_C_CLOCK_READ_READY_INTERRUPT +
    RTC_C_TIME_EVENT_INTERRUPT +
    RTC_C_CLOCK_ALARM_INTERRUPT
    ?
    In case you do not need further support, please close the thread. Many thanks in advance.

    Best regards
    Peter

**Attention** This is a public forum