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