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) && 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  **************************   GLOBAL FUNCTIONS   *******************************
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   /* Inhibit divide by 0 */
00159   EFM_ASSERT(baudrate);
00160 
00161   /*
00162    * We want to use integer division to avoid forcing in float division
00163    * utils, and yet keep rounding effect errors to a minimum.
00164    *
00165    * CLKDIV in asynchronous mode is given by:
00166    *
00167    * CLKDIV = 256 * (fHFPERCLK/(oversample * br) - 1)
00168    * or
00169    * CLKDIV = (256 * fHFPERCLK)/(oversample * br) - 256
00170    *
00171    * The basic problem with integer division in the above formula is that
00172    * the dividend (256 * fHFPERCLK) may become higher than max 32 bit
00173    * integer. Yet, we want to evaluate dividend first before dividing in
00174    * order to get as small rounding effects as possible. We do not want
00175    * to make too harsh restrictions on max fHFPERCLK value either.
00176    *
00177    * One can possibly factorize 256 and oversample/br. However,
00178    * since the last 6 bits of CLKDIV are don't care, we can base our
00179    * integer arithmetic on the below formula
00180    *
00181    * CLKDIV / 64 = (4 * fHFPERCLK)/(oversample * br) - 4
00182    *
00183    * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK
00184    * up to 1GHz without overflowing a 32 bit value!
00185    */
00186 
00187   /* HFPERCLK used to clock all USART/UART peripheral modules */
00188   if (!refFreq)
00189   {
00190     refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00191   }
00192 
00193   /* Map oversampling */
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     /* Invalid input */
00218     EFM_ASSERT(0);
00219     return;
00220   }
00221 
00222   /* Calculate and set CLKDIV with fractional bits.
00223    * The addend (oversample*baudrate)/2 in the first line is to round the
00224    * divisor up by half the divisor before the division in order to reduce the
00225    * integer division error, which consequently results in a higher baudrate
00226    * than desired. */
00227   clkdiv  = 4 * refFreq + (oversample * baudrate) / 2;
00228   clkdiv /= (oversample * baudrate);
00229   clkdiv -= 4;
00230   clkdiv *= 64;
00231 
00232   /* Verify that resulting clock divider is within limits */
00233   EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00234 
00235   /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
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   /* Mask out unused bits */
00285   clkdiv &= _USART_CLKDIV_MASK;
00286 
00287   /* We want to use integer division to avoid forcing in float division */
00288   /* utils, and yet keep rounding effect errors to a minimum. */
00289 
00290   /* Baudrate calculation depends on if synchronous or asynchronous mode */
00291   if (syncmode)
00292   {
00293     /*
00294      * Baudrate is given by:
00295      *
00296      * br = fHFPERCLK/(2 * (1 + (CLKDIV / 256)))
00297      *
00298      * which can be rewritten to
00299      *
00300      * br = (128 * fHFPERCLK)/(256 + CLKDIV)
00301      */
00302     oversample = 1; /* Not used in sync mode, ie 1 */
00303     factor     = 128;
00304   }
00305   else
00306   {
00307     /*
00308      * Baudrate in asynchronous mode is given by:
00309      *
00310      * br = fHFPERCLK/(oversample * (1 + (CLKDIV / 256)))
00311      *
00312      * which can be rewritten to
00313      *
00314      * br = (256 * fHFPERCLK)/(oversample * (256 + CLKDIV))
00315      *
00316      * First of all we can reduce the 256 factor of the dividend with
00317      * (part of) oversample part of the divisor.
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    * The basic problem with integer division in the above formula is that
00346    * the dividend (factor * fHFPERCLK) may become higher than max 32 bit
00347    * integer. Yet we want to evaluate dividend first before dividing in
00348    * order to get as small rounding effects as possible. We do not want
00349    * to make too harsh restrictions on max fHFPERCLK value either.
00350    *
00351    * For division a/b, we can write
00352    *
00353    * a = qb + r
00354    *
00355    * where q is the quotient and r is the remainder, both integers.
00356    *
00357    * The orignal baudrate formula can be rewritten as
00358    *
00359    * br = xa / b = x(qb + r)/b = xq + xr/b
00360    *
00361    * where x is 'factor', a is 'refFreq' and b is 'divisor', referring to
00362    * variable names.
00363    */
00364 
00365   /* Divisor will never exceed max 32 bit value since clkdiv <= 0x1fffc0 */
00366   /* and 'oversample' has been reduced to <= 3. */
00367   divisor = oversample * (256 + clkdiv);
00368 
00369   quotient  = refFreq / divisor;
00370   remainder = refFreq % divisor;
00371 
00372   /* factor <= 128 and since divisor >= 256, the below cannot exceed max */
00373   /* 32 bit value. */
00374   br = factor * quotient;
00375 
00376   /*
00377    * factor <= 128 and remainder < (oversample*(256 + clkdiv)), which
00378    * means dividend (factor * remainder) worst case is
00379    * 128*(3 * (256 + 0x1fffc0)) = 0x30012000.
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   /* HFPERCLK used to clock all USART/UART peripheral modules */
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   /* Inhibit divide by 0 */
00455   EFM_ASSERT(baudrate);
00456 
00457   /*
00458    * We want to use integer division to avoid forcing in float division
00459    * utils, and yet keep rounding effect errors to a minimum.
00460    *
00461    * CLKDIV in synchronous mode is given by:
00462    *
00463    * CLKDIV = 256 * (fHFPERCLK/(2 * br) - 1)
00464    * or
00465    * CLKDIV = (256 * fHFPERCLK)/(2 * br) - 256 = (128 * fHFPERCLK)/br - 256
00466    *
00467    * The basic problem with integer division in the above formula is that
00468    * the dividend (128 * fHFPERCLK) may become higher than max 32 bit
00469    * integer. Yet, we want to evaluate dividend first before dividing in
00470    * order to get as small rounding effects as possible. We do not want
00471    * to make too harsh restrictions on max fHFPERCLK value either.
00472    *
00473    * One can possibly factorize 128 and br. However, since the last
00474    * 6 bits of CLKDIV are don't care, we can base our integer arithmetic
00475    * on the below formula without loosing any extra precision:
00476    *
00477    * CLKDIV / 64 = (2 * fHFPERCLK)/br - 4
00478    *
00479    * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK
00480    * up to 2GHz without overflowing a 32 bit value!
00481    */
00482 
00483   /* HFPERCLK used to clock all USART/UART peripheral modules */
00484   if (!refFreq)
00485   {
00486     refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00487   }
00488 
00489   /* Calculate and set CLKDIV with fractional bits */
00490   clkdiv  = 2 * refFreq;
00491   clkdiv += baudrate - 1;
00492   clkdiv /= baudrate;
00493   clkdiv -= 4;
00494   clkdiv *= 64;
00495   /* Make sure we don't use fractional bits by rounding CLKDIV */
00496   /* up (and thus reducing baudrate, not increasing baudrate above */
00497   /* specified value). */
00498   clkdiv += 0xc0;
00499   clkdiv &= 0xffffff00;
00500 
00501   /* Verify that resulting clock divider is within limits */
00502   EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00503 
00504   /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
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   /* Make sure the module exists on the selected chip */
00531   EFM_ASSERT( USART_REF_VALID(usart)
00532               || USARTRF_REF_VALID(usart)
00533               || UART_REF_VALID(usart) );
00534 
00535   /* Disable as specified */
00536   tmp        = ~((uint32_t) (enable));
00537   tmp       &= _USART_CMD_RXEN_MASK | _USART_CMD_TXEN_MASK;
00538   usart->CMD = tmp << 1;
00539 
00540   /* Enable as specified */
00541   usart->CMD = (uint32_t) (enable);
00542 }
00543 
00544 
00545 /***************************************************************************/
00568 void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init)
00569 {
00570   /* Make sure the module exists on the selected chip */
00571   EFM_ASSERT( USART_REF_VALID(usart)
00572               || USARTRF_REF_VALID(usart)
00573               || UART_REF_VALID(usart) );
00574 
00575   /* Init USART registers to HW reset state. */
00576   USART_Reset(usart);
00577 
00578 #if defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
00579   /* Disable majority vote if specified. */
00580   if (init->mvdis)
00581   {
00582     usart->CTRL |= USART_CTRL_MVDIS;
00583   }
00584 
00585   /* Configure PRS input mode. */
00586   if (init->prsRxEnable)
00587   {
00588     usart->INPUT = (uint32_t) init->prsRxCh | USART_INPUT_RXPRS;
00589   }
00590 #endif
00591 
00592   /* Configure databits, stopbits and parity */
00593   usart->FRAME = (uint32_t) (init->databits) |
00594                  (uint32_t) (init->stopbits) |
00595                  (uint32_t) (init->parity);
00596 
00597   /* Configure baudrate */
00598   USART_BaudrateAsyncSet(usart, init->refFreq, init->baudrate, init->oversampling);
00599 
00600   /* Finally enable (as specified) */
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   /* Make sure the module exists on the selected chip */
00632   EFM_ASSERT( USART_REF_VALID(usart) || USARTRF_REF_VALID(usart) );
00633 
00634   /* Init USART registers to HW reset state. */
00635   USART_Reset(usart);
00636 
00637   /* Set bits for synchronous mode */
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   /* Configure databits, leave stopbits and parity at reset default (not used) */
00648   usart->FRAME = ((uint32_t) (init->databits)) |
00649                  (USART_FRAME_STOPBITS_DEFAULT) |
00650                  (USART_FRAME_PARITY_DEFAULT);
00651 
00652   /* Configure baudrate */
00653   USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate);
00654 
00655   /* Finally enable (as specified) */
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   /* Init USART as async device */
00701   USART_InitAsync(usart, &(init->async));
00702 
00703   /* Set IrDA modulation to RZI (return-to-zero-inverted) */
00704   usart->CTRL |= USART_CTRL_TXINV;
00705 
00706   /* Invert Rx signal before demodulator if enabled */
00707   if (init->irRxInv)
00708   {
00709     usart->CTRL |= USART_CTRL_RXINV;
00710   }
00711 
00712   /* Configure IrDA */
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   /* Enable IrDA */
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   /* Make sure the module exists on the selected chip */
00759   EFM_ASSERT(USART_I2S_VALID(usart));
00760 
00761   /* Override the enable setting. */
00762   enable            = init->sync.enable;
00763   init->sync.enable = usartDisable;
00764 
00765   /* Init USART as a sync device. */
00766   USART_InitSync(usart, &init->sync);
00767 
00768   /* Configure and enable I2CCTRL register acording to selected mode. */
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   /* Clear values that will be reconfigured  */
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   /* Enable new configuration */
00822   usart->TRIGCTRL = trigctrl;
00823 }
00824 
00825 
00826 /***************************************************************************/
00833 void USART_Reset(USART_TypeDef *usart)
00834 {
00835   /* Make sure the module exists on the selected chip */
00836   EFM_ASSERT( USART_REF_VALID(usart)
00837               || USARTRF_REF_VALID(usart)
00838               || UART_REF_VALID(usart) );
00839 
00840   /* Make sure disabled first, before resetting other registers */
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   /* Check that transmit buffer is empty */
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   /* Check that transmit buffer is empty */
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   /* Check that transmit buffer is empty */
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   /* Check that transmit buffer is empty */
01157   while (!(usart->STATUS & USART_STATUS_TXBL))
01158     ;
01159   usart->TXDATAX = (uint32_t) data;
01160 }
01161 
01162 
01165 #endif /* defined(USART_COUNT) && (USART_COUNT > 0) */