Alarm library for use with mbed.

AlarmTimeDate.h

Committer:
charlesgt
Date:
2010-10-31
Revision:
1:f4c7f13e5553
Parent:
0:33dddd0644c5
Child:
2:23e65cacea5a

File content as of revision 1:f4c7f13e5553:

/* mbed AlarmTimeDate Library
 * Copyright (c) 2010 Charles Garcia-Tobin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef __ALARM_TIME_DATE_H__
#define __ALARM_TIME_DATE_H__

/** 
 * Alarm callback function pointer type
 */
typedef void (*AlarmCbFn)(void*);

/** 
 * Alarm callback function pointer type
 */
typedef void (*SleepFn)(void*);

/** 
 * AlarmTimeDate class
 * Alarm class, alarms can be set for a specific date and time and can be set to repeat
 * daily, weekly, fortnightly, monthly or yearly. It is also possible to repeat
 * daily skip whilst skipping weekends.
 * The main program loop needs to call the Tick function below. However the function 
 * does take a SleepFn function pointer which can be used to to sleep the device 
 * the class will generate an RTC interrupt when an alarm goes off
 * Example usage:
 * \code
 * #include "mbed.h"
 * #include "AlarmTimeDate.h"
 *
 * DigitalOut led1(LED1);
 *
 * void __DoSleep(void *) {
 *     __WFE();
 * }
 *
 * void AlarmFn(void *) {
 *     led1 = !led1;    
 *     time_t now = time(NULL);
 *     printf("Expiring %s! ",ctime(&now));
 * }
 *
 *
 * int main() {
 *    led1 = 0;
 *    time_t seconds;
 *
 *    // setup time structure for 29 Oct 2010 00:00:00
 *    struct tm t;
 *    t.tm_sec = 00;    // 0-59
 *    t.tm_min = 00;    // 0-59
 *    t.tm_hour = 00;   // 0-23
 *    t.tm_mday = 29;   // 1-31
 *    t.tm_mon = 9;     // 0-11
 *    t.tm_year = 110;  // year since 1900
 *    seconds = mktime(&t);
 *    set_time(seconds);
 *    AlarmTimeDate::Init();
 *    AlarmTimeDate a1(AlarmFn,NULL,seconds+2);
 *    do {
 *            AlarmTimeDate::PrintAlarms(); 
 *            AlarmTimeDate::Tick(__DoSleep,NULL); 
 *            seconds+=4;
 *            a1.Set(seconds);
 *    } while(1);
 * }
 * \endcode
 **/

 class AlarmTimeDate {
 public:
   /** 
    * repeat types
    */
     enum TRepeat {
        ENone,
        EDaily,
        EDailyNoWeeked,
        EWeekly,
        EFortNightly,
        EMonthly,
        EYearly
        };
     
   /** 
    * @return time of this alarm's expiry as a time_t (secs since 00:00:00 1/1/1970) 
    *         0 if alarm is not set
    */
    time_t AsTimeT() { return iTime; }
   /** 
    * @return time of this alarm's expiry as a tm struct
    *         NULL if alarm is not set
    */
   struct tm* AsTM() { return (iTime) ? localtime(&iTime) : NULL; } 
              
   /** Set alarm using time_t value (secs since 00:00:00 1/1/1970) 
    * @param time_t aTime alarm expiry time
    */
    void Set(time_t aTime) { iTime = aTime; Tick(NULL,NULL); }

   /** Set alarm using tm struct
    * @param struct tm* aTm alarm expiry time
    */
    void Set(struct tm* aTm) {iTime = mktime(aTm); Tick(NULL,NULL); }

   /** 
    * @return repeat type
    */
    TRepeat Repeat() {
        return iRepeat;
        }
    
   /** Set repeat type 
    * @param TRepeat aRepeat
    */
    void SetRepeat(TRepeat aRepeat) {
        iRepeat = aRepeat;
    Tick(NULL,NULL);
        }

   /** Set pointer to pass to alarm callback function
    * @param void* aPtr
    */
    void SetPtr(void *aPtr) { iPtr = aPtr; }

   /** 
    * @return pointer used in alarm callback function
    */
    void* Ptr() { return iPtr; }
    
   /** Set alarm callback function
    * @param AlarmCbFn aFn
    */
    void SetFn(AlarmCbFn aFn) { iFn = aFn; }

   /** 
    * @return pointer to alarm callback function
    */
    AlarmCbFn Fn() { return iFn; }

   /** default constructor, alarm not set
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr);        

   /** fixed time/date 
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    * @param int aHours hour 0 to 23
    * @param int aMins mins 0 to 59
    * @param int aSecs seconds 0 to 59
    * @param int aDayM day of month 1 to 31
    * @param int aMon month 1 to 12
    * @param int aYear 
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr, int aHours, int aMins, int aSecs, int aDayM, int aMon, int aYear);
   /** create daily alarm
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    * @param int aHours
    * @param int aMins
    * @param int aSecs
    * @param bool aSkipWeekends default to false
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr, int aHours, int aMins, int aSecs, bool aSkipWeekends = false);   

   /** weekly or fornightly 
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    * @param int aHours
    * @param int aMins
    * @param int aSecs
    * @param int aDayOfWeek day of week 0..6 (0 is Sunday)create daily alarm
    * @param bool aFortNightly default to false
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr, int aHours, int aMins, int aSecs, int aDayW, bool aFortNightly = false);
  
   /** Monthly
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    * @param int aHours
    * @param int aMins
    * @param int aSecs
    * @param int aDayM day of month 1 to 31
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr, int aHours, int aMins, int aSecs, int aDayM); 

   /** Yearly
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    * @param int aHours
    * @param int aMins
    * @param int aSecs
    * @param int aDayM day of month 1 to 31
    * @param int aMonth 1 to 12
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr, int aHours, int aMins, int aSecs, int aDayM, int aMon); // Yearly
        
   /** construct with tm type
    * note that day of year and day of week are ignored, if repeating is required use SetRepeat
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    * @param aTm 
    * @see SetRepeat
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr, struct tm* aTm );

   /** construct with seconds since 00:00:00 1st Jan 1970
    * @param AlarmCbFn aFn callback function
    * @param void* aPtr callback function parameter
    * @param aSec
    * @see SetRepeat
    */
    AlarmTimeDate(AlarmCbFn aFn, void* aPtr, time_t aSec );

   /** desctructor 
    */
    ~AlarmTimeDate();

   /** print when Alarm will next expire
    */
    void PrintAlarm(); 
      
   /** print all alarms expiry times
    */
    static void PrintAlarms();

   /** Tick the Alarm system, will expire any pending alarms, set next one to expire 
    * and then sleep. The sleep method is provided by the SleepFn function pointer and 
    * should be based around a WFE or WFI.The alarm expiry causes an RTC which will 
    * cause the sleep function to wake, after that Tick will exit and should be called 
    * as part of the main loop of the applicaiton
    * @param SleepFn aFn sleep function
    * @param void* aParam optional paramter to pass into the sleep function
    */
    static void Tick(SleepFn aFn,void* aParam);

   /** Init function to be called once before alarms are used
    */
    static void Init();
private:
    void Queue();
    void DeQueue();
    void Expire();
    void Set();
    static void RTCISR();
    
private:
    time_t  iTime;
    AlarmCbFn iFn;
    void* iPtr;
    AlarmTimeDate* iNext; 
    TRepeat iRepeat;
    };

#endif //__ALARM_TIME_DATE_H__