EFR32 Blue Gecko 1 Software Documentation  efr32bg1-doc-5.1.2
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 /***************************************************************************/
53 /*******************************************************************************
54  ******************************* DEFINES ***********************************
55  ******************************************************************************/
56 
60 #define RTC_COMP_REG_VALID(reg) (((reg) <= 1))
61 
65 /*******************************************************************************
66  ************************** LOCAL FUNCTIONS ********************************
67  ******************************************************************************/
68 
71 #if defined(_EFM32_GECKO_FAMILY)
72 /***************************************************************************/
87 __STATIC_INLINE void regSync(uint32_t mask)
88 {
89  /* Avoid deadlock if modifying the same register twice when freeze mode is */
90  /* activated. */
91  if (RTC->FREEZE & RTC_FREEZE_REGFREEZE)
92  return;
93 
94  /* Wait for any pending previous write operation to have been completed */
95  /* in low frequency domain. This is only required for the Gecko Family */
96  while (RTC->SYNCBUSY & mask)
97  ;
98 }
99 #endif
100 
103 /*******************************************************************************
104  ************************** GLOBAL FUNCTIONS *******************************
105  ******************************************************************************/
106 
107 /***************************************************************************/
117 uint32_t RTC_CompareGet(unsigned int comp)
118 {
119  uint32_t ret;
120 
121  EFM_ASSERT(RTC_COMP_REG_VALID(comp));
122 
123  /* Initialize selected compare value */
124  switch (comp)
125  {
126  case 0:
127  ret = RTC->COMP0;
128  break;
129 
130  case 1:
131  ret = RTC->COMP1;
132  break;
133 
134  default:
135  /* Unknown compare register selected */
136  ret = 0;
137  break;
138  }
139 
140  return ret;
141 }
142 
143 
144 /***************************************************************************/
161 void RTC_CompareSet(unsigned int comp, uint32_t value)
162 {
163  volatile uint32_t *compReg;
164 #if defined(_EFM32_GECKO_FAMILY)
165  uint32_t syncbusy;
166 #endif
167 
168  EFM_ASSERT(RTC_COMP_REG_VALID(comp)
169  && ((value & ~(_RTC_COMP0_COMP0_MASK
170  >> _RTC_COMP0_COMP0_SHIFT)) == 0));
171 
172  /* Initialize selected compare value */
173  switch (comp)
174  {
175  case 0:
176  compReg = &(RTC->COMP0);
177 #if defined(_EFM32_GECKO_FAMILY)
178  syncbusy = RTC_SYNCBUSY_COMP0;
179 #endif
180  break;
181 
182  case 1:
183  compReg = &(RTC->COMP1);
184 #if defined(_EFM32_GECKO_FAMILY)
185  syncbusy = RTC_SYNCBUSY_COMP1;
186 #endif
187  break;
188 
189  default:
190  /* Unknown compare register selected, abort */
191  return;
192  }
193 #if defined(_EFM32_GECKO_FAMILY)
194  /* LF register about to be modified require sync. busy check */
195  regSync(syncbusy);
196 #endif
197 
198  *compReg = value;
199 }
200 
201 
202 /***************************************************************************/
217 void RTC_Enable(bool enable)
218 {
219 #if defined(_EFM32_GECKO_FAMILY)
220  /* LF register about to be modified require sync. busy check */
221  regSync(RTC_SYNCBUSY_CTRL);
222 #endif
223 
224  BUS_RegBitWrite(&(RTC->CTRL), _RTC_CTRL_EN_SHIFT, enable);
225 
226 #if defined(_EFM32_GECKO_FAMILY)
227  /* Wait for CTRL to be updated before returning, because calling code may
228  depend upon that the CTRL register is updated after this function has
229  returned. */
230  regSync(RTC_SYNCBUSY_CTRL);
231 #endif
232 }
233 
234 
235 /***************************************************************************/
261 void RTC_FreezeEnable(bool enable)
262 {
263  if (enable)
264  {
265 #if defined(_EFM32_GECKO_FAMILY)
266  /* Wait for any ongoing LF synchronization to complete. This is just to */
267  /* protect against the rare case when a user */
268  /* - modifies a register requiring LF sync */
269  /* - then enables freeze before LF sync completed */
270  /* - then modifies the same register again */
271  /* since modifying a register while it is in sync progress should be */
272  /* avoided. */
273  while (RTC->SYNCBUSY)
274  ;
275 #endif
276  RTC->FREEZE = RTC_FREEZE_REGFREEZE;
277  }
278  else
279  {
280  RTC->FREEZE = 0;
281  }
282 }
283 
284 
285 /***************************************************************************/
305 void RTC_Init(const RTC_Init_TypeDef *init)
306 {
307  uint32_t tmp;
308 
309  if (init->enable)
310  {
311  tmp = RTC_CTRL_EN;
312  }
313  else
314  {
315  tmp = 0;
316  }
317 
318  /* Configure DEBUGRUN flag, sets whether or not counter should be
319  * updated when debugger is active */
320  if (init->debugRun)
321  {
322  tmp |= RTC_CTRL_DEBUGRUN;
323  }
324 
325  /* Configure COMP0TOP, this will use the COMP0 compare value as an
326  * overflow value, instead of default 24-bit 0x00ffffff */
327  if (init->comp0Top)
328  {
329  tmp |= RTC_CTRL_COMP0TOP;
330  }
331 
332 #if defined(_EFM32_GECKO_FAMILY)
333  /* LF register about to be modified require sync. busy check */
334  regSync(RTC_SYNCBUSY_CTRL);
335 #endif
336 
337  RTC->CTRL = tmp;
338 }
339 
340 
341 
342 /***************************************************************************/
346 void RTC_Reset(void)
347 {
348  /* Restore all essential RTC register to default config */
349  RTC->FREEZE = _RTC_FREEZE_RESETVALUE;
350  RTC->CTRL = _RTC_CTRL_RESETVALUE;
351  RTC->COMP0 = _RTC_COMP0_RESETVALUE;
352  RTC->COMP1 = _RTC_COMP1_RESETVALUE;
353  RTC->IEN = _RTC_IEN_RESETVALUE;
354  RTC->IFC = _RTC_IFC_RESETVALUE;
355 
356 #if defined(_EFM32_GECKO_FAMILY)
357  /* Wait for CTRL, COMP0 and COMP1 to be updated before returning, because the
358  calling code may depend upon that the register values are updated after
359  this function has returned. */
360  regSync(RTC_SYNCBUSY_CTRL | RTC_SYNCBUSY_COMP0 | RTC_SYNCBUSY_COMP1);
361 #endif
362 }
363 
364 
365 
366 /***************************************************************************/
370 void RTC_CounterReset(void)
371 {
372  /* A disable/enable sequnce will start the counter at zero */
373  RTC_Enable(false);
374  RTC_Enable(true);
375 }
376 
377 
380 #endif /* defined(RTC_COUNT) && (RTC_COUNT > 0) */
Emlib peripheral API "assert" implementation.
RAM and peripheral bit-field set and clear API.
Real Time Counter (RTC) peripheral API.
__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:148