em_leuart.c
Go to the documentation of this file.00001
00035 #include "em_leuart.h"
00036 #if defined(LEUART_COUNT) && (LEUART_COUNT > 0)
00037
00038 #include "em_cmu.h"
00039 #include "em_assert.h"
00040
00041
00046
00053
00054
00055
00056
00062 #if (LEUART_COUNT == 1)
00063 #define LEUART_REF_VALID(ref) ((ref) == LEUART0)
00064 #elif (LEUART_COUNT == 2)
00065 #define LEUART_REF_VALID(ref) (((ref) == LEUART0) || ((ref) == LEUART1))
00066 #else
00067 #error Undefined number of low energy UARTs (LEUART).
00068 #endif
00069
00072
00073
00074
00075
00078
00089 __STATIC_INLINE void LEUART_Sync(LEUART_TypeDef *leuart, uint32_t mask)
00090 {
00091
00092
00093 if (leuart->FREEZE & LEUART_FREEZE_REGFREEZE)
00094 {
00095 return;
00096 }
00097
00098
00099
00100 while (leuart->SYNCBUSY & mask)
00101 ;
00102 }
00103
00106
00107
00108
00109
00110
00130 uint32_t LEUART_BaudrateCalc(uint32_t refFreq, uint32_t clkdiv)
00131 {
00132 uint32_t divisor;
00133 uint32_t remainder;
00134 uint32_t quotient;
00135 uint32_t br;
00136
00137
00138 clkdiv &= _LEUART_CLKDIV_MASK;
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 divisor = 256 + clkdiv;
00178
00179 quotient = refFreq / divisor;
00180 remainder = refFreq % divisor;
00181
00182
00183 br = 256 * quotient;
00184
00185
00186
00187
00188
00189 br += (256 * remainder) / divisor;
00190
00191 return br;
00192 }
00193
00194
00195
00209 uint32_t LEUART_BaudrateGet(LEUART_TypeDef *leuart)
00210 {
00211 uint32_t freq;
00212 CMU_Clock_TypeDef clock;
00213
00214
00215 if (leuart == LEUART0)
00216 {
00217 clock = cmuClock_LEUART0;
00218 }
00219 #if (LEUART_COUNT > 1)
00220 else if (leuart == LEUART1)
00221 {
00222 clock = cmuClock_LEUART1;
00223 }
00224 #endif
00225 else
00226 {
00227 EFM_ASSERT(0);
00228 return 0;
00229 }
00230
00231 freq = CMU_ClockFreqGet(clock);
00232
00233 return LEUART_BaudrateCalc(freq, leuart->CLKDIV);
00234 }
00235
00236
00237
00257 void LEUART_BaudrateSet(LEUART_TypeDef *leuart,
00258 uint32_t refFreq,
00259 uint32_t baudrate)
00260 {
00261 uint32_t clkdiv;
00262 CMU_Clock_TypeDef clock;
00263
00264
00265 EFM_ASSERT(baudrate);
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 if (!refFreq)
00296 {
00297 if (leuart == LEUART0)
00298 {
00299 clock = cmuClock_LEUART0;
00300 }
00301 #if (LEUART_COUNT > 1)
00302 else if (leuart == LEUART1)
00303 {
00304 clock = cmuClock_LEUART1;
00305 }
00306 #endif
00307 else
00308 {
00309 EFM_ASSERT(0);
00310 return;
00311 }
00312
00313 refFreq = CMU_ClockFreqGet(clock);
00314 }
00315
00316
00317 clkdiv = (32 * refFreq) / baudrate;
00318 clkdiv -= 32;
00319 clkdiv *= 8;
00320
00321
00322 EFM_ASSERT(clkdiv <= _LEUART_CLKDIV_MASK);
00323
00324
00325 clkdiv &= _LEUART_CLKDIV_MASK;
00326
00327
00328 LEUART_Sync(leuart, LEUART_SYNCBUSY_CLKDIV);
00329
00330 leuart->CLKDIV = clkdiv;
00331 }
00332
00333
00334
00354 void LEUART_Enable(LEUART_TypeDef *leuart, LEUART_Enable_TypeDef enable)
00355 {
00356 uint32_t tmp;
00357
00358
00359 EFM_ASSERT(LEUART_REF_VALID(leuart));
00360
00361
00362 tmp = ~((uint32_t)(enable));
00363 tmp &= (_LEUART_CMD_RXEN_MASK | _LEUART_CMD_TXEN_MASK);
00364 tmp <<= 1;
00365
00366 tmp |= (uint32_t)(enable);
00367
00368
00369 LEUART_Sync(leuart, LEUART_SYNCBUSY_CMD);
00370
00371 leuart->CMD = tmp;
00372 }
00373
00374
00375
00402 void LEUART_FreezeEnable(LEUART_TypeDef *leuart, bool enable)
00403 {
00404 if (enable)
00405 {
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 while (leuart->SYNCBUSY)
00416 ;
00417
00418 leuart->FREEZE = LEUART_FREEZE_REGFREEZE;
00419 }
00420 else
00421 {
00422 leuart->FREEZE = 0;
00423 }
00424 }
00425
00426
00427
00458 void LEUART_Init(LEUART_TypeDef *leuart, LEUART_Init_TypeDef const *init)
00459 {
00460
00461 EFM_ASSERT(LEUART_REF_VALID(leuart));
00462
00463
00464 LEUART_Sync(leuart, LEUART_SYNCBUSY_CMD);
00465
00466
00467 leuart->CMD = LEUART_CMD_RXDIS | LEUART_CMD_TXDIS;
00468
00469
00470 LEUART_FreezeEnable(leuart, true);
00471
00472
00473 leuart->CTRL = (leuart->CTRL & ~(_LEUART_CTRL_PARITY_MASK |
00474 _LEUART_CTRL_STOPBITS_MASK)) |
00475 (uint32_t)(init->databits) |
00476 (uint32_t)(init->parity) |
00477 (uint32_t)(init->stopbits);
00478
00479
00480 LEUART_BaudrateSet(leuart, init->refFreq, init->baudrate);
00481
00482
00483 leuart->CMD = (uint32_t)(init->enable);
00484
00485
00486 LEUART_FreezeEnable(leuart, false);
00487 }
00488
00489
00490
00497 void LEUART_Reset(LEUART_TypeDef *leuart)
00498 {
00499
00500 EFM_ASSERT(LEUART_REF_VALID(leuart));
00501
00502
00503 LEUART_FreezeEnable(leuart, true);
00504
00505
00506 leuart->CMD = LEUART_CMD_RXDIS | LEUART_CMD_TXDIS | LEUART_CMD_RXBLOCKDIS |
00507 LEUART_CMD_CLEARTX | LEUART_CMD_CLEARRX;
00508 leuart->CTRL = _LEUART_CTRL_RESETVALUE;
00509 leuart->CLKDIV = _LEUART_CLKDIV_RESETVALUE;
00510 leuart->STARTFRAME = _LEUART_STARTFRAME_RESETVALUE;
00511 leuart->SIGFRAME = _LEUART_SIGFRAME_RESETVALUE;
00512 leuart->IEN = _LEUART_IEN_RESETVALUE;
00513 leuart->IFC = _LEUART_IFC_MASK;
00514 leuart->PULSECTRL = _LEUART_PULSECTRL_RESETVALUE;
00515 leuart->ROUTE = _LEUART_ROUTE_RESETVALUE;
00516
00517
00518 LEUART_FreezeEnable(leuart, false);
00519 }
00520
00521
00522
00543 uint8_t LEUART_Rx(LEUART_TypeDef *leuart)
00544 {
00545 while (!(leuart->STATUS & LEUART_STATUS_RXDATAV))
00546 ;
00547
00548 return (uint8_t)(leuart->RXDATA);
00549 }
00550
00551
00552
00569 uint16_t LEUART_RxExt(LEUART_TypeDef *leuart)
00570 {
00571 while (!(leuart->STATUS & LEUART_STATUS_RXDATAV))
00572 ;
00573
00574 return (uint16_t)(leuart->RXDATAX);
00575 }
00576
00577
00578
00601 void LEUART_Tx(LEUART_TypeDef *leuart, uint8_t data)
00602 {
00603
00604 while (!(leuart->STATUS & LEUART_STATUS_TXBL))
00605 ;
00606
00607
00608 LEUART_Sync(leuart, LEUART_SYNCBUSY_TXDATA);
00609
00610 leuart->TXDATA = (uint32_t)data;
00611 }
00612
00613
00614
00633 void LEUART_TxExt(LEUART_TypeDef *leuart, uint16_t data)
00634 {
00635
00636 while (!(leuart->STATUS & LEUART_STATUS_TXBL))
00637 ;
00638
00639
00640 LEUART_Sync(leuart, LEUART_SYNCBUSY_TXDATAX);
00641
00642 leuart->TXDATAX = (uint32_t)data;
00643 }
00644
00645
00657 void LEUART_TxDmaInEM2Enable(LEUART_TypeDef *leuart, bool enable)
00658 {
00659
00660 LEUART_Sync(leuart, LEUART_SYNCBUSY_CTRL);
00661
00662 if (enable)
00663 {
00664 leuart->CTRL |= LEUART_CTRL_TXDMAWU;
00665 }
00666 else
00667 {
00668 leuart->CTRL &= ~LEUART_CTRL_TXDMAWU;
00669 }
00670 }
00671
00672
00684 void LEUART_RxDmaInEM2Enable(LEUART_TypeDef *leuart, bool enable)
00685 {
00686
00687 LEUART_Sync(leuart, LEUART_SYNCBUSY_CTRL);
00688
00689 if (enable)
00690 {
00691 leuart->CTRL |= LEUART_CTRL_RXDMAWU;
00692 }
00693 else
00694 {
00695 leuart->CTRL &= ~LEUART_CTRL_RXDMAWU;
00696 }
00697 }
00698
00699
00702 #endif