123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /***************************************************************************//**
- * @file
- * @brief Backup Real Time Counter (BURTC) Peripheral API
- * @author Energy Micro AS
- * @version 3.0.0
- *******************************************************************************
- * @section License
- * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
- *******************************************************************************
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- *
- * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
- * obligation to support this Software. Energy Micro AS is providing the
- * Software "AS IS", with no express or implied warranties of any kind,
- * including, but not limited to, any implied warranties of merchantability
- * or fitness for any particular purpose or warranties against infringement
- * of any proprietary rights of a third party.
- *
- * Energy Micro AS will not be liable for any consequential, incidental, or
- * special damages, or any other relief, or for any claim by any third party,
- * arising from your use of this Software.
- *
- ******************************************************************************/
- #include "em_part.h"
- #if defined(BURTC_PRESENT)
- #include "em_burtc.h"
- #include "em_assert.h"
- #include "em_bitband.h"
- /***************************************************************************//**
- * @addtogroup EM_Library
- * @{
- ******************************************************************************/
- /***************************************************************************//**
- * @addtogroup BURTC
- * @brief Backup Real Time Counter (BURTC) Peripheral API
- * @{
- ******************************************************************************/
- /*******************************************************************************
- ******************************* DEFINES ***********************************
- ******************************************************************************/
- /*******************************************************************************
- ************************** LOCAL FUNCTIONS ********************************
- ******************************************************************************/
- /***************************************************************************//**
- * @brief Convert dividend to prescaler logarithmic value. Only works for even
- * numbers equal to 2^n
- * @param[in] div Unscaled dividend,
- * @return Base 2 logarithm of input, as used by fixed prescalers
- ******************************************************************************/
- __STATIC_INLINE uint32_t BURTC_DivToLog2(uint32_t div)
- {
- uint32_t log2;
- /* Prescaler accepts an argument of 128 or less, valid values being 2^n */
- EFM_ASSERT((div > 0) && (div <= 32768));
- /* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
- log2 = (31 - __CLZ(div));
- return log2;
- }
- /*******************************************************************************
- ************************** GLOBAL FUNCTIONS *******************************
- ******************************************************************************/
- /***************************************************************************//**
- * @brief Initialize BURTC
- *
- * @details
- * Configures the BURTC peripheral.
- *
- * @note
- * Before initialization, BURTC module must first be enabled by clearing the
- * reset bit in the RMU, i.e.
- * @verbatim
- * RMU_ResetControl(rmuResetBU, false);
- * @endverbatim
- * Compare channel 0 must be configured outside this function, before
- * initialization if enable is set to true. The counter will always be reset.
- *
- * @param[in] burtcInit
- * Pointer to BURTC initialization structure
- ******************************************************************************/
- void BURTC_Init(const BURTC_Init_TypeDef *burtcInit)
- {
- uint32_t ctrl;
- uint32_t presc;
- /* Check initializer structure integrity */
- EFM_ASSERT(burtcInit != (BURTC_Init_TypeDef *) 0);
- /* Clock divider must be between 1 and 128, really on the form 2^n */
- EFM_ASSERT((burtcInit->clkDiv >= 1) && (burtcInit->clkDiv <= 128));
- /* Ignored compare bits during low power operation must be less than 7 */
- /* Note! Giant Gecko revision C errata, do NOT use LPCOMP=7 */
- EFM_ASSERT(burtcInit->lowPowerComp <= 6);
- /* You cannot enable the BURTC if mode is set to disabled */
- EFM_ASSERT((burtcInit->enable == false) ||
- ((burtcInit->enable == true) && (burtcInit->mode != burtcModeDisable)));
- /* Low power mode is only available with LFRCO or LFXO as clock source */
- EFM_ASSERT((burtcInit->clkSel != burtcClkSelULFRCO) ||
- ((burtcInit->clkSel == burtcClkSelULFRCO) && (burtcInit->lowPowerMode == burtcLPDisable)));
- /* Calculate prescaler value from clock divider input */
- /* Note! If clock select (clkSel) is ULFRCO, a non-zero clkDiv will select */
- /* 1kHz clock source, while any other value will use a 2kHz ULFRCO clock */
- presc = BURTC_DivToLog2(burtcInit->clkDiv);
- /* Make sure all registers are updated simultaneously */
- if (burtcInit->enable)
- {
- BURTC_FreezeEnable(true);
- }
- /* Configure low power mode */
- BURTC->LPMODE = (uint32_t)(burtcInit->lowPowerMode);
- /* New configuration */
- ctrl = ((BURTC_CTRL_RSTEN) |
- (burtcInit->mode) |
- (burtcInit->debugRun << _BURTC_CTRL_DEBUGRUN_SHIFT) |
- (burtcInit->compare0Top << _BURTC_CTRL_COMP0TOP_SHIFT) |
- (burtcInit->lowPowerComp << _BURTC_CTRL_LPCOMP_SHIFT) |
- (presc << _BURTC_CTRL_PRESC_SHIFT) |
- (burtcInit->clkSel) |
- (burtcInit->timeStamp << _BURTC_CTRL_BUMODETSEN_SHIFT));
- /* Clear interrupts */
- BURTC->IFC = 0xFFFFFFFF;
- /* Set new configuration */
- BURTC->CTRL = ctrl;
- /* Enable BURTC and counter */
- if (burtcInit->enable)
- {
- /* To enable BURTC counter, we need to disable reset */
- BURTC_Enable(true);
- /* Clear freeze */
- BURTC_FreezeEnable(false);
- /* Await synchronization into low frequency domain */
- while (BURTC->SYNCBUSY) ;
- }
- }
- /***************************************************************************//**
- * @brief Set BURTC compare channel
- *
- * @param[in] comp Compare channel index, must be 0 for Giant / Leopard Gecko
- *
- * @param[in] value New compare value
- ******************************************************************************/
- void BURTC_CompareSet(unsigned int comp, uint32_t value)
- {
- EFM_ASSERT(comp == 0);
- /* Configure compare channel 0 */
- BURTC->COMP0 = value;
- /* Check if freeze or RSTEN is active, if not wait for synchronization of register */
- if (BURTC->FREEZE & BURTC_FREEZE_REGFREEZE_FREEZE)
- {
- return;
- }
- /* Check if mode is enabled */
- if ((BURTC->CTRL & _BURTC_CTRL_MODE_MASK) == BURTC_CTRL_MODE_DISABLE)
- {
- return;
- }
- while (BURTC->SYNCBUSY & BURTC_SYNCBUSY_COMP0) ;
- }
- /***************************************************************************//**
- * @brief Get BURTC compare value
- *
- * @param[in] comp Compare channel index value, must be 0 for Giant/Leopard.
- *
- * @return Currently configured value for this compare channel
- ******************************************************************************/
- uint32_t BURTC_CompareGet(unsigned int comp)
- {
- EFM_ASSERT(comp == 0);
- return BURTC->COMP0;
- }
- /***************************************************************************//**
- * @brief Reset counter
- *
- * @param[in] mode New mode of operation, after clearing
- ******************************************************************************/
- void BURTC_CounterReset(void)
- {
- /* Set and clear reset bit */
- BITBAND_Peripheral(&BURTC->CTRL, _BURTC_CTRL_RSTEN_SHIFT, 1);
- BITBAND_Peripheral(&BURTC->CTRL, _BURTC_CTRL_RSTEN_SHIFT, 0);
- }
- /***************************************************************************//**
- * @brief
- * Restore BURTC to reset state
- * @note
- * Before accessing the BURTC, BURSTEN in RMU->CTRL must be cleared.
- * LOCK will not be reset to default value, as this will disable access
- * to core BURTC registers.
- ******************************************************************************/
- void BURTC_Reset(void)
- {
- /* Verify RMU BURSTEN is disabled */
- EFM_ASSERT((RMU->CTRL & RMU_CTRL_BURSTEN) == 0);
- /* Restore all essential BURTC registers to default config */
- BURTC->CTRL = _BURTC_CTRL_RESETVALUE;
- BURTC->IEN = _BURTC_IEN_RESETVALUE;
- BURTC->LPMODE = _BURTC_LPMODE_RESETVALUE;
- BURTC->LFXOFDET = _BURTC_LFXOFDET_RESETVALUE;
- BURTC->POWERDOWN = _BURTC_POWERDOWN_RESETVALUE;
- BURTC->FREEZE = _BURTC_FREEZE_RESETVALUE;
- }
- /** @} (end addtogroup BURTC) */
- /** @} (end addtogroup EM_Library) */
- #endif /* BURTC_PRESENT */
|