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.

MSP430 RTC issue

Expert 1175 points
Other Parts Discussed in Thread: MSP430F5418

Hello All,

I have asked this question before, but I think this time I can ask with some more clarity.

The below is my RTC Test code. I am using msp430f5418 with IAR EW 5.

My problem is after some time (we tested with 15 minutes and more) the minutes interrupt is coming earlier than expected.

ie, On first time, after exactly 60 seconds and after 15 minutes the minute interrupt comes on 45th seconds itself.

Why is it so? We are using the library provided by TI for RTC register manipulation.

Can anybody tell me why is it so??

Is it the problem with the code or with the improper usage of library or with the hardware itself??

Thanks in advance...

#include <msp430.h>

#define RTC_VALID_READ_MAX_WAIT  500U

int main()
{
    WDTCTL = WDTPW + WDTHOLD;
    RTCCTL01 = RTCMODE + RTCTEVIE + RTCTEV_0;
    RTCCTL01 |= RTCHOLD;
    /* Calling the routines in the workaround assembly module supplied by TI */
    SetRTCYEAR (2011U);
    SetRTCMON (6U);
    SetRTCDOW (3U);
    SetRTCDAY (4U);
    SetRTCHOUR (23U);
    SetRTCMIN (0U);
    SetRTCSEC (0U);
    RTCCTL01 &= ~RTCHOLD;

    __enable_interrupt();
    while(1)
    {
    }
}

#pragma vector=RTC_VECTOR
__interrupt void handle_rtc_interrupt(void)
{
    switch(RTCIV)
    {
        case 2U:  /* RTC one second Ready Event for valid read */
        {
            int wait_counter = 0U;
            while (!(RTCCTL01&RTCRDY)) /* Wait for RTCRDY to go high, so read will be valid. */
            {
                wait_counter++;
                if (wait_counter > RTC_VALID_READ_MAX_WAIT)
                {
                    break;
                }
            }
            if (wait_counter <= RTC_VALID_READ_MAX_WAIT)
            {
                volatile int min = RTCMIN;
                volatile int sec = RTCSEC;
            }
            RTCCTL01 |= RTCHOLD;
            RTCCTL01 &= ~RTCRDYIE;
            RTCCTL01 &= ~RTCHOLD;
            break;
        }
        case 4U:        /* RTC Minute Interval Event */
        {
            RTCCTL01 |= RTCHOLD;
            RTCCTL01 |= RTCRDYIE;  /* Enable Ready Flag Interrupt */
            RTCCTL01 &= ~RTCHOLD;
            break;
        }
        default:
        {
            break;
        }
    }
}

