Support KL25z requirements
Fork of RTC by
RTC.cpp@0:39767ffe05e6, 2012-12-05 (annotated)
- Committer:
- Sissors
- Date:
- Wed Dec 05 21:03:44 2012 +0000
- Revision:
- 0:39767ffe05e6
- Child:
- 1:be9d058ee5c7
Version 1, lacks comments, seems to work
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:39767ffe05e6 | 8 | void RTC::attach(void (*function)(void), TimeUnit interval) |
Sissors | 0:39767ffe05e6 | 9 | { |
Sissors | 0:39767ffe05e6 | 10 | //Disable IRQs, dont want them to happen while busy here |
Sissors | 0:39767ffe05e6 | 11 | NVIC_DisableIRQ(RTC_IRQn); |
Sissors | 0:39767ffe05e6 | 12 | |
Sissors | 0:39767ffe05e6 | 13 | //Set the IRQ vector |
Sissors | 0:39767ffe05e6 | 14 | NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler); |
Sissors | 0:39767ffe05e6 | 15 | |
Sissors | 0:39767ffe05e6 | 16 | //If this is the first time it is called, delete all interrupt sources |
Sissors | 0:39767ffe05e6 | 17 | //We need to do this because RTC unit isnt affected by system resets apparently |
Sissors | 0:39767ffe05e6 | 18 | if (initialRun) { |
Sissors | 0:39767ffe05e6 | 19 | LPC_RTC->CIIR = 0; |
Sissors | 0:39767ffe05e6 | 20 | LPC_RTC->AMR = 255; |
Sissors | 0:39767ffe05e6 | 21 | initialRun = false; |
Sissors | 0:39767ffe05e6 | 22 | LPC_RTC->ILR = 0x03; |
Sissors | 0:39767ffe05e6 | 23 | } |
Sissors | 0:39767ffe05e6 | 24 | |
Sissors | 0:39767ffe05e6 | 25 | //Set the function pointer |
Sissors | 0:39767ffe05e6 | 26 | attachCB[interval].attach(function); |
Sissors | 0:39767ffe05e6 | 27 | |
Sissors | 0:39767ffe05e6 | 28 | |
Sissors | 0:39767ffe05e6 | 29 | //Set/reset correct interrupt source |
Sissors | 0:39767ffe05e6 | 30 | if (function == NULL) { |
Sissors | 0:39767ffe05e6 | 31 | switch (interval) { |
Sissors | 0:39767ffe05e6 | 32 | case Second: |
Sissors | 0:39767ffe05e6 | 33 | LPC_RTC->CIIR &= ~1; |
Sissors | 0:39767ffe05e6 | 34 | break; |
Sissors | 0:39767ffe05e6 | 35 | case Minute: |
Sissors | 0:39767ffe05e6 | 36 | LPC_RTC->CIIR &= ~2; |
Sissors | 0:39767ffe05e6 | 37 | break; |
Sissors | 0:39767ffe05e6 | 38 | case Hour: |
Sissors | 0:39767ffe05e6 | 39 | LPC_RTC->CIIR &= ~4; |
Sissors | 0:39767ffe05e6 | 40 | break; |
Sissors | 0:39767ffe05e6 | 41 | case Day: |
Sissors | 0:39767ffe05e6 | 42 | LPC_RTC->CIIR &= ~56; |
Sissors | 0:39767ffe05e6 | 43 | break; |
Sissors | 0:39767ffe05e6 | 44 | case Month: |
Sissors | 0:39767ffe05e6 | 45 | LPC_RTC->CIIR &= ~64; |
Sissors | 0:39767ffe05e6 | 46 | break; |
Sissors | 0:39767ffe05e6 | 47 | case Year: |
Sissors | 0:39767ffe05e6 | 48 | LPC_RTC->CIIR &= ~128; |
Sissors | 0:39767ffe05e6 | 49 | break; |
Sissors | 0:39767ffe05e6 | 50 | } |
Sissors | 0:39767ffe05e6 | 51 | } else { |
Sissors | 0:39767ffe05e6 | 52 | switch (interval) { |
Sissors | 0:39767ffe05e6 | 53 | case Second: |
Sissors | 0:39767ffe05e6 | 54 | LPC_RTC->CIIR |= 1; |
Sissors | 0:39767ffe05e6 | 55 | break; |
Sissors | 0:39767ffe05e6 | 56 | case Minute: |
Sissors | 0:39767ffe05e6 | 57 | LPC_RTC->CIIR |= 2; |
Sissors | 0:39767ffe05e6 | 58 | break; |
Sissors | 0:39767ffe05e6 | 59 | case Hour: |
Sissors | 0:39767ffe05e6 | 60 | LPC_RTC->CIIR |= 4; |
Sissors | 0:39767ffe05e6 | 61 | break; |
Sissors | 0:39767ffe05e6 | 62 | case Day: |
Sissors | 0:39767ffe05e6 | 63 | LPC_RTC->CIIR |= 56; |
Sissors | 0:39767ffe05e6 | 64 | break; |
Sissors | 0:39767ffe05e6 | 65 | case Month: |
Sissors | 0:39767ffe05e6 | 66 | LPC_RTC->CIIR |= 64; |
Sissors | 0:39767ffe05e6 | 67 | break; |
Sissors | 0:39767ffe05e6 | 68 | case Year: |
Sissors | 0:39767ffe05e6 | 69 | LPC_RTC->CIIR |= 128; |
Sissors | 0:39767ffe05e6 | 70 | break; |
Sissors | 0:39767ffe05e6 | 71 | } |
Sissors | 0:39767ffe05e6 | 72 | } |
Sissors | 0:39767ffe05e6 | 73 | |
Sissors | 0:39767ffe05e6 | 74 | //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 | 75 | NVIC_EnableIRQ(RTC_IRQn); |
Sissors | 0:39767ffe05e6 | 76 | } |
Sissors | 0:39767ffe05e6 | 77 | |
Sissors | 0:39767ffe05e6 | 78 | |
Sissors | 0:39767ffe05e6 | 79 | void RTC::alarm(void (*function)(void), tm time) |
Sissors | 0:39767ffe05e6 | 80 | { |
Sissors | 0:39767ffe05e6 | 81 | //Disable IRQs, dont want them to happen while busy here |
Sissors | 0:39767ffe05e6 | 82 | NVIC_DisableIRQ(RTC_IRQn); |
Sissors | 0:39767ffe05e6 | 83 | |
Sissors | 0:39767ffe05e6 | 84 | //Set the IRQ vector |
Sissors | 0:39767ffe05e6 | 85 | NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler); |
Sissors | 0:39767ffe05e6 | 86 | |
Sissors | 0:39767ffe05e6 | 87 | //If this is the first time it is called, delete all interrupt sources |
Sissors | 0:39767ffe05e6 | 88 | //We need to do this because RTC unit isnt affected by system resets apparently |
Sissors | 0:39767ffe05e6 | 89 | if (initialRun) { |
Sissors | 0:39767ffe05e6 | 90 | LPC_RTC->CIIR = 0; |
Sissors | 0:39767ffe05e6 | 91 | LPC_RTC->AMR = 255; |
Sissors | 0:39767ffe05e6 | 92 | initialRun = false; |
Sissors | 0:39767ffe05e6 | 93 | LPC_RTC->ILR = 0x03; |
Sissors | 0:39767ffe05e6 | 94 | } |
Sissors | 0:39767ffe05e6 | 95 | |
Sissors | 0:39767ffe05e6 | 96 | //Set the function pointer |
Sissors | 0:39767ffe05e6 | 97 | alarmCB.attach(function); |
Sissors | 0:39767ffe05e6 | 98 | |
Sissors | 0:39767ffe05e6 | 99 | //Set the alarm register |
Sissors | 0:39767ffe05e6 | 100 | if ((time.tm_sec>=0) && (time.tm_sec<60)) { |
Sissors | 0:39767ffe05e6 | 101 | LPC_RTC->ALSEC = time.tm_sec; |
Sissors | 0:39767ffe05e6 | 102 | LPC_RTC->AMR &= ~1; |
Sissors | 0:39767ffe05e6 | 103 | } else |
Sissors | 0:39767ffe05e6 | 104 | LPC_RTC->AMR |= 1; |
Sissors | 0:39767ffe05e6 | 105 | |
Sissors | 0:39767ffe05e6 | 106 | if ((time.tm_min>=0) && (time.tm_min<60)) { |
Sissors | 0:39767ffe05e6 | 107 | LPC_RTC->ALMIN = time.tm_min; |
Sissors | 0:39767ffe05e6 | 108 | LPC_RTC->AMR &= ~2; |
Sissors | 0:39767ffe05e6 | 109 | } else |
Sissors | 0:39767ffe05e6 | 110 | LPC_RTC->AMR |= 2; |
Sissors | 0:39767ffe05e6 | 111 | |
Sissors | 0:39767ffe05e6 | 112 | if ((time.tm_hour>=0) && (time.tm_hour<24)) { |
Sissors | 0:39767ffe05e6 | 113 | LPC_RTC->ALHOUR = time.tm_hour; |
Sissors | 0:39767ffe05e6 | 114 | LPC_RTC->AMR &= ~4; |
Sissors | 0:39767ffe05e6 | 115 | } else |
Sissors | 0:39767ffe05e6 | 116 | LPC_RTC->AMR |= 4; |
Sissors | 0:39767ffe05e6 | 117 | |
Sissors | 0:39767ffe05e6 | 118 | if ((time.tm_mday>=1) && (time.tm_mday<32)) { |
Sissors | 0:39767ffe05e6 | 119 | LPC_RTC->ALDOM = time.tm_mday; |
Sissors | 0:39767ffe05e6 | 120 | LPC_RTC->AMR &= ~8; |
Sissors | 0:39767ffe05e6 | 121 | } else |
Sissors | 0:39767ffe05e6 | 122 | LPC_RTC->AMR |= 8; |
Sissors | 0:39767ffe05e6 | 123 | |
Sissors | 0:39767ffe05e6 | 124 | if ((time.tm_mon>=0) && (time.tm_mon<12)) { |
Sissors | 0:39767ffe05e6 | 125 | LPC_RTC->ALMON = time.tm_mon + 1; //Different definitions |
Sissors | 0:39767ffe05e6 | 126 | LPC_RTC->AMR &= ~64; |
Sissors | 0:39767ffe05e6 | 127 | } else |
Sissors | 0:39767ffe05e6 | 128 | LPC_RTC->AMR |= 64; |
Sissors | 0:39767ffe05e6 | 129 | |
Sissors | 0:39767ffe05e6 | 130 | if ((time.tm_year>=0) && (time.tm_year<1000)) { |
Sissors | 0:39767ffe05e6 | 131 | LPC_RTC->ALYEAR = time.tm_year + 1900; //Different definitions |
Sissors | 0:39767ffe05e6 | 132 | LPC_RTC->AMR &= ~128; |
Sissors | 0:39767ffe05e6 | 133 | } else |
Sissors | 0:39767ffe05e6 | 134 | LPC_RTC->AMR |= 128; |
Sissors | 0:39767ffe05e6 | 135 | |
Sissors | 0:39767ffe05e6 | 136 | //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 | 137 | NVIC_EnableIRQ(RTC_IRQn); |
Sissors | 0:39767ffe05e6 | 138 | } |
Sissors | 0:39767ffe05e6 | 139 | |
Sissors | 0:39767ffe05e6 | 140 | void RTC::alarmOff( void ) { |
Sissors | 0:39767ffe05e6 | 141 | LPC_RTC->AMR = 255; |
Sissors | 0:39767ffe05e6 | 142 | } |
Sissors | 0:39767ffe05e6 | 143 | |
Sissors | 0:39767ffe05e6 | 144 | |
Sissors | 0:39767ffe05e6 | 145 | void RTC::IRQHandler( void ) |
Sissors | 0:39767ffe05e6 | 146 | { |
Sissors | 0:39767ffe05e6 | 147 | if ((LPC_RTC->ILR & 0x01) == 0x01) { |
Sissors | 0:39767ffe05e6 | 148 | //Attach interrupt |
Sissors | 0:39767ffe05e6 | 149 | attachCB[0].call(); |
Sissors | 0:39767ffe05e6 | 150 | |
Sissors | 0:39767ffe05e6 | 151 | //If seconds zero |
Sissors | 0:39767ffe05e6 | 152 | if (LPC_RTC->SEC == 0) { |
Sissors | 0:39767ffe05e6 | 153 | attachCB[1].call(); |
Sissors | 0:39767ffe05e6 | 154 | |
Sissors | 0:39767ffe05e6 | 155 | //If minutes zero |
Sissors | 0:39767ffe05e6 | 156 | if (LPC_RTC->MIN == 0) { |
Sissors | 0:39767ffe05e6 | 157 | attachCB[2].call(); |
Sissors | 0:39767ffe05e6 | 158 | |
Sissors | 0:39767ffe05e6 | 159 | //If hours zero |
Sissors | 0:39767ffe05e6 | 160 | if (LPC_RTC->HOUR == 0) { |
Sissors | 0:39767ffe05e6 | 161 | attachCB[3].call(); |
Sissors | 0:39767ffe05e6 | 162 | |
Sissors | 0:39767ffe05e6 | 163 | //If days zero |
Sissors | 0:39767ffe05e6 | 164 | if (LPC_RTC->DOM == 0) { |
Sissors | 0:39767ffe05e6 | 165 | attachCB[4].call(); |
Sissors | 0:39767ffe05e6 | 166 | |
Sissors | 0:39767ffe05e6 | 167 | //If month zero |
Sissors | 0:39767ffe05e6 | 168 | if (LPC_RTC->MONTH == 0) |
Sissors | 0:39767ffe05e6 | 169 | attachCB[5].call(); |
Sissors | 0:39767ffe05e6 | 170 | } |
Sissors | 0:39767ffe05e6 | 171 | } |
Sissors | 0:39767ffe05e6 | 172 | } |
Sissors | 0:39767ffe05e6 | 173 | } |
Sissors | 0:39767ffe05e6 | 174 | } |
Sissors | 0:39767ffe05e6 | 175 | |
Sissors | 0:39767ffe05e6 | 176 | if ((LPC_RTC->ILR & 0x02) == 0x02) |
Sissors | 0:39767ffe05e6 | 177 | alarmCB.call(); |
Sissors | 0:39767ffe05e6 | 178 | |
Sissors | 0:39767ffe05e6 | 179 | |
Sissors | 0:39767ffe05e6 | 180 | |
Sissors | 0:39767ffe05e6 | 181 | //Reset interrupt status |
Sissors | 0:39767ffe05e6 | 182 | LPC_RTC->ILR = 0x03; |
Sissors | 0:39767ffe05e6 | 183 | } |