added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
50:a417edff4437
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

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