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.

Set an alarm from x seconds later than actual RTC

Other Parts Discussed in Thread: TMS320C5505

Hi,

I am using a TMS320C5505 and I have to set an RTC alarm, 10 seconds after the actual RTC.

To accomplish this I read the RTC, and I am wondering if there exist a nice CSL library that handles automatically the possible change of minutes, hours, days, etc...

To be specific, assuming that the actual RTC value is 23h 59m 55s of 31/12/2014, I'd need to wake-up at

00h 00m 05s of 1/1/2015. Do I have to manually handle these "pathological cases" or is there a CSL function that can do it?

Best 

  • RTC_setAlarm() in csl_rtc.c should be able to do that. First, you'd have to init the rtc with the current time/date using RTC_setTime() and RTC_setDate(), then call RTC_setAlarm() to set the alarm time. There is also an example in the cslv3.3 (http://www.ti.com/tool/sprc133 : C55XCSL-LOWPOWER) : c55xx_csl\ccs_v5.0_examples\rtc\CSL_RTC_Interrupt_Alarm_Example

    Would you have tried the same?

    Best Regards.

  • Dear KRaviS,

    many thanks for your answer. My question was maybe not well posed. I am not interested in how to set an alarm given a certain date. I am interested in how to set an alarm x second after a certain date. For the sake of brevity let's say 0.5 second after the current time read by by RTC. It is not simply possible to add 0.5 sec to the "second field" in the alarm structure since issue such as possible minute, hour, day increase may arise. Additional challenges are given by leap years.

    Is my question clearer now?

  • Dear Daniele,

    Maybe my exaplanation wasn't discreet enough. Please find below my explanation, a sample piece of code to handle the implementation requested by you.

    RTC_SetAlarm() doesn't set an alarm only x seconds after a date. It handles to a resolution of milliseconds as well, as you might have noticed in the CSL_RtcAlarm structure definition.

    Also, your concern w.r.t possible minute, hour, day increase and leap years will be addressed by the RTC hardware itself. The hardware handles leap year compensation alongwith time-count upto a resolution of milliseconds.

    Even if the gap between the current-time and the alarm-time that you set is as low as 0.5 seconds, the RTC should generate the alarm.

    For your requested scenario "actual RTC value is 23h 59m 55s of 31/12/2014, I'd need to wake-up at 00h 00m 05s of 1/1/2015", your code may look something like this:

    CSL_RtcTime      InitTime;
    CSL_RtcAlarm     AlarmTime;
    CSL_RtcIsrAddr   isrAddr;

    RTC_SetAlarm_test()
    {
    ...
    ...
    /* Set the RTC init structure */
        InitDate.year  = 2014;
        InitDate.month = 12;
        InitDate.day   = 31;

        InitTime.hours = 23;
        InitTime.mins  = 59;
        InitTime.secs  = 55;
        InitTime.mSecs = 0;

     /* Set the RTC alarm time */
        AlarmTime.year  = 2015;
        AlarmTime.month = 1;
        AlarmTime.day   = 1;
        AlarmTime.hours = 0;
        AlarmTime.mins  = 0;
        AlarmTime.secs  = 5;
        AlarmTime.mSecs = 0;

        /* Register the ISR function */
        isrAddr.AlarmEvtAddr  = rtc_alarmEvt;

        status = RTC_setCallback(&rtcDispatchTable, &isrAddr);

        IRQ_globalDisable();
        IRQ_clearAll();
        IRQ_disableAll();
        IRQ_setVecs((Uint32)&VECSTART);
        IRQ_clear(RTC_EVENT);
        IRQ_plug (RTC_EVENT, &rtc_isr);
        IRQ_enable(RTC_EVENT);
        IRQ_globalEnable();

        /* Reset the RTC */
        RTC_reset();

        /* Configure the RTC module */
        status = RTC_config(&rtcConfig);

     /* Set the RTC time */
     status = RTC_setTime(&InitTime);
     /* Set the RTC date */
     status = RTC_setDate(&InitDate);

     /* Set the RTC Alarm time */
     status = RTC_setAlarm(&AlarmTime);
     /* Enable the RTC alarm interrupts */
     status = RTC_eventEnable(CSL_RTC_ALARM_INTERRUPT);
     /* Start the RTC */
     RTC_start();
    ...
    ...
    ...
    }

    interrupt void rtc_isr(void)
    {
    ...
    ...
    }

    void rtc_alarmEvt(void)
    {
    ...
    ...
    }

    If you wish to go for a gap 0.5 seconds instead of 10s, you may modify the following statements:

     /* Set the RTC alarm time */
        AlarmTime.year  = 2014;
        AlarmTime.month = 12;
        AlarmTime.day   = 31;
        AlarmTime.hours = 23;
        AlarmTime.mins  = 59;
        AlarmTime.secs  = 55;
        AlarmTime.mSecs = 500;

    Best Regards.

  • Also, in addition to the above, if you wish to work with the current actual real time as indicated "by your watch", then you'd have to set your 'init' fields accordingly. RTC provides a time reference to an application executing on the DSP. And it doesn't know the current real-time by your watch on it's own. You'd need to feed it explicity as in the code above.

    Hence if you wish to have the RTC running by your watch, then RTC init must be one of the very first steps that you've in your app so that it can be run as soon as the dsp is powered on and there is minimum time-lag between RTC and your watch.

    Best Regards.

  • Dear KRaviS,

    thanks again for your prompt answer. I understand your points. But I am looking for something else.

    I'll try to explaing with an example. I have a master that sends a message to the slave having a C5000 DSP. The message from the master contains a field that tells the slave for how long the slave should sleep (lets call it sleep time, say an Uint32 number representing the millisecond). Therefore, the actions that the slave has to undertake once the message has been detected are:

    1) Read current RTC;

    2) Add to the actual RTC the sleep time;

    3) Issue a sleep command.

    My problem stems from the fact that in step 2 I would like to write something like 

    AlarmTime.mSecs = InitTime.mSecs + sleep_time

    but this would not work for the reasons explained due to minute hour and day increase.

    I hope things a clearer now. Sorry for the confusion and thanks for your effort.

  • Sorry. Regret the inconvenience, gaps in understanding. Nevertheless, would like to try to mitigate the same. Kindly let me know if the following helps, or if I've still not been able to nail your concern.

    1. The RTC needs to be initialized and started first to track real-time. Once RTC is running, there are CSL_Library functions such as RTC_getTime() and RTC_getDate() that can be used to poll the current time. To have it run just like a standard watch, what I'd have done would be: Initialize the RTC regs (RTCMIL, RTCSEC, RTCMIN, RTCHOUR) with the init time and include this init section and the RTC-start section of code, say, in the gel file, or as the very first few instrns to be executed in your entry-point func(), say, main(). So that as soon as dsp is powered on, these instructions are executed within the very first micro-seconds, and the RTC-actual current time-lag is minimal. Would have fed in the init time as something, say, 5mins from whatever the watch reads out now. Thereafter, would have compiled, powered on the target, launched and run the code after the 5-min gap.

    2. Please let me know if the concern is that by the time you set the alarm_time to be current_time + sleep_time, time would already have been elapsed in executing these instrns and hence you won't have your alarm at the right instant? Is that what you mean by min/hr/day increase? If so, the dsp is running fast enough (med. speed being 100MHz and peak speed 200MHz) and will be able to execute these instrns quickly enough so that the erroneous lag is minimal.

    3. Something like the following is what I'd be expecting the code to do:

    Either the gel-file or the initial section of your main() should have the following (code for gel-file will be a bit different according to the gel-file syntax, the regs may be directly addressed and updated):

    /* Set the RTC init structure */
        InitDate.year  = 2014;
        InitDate.month = 12;      ---> Current Date in your watch
        InitDate.day   = 31;

        InitTime.hours = 23;
        InitTime.mins  = 59;
        InitTime.secs  = 55;       ---> Current Time in your watch
        InitTime.mSecs = 0;

        /* Configure and enable the RTC interrupts using INTC module */
        IRQ_globalDisable();
        /* Clear any pending interrupts */
        IRQ_clearAll();
        /* Disable all the interrupts */
        IRQ_disableAll();
        IRQ_setVecs((Uint32)&VECSTART);
        IRQ_clear(RTC_EVENT);
        IRQ_plug (RTC_EVENT, &rtc_isr);
        IRQ_enable(RTC_EVENT);
        IRQ_globalEnable();


        /* Reset the RTC */
        RTC_reset();
        /* Configure the RTC module */
        status = RTC_config(&rtcConfig);
        /* Set the RTC time */
        status = RTC_setTime(&InitTime);
        /* Set the RTC date */
        status = RTC_setDate(&InitDate);
        /* Start the RTC */
        RTC_start(); //RTC will start running in the background

    ...
    ...
    ...

    Next, within main() where your app would be maybe having a while(1) polling for the msg from Master:

    while(1) //RTC will still be running in the background
    {
    ...
    ...
      if(Master_msg_received == TRUE)
      {
        status = RTC_getTime(&GetTime);   // GetTime defined as CSL_RtcTime   GetTime;
        status = RTC_getDate(&GetDate);   // GetDate defined as CSL_RtcDate   GetDate;
     
        /* Set the RTC alarm time */
        AlarmTime.year  = GetDate.year + sleep_time_year;
        AlarmTime.month = GetDate.month + sleep_time_month;
        AlarmTime.day   = GetDate.day + sleep_time_day;
        AlarmTime.hours = GetTime.hours + sleep_time_hours;
        AlarmTime.mins  = GetTime.mins + sleep_time_mins;
        AlarmTime.secs  = GetTime.secs + sleep_time_secs;
        AlarmTime.mSecs = GetTime.mSecs + sleep_time_msecs;

     /* Set the RTC Alarm time */
     status = RTC_setAlarm(&AlarmTime);
     /* Enable the RTC alarm interrupts */
     status = RTC_eventEnable(CSL_RTC_ALARM_INTERRUPT);
        ...
        ...
        ...
      }
    ...
    ...
    }

  • Dear KRaviS,

    I guess we are alligned now. I am not really worried about the small error due to the instructions execution. I am more concerned about the sums

        AlarmTime.year  = GetDate.year + sleep_time_year;
        AlarmTime.month = GetDate.month + sleep_time_month;
        AlarmTime.day   = GetDate.day + sleep_time_day;
        AlarmTime.hours = GetTime.hours + sleep_time_hours;
        AlarmTime.mins  = GetTime.mins + sleep_time_mins;
        AlarmTime.secs  = GetTime.secs + sleep_time_secs;
        AlarmTime.mSecs = GetTime.mSecs + sleep_time_msecs;

    Assume that GetTime.mSecs = 800 and the message says to wait for 500ms. Then I cannot really sum 800+500 without taking care of the fact that i have to increase also the AlarmTime.secs and, eventually, also  AlarmTime.mins, etc...My original question was if there are CSL functions that can help this.

    Best

  • Thank You Daniele.

    Yes, you're right. With the currently available release, a CSL function that will simply take in the time-gap as a parameter and generate an alarm after the same gets elapsed, is not available. One would have to feed the exact date and time when the alarm is required to be generated.

    Best Regards.