Support KL25z requirements

Dependents:   kl25z_Usb_Logger

Fork of RTC by Erik -

Revision:
1:be9d058ee5c7
Parent:
0:39767ffe05e6
Child:
2:b61676bcc5c0
--- a/RTC.cpp	Wed Dec 05 21:03:44 2012 +0000
+++ b/RTC.cpp	Fri Dec 07 20:50:43 2012 +0000
@@ -5,8 +5,25 @@
 
 bool RTC::initialRun = true;
 
+
 void RTC::attach(void (*function)(void), TimeUnit interval)
 {
+    //Set the function pointer
+    attachCB[interval].attach(function);
+    _attach(interval);
+}
+
+template<typename T>
+void RTC::attach(T *object, void (T::*member)(void), TimeUnit interval)
+{
+    //Set the function pointer
+    attachCB[interval].attach(object, member);
+    _attach(interval);
+}
+
+
+void RTC::_attach(TimeUnit interval)
+{
     //Disable IRQs, dont want them to happen while busy here
     NVIC_DisableIRQ(RTC_IRQn);
 
@@ -22,61 +39,76 @@
         LPC_RTC->ILR = 0x03;
     }
 
-    //Set the function pointer
-    attachCB[interval].attach(function);
-
+    //Set/reset correct interrupt source
+    switch (interval) {
+        case Second:
+            LPC_RTC->CIIR |= 1;
+            break;
+        case Minute:
+            LPC_RTC->CIIR |= 2;
+            break;
+        case Hour:
+            LPC_RTC->CIIR |= 4;
+            break;
+        case Day:
+            LPC_RTC->CIIR |= 56;
+            break;
+        case Month:
+            LPC_RTC->CIIR |= 64;
+            break;
+        case Year:
+            LPC_RTC->CIIR |= 128;
+            break;
+    }
 
-    //Set/reset correct interrupt source
-    if (function == NULL) {
-        switch (interval) {
-            case Second:
-                LPC_RTC->CIIR &= ~1;
-                break;
-            case Minute:
-                LPC_RTC->CIIR &= ~2;
-                break;
-            case Hour:
-                LPC_RTC->CIIR &= ~4;
-                break;
-            case Day:
-                LPC_RTC->CIIR &= ~56;
-                break;
-            case Month:
-                LPC_RTC->CIIR &= ~64;
-                break;
-            case Year:
-                LPC_RTC->CIIR &= ~128;
-                break;
-        }
-    } else {
-        switch (interval) {
-            case Second:
-                LPC_RTC->CIIR |= 1;
-                break;
-            case Minute:
-                LPC_RTC->CIIR |= 2;
-                break;
-            case Hour:
-                LPC_RTC->CIIR |= 4;
-                break;
-            case Day:
-                LPC_RTC->CIIR |= 56;
-                break;
-            case Month:
-                LPC_RTC->CIIR |= 64;
-                break;
-            case Year:
-                LPC_RTC->CIIR |= 128;
-                break;
-        }
-    }
 
     //We can always enable IRQs, since if all IRQs are disabled by the user the RTC hardware will never raise its IRQ flag anyway
     NVIC_EnableIRQ(RTC_IRQn);
 }
 
+void RTC::detach(TimeUnit interval)
+{
+    switch (interval) {
+        case Second:
+            LPC_RTC->CIIR &= ~1;
+            break;
+        case Minute:
+            LPC_RTC->CIIR &= ~2;
+            break;
+        case Hour:
+            LPC_RTC->CIIR &= ~4;
+            break;
+        case Day:
+            LPC_RTC->CIIR &= ~56;
+            break;
+        case Month:
+            LPC_RTC->CIIR &= ~64;
+            break;
+        case Year:
+            LPC_RTC->CIIR &= ~128;
+            break;
+    }
+    attachCB[interval].attach(NULL);
+}
 
-void RTC::alarm(void (*function)(void), tm time)
+
+void RTC::alarm(void (*function)(void), tm alarmTime)
+{
+    //Set the function pointer
+    alarmCB.attach(function);
+    _alarm(alarmTime);
+}
+
+template<typename T>
+void RTC::alarm(T *object, void (T::*member)(void), tm alarmTime)
+{
+    //Set the function pointer
+    alarmCB.attach(object, member);
+    _alarm(alarmTime);
+}
+
+
+void RTC::_alarm(tm alarmTime)
 {
     //Disable IRQs, dont want them to happen while busy here
     NVIC_DisableIRQ(RTC_IRQn);
@@ -93,53 +125,69 @@
         LPC_RTC->ILR = 0x03;
     }
 
