10 Replies Latest reply on Apr 28, 2013 3:00 PM by user_78878863

    RTC Alarm Modes

    alex.b

      Hello All,

         

      I am working with the RTC component. I would like to schedule an alarm to trigger on time intervals relative to a set time. For example:

         

      Start time = 10:20:32

         

      Next alarm interval = Start time + 10 seconds = 10:20:42

         

      "Next Next" alarm interval = Start time + 20 seconds = 10:21:02

         

      I thought that this might be possible using the RTC's Alarm functionality. I wrote the following code to test it (with the other supporting code for the RTC of course):

         

      RTC_WriteAlarmMask(RTC_ALARM_SEC_MASK);

         

      RTC_WriteAlarmSecond(10u);

         

      Unfortunatley, this seems to not work. I may need to provide a full date and time to compare to. Does anyone have experience dealing with this sort of thing?

         

      Thank you.

        • 1. Re: RTC Alarm Modes
          user_78878863

          Think of the RTC alarm as a cron job specification: it takes the alarm register values specified by the alarm register mask, and compares them to the current time registers. If they all match, it triggers the alarm. (See data sheet page 21) So you need to take the time difference for the next alarm, add it to the current time, and set this as the alarm register values.

          • 2. Re: RTC Alarm Modes
            user_1377889

            You are right, different from your alarm-clock you have to specify not only a time but a date as well. Of course you can read-out the RTC and provide the alarm with the current date the clock provides.

               

            When you want to keep track of several different alarm-times you will have to build a list of events (ordered by time) and create new events when the first occurs. This smells a bit as if you could use a linked-list.

               

             

               

            Bob

            1 of 1 people found this helpful
            • 3. Re: RTC Alarm Modes
              alex.b

               Thank you for all your replies. Further research into the source code has determined that it is a direct comparison. For example:

                 

              alarm.sec == currentTime.sec

                 

              I have come up with an idea for a function:

                 

              RTC_TIME_DATE addInterval(RTC_TIME_DATE currentTime, RTC_TIME_DATE increment)

                 

              This function would return a structure with fields that reflect currentTime + increment. The question that I have now is would this lead to a memory leak?

                 

              If I used the code:

                 

              RTC_TIME_DATE nextTime;

                 

              for(;;)

                 

              {

                 

              //Assume that arguments are valid

                 

              nextTime = addInterval(RTC_GetCurrentTime(), 4_MIN_INCREMENT);

                 

              }

                 

              Wouldn't this cause nextTime to continue to be reassigned to a new struct created in local memory in the function addInterval? Is there a way to use free() on the nextTime pointer before reassigning it?

                 

              Thank you

              • 4. Re: RTC Alarm Modes
                user_78878863

                Typically such function take a pointer to the data structure, so the caller can control it. Your function would look like

                   
                void addInterval(RTC_TIME_DATE *currentTime, RTC_TIME_DATE *increment, RTC_TIME_DATE *target)
                   

                and the main code then has three fixed instances, and calls it like

                   
                addInterval(&currentTime, &increment, &alarmTime);
                   

                That way there is not memory leak.

                • 5. Re: RTC Alarm Modes
                  alex.b

                   hli,

                     

                  Thanks for your input. I agree that that method is probably best. I ended up using the following code:

                     

                   

                     

                  RTC_TIME_DATE* currentTime;

                     

                  RTC_TIME_DATE interval; //Holds the time that an interval will run

                     

                  RTC_TIME_DATE nextConnectTime; //Holds the next time that the system is expected to connect

                     

                   

                     

                   

                     

                  currentTime = RTC_ReadTime();

                     

                  addInterval(currentTime, &interval, &nextConnectTime);

                     

                   

                     

                  Since currentTime is a pointer, everytime you reassign it, it should simply change the memory location it is pointing to. This should prevent any potential memory leaks. So far, this method seems to work, but I haven't run it for an extended period of time to ensure that it does not crash.

                  • 6. Re: RTC Alarm Modes
                    user_78878863

                    Yes, this is the proper way to do it. RTC_ReadTime propably return the same pointer each time, but even if not (the documentation says nothing about it) you can trust it not to leak memory.

                       

                    Just checked the component source code - the method is implemented as:

                       
                        return (&`$INSTANCE_NAME`_currentTimeDate); 
                       

                    So you get a constant value. Therefore note the documentation on this method:

                       
                    * Side Effects: *  You should disable the interrupt for the RTC component before calling any *  read API to avoid an RTC Counter increment in the middle of a time or date *  read operation. Re-enable the interrupts after the data is read. 
                       

                    The value you get a pointer to will change otherwise...

                    • 7. Re: RTC Alarm Modes
                      user_1377889

                      This is exactly what CyEnterCriticalSection() and CyExitCriticalSection() are made for: just to temporarily disable interrupts and restore them back again to the prior state, regardless what that state (en- or disabled) was. Find the description in "System Reference Guide" under Creator -> Help -> Documentation ->system Reference.

                         

                       

                         

                      Happy coding

                         

                      Bob

                      • 8. Re: RTC Alarm Modes
                        user_78878863

                        Unfortunately the data sheet for the RTC is silent about this issue - for RTC_ReadTime it says "side effect - none". The comment is only in the component source code.

                        • 9. Re: RTC Alarm Modes
                          alex.b

                           The only thing that makes sense it that they would return the current time struct. This is exactly the kind of thing that an interrupt going off in the middle of the read could cause trouble. My thought is that I should probably use some kind of "copy" method.

                             

                          RTC_TIME_DATE* currentTime;

                             

                          RTC_TIME_DATE timeStamp;

                             

                          currentTime = RTC_ReadTime();

                             

                          //Copy time would copy the pertinent values from the RTC timer to a struct being used for manipulation

                             

                          CyEnterCriticalSection();

                             

                          copyTime(currentTime, &timeStamp);

                             

                          CyExitCriticalSection();

                             

                          //At the end of this, the timeStamp variable has the current time without needing to wory about the timer changing on us.

                          • 10. Re: RTC Alarm Modes
                            user_78878863

                            Yes, when you don't want to do all your calculation / update stuff in the critical section, copying the time structure (a simple memcpy should be OK) is advisable. But you should include the ReadTime() call in the critical section too (just to be sure).