Support KL25z requirements
Fork of RTC by
Diff: RTC.cpp
- 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