-    //Set the function pointer
-    alarmCB.attach(function);
-    
     //Set the alarm register
-    if ((time.tm_sec>=0) && (time.tm_sec<60)) {
-        LPC_RTC->ALSEC = time.tm_sec;
+    if ((alarmTime.tm_sec>=0) && (alarmTime.tm_sec<60)) {
+        LPC_RTC->ALSEC = alarmTime.tm_sec;
         LPC_RTC->AMR &= ~1;
     } else
         LPC_RTC->AMR |= 1;
 
-    if ((time.tm_min>=0) && (time.tm_min<60)) {
-        LPC_RTC->ALMIN = time.tm_min;
+    if ((alarmTime.tm_min>=0) && (alarmTime.tm_min<60)) {
+        LPC_RTC->ALMIN = alarmTime.tm_min;
         LPC_RTC->AMR &= ~2;
     } else
         LPC_RTC->AMR |= 2;
 
-    if ((time.tm_hour>=0) && (time.tm_hour<24)) {
-        LPC_RTC->ALHOUR = time.tm_hour;
+    if ((alarmTime.tm_hour>=0) && (alarmTime.tm_hour<24)) {
+        LPC_RTC->ALHOUR = alarmTime.tm_hour;
         LPC_RTC->AMR &= ~4;
     } else
         LPC_RTC->AMR |= 4;
 
-    if ((time.tm_mday>=1) && (time.tm_mday<32)) {
-        LPC_RTC->ALDOM = time.tm_mday;
+    if ((alarmTime.tm_mday>=1) && (alarmTime.tm_mday<32)) {
+        LPC_RTC->ALDOM = alarmTime.tm_mday;
         LPC_RTC->AMR &= ~8;
     } else
-        LPC_RTC->AMR |= 8;        
-        
-    if ((time.tm_mon>=0) && (time.tm_mon<12)) {
-        LPC_RTC->ALMON = time.tm_mon + 1;   //Different definitions
+        LPC_RTC->AMR |= 8;
+
+    if ((alarmTime.tm_wday>=0) && (alarmTime.tm_wday<7)) {
+        LPC_RTC->ALDOW = alarmTime.tm_wday;
+        LPC_RTC->AMR &= ~16;
+    } else
+        LPC_RTC->AMR |= 16;
+
+    if ((alarmTime.tm_yday>0) && (alarmTime.tm_yday<367)) {
+        LPC_RTC->ALDOY = alarmTime.tm_yday;
+        LPC_RTC->AMR &= ~32;
+    } else
+        LPC_RTC->AMR |= 32;
+
+    if ((alarmTime.tm_mon>=0) && (alarmTime.tm_mon<12)) {
+        LPC_RTC->ALMON = alarmTime.tm_mon + 1;   //Different definitions
         LPC_RTC->AMR &= ~64;
     } else
-        LPC_RTC->AMR |= 64;    
+        LPC_RTC->AMR |= 64;
 
-    if ((time.tm_year>=0) && (time.tm_year<1000)) {
-        LPC_RTC->ALYEAR = time.tm_year + 1900;   //Different definitions
+    if ((alarmTime.tm_year>=0) && (alarmTime.tm_year<1000)) {
+        LPC_RTC->ALYEAR = alarmTime.tm_year + 1900;   //Different definitions
         LPC_RTC->AMR &= ~128;
     } else
         LPC_RTC->AMR |= 128;
-        
+
+    //DOY and DOW register normally not set
+    time_t t = time(NULL);
+    LPC_RTC->DOY = localtime(&t)->tm_yday+1;
+    LPC_RTC->DOW = localtime(&t)->tm_wday;
+
     //We can always enable IRQs, since if all IRQs are disabled by the user the RTC hardware will never raise its IRQ flag anyway
     NVIC_EnableIRQ(RTC_IRQn);
 }
 
-void RTC::alarmOff( void ) {
+void RTC::alarmOff( void )
+{
     LPC_RTC->AMR = 255;
-    }
+    alarmCB.attach(NULL);
+}
 
 
 void RTC::IRQHandler( void )
@@ -180,4 +228,18 @@
 
     //Reset interrupt status
     LPC_RTC->ILR = 0x03;
-}
\ No newline at end of file
+}
+
+tm RTC::getDefaultTM( void ) {
+    struct tm t;
+    t.tm_sec = -1;   
+    t.tm_min = -1;    
+    t.tm_hour = -1;   
+    t.tm_mday = -1;
+    t.tm_wday = -1;
+    t.tm_yday = -1;   
+    t.tm_mon = -1;    
+    t.tm_year = -1; 
+    
+    return t;
+    }
\ No newline at end of file