em_usart.c
Go to the documentation of this file.00001
00035 #include "em_usart.h"
00036 #if defined(USART_COUNT) && (USART_COUNT > 0)
00037
00038 #include "em_cmu.h"
00039 #include "em_assert.h"
00040
00041
00046
00053
00054
00055
00056
00061 #if (USART_COUNT == 1) && defined(USART0)
00062 #define USART_REF_VALID(ref) ((ref) == USART0)
00063
00064 #elif (USART_COUNT == 1) && defined(USART1)
00065 #define USART_REF_VALID(ref) ((ref) == USART1)
00066
00067 #elif (USART_COUNT == 2) && defined(USART2)
00068 #define USART_REF_VALID(ref) (((ref) == USART1) || ((ref) == USART2))
00069
00070 #elif (USART_COUNT == 2)
00071 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1))
00072
00073 #elif (USART_COUNT == 3)
00074 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1) || \
00075 ((ref) == USART2))
00076 #elif (USART_COUNT == 4)
00077 #define USART_REF_VALID(ref) (((ref) == USART0) || ((ref) == USART1) || \
00078 ((ref) == USART2) || ((ref) == USART3))
00079 #else
00080 #error Undefined number of USARTs.
00081 #endif
00082
00083 #if defined(USARTRF_COUNT) && (USARTRF_COUNT > 0)
00084 #if (USARTRF_COUNT == 1) && defined(USARTRF0)
00085 #define USARTRF_REF_VALID(ref) ((ref) == USARTRF0)
00086 #elif (USARTRF_COUNT == 1) && defined(USARTRF1)
00087 #define USARTRF_REF_VALID(ref) ((ref) == USARTRF1)
00088 #else
00089 #define USARTRF_REF_VALID(ref) (0)
00090 #endif
00091 #else
00092 #define USARTRF_REF_VALID(ref) (0)
00093 #endif
00094
00095 #if defined( _EFM32_HAPPY_FAMILY )
00096 #define USART_IRDA_VALID(ref) (((ref) == USART0) || ((ref) == USART1))
00097 #elif defined(USART0)
00098 #define USART_IRDA_VALID(ref) ((ref) == USART0)
00099 #elif (USART_COUNT == 1) && defined(USART1)
00100 #define USART_IRDA_VALID(ref) ((ref) == USART1)
00101 #else
00102 #define USART_IRDA_VALID(ref) (0)
00103 #endif
00104
00105 #if defined( _EFM32_HAPPY_FAMILY )
00106 #define USART_I2S_VALID(ref) (((ref) == USART0) || ((ref) == USART1))
00107 #elif defined(_EFM32_TINY_FAMILY) || defined(_EFM32_ZERO_FAMILY)
00108 #define USART_I2S_VALID(ref) ((ref) == USART1)
00109 #elif defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
00110 #define USART_I2S_VALID(ref) (((ref) == USART1) || ((ref) == USART2))
00111 #endif
00112
00113 #if (UART_COUNT == 1)
00114 #define UART_REF_VALID(ref) ((ref) == UART0)
00115 #elif (UART_COUNT == 2)
00116 #define UART_REF_VALID(ref) (((ref) == UART0) || ((ref) == UART1))
00117 #else
00118 #define UART_REF_VALID(ref) (0)
00119 #endif
00120
00124
00125
00126
00127
00128
00150 void USART_BaudrateAsyncSet(USART_TypeDef *usart,
00151 uint32_t refFreq,
00152 uint32_t baudrate,
00153 USART_OVS_TypeDef ovs)
00154 {
00155 uint32_t clkdiv;
00156 uint32_t oversample;
00157
00158
00159 EFM_ASSERT(baudrate);
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 if (!refFreq)
00189 {
00190 refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00191 }
00192
00193
00194 switch (ovs)
00195 {
00196 case USART_CTRL_OVS_X16:
00197 EFM_ASSERT(baudrate <= (refFreq / 16));
00198 oversample = 16;
00199 break;
00200
00201 case USART_CTRL_OVS_X8:
00202 EFM_ASSERT(baudrate <= (refFreq / 8));
00203 oversample = 8;
00204 break;
00205
00206 case USART_CTRL_OVS_X6:
00207 EFM_ASSERT(baudrate <= (refFreq / 6));
00208 oversample = 6;
00209 break;
00210
00211 case USART_CTRL_OVS_X4:
00212 EFM_ASSERT(baudrate <= (refFreq / 4));
00213 oversample = 4;
00214 break;
00215
00216 default:
00217
00218 EFM_ASSERT(0);
00219 return;
00220 }
00221
00222
00223
00224
00225
00226
00227 clkdiv = 4 * refFreq + (oversample * baudrate) / 2;
00228 clkdiv /= (oversample * baudrate);
00229 clkdiv -= 4;
00230 clkdiv *= 64;
00231
00232
00233 EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00234
00235
00236 clkdiv &= _USART_CLKDIV_MASK;
00237
00238 usart->CTRL &= ~_USART_CTRL_OVS_MASK;
00239 usart->CTRL |= ovs;
00240 usart->CLKDIV = clkdiv;
00241 }
00242
00243
00244
00272 uint32_t USART_BaudrateCalc(uint32_t refFreq,
00273 uint32_t clkdiv,
00274 bool syncmode,
00275 USART_OVS_TypeDef ovs)
00276 {
00277 uint32_t oversample;
00278 uint32_t divisor;
00279 uint32_t factor;
00280 uint32_t remainder;
00281 uint32_t quotient;
00282 uint32_t br;
00283
00284
00285 clkdiv &= _USART_CLKDIV_MASK;
00286
00287
00288
00289
00290
00291 if (syncmode)
00292 {
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 oversample = 1;
00303 factor = 128;
00304 }
00305 else
00306 {
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 switch (ovs)
00321 {
00322 case USART_CTRL_OVS_X16:
00323 oversample = 1;
00324 factor = 256 / 16;
00325 break;
00326
00327 case USART_CTRL_OVS_X8:
00328 oversample = 1;
00329 factor = 256 / 8;
00330 break;
00331
00332 case USART_CTRL_OVS_X6:
00333 oversample = 3;
00334 factor = 256 / 2;
00335 break;
00336
00337 default:
00338 oversample = 1;
00339 factor = 256 / 4;
00340 break;
00341 }
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 divisor = oversample * (256 + clkdiv);
00368
00369 quotient = refFreq / divisor;
00370 remainder = refFreq % divisor;
00371
00372
00373
00374 br = factor * quotient;
00375
00376
00377
00378
00379
00380
00381 br += (factor * remainder) / divisor;
00382
00383 return br;
00384 }
00385
00386
00387
00401 uint32_t USART_BaudrateGet(USART_TypeDef *usart)
00402 {
00403 uint32_t freq;
00404 USART_OVS_TypeDef ovs;
00405 bool syncmode;
00406
00407 if (usart->CTRL & USART_CTRL_SYNC)
00408 {
00409 syncmode = true;
00410 }
00411 else
00412 {
00413 syncmode = false;
00414 }
00415
00416
00417 freq = CMU_ClockFreqGet(cmuClock_HFPER);
00418 ovs = (USART_OVS_TypeDef) (usart->CTRL & _USART_CTRL_OVS_MASK);
00419 return USART_BaudrateCalc(freq, usart->CLKDIV, syncmode, ovs);
00420 }
00421
00422
00423
00450 void USART_BaudrateSyncSet(USART_TypeDef *usart, uint32_t refFreq, uint32_t baudrate)
00451 {
00452 uint32_t clkdiv;
00453
00454
00455 EFM_ASSERT(baudrate);
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 if (!refFreq)
00485 {
00486 refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00487 }
00488
00489
00490 clkdiv = 2 * refFreq;
00491 clkdiv += baudrate - 1;
00492 clkdiv /= baudrate;
00493 clkdiv -= 4;
00494 clkdiv *= 64;
00495
00496
00497
00498 clkdiv += 0xc0;
00499 clkdiv &= 0xffffff00;
00500
00501
00502 EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00503
00504
00505 clkdiv &= _USART_CLKDIV_DIV_MASK;
00506
00507 usart->CLKDIV = clkdiv;
00508 }
00509
00510
00511
00526 void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable)
00527 {
00528 uint32_t tmp;
00529
00530
00531 EFM_ASSERT( USART_REF_VALID(usart)
00532 || USARTRF_REF_VALID(usart)
00533 || UART_REF_VALID(usart) );
00534
00535
00536 tmp = ~((uint32_t) (enable));
00537 tmp &= _USART_CMD_RXEN_MASK | _USART_CMD_TXEN_MASK;
00538 usart->CMD = tmp << 1;
00539
00540
00541 usart->CMD = (uint32_t) (enable);
00542 }
00543
00544
00545
00568 void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init)
00569 {
00570
00571 EFM_ASSERT( USART_REF_VALID(usart)
00572 || USARTRF_REF_VALID(usart)
00573 || UART_REF_VALID(usart) );
00574
00575
00576 USART_Reset(usart);
00577
00578 #if defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
00579
00580 if (init->mvdis)
00581 {
00582 usart->CTRL |= USART_CTRL_MVDIS;
00583 }
00584
00585
00586 if (init->prsRxEnable)
00587 {
00588 usart->INPUT = (uint32_t) init->prsRxCh | USART_INPUT_RXPRS;
00589 }
00590 #endif
00591
00592
00593 usart->FRAME = (uint32_t) (init->databits) |
00594 (uint32_t) (init->stopbits) |
00595 (uint32_t) (init->parity);
00596
00597
00598 USART_BaudrateAsyncSet(usart, init->refFreq, init->baudrate, init->oversampling);
00599
00600
00601 usart->CMD = (uint32_t) (init->enable);
00602 }
00603
00604
00605
00629 void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init)
00630 {
00631
00632 EFM_ASSERT( USART_REF_VALID(usart) || USARTRF_REF_VALID(usart) );
00633
00634
00635 USART_Reset(usart);
00636
00637
00638 usart->CTRL |= (USART_CTRL_SYNC) |
00639 ((uint32_t) init->clockMode) |
00640 (init->msbf ? USART_CTRL_MSBF : 0);
00641
00642 #if defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN)
00643 usart->CTRL |= (init->prsRxEnable ? USART_INPUT_RXPRS : 0) |
00644 (init->autoTx ? USART_CTRL_AUTOTX : 0);
00645 #endif
00646
00647
00648 usart->FRAME = ((uint32_t) (init->databits)) |
00649 (USART_FRAME_STOPBITS_DEFAULT) |
00650 (USART_FRAME_PARITY_DEFAULT);
00651
00652
00653 USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate);
00654
00655
00656 if (init->master)
00657 {
00658 usart->CMD = USART_CMD_MASTEREN;
00659 }
00660
00661 usart->CMD = (uint32_t) (init->enable);
00662 }
00663
00664
00665 #if defined(USART0) || ((USART_COUNT == 1) && defined(USART1))
00666
00692 void USART_InitIrDA(const USART_InitIrDA_TypeDef *init)
00693 {
00694 #if (USART_COUNT == 1) && defined(USART1)
00695 USART_TypeDef *usart = USART1;
00696 #else
00697 USART_TypeDef *usart = USART0;
00698 #endif
00699
00700
00701 USART_InitAsync(usart, &(init->async));
00702
00703
00704 usart->CTRL |= USART_CTRL_TXINV;
00705
00706
00707 if (init->irRxInv)
00708 {
00709 usart->CTRL |= USART_CTRL_RXINV;
00710 }
00711
00712
00713 usart->IRCTRL |= (uint32_t) init->irPw |
00714 (uint32_t) init->irPrsSel |
00715 ((uint32_t) init->irFilt << _USART_IRCTRL_IRFILT_SHIFT) |
00716 ((uint32_t) init->irPrsEn << _USART_IRCTRL_IRPRSEN_SHIFT);
00717
00718
00719 usart->IRCTRL |= USART_IRCTRL_IREN;
00720 }
00721 #endif
00722
00723
00724 #if defined(_USART_I2SCTRL_MASK)
00725
00754 void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init)
00755 {
00756 USART_Enable_TypeDef enable;
00757
00758
00759 EFM_ASSERT(USART_I2S_VALID(usart));
00760
00761
00762 enable = init->sync.enable;
00763 init->sync.enable = usartDisable;
00764
00765
00766 USART_InitSync(usart, &init->sync);
00767
00768
00769 usart->I2SCTRL = ((uint32_t) init->format) |
00770 ((uint32_t) init->justify) |
00771 (init->delay ? USART_I2SCTRL_DELAY : 0) |
00772 (init->dmaSplit ? USART_I2SCTRL_DMASPLIT : 0) |
00773 (init->mono ? USART_I2SCTRL_MONO : 0) |
00774 (USART_I2SCTRL_EN);
00775
00776 if (enable != usartDisable)
00777 {
00778 USART_Enable(usart, enable);
00779 }
00780 }
00781 #endif
00782
00783
00784
00793 void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init)
00794 {
00795 uint32_t trigctrl;
00796
00797
00798 trigctrl = usart->TRIGCTRL & ~(_USART_TRIGCTRL_RXTEN_MASK |
00799 _USART_TRIGCTRL_TXTEN_MASK |
00800 #if defined(USART_TRIGCTRL_AUTOTXTEN)
00801 _USART_TRIGCTRL_AUTOTXTEN_MASK |
00802 #endif
00803 _USART_TRIGCTRL_TSEL_MASK);
00804
00805 #if defined(USART_TRIGCTRL_AUTOTXTEN)
00806 if (init->autoTxTriggerEnable)
00807 {
00808 trigctrl |= USART_TRIGCTRL_AUTOTXTEN;
00809 }
00810 #endif
00811 if (init->txTriggerEnable)
00812 {
00813 trigctrl |= USART_TRIGCTRL_TXTEN;
00814 }
00815 if (init->rxTriggerEnable)
00816 {
00817 trigctrl |= USART_TRIGCTRL_RXTEN;
00818 }
00819 trigctrl |= init->prsTriggerChannel;
00820
00821
00822 usart->TRIGCTRL = trigctrl;
00823 }
00824
00825
00826
00833 void USART_Reset(USART_TypeDef *usart)
00834 {
00835
00836 EFM_ASSERT( USART_REF_VALID(usart)
00837 || USARTRF_REF_VALID(usart)
00838 || UART_REF_VALID(usart) );
00839
00840
00841 usart->CMD = USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS |
00842 USART_CMD_RXBLOCKDIS | USART_CMD_TXTRIDIS | USART_CMD_CLEARTX | USART_CMD_CLEARRX;
00843 usart->CTRL = _USART_CTRL_RESETVALUE;
00844 usart->FRAME = _USART_FRAME_RESETVALUE;
00845 usart->TRIGCTRL = _USART_TRIGCTRL_RESETVALUE;
00846 usart->CLKDIV = _USART_CLKDIV_RESETVALUE;
00847 usart->IEN = _USART_IEN_RESETVALUE;
00848 usart->IFC = _USART_IFC_MASK;
00849 usart->ROUTE = _USART_ROUTE_RESETVALUE;
00850
00851 if (USART_IRDA_VALID(usart))
00852 {
00853 usart->IRCTRL = _USART_IRCTRL_RESETVALUE;
00854 }
00855
00856 #if defined(_USART_INPUT_RESETVALUE)
00857 usart->INPUT = _USART_INPUT_RESETVALUE;
00858 #endif
00859
00860 #if defined(_USART_I2SCTRL_RESETVALUE)
00861 if (USART_I2S_VALID(usart))
00862 {
00863 usart->I2SCTRL = _USART_I2SCTRL_RESETVALUE;
00864 }
00865 #endif
00866 }
00867
00868
00869
00893 uint8_t USART_Rx(USART_TypeDef *usart)
00894 {
00895 while (!(usart->STATUS & USART_STATUS_RXDATAV))
00896 ;
00897
00898 return (uint8_t) (usart->RXDATA);
00899 }
00900
00901
00902
00926 uint16_t USART_RxDouble(USART_TypeDef *usart)
00927 {
00928 while (!(usart->STATUS & USART_STATUS_RXFULL))
00929 ;
00930
00931 return (uint16_t) (usart->RXDOUBLE);
00932 }
00933
00934
00935
00959 uint32_t USART_RxDoubleExt(USART_TypeDef *usart)
00960 {
00961 while (!(usart->STATUS & USART_STATUS_RXFULL))
00962 ;
00963
00964 return usart->RXDOUBLEX;
00965 }
00966
00967
00968
00992 uint16_t USART_RxExt(USART_TypeDef *usart)
00993 {
00994 while (!(usart->STATUS & USART_STATUS_RXDATAV))
00995 ;
00996
00997 return (uint16_t) (usart->RXDATAX);
00998 }
00999
01000
01001
01020 uint8_t USART_SpiTransfer(USART_TypeDef *usart, uint8_t data)
01021 {
01022 while (!(usart->STATUS & USART_STATUS_TXBL))
01023 ;
01024 usart->TXDATA = (uint32_t) data;
01025 while (!(usart->STATUS & USART_STATUS_TXC))
01026 ;
01027 return (uint8_t) (usart->RXDATA);
01028 }
01029
01030
01031
01054 void USART_Tx(USART_TypeDef *usart, uint8_t data)
01055 {
01056
01057 while (!(usart->STATUS & USART_STATUS_TXBL))
01058 ;
01059 usart->TXDATA = (uint32_t) data;
01060 }
01061
01062
01063
01090 void USART_TxDouble(USART_TypeDef *usart, uint16_t data)
01091 {
01092
01093 while (!(usart->STATUS & USART_STATUS_TXBL))
01094 ;
01095 usart->TXDOUBLE = (uint32_t) data;
01096 }
01097
01098
01099
01126 void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data)
01127 {
01128
01129 while (!(usart->STATUS & USART_STATUS_TXBL))
01130 ;
01131 usart->TXDOUBLEX = data;
01132 }
01133
01134
01135
01154 void USART_TxExt(USART_TypeDef *usart, uint16_t data)
01155 {
01156
01157 while (!(usart->STATUS & USART_STATUS_TXBL))
01158 ;
01159 usart->TXDATAX = (uint32_t) data;
01160 }
01161
01162
01165 #endif