mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
50:a417edff4437
This updates the lib to the mbed lib v125

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file em_letimer.c
<> 144:ef7eb2e8f9f7 3 * @brief Low Energy Timer (LETIMER) Peripheral API
<> 144:ef7eb2e8f9f7 4 * @version 4.2.1
<> 144:ef7eb2e8f9f7 5 *******************************************************************************
<> 144:ef7eb2e8f9f7 6 * @section License
<> 144:ef7eb2e8f9f7 7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 8 *******************************************************************************
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Permission is granted to anyone to use this software for any purpose,
<> 144:ef7eb2e8f9f7 11 * including commercial applications, and to alter it and redistribute it
<> 144:ef7eb2e8f9f7 12 * freely, subject to the following restrictions:
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * 1. The origin of this software must not be misrepresented; you must not
<> 144:ef7eb2e8f9f7 15 * claim that you wrote the original software.
<> 144:ef7eb2e8f9f7 16 * 2. Altered source versions must be plainly marked as such, and must not be
<> 144:ef7eb2e8f9f7 17 * misrepresented as being the original software.
<> 144:ef7eb2e8f9f7 18 * 3. This notice may not be removed or altered from any source distribution.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
<> 144:ef7eb2e8f9f7 21 * obligation to support this Software. Silicon Labs is providing the
<> 144:ef7eb2e8f9f7 22 * Software "AS IS", with no express or implied warranties of any kind,
<> 144:ef7eb2e8f9f7 23 * including, but not limited to, any implied warranties of merchantability
<> 144:ef7eb2e8f9f7 24 * or fitness for any particular purpose or warranties against infringement
<> 144:ef7eb2e8f9f7 25 * of any proprietary rights of a third party.
<> 144:ef7eb2e8f9f7 26 *
<> 144:ef7eb2e8f9f7 27 * Silicon Labs will not be liable for any consequential, incidental, or
<> 144:ef7eb2e8f9f7 28 * special damages, or any other relief, or for any claim by any third party,
<> 144:ef7eb2e8f9f7 29 * arising from your use of this Software.
<> 144:ef7eb2e8f9f7 30 *
<> 144:ef7eb2e8f9f7 31 ******************************************************************************/
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #include "em_letimer.h"
<> 144:ef7eb2e8f9f7 34 #if defined(LETIMER_COUNT) && (LETIMER_COUNT > 0)
<> 144:ef7eb2e8f9f7 35 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 36 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 37
<> 144:ef7eb2e8f9f7 38 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 39 * @addtogroup EM_Library
<> 144:ef7eb2e8f9f7 40 * @{
<> 144:ef7eb2e8f9f7 41 ******************************************************************************/
<> 144:ef7eb2e8f9f7 42
<> 144:ef7eb2e8f9f7 43 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 44 * @addtogroup LETIMER
<> 144:ef7eb2e8f9f7 45 * @brief Low Energy Timer (LETIMER) Peripheral API
<> 144:ef7eb2e8f9f7 46 * @{
<> 144:ef7eb2e8f9f7 47 ******************************************************************************/
<> 144:ef7eb2e8f9f7 48
<> 144:ef7eb2e8f9f7 49 /*******************************************************************************
<> 144:ef7eb2e8f9f7 50 ******************************* DEFINES ***********************************
<> 144:ef7eb2e8f9f7 51 ******************************************************************************/
<> 144:ef7eb2e8f9f7 52
<> 144:ef7eb2e8f9f7 53 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 54
<> 144:ef7eb2e8f9f7 55 /** Validation of valid comparator register for assert statements. */
<> 144:ef7eb2e8f9f7 56 #define LETIMER_COMP_REG_VALID(reg) (((reg) <= 1))
<> 144:ef7eb2e8f9f7 57
<> 144:ef7eb2e8f9f7 58 /** Validation of LETIMER register block pointer reference for assert statements. */
<> 144:ef7eb2e8f9f7 59 #define LETIMER_REF_VALID(ref) ((ref) == LETIMER0)
<> 144:ef7eb2e8f9f7 60
<> 144:ef7eb2e8f9f7 61 /** Validation of valid repeat counter register for assert statements. */
<> 144:ef7eb2e8f9f7 62 #define LETIMER_REP_REG_VALID(reg) (((reg) <= 1))
<> 144:ef7eb2e8f9f7 63
<> 144:ef7eb2e8f9f7 64 /** @endcond */
<> 144:ef7eb2e8f9f7 65
<> 144:ef7eb2e8f9f7 66
<> 144:ef7eb2e8f9f7 67 /*******************************************************************************
<> 144:ef7eb2e8f9f7 68 ************************** LOCAL FUNCTIONS ********************************
<> 144:ef7eb2e8f9f7 69 ******************************************************************************/
<> 144:ef7eb2e8f9f7 70
<> 144:ef7eb2e8f9f7 71 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 72
<> 144:ef7eb2e8f9f7 73 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 74 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 75 * @brief
<> 144:ef7eb2e8f9f7 76 * Wait for ongoing sync of register(s) to low frequency domain to complete.
<> 144:ef7eb2e8f9f7 77 *
<> 144:ef7eb2e8f9f7 78 * @note
<> 144:ef7eb2e8f9f7 79 * This only applies to the Gecko Family, see the reference manual
<> 144:ef7eb2e8f9f7 80 * chapter about Access to Low Energy Peripherals (Asynchronos Registers)
<> 144:ef7eb2e8f9f7 81 * for details.
<> 144:ef7eb2e8f9f7 82 *
<> 144:ef7eb2e8f9f7 83 * @param[in] letimer
<> 144:ef7eb2e8f9f7 84 * Pointer to LETIMER peripheral register block
<> 144:ef7eb2e8f9f7 85 *
<> 144:ef7eb2e8f9f7 86 * @param[in] mask
<> 144:ef7eb2e8f9f7 87 * Bitmask corresponding to SYNCBUSY register defined bits, indicating
<> 144:ef7eb2e8f9f7 88 * registers that must complete any ongoing synchronization.
<> 144:ef7eb2e8f9f7 89 ******************************************************************************/
<> 144:ef7eb2e8f9f7 90 __STATIC_INLINE void regSync(LETIMER_TypeDef *letimer, uint32_t mask)
<> 144:ef7eb2e8f9f7 91 {
<> 144:ef7eb2e8f9f7 92 #if defined(_LETIMER_FREEZE_MASK)
<> 144:ef7eb2e8f9f7 93 /* Avoid deadlock if modifying the same register twice when freeze mode is */
<> 144:ef7eb2e8f9f7 94 /* activated. */
<> 144:ef7eb2e8f9f7 95 if (letimer->FREEZE & LETIMER_FREEZE_REGFREEZE)
<> 144:ef7eb2e8f9f7 96 return;
<> 144:ef7eb2e8f9f7 97 #endif
<> 144:ef7eb2e8f9f7 98
<> 144:ef7eb2e8f9f7 99 /* Wait for any pending previous write operation to have been completed */
<> 144:ef7eb2e8f9f7 100 /* in low frequency domain, only required for Gecko Family of devices */
<> 144:ef7eb2e8f9f7 101 while (letimer->SYNCBUSY & mask)
<> 144:ef7eb2e8f9f7 102 ;
<> 144:ef7eb2e8f9f7 103 }
<> 144:ef7eb2e8f9f7 104 #endif
<> 144:ef7eb2e8f9f7 105
<> 144:ef7eb2e8f9f7 106 /** @endcond */
<> 144:ef7eb2e8f9f7 107
<> 144:ef7eb2e8f9f7 108 /*******************************************************************************
<> 144:ef7eb2e8f9f7 109 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 110 ******************************************************************************/
<> 144:ef7eb2e8f9f7 111
<> 144:ef7eb2e8f9f7 112 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 113 * @brief
<> 144:ef7eb2e8f9f7 114 * Get LETIMER compare register value.
<> 144:ef7eb2e8f9f7 115 *
<> 144:ef7eb2e8f9f7 116 * @param[in] letimer
<> 144:ef7eb2e8f9f7 117 * Pointer to LETIMER peripheral register block
<> 144:ef7eb2e8f9f7 118 *
<> 144:ef7eb2e8f9f7 119 * @param[in] comp
<> 144:ef7eb2e8f9f7 120 * Compare register to get, either 0 or 1
<> 144:ef7eb2e8f9f7 121 *
<> 144:ef7eb2e8f9f7 122 * @return
<> 144:ef7eb2e8f9f7 123 * Compare register value, 0 if invalid register selected.
<> 144:ef7eb2e8f9f7 124 ******************************************************************************/
<> 144:ef7eb2e8f9f7 125 uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp)
<> 144:ef7eb2e8f9f7 126 {
<> 144:ef7eb2e8f9f7 127 uint32_t ret;
<> 144:ef7eb2e8f9f7 128
<> 144:ef7eb2e8f9f7 129 EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_COMP_REG_VALID(comp));
<> 144:ef7eb2e8f9f7 130
<> 144:ef7eb2e8f9f7 131 /* Initialize selected compare value */
<> 144:ef7eb2e8f9f7 132 switch (comp)
<> 144:ef7eb2e8f9f7 133 {
<> 144:ef7eb2e8f9f7 134 case 0:
<> 144:ef7eb2e8f9f7 135 ret = letimer->COMP0;
<> 144:ef7eb2e8f9f7 136 break;
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 case 1:
<> 144:ef7eb2e8f9f7 139 ret = letimer->COMP1;
<> 144:ef7eb2e8f9f7 140 break;
<> 144:ef7eb2e8f9f7 141
<> 144:ef7eb2e8f9f7 142 default:
<> 144:ef7eb2e8f9f7 143 /* Unknown compare register selected */
<> 144:ef7eb2e8f9f7 144 ret = 0;
<> 144:ef7eb2e8f9f7 145 break;
<> 144:ef7eb2e8f9f7 146 }
<> 144:ef7eb2e8f9f7 147
<> 144:ef7eb2e8f9f7 148 return(ret);
<> 144:ef7eb2e8f9f7 149 }
<> 144:ef7eb2e8f9f7 150
<> 144:ef7eb2e8f9f7 151
<> 144:ef7eb2e8f9f7 152 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 153 * @brief
<> 144:ef7eb2e8f9f7 154 * Set LETIMER compare register value.
<> 144:ef7eb2e8f9f7 155 *
<> 144:ef7eb2e8f9f7 156 * @note
<> 144:ef7eb2e8f9f7 157 * The setting of a compare register requires synchronization into the
<> 144:ef7eb2e8f9f7 158 * low frequency domain. If the same register is modified before a previous
<> 144:ef7eb2e8f9f7 159 * update has completed, this function will stall until the previous
<> 144:ef7eb2e8f9f7 160 * synchronization has completed. This only applies to the Gecko Family, see
<> 144:ef7eb2e8f9f7 161 * comment in the LETIMER_Sync() internal function call.
<> 144:ef7eb2e8f9f7 162 *
<> 144:ef7eb2e8f9f7 163 * @param[in] letimer
<> 144:ef7eb2e8f9f7 164 * Pointer to LETIMER peripheral register block
<> 144:ef7eb2e8f9f7 165 *
<> 144:ef7eb2e8f9f7 166 * @param[in] comp
<> 144:ef7eb2e8f9f7 167 * Compare register to set, either 0 or 1
<> 144:ef7eb2e8f9f7 168 *
<> 144:ef7eb2e8f9f7 169 * @param[in] value
<> 144:ef7eb2e8f9f7 170 * Initialization value (<= 0x0000ffff)
<> 144:ef7eb2e8f9f7 171 ******************************************************************************/
<> 144:ef7eb2e8f9f7 172 void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
<> 144:ef7eb2e8f9f7 173 unsigned int comp,
<> 144:ef7eb2e8f9f7 174 uint32_t value)
<> 144:ef7eb2e8f9f7 175 {
<> 144:ef7eb2e8f9f7 176 volatile uint32_t *compReg;
<> 144:ef7eb2e8f9f7 177
<> 144:ef7eb2e8f9f7 178 EFM_ASSERT(LETIMER_REF_VALID(letimer)
<> 144:ef7eb2e8f9f7 179 && LETIMER_COMP_REG_VALID(comp)
<> 144:ef7eb2e8f9f7 180 && ((value & ~(_LETIMER_COMP0_COMP0_MASK
<> 144:ef7eb2e8f9f7 181 >> _LETIMER_COMP0_COMP0_SHIFT))
<> 144:ef7eb2e8f9f7 182 == 0));
<> 144:ef7eb2e8f9f7 183
<> 144:ef7eb2e8f9f7 184 /* Initialize selected compare value */
<> 144:ef7eb2e8f9f7 185 switch (comp)
<> 144:ef7eb2e8f9f7 186 {
<> 144:ef7eb2e8f9f7 187 case 0:
<> 144:ef7eb2e8f9f7 188 compReg = &(letimer->COMP0);
<> 144:ef7eb2e8f9f7 189 break;
<> 144:ef7eb2e8f9f7 190
<> 144:ef7eb2e8f9f7 191 case 1:
<> 144:ef7eb2e8f9f7 192 compReg = &(letimer->COMP1);
<> 144:ef7eb2e8f9f7 193 break;
<> 144:ef7eb2e8f9f7 194
<> 144:ef7eb2e8f9f7 195 default:
<> 144:ef7eb2e8f9f7 196 /* Unknown compare register selected, abort */
<> 144:ef7eb2e8f9f7 197 return;
<> 144:ef7eb2e8f9f7 198 }
<> 144:ef7eb2e8f9f7 199
<> 144:ef7eb2e8f9f7 200 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 201 /* LF register about to be modified require sync. busy check */
<> 144:ef7eb2e8f9f7 202 regSync(letimer, comp ? LETIMER_SYNCBUSY_COMP1 : LETIMER_SYNCBUSY_COMP0);
<> 144:ef7eb2e8f9f7 203 #endif
<> 144:ef7eb2e8f9f7 204
<> 144:ef7eb2e8f9f7 205 *compReg = value;
<> 144:ef7eb2e8f9f7 206 }
<> 144:ef7eb2e8f9f7 207
<> 144:ef7eb2e8f9f7 208
<> 144:ef7eb2e8f9f7 209 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 210 * @brief
<> 144:ef7eb2e8f9f7 211 * Start/stop LETIMER.
<> 144:ef7eb2e8f9f7 212 *
<> 144:ef7eb2e8f9f7 213 * @note
<> 144:ef7eb2e8f9f7 214 * The enabling/disabling of the LETIMER modifies the LETIMER CMD register
<> 144:ef7eb2e8f9f7 215 * which requires synchronization into the low frequency domain. If this
<> 144:ef7eb2e8f9f7 216 * register is modified before a previous update to the same register has
<> 144:ef7eb2e8f9f7 217 * completed, this function will stall until the previous synchronization has
<> 144:ef7eb2e8f9f7 218 * completed. This only applies to the Gecko Family, see comment in the
<> 144:ef7eb2e8f9f7 219 * LETIMER_Sync() internal function call.
<> 144:ef7eb2e8f9f7 220 *
<> 144:ef7eb2e8f9f7 221 * @param[in] letimer
<> 144:ef7eb2e8f9f7 222 * Pointer to LETIMER peripheral register block.
<> 144:ef7eb2e8f9f7 223 *
<> 144:ef7eb2e8f9f7 224 * @param[in] enable
<> 144:ef7eb2e8f9f7 225 * true to enable counting, false to disable.
<> 144:ef7eb2e8f9f7 226 ******************************************************************************/
<> 144:ef7eb2e8f9f7 227 void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable)
<> 144:ef7eb2e8f9f7 228 {
<> 144:ef7eb2e8f9f7 229 EFM_ASSERT(LETIMER_REF_VALID(letimer));
<> 144:ef7eb2e8f9f7 230
<> 144:ef7eb2e8f9f7 231 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 232 /* LF register about to be modified require sync. busy check */
<> 144:ef7eb2e8f9f7 233 regSync(letimer, LETIMER_SYNCBUSY_CMD);
<> 144:ef7eb2e8f9f7 234 #endif
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 if (enable)
<> 144:ef7eb2e8f9f7 237 {
<> 144:ef7eb2e8f9f7 238 letimer->CMD = LETIMER_CMD_START;
<> 144:ef7eb2e8f9f7 239 }
<> 144:ef7eb2e8f9f7 240 else
<> 144:ef7eb2e8f9f7 241 {
<> 144:ef7eb2e8f9f7 242 letimer->CMD = LETIMER_CMD_STOP;
<> 144:ef7eb2e8f9f7 243 }
<> 144:ef7eb2e8f9f7 244 }
<> 144:ef7eb2e8f9f7 245
<> 144:ef7eb2e8f9f7 246 #if defined(_LETIMER_FREEZE_MASK)
<> 144:ef7eb2e8f9f7 247 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 248 * @brief
<> 144:ef7eb2e8f9f7 249 * LETIMER register synchronization freeze control.
<> 144:ef7eb2e8f9f7 250 *
<> 144:ef7eb2e8f9f7 251 * @details
<> 144:ef7eb2e8f9f7 252 * Some LETIMER registers require synchronization into the low frequency (LF)
<> 144:ef7eb2e8f9f7 253 * domain. The freeze feature allows for several such registers to be
<> 144:ef7eb2e8f9f7 254 * modified before passing them to the LF domain simultaneously (which
<> 144:ef7eb2e8f9f7 255 * takes place when the freeze mode is disabled).
<> 144:ef7eb2e8f9f7 256 *
<> 144:ef7eb2e8f9f7 257 * @note
<> 144:ef7eb2e8f9f7 258 * When enabling freeze mode, this function will wait for all current
<> 144:ef7eb2e8f9f7 259 * ongoing LETIMER synchronization to LF domain to complete (Normally
<> 144:ef7eb2e8f9f7 260 * synchronization will not be in progress.) However for this reason, when
<> 144:ef7eb2e8f9f7 261 * using freeze mode, modifications of registers requiring LF synchronization
<> 144:ef7eb2e8f9f7 262 * should be done within one freeze enable/disable block to avoid unecessary
<> 144:ef7eb2e8f9f7 263 * stalling.
<> 144:ef7eb2e8f9f7 264 *
<> 144:ef7eb2e8f9f7 265 * @param[in] letimer
<> 144:ef7eb2e8f9f7 266 * Pointer to LETIMER peripheral register block.
<> 144:ef7eb2e8f9f7 267 *
<> 144:ef7eb2e8f9f7 268 * @param[in] enable
<> 144:ef7eb2e8f9f7 269 * @li true - enable freeze, modified registers are not propagated to the
<> 144:ef7eb2e8f9f7 270 * LF domain
<> 144:ef7eb2e8f9f7 271 * @li false - disables freeze, modified registers are propagated to LF
<> 144:ef7eb2e8f9f7 272 * domain
<> 144:ef7eb2e8f9f7 273 ******************************************************************************/
<> 144:ef7eb2e8f9f7 274 void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable)
<> 144:ef7eb2e8f9f7 275 {
<> 144:ef7eb2e8f9f7 276 if (enable)
<> 144:ef7eb2e8f9f7 277 {
<> 144:ef7eb2e8f9f7 278 /*
<> 144:ef7eb2e8f9f7 279 * Wait for any ongoing LF synchronization to complete. This is just to
<> 144:ef7eb2e8f9f7 280 * protect against the rare case when a user
<> 144:ef7eb2e8f9f7 281 * - modifies a register requiring LF sync
<> 144:ef7eb2e8f9f7 282 * - then enables freeze before LF sync completed
<> 144:ef7eb2e8f9f7 283 * - then modifies the same register again
<> 144:ef7eb2e8f9f7 284 * since modifying a register while it is in sync progress should be
<> 144:ef7eb2e8f9f7 285 * avoided.
<> 144:ef7eb2e8f9f7 286 */
<> 144:ef7eb2e8f9f7 287 while (letimer->SYNCBUSY)
<> 144:ef7eb2e8f9f7 288 ;
<> 144:ef7eb2e8f9f7 289
<> 144:ef7eb2e8f9f7 290 letimer->FREEZE = LETIMER_FREEZE_REGFREEZE;
<> 144:ef7eb2e8f9f7 291 }
<> 144:ef7eb2e8f9f7 292 else
<> 144:ef7eb2e8f9f7 293 {
<> 144:ef7eb2e8f9f7 294 letimer->FREEZE = 0;
<> 144:ef7eb2e8f9f7 295 }
<> 144:ef7eb2e8f9f7 296 }
<> 144:ef7eb2e8f9f7 297 #endif /* defined(_LETIMER_FREEZE_MASK) */
<> 144:ef7eb2e8f9f7 298
<> 144:ef7eb2e8f9f7 299 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 300 * @brief
<> 144:ef7eb2e8f9f7 301 * Initialize LETIMER.
<> 144:ef7eb2e8f9f7 302 *
<> 144:ef7eb2e8f9f7 303 * @details
<> 144:ef7eb2e8f9f7 304 * Note that the compare/repeat values must be set separately with
<> 144:ef7eb2e8f9f7 305 * LETIMER_CompareSet() and LETIMER_RepeatSet(). That should probably be done
<> 144:ef7eb2e8f9f7 306 * prior to the use of this function if configuring the LETIMER to start when
<> 144:ef7eb2e8f9f7 307 * initialization is completed.
<> 144:ef7eb2e8f9f7 308 *
<> 144:ef7eb2e8f9f7 309 * @note
<> 144:ef7eb2e8f9f7 310 * The initialization of the LETIMER modifies the LETIMER CTRL/CMD registers
<> 144:ef7eb2e8f9f7 311 * which require synchronization into the low frequency domain. If any of those
<> 144:ef7eb2e8f9f7 312 * registers are modified before a previous update to the same register has
<> 144:ef7eb2e8f9f7 313 * completed, this function will stall until the previous synchronization has
<> 144:ef7eb2e8f9f7 314 * completed. This only applies to the Gecko Family, see comment in the
<> 144:ef7eb2e8f9f7 315 * LETIMER_Sync() internal function call.
<> 144:ef7eb2e8f9f7 316 *
<> 144:ef7eb2e8f9f7 317 * @param[in] letimer
<> 144:ef7eb2e8f9f7 318 * Pointer to LETIMER peripheral register block.
<> 144:ef7eb2e8f9f7 319 *
<> 144:ef7eb2e8f9f7 320 * @param[in] init
<> 144:ef7eb2e8f9f7 321 * Pointer to LETIMER initialization structure.
<> 144:ef7eb2e8f9f7 322 ******************************************************************************/
<> 144:ef7eb2e8f9f7 323 void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init)
<> 144:ef7eb2e8f9f7 324 {
<> 144:ef7eb2e8f9f7 325 uint32_t tmp = 0;
<> 144:ef7eb2e8f9f7 326
<> 144:ef7eb2e8f9f7 327 EFM_ASSERT(LETIMER_REF_VALID(letimer));
<> 144:ef7eb2e8f9f7 328
<> 144:ef7eb2e8f9f7 329 /* Stop timer if specified to be disabled and running */
<> 144:ef7eb2e8f9f7 330 if (!(init->enable) && (letimer->STATUS & LETIMER_STATUS_RUNNING))
<> 144:ef7eb2e8f9f7 331 {
<> 144:ef7eb2e8f9f7 332 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 333 /* LF register about to be modified require sync. busy check */
<> 144:ef7eb2e8f9f7 334 regSync(letimer, LETIMER_SYNCBUSY_CMD);
<> 144:ef7eb2e8f9f7 335 #endif
<> 144:ef7eb2e8f9f7 336 letimer->CMD = LETIMER_CMD_STOP;
<> 144:ef7eb2e8f9f7 337 }
<> 144:ef7eb2e8f9f7 338
<> 144:ef7eb2e8f9f7 339 /* Configure DEBUGRUN flag, sets whether or not counter should be
<> 144:ef7eb2e8f9f7 340 * updated when debugger is active */
<> 144:ef7eb2e8f9f7 341 if (init->debugRun)
<> 144:ef7eb2e8f9f7 342 {
<> 144:ef7eb2e8f9f7 343 tmp |= LETIMER_CTRL_DEBUGRUN;
<> 144:ef7eb2e8f9f7 344 }
<> 144:ef7eb2e8f9f7 345
<> 144:ef7eb2e8f9f7 346 #if defined(LETIMER_CTRL_RTCC0TEN)
<> 144:ef7eb2e8f9f7 347 if (init->rtcComp0Enable)
<> 144:ef7eb2e8f9f7 348 {
<> 144:ef7eb2e8f9f7 349 tmp |= LETIMER_CTRL_RTCC0TEN;
<> 144:ef7eb2e8f9f7 350 }
<> 144:ef7eb2e8f9f7 351
<> 144:ef7eb2e8f9f7 352 if (init->rtcComp1Enable)
<> 144:ef7eb2e8f9f7 353 {
<> 144:ef7eb2e8f9f7 354 tmp |= LETIMER_CTRL_RTCC1TEN;
<> 144:ef7eb2e8f9f7 355 }
<> 144:ef7eb2e8f9f7 356 #endif
<> 144:ef7eb2e8f9f7 357
<> 144:ef7eb2e8f9f7 358 if (init->comp0Top)
<> 144:ef7eb2e8f9f7 359 {
<> 144:ef7eb2e8f9f7 360 tmp |= LETIMER_CTRL_COMP0TOP;
<> 144:ef7eb2e8f9f7 361 }
<> 144:ef7eb2e8f9f7 362
<> 144:ef7eb2e8f9f7 363 if (init->bufTop)
<> 144:ef7eb2e8f9f7 364 {
<> 144:ef7eb2e8f9f7 365 tmp |= LETIMER_CTRL_BUFTOP;
<> 144:ef7eb2e8f9f7 366 }
<> 144:ef7eb2e8f9f7 367
<> 144:ef7eb2e8f9f7 368 if (init->out0Pol)
<> 144:ef7eb2e8f9f7 369 {
<> 144:ef7eb2e8f9f7 370 tmp |= LETIMER_CTRL_OPOL0;
<> 144:ef7eb2e8f9f7 371 }
<> 144:ef7eb2e8f9f7 372
<> 144:ef7eb2e8f9f7 373 if (init->out1Pol)
<> 144:ef7eb2e8f9f7 374 {
<> 144:ef7eb2e8f9f7 375 tmp |= LETIMER_CTRL_OPOL1;
<> 144:ef7eb2e8f9f7 376 }
<> 144:ef7eb2e8f9f7 377
<> 144:ef7eb2e8f9f7 378 tmp |= init->ufoa0 << _LETIMER_CTRL_UFOA0_SHIFT;
<> 144:ef7eb2e8f9f7 379 tmp |= init->ufoa1 << _LETIMER_CTRL_UFOA1_SHIFT;
<> 144:ef7eb2e8f9f7 380 tmp |= init->repMode << _LETIMER_CTRL_REPMODE_SHIFT;
<> 144:ef7eb2e8f9f7 381
<> 144:ef7eb2e8f9f7 382 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 383 /* LF register about to be modified require sync. busy check */
<> 144:ef7eb2e8f9f7 384 regSync(letimer, LETIMER_SYNCBUSY_CTRL);
<> 144:ef7eb2e8f9f7 385 #endif
<> 144:ef7eb2e8f9f7 386 letimer->CTRL = tmp;
<> 144:ef7eb2e8f9f7 387
<> 144:ef7eb2e8f9f7 388 /* Start timer if specified to be enabled and not already running */
<> 144:ef7eb2e8f9f7 389 if (init->enable && !(letimer->STATUS & LETIMER_STATUS_RUNNING))
<> 144:ef7eb2e8f9f7 390 {
<> 144:ef7eb2e8f9f7 391 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 392 /* LF register about to be modified require sync. busy check */
<> 144:ef7eb2e8f9f7 393 regSync(letimer, LETIMER_SYNCBUSY_CMD);
<> 144:ef7eb2e8f9f7 394 #endif
<> 144:ef7eb2e8f9f7 395 letimer->CMD = LETIMER_CMD_START;
<> 144:ef7eb2e8f9f7 396 }
<> 144:ef7eb2e8f9f7 397 }
<> 144:ef7eb2e8f9f7 398
<> 144:ef7eb2e8f9f7 399
<> 144:ef7eb2e8f9f7 400 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 401 * @brief
<> 144:ef7eb2e8f9f7 402 * Get LETIMER repeat register value.
<> 144:ef7eb2e8f9f7 403 *
<> 144:ef7eb2e8f9f7 404 * @param[in] letimer
<> 144:ef7eb2e8f9f7 405 * Pointer to LETIMER peripheral register block
<> 144:ef7eb2e8f9f7 406 *
<> 144:ef7eb2e8f9f7 407 * @param[in] rep
<> 144:ef7eb2e8f9f7 408 * Repeat register to get, either 0 or 1
<> 144:ef7eb2e8f9f7 409 *
<> 144:ef7eb2e8f9f7 410 * @return
<> 144:ef7eb2e8f9f7 411 * Repeat register value, 0 if invalid register selected.
<> 144:ef7eb2e8f9f7 412 ******************************************************************************/
<> 144:ef7eb2e8f9f7 413 uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep)
<> 144:ef7eb2e8f9f7 414 {
<> 144:ef7eb2e8f9f7 415 uint32_t ret;
<> 144:ef7eb2e8f9f7 416
<> 144:ef7eb2e8f9f7 417 EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_REP_REG_VALID(rep));
<> 144:ef7eb2e8f9f7 418
<> 144:ef7eb2e8f9f7 419 /* Initialize selected compare value */
<> 144:ef7eb2e8f9f7 420 switch (rep)
<> 144:ef7eb2e8f9f7 421 {
<> 144:ef7eb2e8f9f7 422 case 0:
<> 144:ef7eb2e8f9f7 423 ret = letimer->REP0;
<> 144:ef7eb2e8f9f7 424 break;
<> 144:ef7eb2e8f9f7 425
<> 144:ef7eb2e8f9f7 426 case 1:
<> 144:ef7eb2e8f9f7 427 ret = letimer->REP1;
<> 144:ef7eb2e8f9f7 428 break;
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 default:
<> 144:ef7eb2e8f9f7 431 /* Unknown compare register selected */
<> 144:ef7eb2e8f9f7 432 ret = 0;
<> 144:ef7eb2e8f9f7 433 break;
<> 144:ef7eb2e8f9f7 434 }
<> 144:ef7eb2e8f9f7 435
<> 144:ef7eb2e8f9f7 436 return(ret);
<> 144:ef7eb2e8f9f7 437 }
<> 144:ef7eb2e8f9f7 438
<> 144:ef7eb2e8f9f7 439
<> 144:ef7eb2e8f9f7 440 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 441 * @brief
<> 144:ef7eb2e8f9f7 442 * Set LETIMER repeat counter register value.
<> 144:ef7eb2e8f9f7 443 *
<> 144:ef7eb2e8f9f7 444 * @note
<> 144:ef7eb2e8f9f7 445 * The setting of a repeat counter register requires synchronization into the
<> 144:ef7eb2e8f9f7 446 * low frequency domain. If the same register is modified before a previous
<> 144:ef7eb2e8f9f7 447 * update has completed, this function will stall until the previous
<> 144:ef7eb2e8f9f7 448 * synchronization has completed. This only applies to the Gecko Family, see
<> 144:ef7eb2e8f9f7 449 * comment in the LETIMER_Sync() internal function call.
<> 144:ef7eb2e8f9f7 450 *
<> 144:ef7eb2e8f9f7 451 * @param[in] letimer
<> 144:ef7eb2e8f9f7 452 * Pointer to LETIMER peripheral register block
<> 144:ef7eb2e8f9f7 453 *
<> 144:ef7eb2e8f9f7 454 * @param[in] rep
<> 144:ef7eb2e8f9f7 455 * Repeat counter register to set, either 0 or 1
<> 144:ef7eb2e8f9f7 456 *
<> 144:ef7eb2e8f9f7 457 * @param[in] value
<> 144:ef7eb2e8f9f7 458 * Initialization value (<= 0x0000ffff)
<> 144:ef7eb2e8f9f7 459 ******************************************************************************/
<> 144:ef7eb2e8f9f7 460 void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
<> 144:ef7eb2e8f9f7 461 unsigned int rep,
<> 144:ef7eb2e8f9f7 462 uint32_t value)
<> 144:ef7eb2e8f9f7 463 {
<> 144:ef7eb2e8f9f7 464 volatile uint32_t *repReg;
<> 144:ef7eb2e8f9f7 465 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 466 uint32_t syncbusy;
<> 144:ef7eb2e8f9f7 467 #endif
<> 144:ef7eb2e8f9f7 468 EFM_ASSERT(LETIMER_REF_VALID(letimer)
<> 144:ef7eb2e8f9f7 469 && LETIMER_REP_REG_VALID(rep)
<> 144:ef7eb2e8f9f7 470 && ((value & ~(_LETIMER_REP0_REP0_MASK
<> 144:ef7eb2e8f9f7 471 >> _LETIMER_REP0_REP0_SHIFT))
<> 144:ef7eb2e8f9f7 472 == 0));
<> 144:ef7eb2e8f9f7 473
<> 144:ef7eb2e8f9f7 474 /* Initialize selected compare value */
<> 144:ef7eb2e8f9f7 475 switch (rep)
<> 144:ef7eb2e8f9f7 476 {
<> 144:ef7eb2e8f9f7 477 case 0:
<> 144:ef7eb2e8f9f7 478 repReg = &(letimer->REP0);
<> 144:ef7eb2e8f9f7 479 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 480 syncbusy = LETIMER_SYNCBUSY_REP0;
<> 144:ef7eb2e8f9f7 481 #endif
<> 144:ef7eb2e8f9f7 482 break;
<> 144:ef7eb2e8f9f7 483
<> 144:ef7eb2e8f9f7 484 case 1:
<> 144:ef7eb2e8f9f7 485 repReg = &(letimer->REP1);
<> 144:ef7eb2e8f9f7 486 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 487 syncbusy = LETIMER_SYNCBUSY_REP1;
<> 144:ef7eb2e8f9f7 488 #endif
<> 144:ef7eb2e8f9f7 489 break;
<> 144:ef7eb2e8f9f7 490
<> 144:ef7eb2e8f9f7 491 default:
<> 144:ef7eb2e8f9f7 492 /* Unknown compare register selected, abort */
<> 144:ef7eb2e8f9f7 493 return;
<> 144:ef7eb2e8f9f7 494 }
<> 144:ef7eb2e8f9f7 495
<> 144:ef7eb2e8f9f7 496 #if defined(_EFM32_GECKO_FAMILY)
<> 144:ef7eb2e8f9f7 497 /* LF register about to be modified require sync. busy check */
<> 144:ef7eb2e8f9f7 498 regSync(letimer, syncbusy);
<> 144:ef7eb2e8f9f7 499 #endif
<> 144:ef7eb2e8f9f7 500
<> 144:ef7eb2e8f9f7 501 *repReg = value;
<> 144:ef7eb2e8f9f7 502 }
<> 144:ef7eb2e8f9f7 503
<> 144:ef7eb2e8f9f7 504
<> 144:ef7eb2e8f9f7 505 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 506 * @brief
<> 144:ef7eb2e8f9f7 507 * Reset LETIMER to same state as after a HW reset.
<> 144:ef7eb2e8f9f7 508 *
<> 144:ef7eb2e8f9f7 509 * @note
<> 144:ef7eb2e8f9f7 510 * The ROUTE register is NOT reset by this function, in order to allow for
<> 144:ef7eb2e8f9f7 511 * centralized setup of this feature.
<> 144:ef7eb2e8f9f7 512 *
<> 144:ef7eb2e8f9f7 513 * @param[in] letimer
<> 144:ef7eb2e8f9f7 514 * Pointer to LETIMER peripheral register block.
<> 144:ef7eb2e8f9f7 515 ******************************************************************************/
<> 144:ef7eb2e8f9f7 516 void LETIMER_Reset(LETIMER_TypeDef *letimer)
<> 144:ef7eb2e8f9f7 517 {
<> 144:ef7eb2e8f9f7 518 #if defined(_LETIMER_FREEZE_MASK)
<> 144:ef7eb2e8f9f7 519 /* Freeze registers to avoid stalling for LF synchronization */
<> 144:ef7eb2e8f9f7 520 LETIMER_FreezeEnable(letimer, true);
<> 144:ef7eb2e8f9f7 521 #endif
<> 144:ef7eb2e8f9f7 522
<> 144:ef7eb2e8f9f7 523 /* Make sure disabled first, before resetting other registers */
<> 144:ef7eb2e8f9f7 524 letimer->CMD = LETIMER_CMD_STOP | LETIMER_CMD_CLEAR
<> 144:ef7eb2e8f9f7 525 | LETIMER_CMD_CTO0 | LETIMER_CMD_CTO1;
<> 144:ef7eb2e8f9f7 526 letimer->CTRL = _LETIMER_CTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 527 letimer->COMP0 = _LETIMER_COMP0_RESETVALUE;
<> 144:ef7eb2e8f9f7 528 letimer->COMP1 = _LETIMER_COMP1_RESETVALUE;
<> 144:ef7eb2e8f9f7 529 letimer->REP0 = _LETIMER_REP0_RESETVALUE;
<> 144:ef7eb2e8f9f7 530 letimer->REP1 = _LETIMER_REP1_RESETVALUE;
<> 144:ef7eb2e8f9f7 531 letimer->IEN = _LETIMER_IEN_RESETVALUE;
<> 144:ef7eb2e8f9f7 532 letimer->IFC = _LETIMER_IFC_MASK;
<> 144:ef7eb2e8f9f7 533 /* Do not reset route register, setting should be done independently */
<> 144:ef7eb2e8f9f7 534
<> 144:ef7eb2e8f9f7 535 #if defined(_LETIMER_FREEZE_MASK)
<> 144:ef7eb2e8f9f7 536 /* Unfreeze registers, pass new settings on to LETIMER */
<> 144:ef7eb2e8f9f7 537 LETIMER_FreezeEnable(letimer, false);
<> 144:ef7eb2e8f9f7 538 #endif
<> 144:ef7eb2e8f9f7 539 }
<> 144:ef7eb2e8f9f7 540
<> 144:ef7eb2e8f9f7 541
<> 144:ef7eb2e8f9f7 542 /** @} (end addtogroup LETIMER) */
<> 144:ef7eb2e8f9f7 543 /** @} (end addtogroup EM_Library) */
<> 144:ef7eb2e8f9f7 544 #endif /* defined(LETIMER_COUNT) && (LETIMER_COUNT > 0) */