Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions

iec60335_class_b_timer_rtc_test.c

Go to the documentation of this file.
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 *********************************/