EZR32 Leopard Gecko Software Documentation  ezr32lg-doc-4.2.1
em_burtc.c
Go to the documentation of this file.
1 /***************************************************************************/
34 #include "em_burtc.h"
35 #if defined(BURTC_PRESENT)
36 
37 /***************************************************************************/
42 /***************************************************************************/
48 /*******************************************************************************
49  ******************************* DEFINES ***********************************
50  ******************************************************************************/
51 
52 /*******************************************************************************
53  ************************** LOCAL FUNCTIONS ********************************
54  ******************************************************************************/
55 
57 /***************************************************************************/
63 __STATIC_INLINE uint32_t divToLog2(uint32_t div)
64 {
65  uint32_t log2;
66 
67  /* Prescaler accepts an argument of 128 or less, valid values being 2^n */
68  EFM_ASSERT((div > 0) && (div <= 32768));
69 
70  /* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
71  log2 = (31 - __CLZ(div));
72 
73  return log2;
74 }
75 
76 
77 /***************************************************************************/
85 __STATIC_INLINE void regSync(uint32_t mask)
86 {
87  /* Avoid deadlock if modifying the same register twice when freeze mode is
88  activated, or when no clock is selected for the BURTC. If no clock is
89  selected, then the sync is done once the clock source is set. */
90  if ((BURTC->FREEZE & BURTC_FREEZE_REGFREEZE)
92  {
93  return;
94  }
95  /* Wait for any pending previous write operation to have been completed */
96  /* in low frequency domain. This is only required for the Gecko Family */
97  while (BURTC->SYNCBUSY & mask)
98  ;
99 }
103 /*******************************************************************************
104  ************************** GLOBAL FUNCTIONS *******************************
105  ******************************************************************************/
106 
107 /***************************************************************************/
125 void BURTC_Init(const BURTC_Init_TypeDef *burtcInit)
126 {
127  uint32_t ctrl;
128  uint32_t presc;
129 
130  /* Check initializer structure integrity */
131  EFM_ASSERT(burtcInit != (BURTC_Init_TypeDef *) 0);
132  /* Clock divider must be between 1 and 128, really on the form 2^n */
133  EFM_ASSERT((burtcInit->clkDiv >= 1) && (burtcInit->clkDiv <= 128));
134  /* Ignored compare bits during low power operation must be less than 7 */
135  /* Note! Giant Gecko revision C errata, do NOT use LPCOMP=7 */
136  EFM_ASSERT(burtcInit->lowPowerComp <= 6);
137  /* You cannot enable the BURTC if mode is set to disabled */
138  EFM_ASSERT((burtcInit->enable == false) ||
139  ((burtcInit->enable == true)
140  && (burtcInit->mode != burtcModeDisable)));
141  /* Low power mode is only available with LFRCO or LFXO as clock source */
142  EFM_ASSERT((burtcInit->clkSel != burtcClkSelULFRCO)
143  || ((burtcInit->clkSel == burtcClkSelULFRCO)
144  && (burtcInit->lowPowerMode == burtcLPDisable)));
145 
146  /* Calculate prescaler value from clock divider input */
147  /* Note! If clock select (clkSel) is ULFRCO, a clock divisor (clkDiv) of
148  value 1 will select a 2kHz ULFRCO clock, while any other value will
149  select a 1kHz ULFRCO clock source. */
150  presc = divToLog2(burtcInit->clkDiv);
151 
152  /* Make sure all registers are updated simultaneously */
153  if (burtcInit->enable)
154  {
155  BURTC_FreezeEnable(true);
156  }
157 
158  /* Modification of LPMODE register requires sync with potential ongoing
159  * register updates in LF domain. */
160  regSync(BURTC_SYNCBUSY_LPMODE);
161 
162  /* Configure low power mode */
163  BURTC->LPMODE = (uint32_t) (burtcInit->lowPowerMode);
164 
165  /* New configuration */
166  ctrl = (BURTC_CTRL_RSTEN
167  | (burtcInit->mode)
168  | (burtcInit->debugRun << _BURTC_CTRL_DEBUGRUN_SHIFT)
169  | (burtcInit->compare0Top << _BURTC_CTRL_COMP0TOP_SHIFT)
170  | (burtcInit->lowPowerComp << _BURTC_CTRL_LPCOMP_SHIFT)
171  | (presc << _BURTC_CTRL_PRESC_SHIFT)
172  | (burtcInit->clkSel)
173  | (burtcInit->timeStamp << _BURTC_CTRL_BUMODETSEN_SHIFT));
174 
175  /* Clear interrupts */
176  BURTC_IntClear(0xFFFFFFFF);
177 
178  /* Set new configuration */
179  BURTC->CTRL = ctrl;
180 
181  /* Enable BURTC and counter */
182  if (burtcInit->enable)
183  {
184  /* To enable BURTC counter, we need to disable reset */
185  BURTC_Enable(true);
186 
187  /* Clear freeze */
188  BURTC_FreezeEnable(false);
189  }
190 }
191 
192 
193 /***************************************************************************/
200 void BURTC_CompareSet(unsigned int comp, uint32_t value)
201 {
202  (void) comp; /* Unused parameter when EFM_ASSERT is undefined. */
203 
204  EFM_ASSERT(comp == 0);
205 
206  /* Modification of COMP0 register requires sync with potential ongoing
207  * register updates in LF domain. */
208  regSync(BURTC_SYNCBUSY_COMP0);
209 
210  /* Configure compare channel 0 */
211  BURTC->COMP0 = value;
212 }
213 
214 
215 /***************************************************************************/
222 uint32_t BURTC_CompareGet(unsigned int comp)
223 {
224  (void) comp; /* Unused parameter when EFM_ASSERT is undefined. */
225 
226  EFM_ASSERT(comp == 0);
227 
228  return BURTC->COMP0;
229 }
230 
231 
232 /***************************************************************************/
236 {
237  /* Set and clear reset bit */
240 }
241 
242 
243 /***************************************************************************/
251 void BURTC_Reset(void)
252 {
253  bool buResetState;
254 
255  /* Read reset state, set reset and restore state */
256  buResetState = BUS_RegBitRead(&RMU->CTRL, _RMU_CTRL_BURSTEN_SHIFT);
258  BUS_RegBitWrite(&RMU->CTRL, _RMU_CTRL_BURSTEN_SHIFT, buResetState);
259 }
260 
261 
262 /***************************************************************************/
269 uint32_t BURTC_ClockFreqGet(void)
270 {
271  uint32_t clkSel;
272  uint32_t clkDiv;
273  uint32_t frequency;
274 
275  clkSel = BURTC->CTRL & _BURTC_CTRL_CLKSEL_MASK;
277 
278  switch (clkSel)
279  {
282  if (_BURTC_CTRL_PRESC_DIV1 == clkDiv)
283  {
284  frequency = 2000; /* 2KHz when clock divisor is 1. */
285  }
286  else
287  {
288  frequency = SystemULFRCOClockGet(); /* 1KHz when divisor is different
289  from 1. */
290  }
291  break;
292 
295  frequency = SystemLFRCOClockGet() / (1 << clkDiv); /* freq=32768/2^clkDiv */
296  break;
297 
300  frequency = SystemLFXOClockGet() / (1 << clkDiv); /* freq=32768/2^clkDiv */
301  break;
302 
303  default:
304  /* No clock selected for BURTC. */
305  frequency = 0;
306  }
307  return frequency;
308 }
309 
310 
314 #endif /* BURTC_PRESENT */
#define BURTC_CTRL_RSTEN
Definition: ezr32lg_burtc.h:90
#define _BURTC_CTRL_PRESC_DIV1
#define _BURTC_CTRL_PRESC_MASK
#define _RMU_CTRL_BURSTEN_SHIFT
Definition: ezr32lg_rmu.h:62
#define BURTC_SYNCBUSY_LPMODE
#define BURTC
void BURTC_Reset(void)
Restore BURTC to reset state.
Definition: em_burtc.c:251
#define _BURTC_CTRL_RSTEN_SHIFT
Definition: ezr32lg_burtc.h:91
__STATIC_INLINE unsigned int BUS_RegBitRead(volatile const uint32_t *addr, unsigned int bit)
Perform a single-bit read operation on a peripheral register.
Definition: em_bus.h:185
#define BURTC_SYNCBUSY_COMP0
void BURTC_Init(const BURTC_Init_TypeDef *burtcInit)
Initialize BURTC.
Definition: em_burtc.c:125
#define RMU
uint32_t SystemLFRCOClockGet(void)
Get low frequency RC oscillator clock frequency for target system.
#define _BURTC_CTRL_COMP0TOP_SHIFT
Definition: ezr32lg_burtc.h:96
#define _BURTC_CTRL_DEBUGRUN_SHIFT
Definition: ezr32lg_burtc.h:86
#define _BURTC_CTRL_LPCOMP_SHIFT
BURTC_ClkSel_TypeDef clkSel
Definition: em_burtc.h:122
uint32_t SystemLFXOClockGet(void)
Get low frequency crystal oscillator clock frequency for target system.
BURTC_LP_TypeDef lowPowerMode
Definition: em_burtc.h:130
uint32_t BURTC_CompareGet(unsigned int comp)
Get BURTC compare value.
Definition: em_burtc.c:222
__STATIC_INLINE void BURTC_IntClear(uint32_t flags)
Clear one or more pending BURTC interrupts.
Definition: em_burtc.h:160
Backup Real Time Counter (BURTC) peripheral API.
uint32_t lowPowerComp
Definition: em_burtc.h:125
uint32_t SystemULFRCOClockGet(void)
Get ultra low frequency RC oscillator clock frequency for target system.
uint32_t clkDiv
Definition: em_burtc.h:123
#define _BURTC_CTRL_CLKSEL_NONE
#define BURTC_CTRL_CLKSEL_LFXO
#define BURTC_FREEZE_REGFREEZE
__STATIC_INLINE void BURTC_FreezeEnable(bool enable)
Freeze register updates until enabled.
Definition: em_burtc.h:331
__STATIC_INLINE void BURTC_Enable(bool enable)
Enable or Disable BURTC peripheral reset and start counter.
Definition: em_burtc.h:285
__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 BURTC_CTRL_CLKSEL_LFRCO
uint32_t BURTC_ClockFreqGet(void)
Get clock frequency of the BURTC.
Definition: em_burtc.c:269
void BURTC_CounterReset(void)
Reset counter.
Definition: em_burtc.c:235
#define BURTC_CTRL_CLKSEL_ULFRCO
#define _BURTC_CTRL_CLKSEL_MASK
#define _BURTC_CTRL_PRESC_SHIFT
#define _BURTC_CTRL_BUMODETSEN_SHIFT
void BURTC_CompareSet(unsigned int comp, uint32_t value)
Set BURTC compare channel.
Definition: em_burtc.c:200
BURTC_Mode_TypeDef mode
Definition: em_burtc.h:120