![]() |
Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions
|
00001 /***************************************************************************/ 00030 #include "iec60335_class_b.h" 00031 00037 #ifdef TESSY 00038 00039 uint32_t TS_TessyDummyRTC(void); 00040 uint32_t TS_TessyDummyCMU(void); 00041 uint32_t TS_TessyDummyIntermediate(unsigned long interm); 00042 #define SyncRTC() (TS_TessyDummyRTC()) 00043 #define SyncCMU() (TS_TessyDummyCMU()) 00044 #define GetIRQRTC() (TS_TessyDummyRTC()) 00045 00046 #else 00047 #define SyncRTC() (RTC->SYNCBUSY & 1) 00048 #define SyncCMU() (CMU->OSCENCMD & 0x80) 00049 #define GetIRQRTC() (RTC->IF & RTC_IF_COMP0) 00050 #endif 00051 00052 ClockTest_t ClockTest; /* RTC/Timer-test requires fixed data */ 00053 00058 #if defined (__ICCARM__) 00059 #pragma section="IEC60335_code" 00060 #else 00061 __attribute__((section(".IEC60335_code"))) 00062 #endif 00063 00064 void IEC60335_resetClockTest(uint32_t ratio, uint32_t tolerance) 00065 { 00066 /* reset counter */ 00067 if (ratio == 0) 00068 { 00069 ClockTest.timerCounter = 0; 00070 ClockTest.baseTicks = 0; 00071 ClockTest.result = IEC60335_testInProgress + 1; 00072 } 00073 else 00074 { 00075 ClockTest.Ratio = ratio; 00076 ClockTest.Tolerance = tolerance; 00077 ClockTest.timerCounter = 0; 00078 ClockTest.baseTicks = 0; 00079 } 00080 } 00081 00085 #if defined (__ICCARM__) 00086 #pragma section="IEC60335_code" 00087 #else 00088 __attribute__((section(".IEC60335_code"))) 00089 #endif 00090 00091 void IEC60335_ClassB_initClockTest(uint32_t ratio, uint32_t tolerance) 00092 { 00093 /* setup parameter */ 00094 IEC60335_resetClockTest(ratio, tolerance); 00095 00096 /* start RTC */ 00097 if (!RTC->CTRL & RTC_CTRL_EN) 00098 { 00099 /* enable LE clock */ 00100 CMU->HFCORECLKEN0 |= 4; 00101 CMU->OSCENCMD = 0x40; /* enable osc LFXO */ 00102 while (SyncCMU()) ; /* wait for stabilizing */ 00103 CMU->LFCLKSEL |= CMU_LFCLKSEL_LFA_LFXO; 00104 /* enable RTC clock */ 00105 CMU->LFACLKEN0 = 1; 00106 CMU->LFAPRESC0 = CMU_LFAPRESC0_RTC_DIV4096; 00107 while (SyncRTC()) ; 00108 RTC->IEN = 0; /* ints off */ 00109 RTC->IFC = 7; 00110 /* set compare */ 00111 while (SyncRTC()) ; 00112 RTC->COMP0 = 0x666; 00113 while (SyncRTC()) ; 00114 /* run RTC */ 00115 RTC->CTRL |= RTC_CTRL_EN | RTC_CTRL_DEBUGRUN | RTC_CTRL_COMP0TOP; 00116 } 00117 #if (USE_SYSTICK == 1) 00118 00120 /* Setup SysTick Timer for 10 msec interrupts */ 00121 /* set reload register */ 00122 SysTick->LOAD = ((14000000 / 100) & SysTick_LOAD_RELOAD_Msk) - 1; 00123 /* set Priority for Cortex-M3 System Interrupts */ 00124 SCB->SHP[((uint32_t)(SysTick_IRQn) & 0xF) - 4] = ((((1 << __NVIC_PRIO_BITS) - 1) << (8 - __NVIC_PRIO_BITS)) & 0xff); 00125 /* Load the SysTick Counter Value */ 00126 SysTick->VAL = 0; 00127 /* Enable SysTick IRQ and SysTick Timer */ 00128 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; 00129 00131 #elif (USE_TIMER0) 00132 00133 /* start timer0 */ 00134 /* Enable Timer Clock */ 00135 CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_TIMER0; 00136 /* Configure TIMER from HFPERCLK */ 00137 TIMER0->CTRL = TIMER_CTRL_CLKSEL_PRESCHFPERCLK | TIMER_CTRL_PRESC_DIV32 | \ 00138 TIMER_CTRL_FALLA_NONE | TIMER_CTRL_RISEA_NONE | \ 00139 (0 << _TIMER_CTRL_DEBUGRUN_SHIFT) | TIMER_CTRL_MODE_UP; 00140 /* 32K ticks interrupts */ 00141 TIMER0->TOP = 4 * 1024; 00142 /* Clear pending interrupt */ 00143 NVIC->ICPR[((uint32_t)(TIMER0_IRQn) >> 5)] = (1 << ((uint32_t)(TIMER0_IRQn) & 0x1F)); 00144 00145 TIMER0->IFC = TIMER_IEN_OF; 00146 TIMER0->IEN = TIMER_IEN_OF; 00147 /* enable interrupt */ 00148 NVIC->ISER[((uint32_t)(TIMER0_IRQn) >> 5)] = (1 << ((uint32_t)(TIMER0_IRQn) & 0x1F)); 00149 TIMER0->CMD = TIMER_CMD_START; 00151 #elif (USE_TIMER1) 00152 00153 /* start timer1 */ 00154 /* TODO : implement timer1 setup here */ 00156 #endif 00157 } 00158 00174 #if (defined (__ICCARM__)) 00175 #pragma section="IEC60335_code" 00176 #else 00177 __attribute__((section(".IEC60335_code"))) 00178 #endif 00179 00180 testResult_t IEC60335_ClassB_Clocktest_PollHandler(void) 00181 { 00182 testResult_t result = IEC60335_testFailed; 00183 uint32_t absolutUP, absolutLOW, intermediate; 00184 ClockTest.result = IEC60335_testInProgress; 00185 00186 /* wait on RTC flag if running */ 00187 if (RTC->CTRL & RTC_CTRL_EN) 00188 { 00189 while (0 == (GetIRQRTC())) ; 00190 RTC->IFC = RTC_IFC_COMP0; 00191 ClockTest.baseTicks++; 00192 } 00193 else /* else quit here */ 00194 { 00195 return(result); 00196 } 00197 /* calculate tolerance band extremes */ 00198 intermediate = ClockTest.Ratio * ClockTest.Tolerance / 100; 00199 #if TESSY 00200 00201 intermediate = TS_TessyDummyIntermediate(intermediate); 00203 #endif 00204 if (intermediate > (0x80000000 - 1)) 00205 { 00206 ClockTest.result = IEC60335_testFailed; 00207 return(result); 00208 } 00209 else 00210 { 00211 /* absolutLOW must not be negative */ 00212 if (ClockTest.Ratio >= intermediate) 00213 { 00214 absolutLOW = ClockTest.Ratio - intermediate; 00215 } 00216 else 00217 { 00218 absolutLOW = 0; 00219 } 00220 absolutUP = intermediate + ClockTest.Ratio; 00221 } 00222 /* calculate average counter/baseTicks */ 00223 intermediate = ClockTest.timerCounter / ClockTest.baseTicks; 00224 if ((intermediate > absolutLOW) && (intermediate < absolutUP)) 00225 { 00226 result = IEC60335_testPassed; 00227 /* reset the counters */ 00228 IEC60335_resetClockTest(0, 0); 00229 /* stop Interrupts */ 00230 #if (USE_SYSTICK == 1) 00231 00232 /* Disable SysTick IRQ and SysTick Timer */ 00233 SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); 00235 #elif (USE_TIMER0) 00236 00237 if (TIMER0->CMD != TIMER_CMD_START) 00238 { 00239 ClockTest.result = IEC60335_testFailed; 00240 return(IEC60335_testFailed); 00241 } 00242 ClockTest.result = IEC60335_testPassed; 00243 /* disable interrupt */ 00244 NVIC->ICER[((uint32_t)(TIMER0_IRQn) >> 5)] = (1 << ((uint32_t)(TIMER0_IRQn) & 0x1F)); 00245 /* Clear pending interrupt */ 00246 NVIC->ICPR[((uint32_t)(TIMER0_IRQn) >> 5)] = (1 << ((uint32_t)(TIMER0_IRQn) & 0x1F)); 00247 TIMER0->IFC = TIMER_IEN_OF; 00248 TIMER0->IEN &= ~TIMER_IEN_OF; 00250 #elif (USE_TIMER1) 00251 00252 /* TODO : implement timer1 stop here */ 00254 #endif 00255 } 00256 00257 return(result); 00258 } 00259 00269 #if defined (__ICCARM__) 00270 #pragma section="IEC60335_code" 00271 #else 00272 __attribute__((section(".IEC60335_code"))) 00273 #endif 00274 00275 void IEC60335_ClassB_Clocktest_RTCHandler(void) 00276 { 00277 uint32_t absolutUP, absolutLOW, intermediate; 00278 ClockTest.result = IEC60335_testInProgress; 00279 /* TODO: call this vector if RTC is used with interrupt */ 00280 /* check comp0 interrupt */ 00281 if (RTC->IF & RTC_IF_COMP0) 00282 { 00283 ClockTest.baseTicks++; 00284 RTC->IFC = RTC_IFC_COMP0; /* clear the interrupt flag */ 00285 /* calculate tolerance band extremes */ 00286 intermediate = ClockTest.Ratio * ClockTest.Tolerance / 100; 00287 00288 /* absolutLOW must not be negative */ 00289 if (ClockTest.Ratio >= intermediate) 00290 { 00291 absolutLOW = ClockTest.Ratio - intermediate; 00292 } 00293 else 00294 { 00295 absolutLOW = 0; 00296 } 00297 absolutUP = intermediate + ClockTest.Ratio; 00298 00299 /* calculate average counter/baseTicks */ 00300 intermediate = ClockTest.timerCounter / ClockTest.baseTicks; 00301 if ((intermediate > absolutLOW) && (intermediate < absolutUP)) 00302 { 00303 /* reset the counters */ 00304 IEC60335_resetClockTest(0, 0); 00305 /* stop Interrupts */ 00306 #if (USE_SYSTICK == 1) 00307 00308 /* Disable SysTick IRQ and SysTick Timer */ 00309 SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); 00311 #elif (USE_TIMER0) 00312 00313 if (TIMER0->CMD != TIMER_CMD_START) 00314 { 00315 ClockTest.result = IEC60335_testFailed; 00316 return; 00317 } 00318 ClockTest.result = IEC60335_testPassed; 00319 /* disable interrupt */ 00320 NVIC->ICER[((uint32_t)(TIMER0_IRQn) >> 5)] = (1 << ((uint32_t)(TIMER0_IRQn) & 0x1F)); 00321 /* Clear pending interrupt */ 00322 NVIC->ICPR[((uint32_t)(TIMER0_IRQn) >> 5)] = (1 << ((uint32_t)(TIMER0_IRQn) & 0x1F)); 00323 TIMER0->IFC = TIMER_IEN_OF; 00324 TIMER0->IEN &= ~TIMER_IEN_OF; 00326 #elif (USE_TIMER1) 00327 00328 /* TODO : implement timer1 stop here */ 00330 #endif 00331 } 00332 } 00333 } 00334 00335 00340 /************************************** EOF *********************************/