Hari

  • Hi Hari,

    you're using DCO for supplying ACLK to the RTC, right? If you want to have y accurate timing you should use a external 32kHz crystal instead.

    Kind regards
    aBUGSworstnightmare

  • Can you clarify this a little bit more:

    Hari said:

    My problem is after some time (we tested with 15 minutes and more) the minutes interrupt is coming earlier than expected.

    ie, On first time, after exactly 60 seconds and after 15 minutes the minute interrupt comes on 45th seconds itself.

    On a true timeline, do your minute interrupts come at:

    01:00  01:59  02:58  03:57  04:56  05:55  06:54  07:53 ... 14:45

    or do they come at:

    01:00  02:00  03:00  04:00  05:00  06:00 ...  13:00  14:00  14:45

     

    Assuming they come according to the first timeline, then your RTC is running about 1.6% too fast.  Maybe REFO really is that fast (33293 Hz), although I've never seen REFO faster than 33100 Hz at room temp.  Anyway, that goes directly to 'Nightmare's point about using a quartz crystal, which it appears you are not. (You should be!)

    Can you drive ACLK to an external pin and measure it with a frequency counter or a scope with a dedicated readout for trigger frequency?

    Jeff

  • Jeff Tenney said:
    Maybe REFO really is that fast (33293 Hz), although I've never seen REFO faster than 33100 Hz at room temp. 

    At room temp, 3V, the tolerance is specified with +-1.5%. But over full temp and VCC range, it is up to +-3.5%.
    If the MSP is operated at <>3V, 1.6% are not outside the specs.

    However, the descrption of the problem sounds rather like your second option: all is well for the first minutes, and suddenyl the interrupt comes when the seconds register shows 45 seconds. Which should be impossible since the interrupt trigger is most likely connected with the seconds counter overflow.

    In this other thread I asked how the it is determined that it happens after 45 seconds. With a breakpointinside the ISR and reading the RTC registers? Since the code contains no signalling or debug ourput section.

  • Hello Jeff,

    Thank you for your replay.

    Jeff Tenney said:

    Can you clarify this a little bit more:

    On a true timeline, do your minute interrupts come at:

    01:00  01:59  02:58  03:57  04:56  05:55  06:54  07:53 ... 14:45

    or do they come at:

    01:00  02:00  03:00  04:00  05:00  06:00 ...  13:00  14:00  14:45

    The first time line is what I meant.

    I am using the default clock source for RTC.

    The ACLK is connected to external crystal of frequency 32 KHz.

    Also I have measured the ACLK frequency fo confirmation. It is showing 32khz.

    Thanks.

  • Hello JMG,

    Thanks for your replay.

    I tested it using two ways.

    1. By setting a break point on the ISR.

         When First RTC interrupt comes the code break's at the ISR. Then  I started an external seconds counter device and removed the break point to continue its execution.

         After some minutes I again set a break point in ISR. But the interrupt comes too earlier than I expected.

    2. By displaying the minute on the LCD attached with the MSP.

         I start the program with no break points. The system displays time on the LCD. When it changes its time form 0:0 to 0:1 i started my external seconds counter device.

         After each minute I observed both LCD and seconds counter display.

    In both cases I didn't get the expected time difference.

    can you explain what can be the problem??

     

    Thanks

    Hari

  • Hai aBUGSworstnightmare,

    I am using the default clock for RTC.

    It is by default external crystal right?

    We have an an external crystal of 32khz.

     

    Thanks

  • Hari said:
    I am using the default clock for RTC.

    Which is ACLK by default.

    Hari said:
    It is by default external crystal right?

    No. ACLK is set to the external crystal by default, yes, but falls back to the internal REFO if the external crystal is not properly oscillating.

    In your code I don't see you setting the XCAP bits for setting ht eload capacitance for the crystal. By default it is the highest possible setting, but it might be too much for the crystal you use (check the datasheets from both, MSP and ctrystal), which will result in either the crystal not oscillating at all (then ACLK run on REFO) or at a (possibly significantly) lower frequency than nominal.

    You can output ACLK to a port pin and check its frequency with a scope or frequency counter. I bet in your case it will result in ~32230Hz output frequency.

    The RTC module allows for calibration. it is done by adding/skiipping counts in a 64 min interval. However, this is a long-time calibration resulting in one shorter/longer second every 64 min.

    About the breakpoints: breakpoints in a realtime applicaiton (and measuring a clock IS a realtime applicaiton) is not a good idea. The debugger doesn't freeze time. It just halts the CPU. Sometimes it also stops the clocks (and therefore the RTC-A too, but not the RTC-B), depending on project settings and/or MSP capabilities. The best way to debug realtime events is to put out a signal on an I/O pin. It doesn't cost processor power (5 MCLK cycles at most) and you can attach precision equipment, like a tiemr/counter that gives you the exact interval time/output frequency between two interrupt calls.

  • Hari,

    In spite of your assurances that ACLK is running at exactly 32kHz, I think you should add the following TI code before starting your RTC.   You may need to modify the line with XCAP_3 to match your 32kHz crystal and hardware.

    This code actually enables your 32kHz quartz crystal.  Without this code (or similar), your 32kHz reference is REFO, which stinks for timekeeping.

      P7SEL |= 0x03;                            // Select XT1
      UCSCTL6 &= ~(XT1OFF);                     // XT1 On
      UCSCTL6 |= XCAP_3;                        // Internal load cap

      // Loop until XT1,XT2 & DCO stabilizes
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

      UCSCTL6 &= ~(XT1DRIVE_3);                 // Xtal is now stable, reduce drive
                                                // strength

    Jeff

     

  • Jeff Tenney said:
      P7SEL |= 0x03;                            // Select XT1
    UCSCTL6 &= ~(XT1OFF);                     // XT1 On

    You're right, these are the crucial configs. I forgot that the 5x series has an XT1OFF bit and that it is set as default and the XT1 pins are GPIO. All other MSP series have the XT1 always active as default, usually with dedicated pins, and you cannot direclty disable it unless you set it to digital bypass.

    Yes, without these lines, ACLK is definitely running on REFO with +-1.5% (and +-3.5% over full operating range of temp and VCC).
    Here it shows that I never used XT1 on the 5438 so far, else I'd have remembered this.

    However, the rest of this init code is no really necessary if the default load matches and you don't care for power consumption or the initial startup time.

     

  • JMG,

    Actually I avoid using UCSCTL6 &= ~XT1OFF in my own code.  XT1 runs just fine even with XT1OFF set, as backwards as that may sound, as long as XT1 is supposed to drive ACLK.  So actually its the P7SEL statement that gets XT1 going.

    However, on the 5xx/6xx, software must intervene after XT1 is oscillating properly to make the switchover from REFO to XT1.  The software must clear both XT1LFOFFG and OFIFG for the UCS to switch from REFO to XT1.  So really all that code is necessary (with the exception of the clearing of XT1OFF) to get onto XT1.  It's different from MSP430s without REFO.

    Jeff

  • Jeff Tenney said:
    XT1 runs just fine even with XT1OFF set, as backwards as that may sound, as long as XT1 is supposed to drive ACLK.

    That's right - as long as ACLK is active and used by a module that makes an unconditional clock request to ACLK.
    If you enter an LPM that stops ACLK, it will immediately stop the crystal too (requiring another long init delay when re-enabled).
    So it depends on your application whether you want this. No problem as long as you remember this when it becomes important :)
    But a 2400Bd UART receiver sourced by the crystal while the cpu is in LPM4 won't work - or rather will work with REFO then, as ACLK is only requested after the start bit edge has been received - and before the crystal is up, the byte transfer is already ended. Same happens for the FLL.

  • Hello All,

    I have added the code provided by Jeff to my code and tested for 24 hours. It was synchronized with my computers clock.

    It is working well. I measured the frequency of ACLK with a scope. Before stabilizing the clock it shows varying values from 32.89 to 33.13 KHz.

    After stabilizing it shows frequency from 32.68 to 32.89 KHz. Is it OK right?? It is working properly now. I am continuing the testing to test whether there is any problem.

    Thanks for all of you for helping me to solve this problem.....

     

    Hari

  • Once again Thanks for all.

    The RTC is working properly for three days.

    Now I understood the importance of stabilization of crystal.

     

    Thanks you

    HariKK

**Attention** This is a public forum