em_letimer.c
Go to the documentation of this file.00001
00034 #include "em_letimer.h"
00035 #if defined(LETIMER_COUNT) && (LETIMER_COUNT > 0)
00036 #include "em_cmu.h"
00037 #include "em_assert.h"
00038
00039
00044
00050
00051
00052
00053
00057 #define LETIMER_COMP_REG_VALID(reg) (((reg) <= 1))
00058
00060 #define LETIMER_REF_VALID(ref) ((ref) == LETIMER0)
00061
00063 #define LETIMER_REP_REG_VALID(reg) (((reg) <= 1))
00064
00068
00069
00070
00071
00074 #if defined(_EFM32_GECKO_FAMILY)
00075
00091 __STATIC_INLINE void LETIMER_Sync(LETIMER_TypeDef *letimer, uint32_t mask)
00092 {
00093
00094
00095 if (letimer->FREEZE & LETIMER_FREEZE_REGFREEZE)
00096 return;
00097
00098
00099
00100 while (letimer->SYNCBUSY & mask)
00101 ;
00102 }
00103 #endif
00104
00107
00108
00109
00110
00111
00124 uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp)
00125 {
00126 uint32_t ret;
00127
00128 EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_COMP_REG_VALID(comp));
00129
00130
00131 switch (comp)
00132 {
00133 case 0:
00134 ret = letimer->COMP0;
00135 break;
00136
00137 case 1:
00138 ret = letimer->COMP1;
00139 break;
00140
00141 default:
00142
00143 ret = 0;
00144 break;
00145 }
00146
00147 return(ret);
00148 }
00149
00150
00151
00171 void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
00172 unsigned int comp,
00173 uint32_t value)
00174 {
00175 volatile uint32_t *compReg;
00176
00177 EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
00178 LETIMER_COMP_REG_VALID(comp) &&
00179 ((value & ~(_LETIMER_COMP0_COMP0_MASK >> _LETIMER_COMP0_COMP0_SHIFT)) == 0));
00180
00181
00182 switch (comp)
00183 {
00184 case 0:
00185 compReg = &(letimer->COMP0);
00186 break;
00187
00188 case 1:
00189 compReg = &(letimer->COMP1);
00190 break;
00191
00192 default:
00193
00194 return;
00195 }
00196
00197 #if defined(_EFM32_GECKO_FAMILY)
00198
00199 LETIMER_Sync(letimer, comp ? LETIMER_SYNCBUSY_COMP1 : LETIMER_SYNCBUSY_COMP0);
00200 #endif
00201
00202 *compReg = value;
00203 }
00204
00205
00206
00224 void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable)
00225 {
00226 EFM_ASSERT(LETIMER_REF_VALID(letimer));
00227
00228 #if defined(_EFM32_GECKO_FAMILY)
00229
00230 LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
00231 #endif
00232
00233 if (enable)
00234 {
00235 letimer->CMD = LETIMER_CMD_START;
00236 }
00237 else
00238 {
00239 letimer->CMD = LETIMER_CMD_STOP;
00240 }
00241 }
00242
00243
00244
00271 void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable)
00272 {
00273 if (enable)
00274 {
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 while (letimer->SYNCBUSY)
00285 ;
00286
00287 letimer->FREEZE = LETIMER_FREEZE_REGFREEZE;
00288 }
00289 else
00290 {
00291 letimer->FREEZE = 0;
00292 }
00293 }
00294
00295
00296
00320 void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init)
00321 {
00322 uint32_t tmp = 0;
00323
00324 EFM_ASSERT(LETIMER_REF_VALID(letimer));
00325
00326
00327 if (!(init->enable) && (letimer->STATUS & LETIMER_STATUS_RUNNING))
00328 {
00329 #if defined(_EFM32_GECKO_FAMILY)
00330
00331 LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
00332 #endif
00333 letimer->CMD = LETIMER_CMD_STOP;
00334 }
00335
00336
00337
00338 if (init->debugRun)
00339 {
00340 tmp |= LETIMER_CTRL_DEBUGRUN;
00341 }
00342
00343 if (init->rtcComp0Enable)
00344 {
00345 tmp |= LETIMER_CTRL_RTCC0TEN;
00346 }
00347
00348 if (init->rtcComp1Enable)
00349 {
00350 tmp |= LETIMER_CTRL_RTCC1TEN;
00351 }
00352
00353 if (init->comp0Top)
00354 {
00355 tmp |= LETIMER_CTRL_COMP0TOP;
00356 }
00357
00358 if (init->bufTop)
00359 {
00360 tmp |= LETIMER_CTRL_BUFTOP;
00361 }
00362
00363 if (init->out0Pol)
00364 {
00365 tmp |= LETIMER_CTRL_OPOL0;
00366 }
00367
00368 if (init->out1Pol)
00369 {
00370 tmp |= LETIMER_CTRL_OPOL1;
00371 }
00372
00373 tmp |= init->ufoa0 << _LETIMER_CTRL_UFOA0_SHIFT;
00374 tmp |= init->ufoa1 << _LETIMER_CTRL_UFOA1_SHIFT;
00375 tmp |= init->repMode << _LETIMER_CTRL_REPMODE_SHIFT;
00376
00377 #if defined(_EFM32_GECKO_FAMILY)
00378
00379 LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CTRL);
00380 #endif
00381 letimer->CTRL = tmp;
00382
00383
00384 if (init->enable && !(letimer->STATUS & LETIMER_STATUS_RUNNING))
00385 {
00386 #if defined(_EFM32_GECKO_FAMILY)
00387
00388 LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
00389 #endif
00390 letimer->CMD = LETIMER_CMD_START;
00391 }
00392 }
00393
00394
00395
00408 uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep)
00409 {
00410 uint32_t ret;
00411
00412 EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_REP_REG_VALID(rep));
00413
00414
00415 switch (rep)
00416 {
00417 case 0:
00418 ret = letimer->REP0;
00419 break;
00420
00421 case 1:
00422 ret = letimer->REP1;
00423 break;
00424
00425 default:
00426
00427 ret = 0;
00428 break;
00429 }
00430
00431 return(ret);
00432 }
00433
00434
00435
00455 void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
00456 unsigned int rep,
00457 uint32_t value)
00458 {
00459 volatile uint32_t *repReg;
00460 #if defined(_EFM32_GECKO_FAMILY)
00461 uint32_t syncbusy;
00462 #endif
00463 EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
00464 LETIMER_REP_REG_VALID(rep) &&
00465 ((value & ~(_LETIMER_REP0_REP0_MASK >> _LETIMER_REP0_REP0_SHIFT)) == 0));
00466
00467
00468 switch (rep)
00469 {
00470 case 0:
00471 repReg = &(letimer->REP0);
00472 #if defined(_EFM32_GECKO_FAMILY)
00473 syncbusy = LETIMER_SYNCBUSY_REP0;
00474 #endif
00475 break;
00476
00477 case 1:
00478 repReg = &(letimer->REP1);
00479 #if defined(_EFM32_GECKO_FAMILY)
00480 syncbusy = LETIMER_SYNCBUSY_REP1;
00481 #endif
00482 break;
00483
00484 default:
00485
00486 return;
00487 }
00488
00489 #if defined(_EFM32_GECKO_FAMILY)
00490
00491 LETIMER_Sync(letimer, syncbusy);
00492 #endif
00493
00494 *repReg = value;
00495 }
00496
00497
00498
00509 void LETIMER_Reset(LETIMER_TypeDef *letimer)
00510 {
00511
00512 LETIMER_FreezeEnable(letimer, true);
00513
00514
00515 letimer->CMD = LETIMER_CMD_STOP | LETIMER_CMD_CLEAR |
00516 LETIMER_CMD_CTO0 | LETIMER_CMD_CTO1;
00517 letimer->CTRL = _LETIMER_CTRL_RESETVALUE;
00518 letimer->COMP0 = _LETIMER_COMP0_RESETVALUE;
00519 letimer->COMP1 = _LETIMER_COMP1_RESETVALUE;
00520 letimer->REP0 = _LETIMER_REP0_RESETVALUE;
00521 letimer->REP1 = _LETIMER_REP1_RESETVALUE;
00522 letimer->IEN = _LETIMER_IEN_RESETVALUE;
00523 letimer->IFC = _LETIMER_IFC_MASK;
00524
00525
00526
00527 LETIMER_FreezeEnable(letimer, false);
00528 }
00529
00530
00533 #endif