Support KL25z requirements
Fork of RTC by
RTC.cpp
- Committer:
- Sissors
- Date:
- 2012-12-05
- Revision:
- 0:39767ffe05e6
- Child:
- 1:be9d058ee5c7
File content as of revision 0:39767ffe05e6:
#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; }