teste de publish
Dependencies: DS1820 HighSpeedAnalogIn devices mbed
RTC/RTC.cpp
- Committer:
- brunofgc
- Date:
- 2018-06-08
- Revision:
- 38:07d3907b74e5
- Parent:
- 0:1c0a769988ee
File content as of revision 38:07d3907b74e5:
#include "RTC.h" FunctionPointer RTC::attachCB[6]; FunctionPointer RTC::alarmCB; 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); //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/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; } //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 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); //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 alarm register 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 ((alarmTime.tm_min>=0) && (alarmTime.tm_min<60)) { LPC_RTC->ALMIN = alarmTime.tm_min; LPC_RTC->AMR &= ~2; } else LPC_RTC->AMR |= 2; 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 ((alarmTime.tm_mday>=1) && (alarmTime.tm_mday<32)) { LPC_RTC->ALDOM = alarmTime.tm_mday; LPC_RTC->AMR &= ~8; } else 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; 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 ) { LPC_RTC->AMR = 255; alarmCB.attach(NULL); } 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; } 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; }