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