em_burtc.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /***************************************************************************//**
  2. * @file
  3. * @brief Backup Real Time Counter (BURTC) Peripheral API
  4. * @author Energy Micro AS
  5. * @version 3.0.0
  6. *******************************************************************************
  7. * @section License
  8. * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
  9. *******************************************************************************
  10. *
  11. * Permission is granted to anyone to use this software for any purpose,
  12. * including commercial applications, and to alter it and redistribute it
  13. * freely, subject to the following restrictions:
  14. *
  15. * 1. The origin of this software must not be misrepresented; you must not
  16. * claim that you wrote the original software.
  17. * 2. Altered source versions must be plainly marked as such, and must not be
  18. * misrepresented as being the original software.
  19. * 3. This notice may not be removed or altered from any source distribution.
  20. *
  21. * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
  22. * obligation to support this Software. Energy Micro AS is providing the
  23. * Software "AS IS", with no express or implied warranties of any kind,
  24. * including, but not limited to, any implied warranties of merchantability
  25. * or fitness for any particular purpose or warranties against infringement
  26. * of any proprietary rights of a third party.
  27. *
  28. * Energy Micro AS will not be liable for any consequential, incidental, or
  29. * special damages, or any other relief, or for any claim by any third party,
  30. * arising from your use of this Software.
  31. *
  32. ******************************************************************************/
  33. #include "em_part.h"
  34. #if defined(BURTC_PRESENT)
  35. #include "em_burtc.h"
  36. #include "em_assert.h"
  37. #include "em_bitband.h"
  38. /***************************************************************************//**
  39. * @addtogroup EM_Library
  40. * @{
  41. ******************************************************************************/
  42. /***************************************************************************//**
  43. * @addtogroup BURTC
  44. * @brief Backup Real Time Counter (BURTC) Peripheral API
  45. * @{
  46. ******************************************************************************/
  47. /*******************************************************************************
  48. ******************************* DEFINES ***********************************
  49. ******************************************************************************/
  50. /*******************************************************************************
  51. ************************** LOCAL FUNCTIONS ********************************
  52. ******************************************************************************/
  53. /***************************************************************************//**
  54. * @brief Convert dividend to prescaler logarithmic value. Only works for even
  55. * numbers equal to 2^n
  56. * @param[in] div Unscaled dividend,
  57. * @return Base 2 logarithm of input, as used by fixed prescalers
  58. ******************************************************************************/
  59. __STATIC_INLINE uint32_t BURTC_DivToLog2(uint32_t div)
  60. {
  61. uint32_t log2;
  62. /* Prescaler accepts an argument of 128 or less, valid values being 2^n */
  63. EFM_ASSERT((div > 0) && (div <= 32768));
  64. /* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
  65. log2 = (31 - __CLZ(div));
  66. return log2;
  67. }
  68. /*******************************************************************************
  69. ************************** GLOBAL FUNCTIONS *******************************
  70. ******************************************************************************/
  71. /***************************************************************************//**
  72. * @brief Initialize BURTC
  73. *
  74. * @details
  75. * Configures the BURTC peripheral.
  76. *
  77. * @note
  78. * Before initialization, BURTC module must first be enabled by clearing the
  79. * reset bit in the RMU, i.e.
  80. * @verbatim
  81. * RMU_ResetControl(rmuResetBU, false);
  82. * @endverbatim
  83. * Compare channel 0 must be configured outside this function, before
  84. * initialization if enable is set to true. The counter will always be reset.
  85. *
  86. * @param[in] burtcInit
  87. * Pointer to BURTC initialization structure
  88. ******************************************************************************/
  89. void BURTC_Init(const BURTC_Init_TypeDef *burtcInit)
  90. {
  91. uint32_t ctrl;
  92. uint32_t presc;
  93. /* Check initializer structure integrity */
  94. EFM_ASSERT(burtcInit != (BURTC_Init_TypeDef *) 0);
  95. /* Clock divider must be between 1 and 128, really on the form 2^n */
  96. EFM_ASSERT((burtcInit->clkDiv >= 1) && (burtcInit->clkDiv <= 128));
  97. /* Ignored compare bits during low power operation must be less than 7 */
  98. /* Note! Giant Gecko revision C errata, do NOT use LPCOMP=7 */
  99. EFM_ASSERT(burtcInit->lowPowerComp <= 6);
  100. /* You cannot enable the BURTC if mode is set to disabled */
  101. EFM_ASSERT((burtcInit->enable == false) ||
  102. ((burtcInit->enable == true) && (burtcInit->mode != burtcModeDisable)));
  103. /* Low power mode is only available with LFRCO or LFXO as clock source */
  104. EFM_ASSERT((burtcInit->clkSel != burtcClkSelULFRCO) ||
  105. ((burtcInit->clkSel == burtcClkSelULFRCO) && (burtcInit->lowPowerMode == burtcLPDisable)));
  106. /* Calculate prescaler value from clock divider input */
  107. /* Note! If clock select (clkSel) is ULFRCO, a non-zero clkDiv will select */
  108. /* 1kHz clock source, while any other value will use a 2kHz ULFRCO clock */
  109. presc = BURTC_DivToLog2(burtcInit->clkDiv);
  110. /* Make sure all registers are updated simultaneously */
  111. if (burtcInit->enable)
  112. {
  113. BURTC_FreezeEnable(true);
  114. }
  115. /* Configure low power mode */
  116. BURTC->LPMODE = (uint32_t)(burtcInit->lowPowerMode);
  117. /* New configuration */
  118. ctrl = ((BURTC_CTRL_RSTEN) |
  119. (burtcInit->mode) |
  120. (burtcInit->debugRun << _BURTC_CTRL_DEBUGRUN_SHIFT) |
  121. (burtcInit->compare0Top << _BURTC_CTRL_COMP0TOP_SHIFT) |
  122. (burtcInit->lowPowerComp << _BURTC_CTRL_LPCOMP_SHIFT) |
  123. (presc << _BURTC_CTRL_PRESC_SHIFT) |
  124. (burtcInit->clkSel) |
  125. (burtcInit->timeStamp << _BURTC_CTRL_BUMODETSEN_SHIFT));
  126. /* Clear interrupts */
  127. BURTC->IFC = 0xFFFFFFFF;
  128. /* Set new configuration */
  129. BURTC->CTRL = ctrl;
  130. /* Enable BURTC and counter */
  131. if (burtcInit->enable)
  132. {
  133. /* To enable BURTC counter, we need to disable reset */
  134. BURTC_Enable(true);
  135. /* Clear freeze */
  136. BURTC_FreezeEnable(false);
  137. /* Await synchronization into low frequency domain */
  138. while (BURTC->SYNCBUSY) ;
  139. }
  140. }
  141. /***************************************************************************//**
  142. * @brief Set BURTC compare channel
  143. *
  144. * @param[in] comp Compare channel index, must be 0 for Giant / Leopard Gecko
  145. *
  146. * @param[in] value New compare value
  147. ******************************************************************************/
  148. void BURTC_CompareSet(unsigned int comp, uint32_t value)
  149. {
  150. EFM_ASSERT(comp == 0);
  151. /* Configure compare channel 0 */
  152. BURTC->COMP0 = value;
  153. /* Check if freeze or RSTEN is active, if not wait for synchronization of register */
  154. if (BURTC->FREEZE & BURTC_FREEZE_REGFREEZE_FREEZE)
  155. {
  156. return;
  157. }
  158. /* Check if mode is enabled */
  159. if ((BURTC->CTRL & _BURTC_CTRL_MODE_MASK) == BURTC_CTRL_MODE_DISABLE)
  160. {
  161. return;
  162. }
  163. while (BURTC->SYNCBUSY & BURTC_SYNCBUSY_COMP0) ;
  164. }
  165. /***************************************************************************//**
  166. * @brief Get BURTC compare value
  167. *
  168. * @param[in] comp Compare channel index value, must be 0 for Giant/Leopard.
  169. *
  170. * @return Currently configured value for this compare channel
  171. ******************************************************************************/
  172. uint32_t BURTC_CompareGet(unsigned int comp)
  173. {
  174. EFM_ASSERT(comp == 0);
  175. return BURTC->COMP0;
  176. }
  177. /***************************************************************************//**
  178. * @brief Reset counter
  179. *
  180. * @param[in] mode New mode of operation, after clearing
  181. ******************************************************************************/
  182. void BURTC_CounterReset(void)
  183. {
  184. /* Set and clear reset bit */
  185. BITBAND_Peripheral(&BURTC->CTRL, _BURTC_CTRL_RSTEN_SHIFT, 1);
  186. BITBAND_Peripheral(&BURTC->CTRL, _BURTC_CTRL_RSTEN_SHIFT, 0);
  187. }
  188. /***************************************************************************//**
  189. * @brief
  190. * Restore BURTC to reset state
  191. * @note
  192. * Before accessing the BURTC, BURSTEN in RMU->CTRL must be cleared.
  193. * LOCK will not be reset to default value, as this will disable access
  194. * to core BURTC registers.
  195. ******************************************************************************/
  196. void BURTC_Reset(void)
  197. {
  198. /* Verify RMU BURSTEN is disabled */
  199. EFM_ASSERT((RMU->CTRL & RMU_CTRL_BURSTEN) == 0);
  200. /* Restore all essential BURTC registers to default config */
  201. BURTC->CTRL = _BURTC_CTRL_RESETVALUE;
  202. BURTC->IEN = _BURTC_IEN_RESETVALUE;
  203. BURTC->LPMODE = _BURTC_LPMODE_RESETVALUE;
  204. BURTC->LFXOFDET = _BURTC_LFXOFDET_RESETVALUE;
  205. BURTC->POWERDOWN = _BURTC_POWERDOWN_RESETVALUE;
  206. BURTC->FREEZE = _BURTC_FREEZE_RESETVALUE;
  207. }
  208. /** @} (end addtogroup BURTC) */
  209. /** @} (end addtogroup EM_Library) */
  210. #endif /* BURTC_PRESENT */