teste de publish
Dependencies: DS1820 HighSpeedAnalogIn devices mbed
RTC.cpp
00001 #include "RTC.h" 00002 00003 FunctionPointer RTC::attachCB[6]; 00004 FunctionPointer RTC::alarmCB; 00005 00006 bool RTC::initialRun = true; 00007 00008 00009 void RTC::attach(void (*function)(void), TimeUnit interval) 00010 { 00011 //Set the function pointer 00012 attachCB[interval].attach(function); 00013 _attach(interval); 00014 } 00015 00016 template<typename T> 00017 void RTC::attach(T *object, void (T::*member)(void), TimeUnit interval) 00018 { 00019 //Set the function pointer 00020 attachCB[interval].attach(object, member); 00021 _attach(interval); 00022 } 00023 00024 00025 void RTC::_attach(TimeUnit interval) 00026 { 00027 //Disable IRQs, dont want them to happen while busy here 00028 NVIC_DisableIRQ(RTC_IRQn); 00029 00030 //Set the IRQ vector 00031 NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler); 00032 00033 //If this is the first time it is called, delete all interrupt sources 00034 //We need to do this because RTC unit isnt affected by system resets apparently 00035 if (initialRun) { 00036 LPC_RTC->CIIR = 0; 00037 LPC_RTC->AMR = 255; 00038 initialRun = false; 00039 LPC_RTC->ILR = 0x03; 00040 } 00041 00042 //Set/reset correct interrupt source 00043 switch (interval) { 00044 case Second: 00045 LPC_RTC->CIIR |= 1; 00046 break; 00047 case Minute: 00048 LPC_RTC->CIIR |= 2; 00049 break; 00050 case Hour: 00051 LPC_RTC->CIIR |= 4; 00052 break; 00053 case Day: 00054 LPC_RTC->CIIR |= 56; 00055 break; 00056 case Month: 00057 LPC_RTC->CIIR |= 64; 00058 break; 00059 case Year: 00060 LPC_RTC->CIIR |= 128; 00061 break; 00062 } 00063 00064 00065 //We can always enable IRQs, since if all IRQs are disabled by the user the RTC hardware will never raise its IRQ flag anyway 00066 NVIC_EnableIRQ(RTC_IRQn); 00067 } 00068 00069 void RTC::detach(TimeUnit interval) 00070 { 00071 switch (interval) { 00072 case Second: 00073 LPC_RTC->CIIR &= ~1; 00074 break; 00075 case Minute: 00076 LPC_RTC->CIIR &= ~2; 00077 break; 00078 case Hour: 00079 LPC_RTC->CIIR &= ~4; 00080 break; 00081 case Day: 00082 LPC_RTC->CIIR &= ~56; 00083 break; 00084 case Month: 00085 LPC_RTC->CIIR &= ~64; 00086 break; 00087 case Year: 00088 LPC_RTC->CIIR &= ~128; 00089 break; 00090 } 00091 attachCB[interval].attach(NULL); 00092 } 00093 00094 00095 void RTC::alarm(void (*function)(void), tm alarmTime) 00096 { 00097 //Set the function pointer 00098 alarmCB.attach(function); 00099 _alarm(alarmTime); 00100 } 00101 00102 template<typename T> 00103 void RTC::alarm(T *object, void (T::*member)(void), tm alarmTime) 00104 { 00105 //Set the function pointer 00106 alarmCB.attach(object, member); 00107 _alarm(alarmTime); 00108 } 00109 00110 00111 void RTC::_alarm(tm alarmTime) 00112 { 00113 //Disable IRQs, dont want them to happen while busy here 00114 NVIC_DisableIRQ(RTC_IRQn); 00115 00116 //Set the IRQ vector 00117 NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC::IRQHandler); 00118 00119 //If this is the first time it is called, delete all interrupt sources 00120 //We need to do this because RTC unit isnt affected by system resets apparently 00121 if (initialRun) { 00122 LPC_RTC->CIIR = 0; 00123 LPC_RTC->AMR = 255; 00124 initialRun = false; 00125 LPC_RTC->ILR = 0x03; 00126 } 00127 00128 //Set the alarm register 00129 if ((alarmTime.tm_sec>=0) && (alarmTime.tm_sec<60)) { 00130 LPC_RTC->ALSEC = alarmTime.tm_sec; 00131 LPC_RTC->AMR &= ~1; 00132 } else 00133 LPC_RTC->AMR |= 1; 00134 00135 if ((alarmTime.tm_min>=0) && (alarmTime.tm_min<60)) { 00136 LPC_RTC->ALMIN = alarmTime.tm_min; 00137 LPC_RTC->AMR &= ~2; 00138 } else 00139 LPC_RTC->AMR |= 2; 00140 00141 if ((alarmTime.tm_hour>=0) && (alarmTime.tm_hour<24)) { 00142 LPC_RTC->ALHOUR = alarmTime.tm_hour; 00143 LPC_RTC->AMR &= ~4; 00144 } else 00145 LPC_RTC->AMR |= 4; 00146 00147 if ((alarmTime.tm_mday>=1) && (alarmTime.tm_mday<32)) { 00148 LPC_RTC->ALDOM = alarmTime.tm_mday; 00149 LPC_RTC->AMR &= ~8; 00150 } else 00151 LPC_RTC->AMR |= 8; 00152 00153 if ((alarmTime.tm_wday>=0) && (alarmTime.tm_wday<7)) { 00154 LPC_RTC->ALDOW = alarmTime.tm_wday; 00155 LPC_RTC->AMR &= ~16; 00156 } else 00157 LPC_RTC->AMR |= 16; 00158 00159 if ((alarmTime.tm_yday>0) && (alarmTime.tm_yday<367)) { 00160 LPC_RTC->ALDOY = alarmTime.tm_yday; 00161 LPC_RTC->AMR &= ~32; 00162 } else 00163 LPC_RTC->AMR |= 32; 00164 00165 if ((alarmTime.tm_mon>=0) && (alarmTime.tm_mon<12)) { 00166 LPC_RTC->ALMON = alarmTime.tm_mon + 1; //Different definitions 00167 LPC_RTC->AMR &= ~64; 00168 } else 00169 LPC_RTC->AMR |= 64; 00170 00171 if ((alarmTime.tm_year>=0) && (alarmTime.tm_year<1000)) { 00172 LPC_RTC->ALYEAR = alarmTime.tm_year + 1900; //Different definitions 00173 LPC_RTC->AMR &= ~128; 00174 } else 00175 LPC_RTC->AMR |= 128; 00176 00177 //DOY and DOW register normally not set 00178 time_t t = time(NULL); 00179 LPC_RTC->DOY = localtime(&t)->tm_yday+1; 00180 LPC_RTC->DOW = localtime(&t)->tm_wday; 00181 00182 //We can always enable IRQs, since if all IRQs are disabled by the user the RTC hardware will never raise its IRQ flag anyway 00183 NVIC_EnableIRQ(RTC_IRQn); 00184 } 00185 00186 void RTC::alarmOff( void ) 00187 { 00188 LPC_RTC->AMR = 255; 00189 alarmCB.attach(NULL); 00190 } 00191 00192 00193 void RTC::IRQHandler( void ) 00194 { 00195 if ((LPC_RTC->ILR & 0x01) == 0x01) { 00196 //Attach interrupt 00197 attachCB[0].call(); 00198 00199 //If seconds zero 00200 if (LPC_RTC->SEC == 0) { 00201 attachCB[1].call(); 00202 00203 //If minutes zero 00204 if (LPC_RTC->MIN == 0) { 00205 attachCB[2].call(); 00206 00207 //If hours zero 00208 if (LPC_RTC->HOUR == 0) { 00209 attachCB[3].call(); 00210 00211 //If days zero 00212 if (LPC_RTC->DOM == 0) { 00213 attachCB[4].call(); 00214 00215 //If month zero 00216 if (LPC_RTC->MONTH == 0) 00217 attachCB[5].call(); 00218 } 00219 } 00220 } 00221 } 00222 } 00223 00224 if ((LPC_RTC->ILR & 0x02) == 0x02) 00225 alarmCB.call(); 00226 00227 00228 00229 //Reset interrupt status 00230 LPC_RTC->ILR = 0x03; 00231 } 00232 00233 tm RTC::getDefaultTM( void ) { 00234 struct tm t; 00235 t.tm_sec = -1; 00236 t.tm_min = -1; 00237 t.tm_hour = -1; 00238 t.tm_mday = -1; 00239 t.tm_wday = -1; 00240 t.tm_yday = -1; 00241 t.tm_mon = -1; 00242 t.tm_year = -1; 00243 00244 return t; 00245 }
Generated on Wed Jul 13 2022 12:46:24 by 1.7.2