Support KL25z requirements

Dependents:   kl25z_Usb_Logger

Fork of RTC by Erik -

Files at this revision

API Documentation at this revision

Comitter:
Sissors
Date:
Wed Dec 05 21:03:44 2012 +0000
Child:
1:be9d058ee5c7
Commit message:
Version 1, lacks comments, seems to work

Changed in this revision

RTC.cpp Show annotated file Show diff for this revision Revisions of this file
RTC.h Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RTC.h	Wed Dec 05 21:03:44 2012 +0000
@@ -0,0 +1,30 @@
+#ifndef RTC_H
+#define RTC_H
+
+#include "mbed.h"
+
+
+class RTC {
+public:
+    enum TimeUnit {Second, Minute, Hour, 
+                    Day, Month, Year};
+
+    static void attach(void (*function)(void), TimeUnit interval);
+    
+    static void alarm(void (*function)(void), tm time);
+    
+    static void alarmOff( void );
+
+private:
+    static void IRQHandler( void );
+
+    static FunctionPointer attachCB[6];
+    static FunctionPointer alarmCB;
+    
+    //If someone knows a nicer way to do this, please tell me
+    static bool initialRun;
+
+
+};
+
+#endif
\ No newline at end of file