Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Mini_DK_clk MakerBotServer GT-ACQUAPLUS_Consumo GT-ACQUAPLUS_Eficiencia ... more
Revision 1:be9d058ee5c7, committed 2012-12-07
- Comitter:
- Sissors
- Date:
- Fri Dec 07 20:50:43 2012 +0000
- Parent:
- 0:39767ffe05e6
- Commit message:
- v1.0;
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 |
diff -r 39767ffe05e6 -r be9d058ee5c7 RTC.cpp
--- 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
diff -r 39767ffe05e6 -r be9d058ee5c7 RTC.h
--- a/RTC.h Wed Dec 05 21:03:44 2012 +0000
+++ b/RTC.h Fri Dec 07 20:50:43 2012 +0000
@@ -3,17 +3,116 @@
#include "mbed.h"
-
+/**
+* Library to get access to the interrupt functionality of the LPC1768's RTC.
+*
+* This class is completely static: which means you don't have to create an RTC object,
+* there is always one object automatically created when you include this class. Since
+* there is only one RTC, more than one would make no sense.
+*
+* @code
+* #include "mbed.h"
+* #include "RTC.h"
+*
+* DigitalOut led(LED1);
+*
+* void ledFunction( void )
+* {
+* led = 1;
+* RTC::detach(RTC::Second);
+* }
+*
+* void displayFunction( void )
+* {
+* time_t seconds = time(NULL);
+* printf("%s", ctime(&seconds));
+* }
+*
+* void alarmFunction( void )
+* {
+* error("Not most useful alarm function");
+* }
+*
+* int main()
+* {
+* set_time(1256729737); // Set time to Wed, 28 Oct 2009 11:35:37
+*
+* tm t = RTC::getDefaultTM();
+* t.tm_sec = 5;
+* t.tm_min = 36;
+*
+* RTC::alarm(&alarmFunction, t);
+* RTC::attach(&displayFunction, RTC::Second);
+* RTC::attach(&ledFunction, RTC::Minute);
+*
+* while(1);
+* }
+* @endcode
+**/
class RTC {
public:
+ /**
+ * Available time units for interrupts
+ *
+ * RTC::Second, RTC::Minute, RTC::Hour,
+ * RTC::Day, RTC::Month, RTC::Year
+ */
enum TimeUnit {Second, Minute, Hour,
Day, Month, Year};
-
+
+ /**
+ * Call a function when the specified time unit increases
+ *
+ * You can attach one function for each TimeUnit. When several are
+ * attached the smalles TimeUnit is called first.
+ *
+ * Member functions of a class can be attached the normal way (similar to for example Ticker).
+ *
+ * @param function - the function to call
+ * @param interval - the TimeUnit which specifies the interval
+ */
static void attach(void (*function)(void), TimeUnit interval);
+ template<typename T>
+ void attach(T *object, void (T::*member)(void), TimeUnit interval);
+
+ /**
+ * Detach an interrupt function
+ *
+ * @param interval - the TimeUnit of the interrupt to detach
+ */
+ static void detach(TimeUnit interval);
- static void alarm(void (*function)(void), tm time);
+ /**
+ * Call a function when a specified time is reached
+ *
+ * Only one alarm is possible. Make fields of the tm structure -1 for don't care.
+ *
+ * Member functions of a class can be attached the normal way (similar to for example Ticker).
+ *
+ * @param function - the function to call
+ * @param alarmTime - tm structure which specifies when to activate the alarm
+ */
+ static void alarm(void (*function)(void), tm alarmTime);
+ template<typename T>
+ void alarm(T *object, void (T::*member)(void), tm alarmTime);
+ /**
+ * Disable the alarm
+ */
static void alarmOff( void );
+
+ /**
+ * Returns a default tm structure where each field is initialized
+ * to -1, so it is ignored by the alarm function.
+ *
+ * Available fields: http://www.cplusplus.com/reference/ctime/tm/
+ * Except tm_isdst all of them can be used for the alarm
+ *
+ * @param return - tm structure initialized to -1
+ */
+ static tm getDefaultTM( void );
+
+
private:
static void IRQHandler( void );
@@ -23,6 +122,8 @@
//If someone knows a nicer way to do this, please tell me
static bool initialRun;
+ static void _attach(TimeUnit interval);
+ static void _alarm(tm alarmTime);
};