rtcdrv.c

Go to the documentation of this file.
00001 /***************************************************************************/
00036 #include <stddef.h>
00037 #include "em_device.h"
00038 #include "em_cmu.h"
00039 #include "em_emu.h"
00040 #include "em_rtc.h"
00041 #include "rtcdrv.h"
00042 
00043 static void          (*rtcCb)(void);        
00044 static uint8_t       rtcInitialized = 0;    
00045 static volatile bool rtcDelayComplete;      
00046 static uint32_t      rtcFreq;               
00048 /***************************************************************************/
00051 static void DelayCB(void)
00052 {
00053   rtcDelayComplete = true;
00054 }
00055 
00056 /***************************************************************************/
00065 void RTCDRV_Setup(CMU_Select_TypeDef lfaClockSrc, CMU_ClkDiv_TypeDef rtcPrescale)
00066 {
00067   RTC_Init_TypeDef init;
00068 
00069   rtcInitialized = 1;
00070 
00071   /* Ensure LE modules are accessible */
00072   CMU_ClockEnable(cmuClock_CORELE, true);
00073 
00074   /* Enable LFACLK in CMU (will also enable oscillator if not enabled) */
00075   CMU_ClockSelectSet(cmuClock_LFA, lfaClockSrc);
00076 
00077   /* Use the prescaler to reduce power consumption. */
00078   CMU_ClockDivSet(cmuClock_RTC, rtcPrescale);
00079 
00080   rtcFreq = CMU_ClockFreqGet(cmuClock_RTC);
00081 
00082   /* Enable clock to RTC module */
00083   CMU_ClockEnable(cmuClock_RTC, true);
00084 
00085   init.enable   = false;
00086   init.debugRun = false;
00087   init.comp0Top = false; /* Count to max before wrapping */
00088   RTC_Init(&init);
00089 
00090   /* Disable interrupt generation from RTC0 */
00091   RTC_IntDisable(_RTC_IF_MASK);
00092 
00093   /* Enable interrupts */
00094   NVIC_ClearPendingIRQ(RTC_IRQn);
00095   NVIC_EnableIRQ(RTC_IRQn);
00096 }
00097 
00098 /***************************************************************************/
00103 void RTCDRV_Delay(uint32_t msec, bool useEM2)
00104 {
00105   rtcDelayComplete = false;
00106   RTCDRV_Trigger(msec, DelayCB);
00107 
00108   while (!rtcDelayComplete)
00109   {
00110     if (useEM2)
00111     {
00112       EMU_EnterEM2(true);
00113     }
00114   }
00115 }
00116 
00117 /***************************************************************************/
00120 void RTC_IRQHandler(void)
00121 {
00122   /* Disable RTC */
00123   RTC_Enable(false);
00124 
00125   /* Clear interrupt source */
00126   RTC_IntClear(RTC_IF_COMP0);
00127 
00128   /* Disable interrupt */
00129   RTC_IntDisable(RTC_IF_COMP0);
00130 
00131   /* Trigger callback if defined */
00132   if (rtcCb)
00133   {
00134     rtcCb();
00135   }
00136 }
00137 
00138 
00139 /***************************************************************************/
00144 void RTCDRV_Trigger(uint32_t msec, void (*cb)(void))
00145 {
00146   /* Disable RTC - this will also reset the counter. */
00147   RTC_Enable(false);
00148 
00149   /* Auto init if not configured already */
00150   if (!rtcInitialized)
00151   {
00152     /* Default to LFRCO as clock source and prescale by 32. */
00153     RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32);
00154   }
00155 
00156   /* Register callback */
00157   rtcCb = cb;
00158 
00159   /* Clear interrupt source */
00160   RTC_IntClear(RTC_IF_COMP0);
00161 
00162   /* Calculate trigger value in ticks based on 32768Hz clock */
00163   RTC_CompareSet(0, (rtcFreq * msec) / 1000);
00164 
00165   /* Enable RTC */
00166   RTC_Enable(true);
00167 
00168   /* Enable interrupt on COMP0 */
00169   RTC_IntEnable(RTC_IF_COMP0);
00170 }