Support KL25z requirements

Dependents:   kl25z_Usb_Logger

Fork of RTC by Erik -

Revision:
0:39767ffe05e6
Child:
1:be9d058ee5c7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RTC.cpp	Wed Dec 05 21:03:44 2012 +0000
@@ -0,0 +1,183 @@
+#include "RTC.h"
+
+FunctionPointer RTC::attachCB[6];
+FunctionPointer RTC::alarmCB;
+
+bool RTC::initialRun = true;
+
+void RTC::attach(void (*function)(void), TimeUnit interval)
+{
+    //Disable IRQs, dont want them to happen while busy here
+    NVIC_DisableIRQ(RTC_IRQn);
+
+    //Set the IRQ vector
+    NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler);
+
+    //If this is the first time it is called, delete all interrupt sources
+    //We need to do this because RTC unit isnt affected by system resets apparently
+    if (initialRun) {
+        LPC_RTC->CIIR = 0;
+        LPC_RTC->AMR = 255;
+        initialRun = false;
+        LPC_RTC->ILR = 0x03;
+    }
+
+    //Set the function pointer
+    attachCB[interval].attach(function);
+
+
+    //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::alarm(void (*function)(void), tm time)
+{
+    //Disable IRQs, dont want them to happen while busy here
+    NVIC_DisableIRQ(RTC_IRQn);
+
+    //Set the IRQ vector
+    NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler);
+
+    //If this is the first time it is called, delete all interrupt sources
+    //We need to do this because RTC unit isnt affected by system resets apparently
+    if (initialRun) {
+        LPC_RTC->CIIR = 0;
+        LPC_RTC->AMR = 255;
+        initialRun = false;
+        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;
+        LPC_RTC->AMR &= ~1;
+    } else
+        LPC_RTC->AMR |= 1;
+
+    if ((time.tm_min>=0) && (time.tm_min<60)) {
+        LPC_RTC->ALMIN = time.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;
+        LPC_RTC->AMR &= ~4;
+    } else
+        LPC_RTC->AMR |= 4;
+
+    if ((time.tm_mday>=1) && (time.tm_mday<32)) {
+        LPC_RTC->ALDOM = time.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 &= ~64;
+    } else
+        LPC_RTC->AMR |= 64;    
+
+    if ((time.tm_year>=0) && (time.tm_year<1000)) {
+        LPC_RTC->ALYEAR = time.tm_year + 1900;   //Different definitions
+        LPC_RTC->AMR &= ~128;
+    } else
+        LPC_RTC->AMR |= 128;
+        
+    //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 ) {
+    LPC_RTC->AMR = 255;
+    }
+
+
+void RTC::IRQHandler( void )
+{
+    if ((LPC_RTC->ILR & 0x01) == 0x01) {
+        //Attach interrupt
+        attachCB[0].call();
+
+        //If seconds zero
+        if (LPC_RTC->SEC == 0) {
+            attachCB[1].call();
+
+            //If minutes zero
+            if (LPC_RTC->MIN == 0) {
+                attachCB[2].call();
+
+                //If hours zero
+                if (LPC_RTC->HOUR == 0) {
+                    attachCB[3].call();
+
+                    //If days zero
+                    if (LPC_RTC->DOM == 0) {
+                        attachCB[4].call();
+
+                        //If month zero
+                        if (LPC_RTC->MONTH == 0)
+                            attachCB[5].call();
+                    }
+                }
+            }
+        }
+    }
+
+    if ((LPC_RTC->ILR & 0x02) == 0x02)
+        alarmCB.call();
+
+
+
+    //Reset interrupt status
+    LPC_RTC->ILR = 0x03;
+}
\ No newline at end of file