added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Fri Jan 15 07:45:16 2016 +0000
Revision:
50:a417edff4437
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Synchronized with git revision 6010f32619bfcbb01cc73747d4ff9040863482d9

Full URL: https://github.com/mbedmicro/mbed/commit/6010f32619bfcbb01cc73747d4ff9040863482d9/

Remove doubling of buffer size in realiseEndpoint()

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