Support KL25z requirements

Dependents:   kl25z_Usb_Logger

Fork of RTC by Erik -

Committer:
Sissors
Date:
Fri Dec 07 20:50:43 2012 +0000
Revision:
1:be9d058ee5c7
Parent:
0:39767ffe05e6
Child:
2:b61676bcc5c0
v1.0;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:39767ffe05e6 1 #include "RTC.h"
Sissors 0:39767ffe05e6 2
Sissors 0:39767ffe05e6 3 FunctionPointer RTC::attachCB[6];
Sissors 0:39767ffe05e6 4 FunctionPointer RTC::alarmCB;
Sissors 0:39767ffe05e6 5
Sissors 0:39767ffe05e6 6 bool RTC::initialRun = true;
Sissors 0:39767ffe05e6 7
Sissors 1:be9d058ee5c7 8
Sissors 0:39767ffe05e6 9 void RTC::attach(void (*function)(void), TimeUnit interval)
Sissors 0:39767ffe05e6 10 {
Sissors 1:be9d058ee5c7 11 //Set the function pointer
Sissors 1:be9d058ee5c7 12 attachCB[interval].attach(function);
Sissors 1:be9d058ee5c7 13 _attach(interval);
Sissors 1:be9d058ee5c7 14 }
Sissors 1:be9d058ee5c7 15
Sissors 1:be9d058ee5c7 16 template<typename T>
Sissors 1:be9d058ee5c7 17 void RTC::attach(T *object, void (T::*member)(void), TimeUnit interval)
Sissors 1:be9d058ee5c7 18 {
Sissors 1:be9d058ee5c7 19 //Set the function pointer
Sissors 1:be9d058ee5c7 20 attachCB[interval].attach(object, member);
Sissors 1:be9d058ee5c7 21 _attach(interval);
Sissors 1:be9d058ee5c7 22 }
Sissors 1:be9d058ee5c7 23
Sissors 1:be9d058ee5c7 24
Sissors 1:be9d058ee5c7 25 void RTC::_attach(TimeUnit interval)
Sissors 1:be9d058ee5c7 26 {
Sissors 0:39767ffe05e6 27 //Disable IRQs, dont want them to happen while busy here
Sissors 0:39767ffe05e6 28 NVIC_DisableIRQ(RTC_IRQn);
Sissors 0:39767ffe05e6 29
Sissors 0:39767ffe05e6 30 //Set the IRQ vector
Sissors 0:39767ffe05e6 31 NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler);
Sissors 0:39767ffe05e6 32
Sissors 0:39767ffe05e6 33 //If this is the first time it is called, delete all interrupt sources
Sissors 0:39767ffe05e6 34 //We need to do this because RTC unit isnt affected by system resets apparently
Sissors 0:39767ffe05e6 35 if (initialRun) {
Sissors 0:39767ffe05e6 36 LPC_RTC->CIIR = 0;
Sissors 0:39767ffe05e6 37 LPC_RTC->AMR = 255;
Sissors 0:39767ffe05e6 38 initialRun = false;
Sissors 0:39767ffe05e6 39 LPC_RTC->ILR = 0x03;
Sissors 0:39767ffe05e6 40 }
Sissors 0:39767ffe05e6 41
Sissors 1:be9d058ee5c7 42 //Set/reset correct interrupt source
Sissors 1:be9d058ee5c7 43 switch (interval) {
Sissors 1:be9d058ee5c7 44 case Second:
Sissors 1:be9d058ee5c7 45 LPC_RTC->CIIR |= 1;
Sissors 1:be9d058ee5c7 46 break;
Sissors 1:be9d058ee5c7 47 case Minute:
Sissors 1:be9d058ee5c7 48 LPC_RTC->CIIR |= 2;
Sissors 1:be9d058ee5c7 49 break;
Sissors 1:be9d058ee5c7 50 case Hour:
Sissors 1:be9d058ee5c7 51 LPC_RTC->CIIR |= 4;
Sissors 1:be9d058ee5c7 52 break;
Sissors 1:be9d058ee5c7 53 case Day:
Sissors 1:be9d058ee5c7 54 LPC_RTC->CIIR |= 56;
Sissors 1:be9d058ee5c7 55 break;
Sissors 1:be9d058ee5c7 56 case Month:
Sissors 1:be9d058ee5c7 57 LPC_RTC->CIIR |= 64;
Sissors 1:be9d058ee5c7 58 break;
Sissors 1:be9d058ee5c7 59 case Year:
Sissors 1:be9d058ee5c7 60 LPC_RTC->CIIR |= 128;
Sissors 1:be9d058ee5c7 61 break;
Sissors 1:be9d058ee5c7 62 }
Sissors 0:39767ffe05e6 63
Sissors 0:39767ffe05e6 64
Sissors 0:39767ffe05e6 65 //We can always enable IRQs, since if all IRQs are disabled by the user the RTC hardware will never raise its IRQ flag anyway
Sissors 0:39767ffe05e6 66 NVIC_EnableIRQ(RTC_IRQn);
Sissors 0:39767ffe05e6 67 }
Sissors 0:39767ffe05e6 68
Sissors 1:be9d058ee5c7 69 void RTC::detach(TimeUnit interval)
Sissors 1:be9d058ee5c7 70 {
Sissors 1:be9d058ee5c7 71 switch (interval) {
Sissors 1:be9d058ee5c7 72 case Second:
Sissors 1:be9d058ee5c7 73 LPC_RTC->CIIR &= ~1;
Sissors 1:be9d058ee5c7 74 break;
Sissors 1:be9d058ee5c7 75 case Minute:
Sissors 1:be9d058ee5c7 76 LPC_RTC->CIIR &= ~2;
Sissors 1:be9d058ee5c7 77 break;
Sissors 1:be9d058ee5c7 78 case Hour:
Sissors 1:be9d058ee5c7 79 LPC_RTC->CIIR &= ~4;
Sissors 1:be9d058ee5c7 80 break;
Sissors 1:be9d058ee5c7 81 case Day:
Sissors 1:be9d058ee5c7 82 LPC_RTC->CIIR &= ~56;
Sissors 1:be9d058ee5c7 83 break;
Sissors 1:be9d058ee5c7 84 case Month:
Sissors 1:be9d058ee5c7 85 LPC_RTC->CIIR &= ~64;
Sissors 1:be9d058ee5c7 86 break;
Sissors 1:be9d058ee5c7 87 case Year:
Sissors 1:be9d058ee5c7 88 LPC_RTC->CIIR &= ~128;
Sissors 1:be9d058ee5c7 89 break;
Sissors 1:be9d058ee5c7 90 }
Sissors 1:be9d058ee5c7 91 attachCB[interval].attach(NULL);
Sissors 1:be9d058ee5c7 92 }
Sissors 0:39767ffe05e6 93
Sissors 1:be9d058ee5c7 94
Sissors 1:be9d058ee5c7 95 void RTC::alarm(void (*function)(void), tm alarmTime)
Sissors 1:be9d058ee5c7 96 {
Sissors 1:be9d058ee5c7 97 //Set the function pointer
Sissors 1:be9d058ee5c7 98 alarmCB.attach(function);
Sissors 1:be9d058ee5c7 99 _alarm(alarmTime);
Sissors 1:be9d058ee5c7 100 }
Sissors 1:be9d058ee5c7 101
Sissors 1:be9d058ee5c7 102 template<typename T>
Sissors 1:be9d058ee5c7 103 void RTC::alarm(T *object, void (T::*member)(void), tm alarmTime)
Sissors 1:be9d058ee5c7 104 {
Sissors 1:be9d058ee5c7 105 //Set the function pointer
Sissors 1:be9d058ee5c7 106 alarmCB.attach(object, member);
Sissors 1:be9d058ee5c7 107 _alarm(alarmTime);
Sissors 1:be9d058ee5c7 108 }
Sissors 1:be9d058ee5c7 109
Sissors 1:be9d058ee5c7 110
Sissors 1:be9d058ee5c7 111 void RTC::_alarm(tm alarmTime)
Sissors 0:39767ffe05e6 112 {
Sissors 0:39767ffe05e6 113 //Disable IRQs, dont want them to happen while busy here
Sissors 0:39767ffe05e6 114 NVIC_DisableIRQ(RTC_IRQn);
Sissors 0:39767ffe05e6 115
Sissors 0:39767ffe05e6 116 //Set the IRQ vector
Sissors 0:39767ffe05e6 117 NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler);
Sissors 0:39767ffe05e6 118
Sissors 0:39767ffe05e6 119 //If this is the first time it is called, delete all interrupt sources
Sissors 0:39767ffe05e6 120 //We need to do this because RTC unit isnt affected by system resets apparently
Sissors 0:39767ffe05e6 121 if (initialRun) {
Sissors 0:39767ffe05e6 122 LPC_RTC->CIIR = 0;
Sissors 0:39767ffe05e6 123 LPC_RTC->AMR = 255;
Sissors 0:39767ffe05e6 124 initialRun = false;
Sissors 0:39767ffe05e6 125 LPC_RTC->ILR = 0x03;
Sissors 0:39767ffe05e6 126 }
Sissors 0:39767ffe05e6 127
Sissors 0:39767ffe05e6 128 //Set the alarm register
Sissors 1:be9d058ee5c7 129 if ((alarmTime.tm_sec>=0) && (alarmTime.tm_sec<60)) {
Sissors 1:be9d058ee5c7 130 LPC_RTC->ALSEC = alarmTime.tm_sec;
Sissors 0:39767ffe05e6 131 LPC_RTC->AMR &= ~1;
Sissors 0:39767ffe05e6 132 } else
Sissors 0:39767ffe05e6 133 LPC_RTC->AMR |= 1;
Sissors 0:39767ffe05e6 134
Sissors 1:be9d058ee5c7 135 if ((alarmTime.tm_min>=0) && (alarmTime.tm_min<60)) {
Sissors 1:be9d058ee5c7 136 LPC_RTC->ALMIN = alarmTime.tm_min;
Sissors 0:39767ffe05e6 137 LPC_RTC->AMR &= ~2;
Sissors 0:39767ffe05e6 138 } else
Sissors 0:39767ffe05e6 139 LPC_RTC->AMR |= 2;
Sissors 0:39767ffe05e6 140
Sissors 1:be9d058ee5c7 141 if ((alarmTime.tm_hour>=0) && (alarmTime.tm_hour<24)) {
Sissors 1:be9d058ee5c7 142 LPC_RTC->ALHOUR = alarmTime.tm_hour;
Sissors 0:39767ffe05e6 143 LPC_RTC->AMR &= ~4;
Sissors 0:39767ffe05e6 144 } else
Sissors 0:39767ffe05e6 145 LPC_RTC->AMR |= 4;
Sissors 0:39767ffe05e6 146
Sissors 1:be9d058ee5c7 147 if ((alarmTime.tm_mday>=1) && (alarmTime.tm_mday<32)) {
Sissors 1:be9d058ee5c7 148 LPC_RTC->ALDOM = alarmTime.tm_mday;
Sissors 0:39767ffe05e6 149 LPC_RTC->AMR &= ~8;
Sissors 0:39767ffe05e6 150 } else
Sissors 1:be9d058ee5c7 151 LPC_RTC->AMR |= 8;
Sissors 1:be9d058ee5c7 152
Sissors 1:be9d058ee5c7 153 if ((alarmTime.tm_wday>=0) && (alarmTime.tm_wday<7)) {
Sissors 1:be9d058ee5c7 154 LPC_RTC->ALDOW = alarmTime.tm_wday;
Sissors 1:be9d058ee5c7 155 LPC_RTC->AMR &= ~16;
Sissors 1:be9d058ee5c7 156 } else
Sissors 1:be9d058ee5c7 157 LPC_RTC->AMR |= 16;
Sissors 1:be9d058ee5c7 158
Sissors 1:be9d058ee5c7 159 if ((alarmTime.tm_yday>0) && (alarmTime.tm_yday<367)) {
Sissors 1:be9d058ee5c7 160 LPC_RTC->ALDOY = alarmTime.tm_yday;
Sissors 1:be9d058ee5c7 161 LPC_RTC->AMR &= ~32;
Sissors 1:be9d058ee5c7 162 } else
Sissors 1:be9d058ee5c7 163 LPC_RTC->AMR |= 32;
Sissors 1:be9d058ee5c7 164
Sissors 1:be9d058ee5c7 165 if ((alarmTime.tm_mon>=0) && (alarmTime.tm_mon<12)) {
Sissors 1:be9d058ee5c7 166 LPC_RTC->ALMON = alarmTime.tm_mon + 1; //Different definitions
Sissors 0:39767ffe05e6 167 LPC_RTC->AMR &= ~64;
Sissors 0:39767ffe05e6 168 } else
Sissors 1:be9d058ee5c7 169 LPC_RTC->AMR |= 64;
Sissors 0:39767ffe05e6 170
Sissors 1:be9d058ee5c7 171 if ((alarmTime.tm_year>=0) && (alarmTime.tm_year<1000)) {
Sissors 1:be9d058ee5c7 172 LPC_RTC->ALYEAR = alarmTime.tm_year + 1900; //Different definitions
Sissors 0:39767ffe05e6 173 LPC_RTC->AMR &= ~128;
Sissors 0:39767ffe05e6 174 } else
Sissors 0:39767ffe05e6 175 LPC_RTC->AMR |= 128;
Sissors 1:be9d058ee5c7 176
Sissors 1:be9d058ee5c7 177 //DOY and DOW register normally not set
Sissors 1:be9d058ee5c7 178 time_t t = time(NULL);
Sissors 1:be9d058ee5c7 179 LPC_RTC->DOY = localtime(&t)->tm_yday+1;
Sissors 1:be9d058ee5c7 180 LPC_RTC->DOW = localtime(&t)->tm_wday;
Sissors 1:be9d058ee5c7 181
Sissors 0:39767ffe05e6 182 //We can always enable IRQs, since if all IRQs are disabled by the user the RTC hardware will never raise its IRQ flag anyway
Sissors 0:39767ffe05e6 183 NVIC_EnableIRQ(RTC_IRQn);
Sissors 0:39767ffe05e6 184 }
Sissors 0:39767ffe05e6 185
Sissors 1:be9d058ee5c7 186 void RTC::alarmOff( void )
Sissors 1:be9d058ee5c7 187 {
Sissors 0:39767ffe05e6 188 LPC_RTC->AMR = 255;
Sissors 1:be9d058ee5c7 189 alarmCB.attach(NULL);
Sissors 1:be9d058ee5c7 190 }
Sissors 0:39767ffe05e6 191
Sissors 0:39767ffe05e6 192
Sissors 0:39767ffe05e6 193 void RTC::IRQHandler( void )
Sissors 0:39767ffe05e6 194 {
Sissors 0:39767ffe05e6 195 if ((LPC_RTC->ILR & 0x01) == 0x01) {
Sissors 0:39767ffe05e6 196 //Attach interrupt
Sissors 0:39767ffe05e6 197 attachCB[0].call();
Sissors 0:39767ffe05e6 198
Sissors 0:39767ffe05e6 199 //If seconds zero
Sissors 0:39767ffe05e6 200 if (LPC_RTC->SEC == 0) {
Sissors 0:39767ffe05e6 201 attachCB[1].call();
Sissors 0:39767ffe05e6 202
Sissors 0:39767ffe05e6 203 //If minutes zero
Sissors 0:39767ffe05e6 204 if (LPC_RTC->MIN == 0) {
Sissors 0:39767ffe05e6 205 attachCB[2].call();
Sissors 0:39767ffe05e6 206
Sissors 0:39767ffe05e6 207 //If hours zero
Sissors 0:39767ffe05e6 208 if (LPC_RTC->HOUR == 0) {
Sissors 0:39767ffe05e6 209 attachCB[3].call();
Sissors 0:39767ffe05e6 210
Sissors 0:39767ffe05e6 211 //If days zero
Sissors 0:39767ffe05e6 212 if (LPC_RTC->DOM == 0) {
Sissors 0:39767ffe05e6 213 attachCB[4].call();
Sissors 0:39767ffe05e6 214
Sissors 0:39767ffe05e6 215 //If month zero
Sissors 0:39767ffe05e6 216 if (LPC_RTC->MONTH == 0)
Sissors 0:39767ffe05e6 217 attachCB[5].call();
Sissors 0:39767ffe05e6 218 }
Sissors 0:39767ffe05e6 219 }
Sissors 0:39767ffe05e6 220 }
Sissors 0:39767ffe05e6 221 }
Sissors 0:39767ffe05e6 222 }
Sissors 0:39767ffe05e6 223
Sissors 0:39767ffe05e6 224 if ((LPC_RTC->ILR & 0x02) == 0x02)
Sissors 0:39767ffe05e6 225 alarmCB.call();
Sissors 0:39767ffe05e6 226
Sissors 0:39767ffe05e6 227
Sissors 0:39767ffe05e6 228
Sissors 0:39767ffe05e6 229 //Reset interrupt status
Sissors 0:39767ffe05e6 230 LPC_RTC->ILR = 0x03;
Sissors 1:be9d058ee5c7 231 }
Sissors 1:be9d058ee5c7 232
Sissors 1:be9d058ee5c7 233 tm RTC::getDefaultTM( void ) {
Sissors 1:be9d058ee5c7 234 struct tm t;
Sissors 1:be9d058ee5c7 235 t.tm_sec = -1;
Sissors 1:be9d058ee5c7 236 t.tm_min = -1;
Sissors 1:be9d058ee5c7 237 t.tm_hour = -1;
Sissors 1:be9d058ee5c7 238 t.tm_mday = -1;
Sissors 1:be9d058ee5c7 239 t.tm_wday = -1;
Sissors 1:be9d058ee5c7 240 t.tm_yday = -1;
Sissors 1:be9d058ee5c7 241 t.tm_mon = -1;
Sissors 1:be9d058ee5c7 242 t.tm_year = -1;
Sissors 1:be9d058ee5c7 243
Sissors 1:be9d058ee5c7 244 return t;
Sissors 1:be9d058ee5c7 245 }