EZR32 Leopard Gecko Software Documentation  ezr32lg-doc-4.2.1
em_rtc.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include "em_rtc.h"
34 #if defined(RTC_COUNT) && (RTC_COUNT > 0)
35 
36 #include "em_assert.h"
37 #include "em_bus.h"
38 
39 /***************************************************************************/
44 /***************************************************************************/
50 /*******************************************************************************
51  ******************************* DEFINES ***********************************
52  ******************************************************************************/
53 
57 #define RTC_COMP_REG_VALID(reg) (((reg) <= 1))
58 
62 /*******************************************************************************
63  ************************** LOCAL FUNCTIONS ********************************
64  ******************************************************************************/
65 
68 #if defined(_EFM32_GECKO_FAMILY)
69 /***************************************************************************/
84 __STATIC_INLINE void regSync(uint32_t mask)
85 {
86  /* Avoid deadlock if modifying the same register twice when freeze mode is */
87  /* activated. */
88  if (RTC->FREEZE & RTC_FREEZE_REGFREEZE)
89  return;
90 
91  /* Wait for any pending previous write operation to have been completed */
92  /* in low frequency domain. This is only required for the Gecko Family */
93  while (RTC->SYNCBUSY & mask)
94  ;
95 }
96 #endif
97 
100 /*******************************************************************************
101  ************************** GLOBAL FUNCTIONS *******************************
102  ******************************************************************************/
103 
104 /***************************************************************************/
114 uint32_t RTC_CompareGet(unsigned int comp)
115 {
116  uint32_t ret;
117 
118  EFM_ASSERT(RTC_COMP_REG_VALID(comp));
119 
120  /* Initialize selected compare value */
121  switch (comp)
122  {
123  case 0:
124  ret = RTC->COMP0;
125  break;
126 
127  case 1:
128  ret = RTC->COMP1;
129  break;
130 
131  default:
132  /* Unknown compare register selected */
133  ret = 0;
134  break;
135  }
136 
137  return ret;
138 }
139 
140 
141 /***************************************************************************/
158 void RTC_CompareSet(unsigned int comp, uint32_t value)
159 {
160  volatile uint32_t *compReg;
161 #if defined(_EFM32_GECKO_FAMILY)
162  uint32_t syncbusy;
163 #endif
164 
165  EFM_ASSERT(RTC_COMP_REG_VALID(comp)
166  && ((value & ~(_RTC_COMP0_COMP0_MASK
167  >> _RTC_COMP0_COMP0_SHIFT)) == 0));
168 
169  /* Initialize selected compare value */
170  switch (comp)
171  {
172  case 0:
173  compReg = &(RTC->COMP0);
174 #if defined(_EFM32_GECKO_FAMILY)
175  syncbusy = RTC_SYNCBUSY_COMP0;
176 #endif
177  break;
178 
179  case 1:
180  compReg = &(RTC->COMP1);
181 #if defined(_EFM32_GECKO_FAMILY)
182  syncbusy = RTC_SYNCBUSY_COMP1;
183 #endif
184  break;
185 
186  default:
187  /* Unknown compare register selected, abort */
188  return;
189  }
190 #if defined(_EFM32_GECKO_FAMILY)
191  /* LF register about to be modified require sync. busy check */
192  regSync(syncbusy);
193 #endif
194 
195  *compReg = value;
196 }
197 
198 
199 /***************************************************************************/
214 void RTC_Enable(bool enable)
215 {
216 #if defined(_EFM32_GECKO_FAMILY)
217  /* LF register about to be modified require sync. busy check */
218  regSync(RTC_SYNCBUSY_CTRL);
219 #endif
220 
221  BUS_RegBitWrite(&(RTC->CTRL), _RTC_CTRL_EN_SHIFT, enable);
222 
223 #if defined(_EFM32_GECKO_FAMILY)
224  /* Wait for CTRL to be updated before returning, because calling code may
225  depend upon that the CTRL register is updated after this function has
226  returned. */
227  regSync(RTC_SYNCBUSY_CTRL);
228 #endif
229 }
230 
231 
232 /***************************************************************************/
258 void RTC_FreezeEnable(bool enable)
259 {
260  if (enable)
261  {
262 #if defined(_EFM32_GECKO_FAMILY)
263  /* Wait for any ongoing LF synchronization to complete. This is just to */
264  /* protect against the rare case when a user */
265  /* - modifies a register requiring LF sync */
266  /* - then enables freeze before LF sync completed */
267  /* - then modifies the same register again */
268  /* since modifying a register while it is in sync progress should be */
269  /* avoided. */
270  while (RTC->SYNCBUSY)
271  ;
272 #endif
273  RTC->FREEZE = RTC_FREEZE_REGFREEZE;
274  }
275  else
276  {
277  RTC->FREEZE = 0;
278  }
279 }
280 
281 
282 /***************************************************************************/
302 void RTC_Init(const RTC_Init_TypeDef *init)
303 {
304  uint32_t tmp;
305 
306  if (init->enable)
307  {
308  tmp = RTC_CTRL_EN;
309  }
310  else
311  {
312  tmp = 0;
313  }
314 
315  /* Configure DEBUGRUN flag, sets whether or not counter should be
316  * updated when debugger is active */
317  if (init->debugRun)
318  {
319  tmp |= RTC_CTRL_DEBUGRUN;
320  }
321 
322  /* Configure COMP0TOP, this will use the COMP0 compare value as an
323  * overflow value, instead of default 24-bit 0x00ffffff */
324  if (init->comp0Top)
325  {
326  tmp |= RTC_CTRL_COMP0TOP;
327  }
328 
329 #if defined(_EFM32_GECKO_FAMILY)
330  /* LF register about to be modified require sync. busy check */
331  regSync(RTC_SYNCBUSY_CTRL);
332 #endif
333 
334  RTC->CTRL = tmp;
335 }
336 
337 
338 
339 /***************************************************************************/
343 void RTC_Reset(void)
344 {
345  /* Restore all essential RTC register to default config */
346  RTC->FREEZE = _RTC_FREEZE_RESETVALUE;
347  RTC->CTRL = _RTC_CTRL_RESETVALUE;
348  RTC->COMP0 = _RTC_COMP0_RESETVALUE;
349  RTC->COMP1 = _RTC_COMP1_RESETVALUE;
350  RTC->IEN = _RTC_IEN_RESETVALUE;
351  RTC->IFC = _RTC_IFC_RESETVALUE;
352 
353 #if defined(_EFM32_GECKO_FAMILY)
354  /* Wait for CTRL, COMP0 and COMP1 to be updated before returning, because the
355  calling code may depend upon that the register values are updated after
356  this function has returned. */
358 #endif
359 }
360 
361 
362 
363 /***************************************************************************/
368 {
369  /* A disable/enable sequnce will start the counter at zero */
370  RTC_Enable(false);
371  RTC_Enable(true);
372 }
373 
374 
377 #endif /* defined(RTC_COUNT) && (RTC_COUNT > 0) */
#define RTC_CTRL_DEBUGRUN
Definition: ezr32lg_rtc.h:69
void RTC_Reset(void)
Restore RTC to reset state.
Definition: em_rtc.c:343
Emlib peripheral API "assert" implementation.
RAM and peripheral bit-field set and clear API.
void RTC_CounterReset(void)
Restart RTC counter from zero.
Definition: em_rtc.c:367
#define _RTC_COMP0_COMP0_SHIFT
Definition: ezr32lg_rtc.h:95
#define RTC_CTRL_EN
Definition: ezr32lg_rtc.h:64
#define _RTC_IEN_RESETVALUE
Definition: ezr32lg_rtc.h:166
#define _RTC_COMP1_RESETVALUE
Definition: ezr32lg_rtc.h:101
void RTC_CompareSet(unsigned int comp, uint32_t value)
Set RTC compare register value.
Definition: em_rtc.c:158
#define RTC_SYNCBUSY_COMP0
Definition: ezr32lg_rtc.h:205
#define RTC_SYNCBUSY_CTRL
Definition: ezr32lg_rtc.h:200
#define _RTC_FREEZE_RESETVALUE
Definition: ezr32lg_rtc.h:185
#define _RTC_CTRL_RESETVALUE
Definition: ezr32lg_rtc.h:62
#define _RTC_COMP0_RESETVALUE
Definition: ezr32lg_rtc.h:93
#define _RTC_IFC_RESETVALUE
Definition: ezr32lg_rtc.h:147
bool debugRun
Definition: em_rtc.h:63
bool comp0Top
Definition: em_rtc.h:64
void RTC_Init(const RTC_Init_TypeDef *init)
Initialize RTC.
Definition: em_rtc.c:302
#define RTC_SYNCBUSY_COMP1
Definition: ezr32lg_rtc.h:210
#define RTC
Real Time Counter (RTC) peripheral API.
void RTC_Enable(bool enable)
Enable/disable RTC.
Definition: em_rtc.c:214
void RTC_FreezeEnable(bool enable)
RTC register synchronization freeze control.
Definition: em_rtc.c:258
#define RTC_CTRL_COMP0TOP
Definition: ezr32lg_rtc.h:74
uint32_t RTC_CompareGet(unsigned int comp)
Get RTC compare register value.
Definition: em_rtc.c:114
#define _RTC_CTRL_EN_SHIFT
Definition: ezr32lg_rtc.h:65
__STATIC_INLINE void BUS_RegBitWrite(volatile uint32_t *addr, unsigned int bit, unsigned int val)
Perform a single-bit write operation on a peripheral register.
Definition: em_bus.h:146
#define RTC_FREEZE_REGFREEZE
Definition: ezr32lg_rtc.h:187
#define _RTC_COMP0_COMP0_MASK
Definition: ezr32lg_rtc.h:96