Alarm library for use with mbed.

Files at this revision

API Documentation at this revision

Comitter:
charlesgt
Date:
Mon Nov 15 23:22:07 2010 +0000
Parent:
1:f4c7f13e5553
Commit message:
can now set within within expiry function

Changed in this revision

AlarmTimeDate.cpp Show annotated file Show diff for this revision Revisions of this file
AlarmTimeDate.h Show annotated file Show diff for this revision Revisions of this file
diff -r f4c7f13e5553 -r 23e65cacea5a AlarmTimeDate.cpp
--- a/AlarmTimeDate.cpp	Sun Oct 31 08:13:17 2010 +0000
+++ b/AlarmTimeDate.cpp	Mon Nov 15 23:22:07 2010 +0000
@@ -1,6 +1,11 @@
 #include "mbed.h"
 #include "AlarmTimeDate.h"
 
+volatile uint8_t AlarmTimeDate::iRTCIsSet = 0u;
+volatile uint8_t AlarmTimeDate::iIsrCount = 0u;
+volatile uint8_t AlarmTimeDate::iPad0 = 0u;
+volatile uint8_t AlarmTimeDate::iPad1 = 0u;
+
 static AlarmTimeDate* list = NULL;
 
 void AlarmTimeDate::PrintAlarm() {
@@ -171,7 +176,12 @@
 }
 
 void AlarmTimeDate::Set() {
-    struct tm* localt = localtime(&iTime);
+    time_t seconds = time(NULL);
+    if (iTime <= seconds) seconds++;
+    else seconds = iTime;
+    struct tm* localt = localtime(&seconds);
+    __disable_irq();
+    iRTCIsSet = 1;
     LPC_RTC->ALSEC = localt->tm_sec;
     LPC_RTC->ALMIN = localt->tm_min;
     LPC_RTC->ALHOUR = localt->tm_hour;
@@ -179,9 +189,11 @@
     LPC_RTC->ALMON = localt->tm_mon+1;
     LPC_RTC->ALYEAR = localt->tm_year+1900;
     LPC_RTC->AMR = (uint8_t)~0xcfu; // match those above
+    __enable_irq();
 }
 
 void AlarmTimeDate::Expire() {
+    time_t expiry = time(NULL);
     iFn(iPtr);
     struct tm * sectm;
     switch (Repeat()) {
@@ -191,8 +203,9 @@
         case EDailyNoWeeked:
             sectm = localtime(&iTime);
             if (sectm->tm_wday==6)
-                iTime+=7*24*3600;  // its friday, skip it to sunday
+                iTime+=2*24*3600;  // its friday, skip it to sunday
             iTime+=24*3600;
+            break;
         case EWeekly:
             iTime+=7*24*3600;
             break;
@@ -201,8 +214,8 @@
             break;
         case EMonthly:
             sectm = localtime(&iTime);
-            if (++sectm->tm_mon==32) {
-                sectm->tm_mon=1;
+            if (++sectm->tm_mon==12) {
+                sectm->tm_mon=0;
                 sectm->tm_year++;
             }
             iTime = mktime(sectm);
@@ -213,7 +226,8 @@
             iTime = mktime(sectm);
             break;
         default:
-            iTime = 0;
+            // could have been reset
+            if ( expiry >= iTime ) iTime = 0;
     }
 }
 
@@ -227,10 +241,22 @@
 
 void AlarmTimeDate::RTCISR() {
     LPC_RTC->ILR = 0x3;
+    iRTCIsSet = 0;
+    iIsrCount++;
+    printf("I:%d\n",iIsrCount);
 }
 
 void AlarmTimeDate::Tick(SleepFn aFn,void* aParam) {
-    if (aFn) aFn(aParam); // sleep first
+redo:
+    printf("ticking %d\n",++iPad0);
+    if (aFn) printf("Sleeping at %x\n",time(NULL));
+    if (aFn && iRTCIsSet) {
+        aFn(aParam);
+    }
+    __disable_irq();
+    if (iIsrCount) iIsrCount--;
+    __enable_irq();
+    if (aFn ) printf("waking at %x\n",time(NULL));
     AlarmTimeDate* p = list;
     AlarmTimeDate* toSet = NULL;
     time_t seconds = time(NULL);
@@ -239,7 +265,6 @@
         if (p->iTime && p->iTime <= seconds) p->Expire();
         p = p->iNext;
     }
-    seconds = time(NULL);
     p = list;
     while (p) {
         if (p->iTime) {
@@ -256,6 +281,10 @@
         p = p->iNext;
     }
     if (toSet) {
+        printf("found something to set %x\n",toSet->iTime);
         toSet->Set();
     }
-}
+
+    printf("ticking done %d:%d\n",--iPad0,iIsrCount);
+    if (iIsrCount) goto redo;
+}
\ No newline at end of file
diff -r f4c7f13e5553 -r 23e65cacea5a AlarmTimeDate.h
--- a/AlarmTimeDate.h	Sun Oct 31 08:13:17 2010 +0000
+++ b/AlarmTimeDate.h	Mon Nov 15 23:22:07 2010 +0000
@@ -19,7 +19,6 @@
  * 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__
 
@@ -40,6 +39,8 @@
  * 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 
+ * note sleep will be called with interrupts off,the wake interrupt of the RTC 
+ * will wake out of sleep
  * the class will generate an RTC interrupt when an alarm goes off
  * Example usage:
  * \code
@@ -133,8 +134,9 @@
     */
     void SetRepeat(TRepeat aRepeat) {
         iRepeat = aRepeat;
-    Tick(NULL,NULL);
+        Tick(NULL,NULL);
         }
+        
 
    /** Set pointer to pass to alarm callback function
     * @param void* aPtr
@@ -270,6 +272,10 @@
     void* iPtr;
     AlarmTimeDate* iNext; 
     TRepeat iRepeat;
+    static volatile uint8_t iRTCIsSet;
+    static volatile uint8_t iIsrCount;
+    static volatile uint8_t iPad0;
+    static volatile uint8_t iPad1;
     };
 
 #endif //__ALARM_TIME_DATE_H__