mbed library sources. Supersedes mbed-src.

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

Committer:
<>
Date:
Tue Nov 08 17:45:16 2016 +0000
Revision:
150:02e0a0aed4ec
Parent:
149:156823d33999
Child:
161:2cc1468da177
This updates the lib to the mbed lib v129

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