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  *******************************   DEFINES   ***********************************
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)
00068 #define USART_REF_VALID(ref)    (((ref) == USART0) || ((ref) == USART1))
00069 
00070 #elif (USART_COUNT == 3)
00071 #define USART_REF_VALID(ref)    (((ref) == USART0) || ((ref) == USART1) || \
00072                                  ((ref) == USART2))
00073 #elif (USART_COUNT == 4)
00074 #define USART_REF_VALID(ref)    (((ref) == USART0) || ((ref) == USART1) || \
00075                                  ((ref) == USART2) || ((ref) == USART3))
00076 #else
00077 #error Undefined number of USARTs.
00078 #endif
00079 
00080 #if defined(USART0)
00081 #define USART_IRDA_VALID(ref)    ((ref) == USART0)
00082 #elif (USART_COUNT == 1) && defined(USART1)
00083 #define USART_IRDA_VALID(ref)    ((ref) == USART1)
00084 #else
00085 #define USART_IRDA_VALID(ref)    (0)
00086 #endif
00087 
00088 #if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_ZERO_FAMILY)
00089 #define USART_I2S_VALID(ref)    ((ref) == USART1)
00090 
00091 #elif defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
00092 #define USART_I2S_VALID(ref)    (((ref) == USART1) || ((ref) == USART2))
00093 #endif
00094 
00095 #if (UART_COUNT == 1)
00096 #define UART_REF_VALID(ref)    ((ref) == UART0)
00097 #elif (UART_COUNT == 2)
00098 #define UART_REF_VALID(ref)    (((ref) == UART0) || ((ref) == UART1))
00099 #else
00100 #define UART_REF_VALID(ref)    (0)
00101 #endif
00102 
00106 /*******************************************************************************
00107  **************************   GLOBAL FUNCTIONS   *******************************
00108  ******************************************************************************/
00109 
00110 /***************************************************************************/
00132 void USART_BaudrateAsyncSet(USART_TypeDef *usart,
00133                             uint32_t refFreq,
00134                             uint32_t baudrate,
00135                             USART_OVS_TypeDef ovs)
00136 {
00137   uint32_t clkdiv;
00138   uint32_t oversample;
00139 
00140   /* Inhibit divide by 0 */
00141   EFM_ASSERT(baudrate);
00142 
00143   /*
00144    * We want to use integer division to avoid forcing in float division
00145    * utils, and yet keep rounding effect errors to a minimum.
00146    *
00147    * CLKDIV in asynchronous mode is given by:
00148    *
00149    * CLKDIV = 256 * (fHFPERCLK/(oversample * br) - 1)
00150    * or
00151    * CLKDIV = (256 * fHFPERCLK)/(oversample * br) - 256
00152    *
00153    * The basic problem with integer division in the above formula is that
00154    * the dividend (256 * fHFPERCLK) may become higher than max 32 bit
00155    * integer. Yet, we want to evaluate dividend first before dividing in
00156    * order to get as small rounding effects as possible. We do not want
00157    * to make too harsh restrictions on max fHFPERCLK value either.
00158    *
00159    * One can possibly factorize 256 and oversample/br. However,
00160    * since the last 6 bits of CLKDIV are don't care, we can base our
00161    * integer arithmetic on the below formula
00162    *
00163    * CLKDIV / 64 = (4 * fHFPERCLK)/(oversample * br) - 4
00164    *
00165    * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK
00166    * up to 1GHz without overflowing a 32 bit value!
00167    */
00168 
00169   /* HFPERCLK used to clock all USART/UART peripheral modules */
00170   if (!refFreq)
00171   {
00172     refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00173   }
00174 
00175   /* Map oversampling */
00176   switch (ovs)
00177   {
00178   case USART_CTRL_OVS_X16:
00179     EFM_ASSERT(baudrate <= (refFreq / 16));
00180     oversample = 16;
00181     break;
00182 
00183   case USART_CTRL_OVS_X8:
00184     EFM_ASSERT(baudrate <= (refFreq / 8));
00185     oversample = 8;
00186     break;
00187 
00188   case USART_CTRL_OVS_X6:
00189     EFM_ASSERT(baudrate <= (refFreq / 6));
00190     oversample = 6;
00191     break;
00192 
00193   case USART_CTRL_OVS_X4:
00194     EFM_ASSERT(baudrate <= (refFreq / 4));
00195     oversample = 4;
00196     break;
00197 
00198   default:
00199     /* Invalid input */
00200     EFM_ASSERT(0);
00201     return;
00202   }
00203 
00204   /* Calculate and set CLKDIV with fractional bits.
00205    * The addend (oversample*baudrate)/2 in the first line is to round the
00206    * divisor up by half the divisor before the division in order to reduce the
00207    * integer division error, which consequently results in a higher baudrate
00208    * than desired. */
00209   clkdiv  = 4 * refFreq + (oversample * baudrate) / 2;
00210   clkdiv /= (oversample * baudrate);
00211   clkdiv -= 4;
00212   clkdiv *= 64;
00213 
00214   /* Verify that resulting clock divider is within limits */
00215   EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00216 
00217   /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
00218   clkdiv &= _USART_CLKDIV_MASK;
00219 
00220   usart->CTRL  &= ~_USART_CTRL_OVS_MASK;
00221   usart->CTRL  |= ovs;
00222   usart->CLKDIV = clkdiv;
00223 }
00224 
00225 
00226 /***************************************************************************/
00254 uint32_t USART_BaudrateCalc(uint32_t refFreq,
00255                             uint32_t clkdiv,
00256                             bool syncmode,
00257                             USART_OVS_TypeDef ovs)
00258 {
00259   uint32_t oversample;
00260   uint32_t divisor;
00261   uint32_t factor;
00262   uint32_t remainder;
00263   uint32_t quotient;
00264   uint32_t br;
00265 
00266   /* Mask out unused bits */
00267   clkdiv &= _USART_CLKDIV_MASK;
00268 
00269   /* We want to use integer division to avoid forcing in float division */
00270   /* utils, and yet keep rounding effect errors to a minimum. */
00271 
00272   /* Baudrate calculation depends on if synchronous or asynchronous mode */
00273   if (syncmode)
00274   {
00275     /*
00276      * Baudrate is given by:
00277      *
00278      * br = fHFPERCLK/(2 * (1 + (CLKDIV / 256)))
00279      *
00280      * which can be rewritten to
00281      *
00282      * br = (128 * fHFPERCLK)/(256 + CLKDIV)
00283      */
00284     oversample = 1; /* Not used in sync mode, ie 1 */
00285     factor     = 128;
00286   }
00287   else
00288   {
00289     /*
00290      * Baudrate in asynchronous mode is given by:
00291      *
00292      * br = fHFPERCLK/(oversample * (1 + (CLKDIV / 256)))
00293      *
00294      * which can be rewritten to
00295      *
00296      * br = (256 * fHFPERCLK)/(oversample * (256 + CLKDIV))
00297      *
00298      * First of all we can reduce the 256 factor of the dividend with
00299      * (part of) oversample part of the divisor.
00300      */
00301 
00302     switch (ovs)
00303     {
00304     case USART_CTRL_OVS_X16:
00305       oversample = 1;
00306       factor     = 256 / 16;
00307       break;
00308 
00309     case USART_CTRL_OVS_X8:
00310       oversample = 1;
00311       factor     = 256 / 8;
00312       break;
00313 
00314     case USART_CTRL_OVS_X6:
00315       oversample = 3;
00316       factor     = 256 / 2;
00317       break;
00318 
00319     default:
00320       oversample = 1;
00321       factor     = 256 / 4;
00322       break;
00323     }
00324   }
00325 
00326   /*
00327    * The basic problem with integer division in the above formula is that
00328    * the dividend (factor * fHFPERCLK) may become higher than max 32 bit
00329    * integer. Yet we want to evaluate dividend first before dividing in
00330    * order to get as small rounding effects as possible. We do not want
00331    * to make too harsh restrictions on max fHFPERCLK value either.
00332    *
00333    * For division a/b, we can write
00334    *
00335    * a = qb + r
00336    *
00337    * where q is the quotient and r is the remainder, both integers.
00338    *
00339    * The orignal baudrate formula can be rewritten as
00340    *
00341    * br = xa / b = x(qb + r)/b = xq + xr/b
00342    *
00343    * where x is 'factor', a is 'refFreq' and b is 'divisor', referring to
00344    * variable names.
00345    */
00346 
00347   /* Divisor will never exceed max 32 bit value since clkdiv <= 0x1fffc0 */
00348   /* and 'oversample' has been reduced to <= 3. */
00349   divisor = oversample * (256 + clkdiv);
00350 
00351   quotient  = refFreq / divisor;
00352   remainder = refFreq % divisor;
00353 
00354   /* factor <= 128 and since divisor >= 256, the below cannot exceed max */
00355   /* 32 bit value. */
00356   br = factor * quotient;
00357 
00358   /*
00359    * factor <= 128 and remainder < (oversample*(256 + clkdiv)), which
00360    * means dividend (factor * remainder) worst case is
00361    * 128*(3 * (256 + 0x1fffc0)) = 0x30012000.
00362    */
00363   br += (factor * remainder) / divisor;
00364 
00365   return br;
00366 }
00367 
00368 
00369 /***************************************************************************/
00383 uint32_t USART_BaudrateGet(USART_TypeDef *usart)
00384 {
00385   uint32_t          freq;
00386   USART_OVS_TypeDef ovs;
00387   bool              syncmode;
00388 
00389   if (usart->CTRL & USART_CTRL_SYNC)
00390   {
00391     syncmode = true;
00392   }
00393   else
00394   {
00395     syncmode = false;
00396   }
00397 
00398   /* HFPERCLK used to clock all USART/UART peripheral modules */
00399   freq = CMU_ClockFreqGet(cmuClock_HFPER);
00400   ovs  = (USART_OVS_TypeDef) (usart->CTRL & _USART_CTRL_OVS_MASK);
00401   return USART_BaudrateCalc(freq, usart->CLKDIV, syncmode, ovs);
00402 }
00403 
00404 
00405 /***************************************************************************/
00432 void USART_BaudrateSyncSet(USART_TypeDef *usart, uint32_t refFreq, uint32_t baudrate)
00433 {
00434   uint32_t clkdiv;
00435 
00436   /* Inhibit divide by 0 */
00437   EFM_ASSERT(baudrate);
00438 
00439   /*
00440    * We want to use integer division to avoid forcing in float division
00441    * utils, and yet keep rounding effect errors to a minimum.
00442    *
00443    * CLKDIV in synchronous mode is given by:
00444    *
00445    * CLKDIV = 256 * (fHFPERCLK/(2 * br) - 1)
00446    * or
00447    * CLKDIV = (256 * fHFPERCLK)/(2 * br) - 256 = (128 * fHFPERCLK)/br - 256
00448    *
00449    * The basic problem with integer division in the above formula is that
00450    * the dividend (128 * fHFPERCLK) may become higher than max 32 bit
00451    * integer. Yet, we want to evaluate dividend first before dividing in
00452    * order to get as small rounding effects as possible. We do not want
00453    * to make too harsh restrictions on max fHFPERCLK value either.
00454    *
00455    * One can possibly factorize 128 and br. However, since the last
00456    * 6 bits of CLKDIV are don't care, we can base our integer arithmetic
00457    * on the below formula without loosing any extra precision:
00458    *
00459    * CLKDIV / 64 = (2 * fHFPERCLK)/br - 4
00460    *
00461    * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK
00462    * up to 2GHz without overflowing a 32 bit value!
00463    */
00464 
00465   /* HFPERCLK used to clock all USART/UART peripheral modules */
00466   if (!refFreq)
00467   {
00468     refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00469   }
00470 
00471   /* Calculate and set CLKDIV with fractional bits */
00472   clkdiv  = 2 * refFreq;
00473   clkdiv += baudrate - 1;
00474   clkdiv /= baudrate;
00475   clkdiv -= 4;
00476   clkdiv *= 64;
00477   /* Make sure we don't use fractional bits by rounding CLKDIV */
00478   /* up (and thus reducing baudrate, not increasing baudrate above */
00479   /* specified value). */
00480   clkdiv += 0xc0;
00481   clkdiv &= 0xffffff00;
00482 
00483   /* Verify that resulting clock divider is within limits */
00484   EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00485 
00486   /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
00487   clkdiv &= _USART_CLKDIV_DIV_MASK;
00488 
00489   usart->CLKDIV = clkdiv;
00490 }
00491 
00492 
00493 /***************************************************************************/
00508 void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable)
00509 {
00510   uint32_t tmp;
00511 
00512   /* Make sure the module exists on the selected chip */
00513   EFM_ASSERT(USART_REF_VALID(usart) || (UART_REF_VALID(usart)));
00514 
00515   /* Disable as specified */
00516   tmp        = ~((uint32_t) (enable));
00517   tmp       &= _USART_CMD_RXEN_MASK | _USART_CMD_TXEN_MASK;
00518   usart->CMD = tmp << 1;
00519 
00520   /* Enable as specified */
00521   usart->CMD = (uint32_t) (enable);
00522 }
00523 
00524 
00525 /***************************************************************************/
00548 void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init)
00549 {
00550   /* Make sure the module exists on the selected chip */
00551   EFM_ASSERT(USART_REF_VALID(usart) || UART_REF_VALID(usart));
00552 
00553   /* Init USART registers to HW reset state. */
00554   USART_Reset(usart);
00555 
00556 #if defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
00557   /* Disable majority vote if specified. */
00558   if (init->mvdis)
00559   {
00560     usart->CTRL |= USART_CTRL_MVDIS;
00561   }
00562 
00563   /* Configure PRS input mode. */
00564   if (init->prsRxEnable)
00565   {
00566     usart->INPUT = (uint32_t) init->prsRxCh | USART_INPUT_RXPRS;
00567   }
00568 #endif
00569 
00570   /* Configure databits, stopbits and parity */
00571   usart->FRAME = (uint32_t) (init->databits) |
00572                  (uint32_t) (init->stopbits) |
00573                  (uint32_t) (init->parity);
00574 
00575   /* Configure baudrate */
00576   USART_BaudrateAsyncSet(usart, init->refFreq, init->baudrate, init->oversampling);
00577 
00578   /* Finally enable (as specified) */
00579   usart->CMD = (uint32_t) (init->enable);
00580 }
00581 
00582 
00583 /***************************************************************************/
00607 void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init)
00608 {
00609   /* Make sure the module exists on the selected chip */
00610   EFM_ASSERT(USART_REF_VALID(usart));
00611 
00612   /* Init USART registers to HW reset state. */
00613   USART_Reset(usart);
00614 
00615   /* Set bits for synchronous mode */
00616   usart->CTRL |= (USART_CTRL_SYNC) |
00617                  ((uint32_t) init->clockMode) |
00618                  (init->msbf ? USART_CTRL_MSBF : 0);
00619 
00620 #if defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN)
00621   usart->CTRL |= (init->prsRxEnable ? USART_INPUT_RXPRS : 0) |
00622                  (init->autoTx      ? USART_CTRL_AUTOTX : 0);
00623 #endif
00624 
00625   /* Configure databits, leave stopbits and parity at reset default (not used) */
00626   usart->FRAME = ((uint32_t) (init->databits)) |
00627                  (USART_FRAME_STOPBITS_DEFAULT) |
00628                  (USART_FRAME_PARITY_DEFAULT);
00629 
00630   /* Configure baudrate */
00631   USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate);
00632 
00633   /* Finally enable (as specified) */
00634   if (init->master)
00635   {
00636     usart->CMD = USART_CMD_MASTEREN;
00637   }
00638 
00639   usart->CMD = (uint32_t) (init->enable);
00640 }
00641 
00642 
00643 #if defined(USART0) || ((USART_COUNT == 1) && defined(USART1))
00644 /***************************************************************************/
00670 void USART_InitIrDA(const USART_InitIrDA_TypeDef *init)
00671 {
00672   #if (USART_COUNT == 1) && defined(USART1)
00673   USART_TypeDef *usart = USART1;
00674   #else
00675   USART_TypeDef *usart = USART0;
00676   #endif
00677 
00678   /* Init USART as async device */
00679   USART_InitAsync(usart, &(init->async));
00680 
00681   /* Set IrDA modulation to RZI (return-to-zero-inverted) */
00682   usart->CTRL |= USART_CTRL_TXINV;
00683 
00684   /* Invert Rx signal before demodulator if enabled */
00685   if (init->irRxInv)
00686   {
00687     usart->CTRL |= USART_CTRL_RXINV;
00688   }
00689 
00690   /* Configure IrDA */
00691   usart->IRCTRL |= (uint32_t) init->irPw |
00692                    (uint32_t) init->irPrsSel |
00693                    ((uint32_t) init->irFilt << _USART_IRCTRL_IRFILT_SHIFT) |
00694                    ((uint32_t) init->irPrsEn << _USART_IRCTRL_IRPRSEN_SHIFT);
00695 
00696   /* Enable IrDA */
00697   usart->IRCTRL |= USART_IRCTRL_IREN;
00698 }
00699 #endif
00700 
00701 
00702 #if defined(_USART_I2SCTRL_MASK)
00703 /***************************************************************************/
00732 void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init)
00733 {
00734   USART_Enable_TypeDef enable;
00735 
00736   /* Make sure the module exists on the selected chip */
00737   EFM_ASSERT(USART_I2S_VALID(usart));
00738 
00739   /* Override the enable setting. */
00740   enable            = init->sync.enable;
00741   init->sync.enable = usartDisable;
00742 
00743   /* Init USART as a sync device. */
00744   USART_InitSync(usart, &init->sync);
00745 
00746   /* Configure and enable I2CCTRL register acording to selected mode. */
00747   usart->I2SCTRL = ((uint32_t) init->format) |
00748                    ((uint32_t) init->justify) |
00749                    (init->delay    ? USART_I2SCTRL_DELAY    : 0) |
00750                    (init->dmaSplit ? USART_I2SCTRL_DMASPLIT : 0) |
00751                    (init->mono     ? USART_I2SCTRL_MONO     : 0) |
00752                    (USART_I2SCTRL_EN);
00753 
00754   if (enable != usartDisable)
00755   {
00756     USART_Enable(usart, enable);
00757   }
00758 }
00759 #endif
00760 
00761 
00762 /***************************************************************************/
00771 void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init)
00772 {
00773   uint32_t trigctrl;
00774 
00775   /* Clear values that will be reconfigured  */
00776   trigctrl = usart->TRIGCTRL & ~(_USART_TRIGCTRL_RXTEN_MASK |
00777                                  _USART_TRIGCTRL_TXTEN_MASK |
00778 #if defined(USART_TRIGCTRL_AUTOTXTEN)
00779                                  _USART_TRIGCTRL_AUTOTXTEN_MASK |
00780 #endif
00781                                  _USART_TRIGCTRL_TSEL_MASK);
00782 
00783 #if defined(USART_TRIGCTRL_AUTOTXTEN)
00784   if (init->autoTxTriggerEnable)
00785   {
00786     trigctrl |= USART_TRIGCTRL_AUTOTXTEN;
00787   }
00788 #endif
00789   if (init->txTriggerEnable)
00790   {
00791     trigctrl |= USART_TRIGCTRL_TXTEN;
00792   }
00793   if (init->rxTriggerEnable)
00794   {
00795     trigctrl |= USART_TRIGCTRL_RXTEN;
00796   }
00797   trigctrl |= init->prsTriggerChannel;
00798 
00799   /* Enable new configuration */
00800   usart->TRIGCTRL = trigctrl;
00801 }
00802 
00803 
00804 /***************************************************************************/
00811 void USART_Reset(USART_TypeDef *usart)
00812 {
00813   /* Make sure the module exists on the selected chip */
00814   EFM_ASSERT(USART_REF_VALID(usart) || UART_REF_VALID(usart));
00815 
00816   /* Make sure disabled first, before resetting other registers */
00817   usart->CMD = USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS |
00818                USART_CMD_RXBLOCKDIS | USART_CMD_TXTRIDIS | USART_CMD_CLEARTX | USART_CMD_CLEARRX;
00819   usart->CTRL     = _USART_CTRL_RESETVALUE;
00820   usart->FRAME    = _USART_FRAME_RESETVALUE;
00821   usart->TRIGCTRL = _USART_TRIGCTRL_RESETVALUE;
00822   usart->CLKDIV   = _USART_CLKDIV_RESETVALUE;
00823   usart->IEN      = _USART_IEN_RESETVALUE;
00824   usart->IFC      = _USART_IFC_MASK;
00825   usart->ROUTE    = _USART_ROUTE_RESETVALUE;
00826 
00827   if (USART_IRDA_VALID(usart))
00828   {
00829     usart->IRCTRL = _USART_IRCTRL_RESETVALUE;
00830   }
00831 
00832 #if defined(_USART_INPUT_RESETVALUE)
00833   usart->INPUT = _USART_INPUT_RESETVALUE;
00834 #endif
00835 
00836 #if defined(_USART_I2SCTRL_RESETVALUE)
00837   if (USART_I2S_VALID(usart))
00838   {
00839     usart->I2SCTRL = _USART_I2SCTRL_RESETVALUE;
00840   }
00841 #endif
00842 }
00843 
00844 
00845 /***************************************************************************/
00869 uint8_t USART_Rx(USART_TypeDef *usart)
00870 {
00871   while (!(usart->STATUS & USART_STATUS_RXDATAV))
00872     ;
00873 
00874   return (uint8_t) (usart->RXDATA);
00875 }
00876 
00877 
00878 /***************************************************************************/
00902 uint16_t USART_RxDouble(USART_TypeDef *usart)
00903 {
00904   while (!(usart->STATUS & USART_STATUS_RXFULL))
00905     ;
00906 
00907   return (uint16_t) (usart->RXDOUBLE);
00908 }
00909 
00910 
00911 /***************************************************************************/
00935 uint32_t USART_RxDoubleExt(USART_TypeDef *usart)
00936 {
00937   while (!(usart->STATUS & USART_STATUS_RXFULL))
00938     ;
00939 
00940   return usart->RXDOUBLEX;
00941 }
00942 
00943 
00944 /***************************************************************************/
00968 uint16_t USART_RxExt(USART_TypeDef *usart)
00969 {
00970   while (!(usart->STATUS & USART_STATUS_RXDATAV))
00971     ;
00972 
00973   return (uint16_t) (usart->RXDATAX);
00974 }
00975 
00976 
00977 /***************************************************************************/
00996 uint8_t USART_SpiTransfer(USART_TypeDef *usart, uint8_t data)
00997 {
00998   while (!(usart->STATUS & USART_STATUS_TXBL))
00999     ;
01000   usart->TXDATA = (uint32_t) data;
01001   while (!(usart->STATUS & USART_STATUS_TXC))
01002     ;
01003   return (uint8_t) (usart->RXDATA);
01004 }
01005 
01006 
01007 /***************************************************************************/
01030 void USART_Tx(USART_TypeDef *usart, uint8_t data)
01031 {
01032   /* Check that transmit buffer is empty */
01033   while (!(usart->STATUS & USART_STATUS_TXBL))
01034     ;
01035   usart->TXDATA = (uint32_t) data;
01036 }
01037 
01038 
01039 /***************************************************************************/
01066 void USART_TxDouble(USART_TypeDef *usart, uint16_t data)
01067 {
01068   /* Check that transmit buffer is empty */
01069   while (!(usart->STATUS & USART_STATUS_TXBL))
01070     ;
01071   usart->TXDOUBLE = (uint32_t) data;
01072 }
01073 
01074 
01075 /***************************************************************************/
01102 void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data)
01103 {
01104   /* Check that transmit buffer is empty */
01105   while (!(usart->STATUS & USART_STATUS_TXBL))
01106     ;
01107   usart->TXDOUBLEX = data;
01108 }
01109 
01110 
01111 /***************************************************************************/
01130 void USART_TxExt(USART_TypeDef *usart, uint16_t data)
01131 {
01132   /* Check that transmit buffer is empty */
01133   while (!(usart->STATUS & USART_STATUS_TXBL))
01134     ;
01135   usart->TXDATAX = (uint32_t) data;
01136 }
01137 
01138 
01141 #endif /* defined(USART_COUNT) && (USART_COUNT > 0) */