mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
179:b0033dcd6934
mbed library release version 165

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