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 (USARTRF_COUNT == 1) && defined(USARTRF0)
00084 #define USARTRF_REF_VALID(ref)  ((ref) == USARTRF0)
00085 #else
00086 #define USARTRF_REF_VALID(ref)  (0)
00087 #endif
00088 
00089 #if defined( _EFM32_HAPPY_FAMILY )
00090 #define USART_IRDA_VALID(ref)    (((ref) == USART0) || ((ref) == USART1))
00091 #elif defined(USART0)
00092 #define USART_IRDA_VALID(ref)    ((ref) == USART0)
00093 #elif (USART_COUNT == 1) && defined(USART1)
00094 #define USART_IRDA_VALID(ref)    ((ref) == USART1)
00095 #else
00096 #define USART_IRDA_VALID(ref)    (0)
00097 #endif
00098 
00099 #if defined( _EFM32_HAPPY_FAMILY )
00100 #define USART_I2S_VALID(ref)    (((ref) == USART0) || ((ref) == USART1))
00101 #elif defined(_EFM32_TINY_FAMILY) || defined(_EFM32_ZERO_FAMILY)
00102 #define USART_I2S_VALID(ref)    ((ref) == USART1)
00103 #elif defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
00104 #define USART_I2S_VALID(ref)    (((ref) == USART1) || ((ref) == USART2))
00105 #endif
00106 
00107 #if (UART_COUNT == 1)
00108 #define UART_REF_VALID(ref)    ((ref) == UART0)
00109 #elif (UART_COUNT == 2)
00110 #define UART_REF_VALID(ref)    (((ref) == UART0) || ((ref) == UART1))
00111 #else
00112 #define UART_REF_VALID(ref)    (0)
00113 #endif
00114 
00118 /*******************************************************************************
00119  **************************   GLOBAL FUNCTIONS   *******************************
00120  ******************************************************************************/
00121 
00122 /***************************************************************************/
00144 void USART_BaudrateAsyncSet(USART_TypeDef *usart,
00145                             uint32_t refFreq,
00146                             uint32_t baudrate,
00147                             USART_OVS_TypeDef ovs)
00148 {
00149   uint32_t clkdiv;
00150   uint32_t oversample;
00151 
00152   /* Inhibit divide by 0 */
00153   EFM_ASSERT(baudrate);
00154 
00155   /*
00156    * We want to use integer division to avoid forcing in float division
00157    * utils, and yet keep rounding effect errors to a minimum.
00158    *
00159    * CLKDIV in asynchronous mode is given by:
00160    *
00161    * CLKDIV = 256 * (fHFPERCLK/(oversample * br) - 1)
00162    * or
00163    * CLKDIV = (256 * fHFPERCLK)/(oversample * br) - 256
00164    *
00165    * The basic problem with integer division in the above formula is that
00166    * the dividend (256 * fHFPERCLK) may become higher than max 32 bit
00167    * integer. Yet, we want to evaluate dividend first before dividing in
00168    * order to get as small rounding effects as possible. We do not want
00169    * to make too harsh restrictions on max fHFPERCLK value either.
00170    *
00171    * One can possibly factorize 256 and oversample/br. However,
00172    * since the last 6 bits of CLKDIV are don't care, we can base our
00173    * integer arithmetic on the below formula
00174    *
00175    * CLKDIV / 64 = (4 * fHFPERCLK)/(oversample * br) - 4
00176    *
00177    * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK
00178    * up to 1GHz without overflowing a 32 bit value!
00179    */
00180 
00181   /* HFPERCLK used to clock all USART/UART peripheral modules */
00182   if (!refFreq)
00183   {
00184     refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00185   }
00186 
00187   /* Map oversampling */
00188   switch (ovs)
00189   {
00190   case USART_CTRL_OVS_X16:
00191     EFM_ASSERT(baudrate <= (refFreq / 16));
00192     oversample = 16;
00193     break;
00194 
00195   case USART_CTRL_OVS_X8:
00196     EFM_ASSERT(baudrate <= (refFreq / 8));
00197     oversample = 8;
00198     break;
00199 
00200   case USART_CTRL_OVS_X6:
00201     EFM_ASSERT(baudrate <= (refFreq / 6));
00202     oversample = 6;
00203     break;
00204 
00205   case USART_CTRL_OVS_X4:
00206     EFM_ASSERT(baudrate <= (refFreq / 4));
00207     oversample = 4;
00208     break;
00209 
00210   default:
00211     /* Invalid input */
00212     EFM_ASSERT(0);
00213     return;
00214   }
00215 
00216   /* Calculate and set CLKDIV with fractional bits.
00217    * The addend (oversample*baudrate)/2 in the first line is to round the
00218    * divisor up by half the divisor before the division in order to reduce the
00219    * integer division error, which consequently results in a higher baudrate
00220    * than desired. */
00221   clkdiv  = 4 * refFreq + (oversample * baudrate) / 2;
00222   clkdiv /= (oversample * baudrate);
00223   clkdiv -= 4;
00224   clkdiv *= 64;
00225 
00226   /* Verify that resulting clock divider is within limits */
00227   EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00228 
00229   /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
00230   clkdiv &= _USART_CLKDIV_MASK;
00231 
00232   usart->CTRL  &= ~_USART_CTRL_OVS_MASK;
00233   usart->CTRL  |= ovs;
00234   usart->CLKDIV = clkdiv;
00235 }
00236 
00237 
00238 /***************************************************************************/
00266 uint32_t USART_BaudrateCalc(uint32_t refFreq,
00267                             uint32_t clkdiv,
00268                             bool syncmode,
00269                             USART_OVS_TypeDef ovs)
00270 {
00271   uint32_t oversample;
00272   uint32_t divisor;
00273   uint32_t factor;
00274   uint32_t remainder;
00275   uint32_t quotient;
00276   uint32_t br;
00277 
00278   /* Mask out unused bits */
00279   clkdiv &= _USART_CLKDIV_MASK;
00280 
00281   /* We want to use integer division to avoid forcing in float division */
00282   /* utils, and yet keep rounding effect errors to a minimum. */
00283 
00284   /* Baudrate calculation depends on if synchronous or asynchronous mode */
00285   if (syncmode)
00286   {
00287     /*
00288      * Baudrate is given by:
00289      *
00290      * br = fHFPERCLK/(2 * (1 + (CLKDIV / 256)))
00291      *
00292      * which can be rewritten to
00293      *
00294      * br = (128 * fHFPERCLK)/(256 + CLKDIV)
00295      */
00296     oversample = 1; /* Not used in sync mode, ie 1 */
00297     factor     = 128;
00298   }
00299   else
00300   {
00301     /*
00302      * Baudrate in asynchronous mode is given by:
00303      *
00304      * br = fHFPERCLK/(oversample * (1 + (CLKDIV / 256)))
00305      *
00306      * which can be rewritten to
00307      *
00308      * br = (256 * fHFPERCLK)/(oversample * (256 + CLKDIV))
00309      *
00310      * First of all we can reduce the 256 factor of the dividend with
00311      * (part of) oversample part of the divisor.
00312      */
00313 
00314     switch (ovs)
00315     {
00316     case USART_CTRL_OVS_X16:
00317       oversample = 1;
00318       factor     = 256 / 16;
00319       break;
00320 
00321     case USART_CTRL_OVS_X8:
00322       oversample = 1;
00323       factor     = 256 / 8;
00324       break;
00325 
00326     case USART_CTRL_OVS_X6:
00327       oversample = 3;
00328       factor     = 256 / 2;
00329       break;
00330 
00331     default:
00332       oversample = 1;
00333       factor     = 256 / 4;
00334       break;
00335     }
00336   }
00337 
00338   /*
00339    * The basic problem with integer division in the above formula is that
00340    * the dividend (factor * fHFPERCLK) may become higher than max 32 bit
00341    * integer. Yet we want to evaluate dividend first before dividing in
00342    * order to get as small rounding effects as possible. We do not want
00343    * to make too harsh restrictions on max fHFPERCLK value either.
00344    *
00345    * For division a/b, we can write
00346    *
00347    * a = qb + r
00348    *
00349    * where q is the quotient and r is the remainder, both integers.
00350    *
00351    * The orignal baudrate formula can be rewritten as
00352    *
00353    * br = xa / b = x(qb + r)/b = xq + xr/b
00354    *
00355    * where x is 'factor', a is 'refFreq' and b is 'divisor', referring to
00356    * variable names.
00357    */
00358 
00359   /* Divisor will never exceed max 32 bit value since clkdiv <= 0x1fffc0 */
00360   /* and 'oversample' has been reduced to <= 3. */
00361   divisor = oversample * (256 + clkdiv);
00362 
00363   quotient  = refFreq / divisor;
00364   remainder = refFreq % divisor;
00365 
00366   /* factor <= 128 and since divisor >= 256, the below cannot exceed max */
00367   /* 32 bit value. */
00368   br = factor * quotient;
00369 
00370   /*
00371    * factor <= 128 and remainder < (oversample*(256 + clkdiv)), which
00372    * means dividend (factor * remainder) worst case is
00373    * 128*(3 * (256 + 0x1fffc0)) = 0x30012000.
00374    */
00375   br += (factor * remainder) / divisor;
00376 
00377   return br;
00378 }
00379 
00380 
00381 /***************************************************************************/
00395 uint32_t USART_BaudrateGet(USART_TypeDef *usart)
00396 {
00397   uint32_t          freq;
00398   USART_OVS_TypeDef ovs;
00399   bool              syncmode;
00400 
00401   if (usart->CTRL & USART_CTRL_SYNC)
00402   {
00403     syncmode = true;
00404   }
00405   else
00406   {
00407     syncmode = false;
00408   }
00409 
00410   /* HFPERCLK used to clock all USART/UART peripheral modules */
00411   freq = CMU_ClockFreqGet(cmuClock_HFPER);
00412   ovs  = (USART_OVS_TypeDef) (usart->CTRL & _USART_CTRL_OVS_MASK);
00413   return USART_BaudrateCalc(freq, usart->CLKDIV, syncmode, ovs);
00414 }
00415 
00416 
00417 /***************************************************************************/
00444 void USART_BaudrateSyncSet(USART_TypeDef *usart, uint32_t refFreq, uint32_t baudrate)
00445 {
00446   uint32_t clkdiv;
00447 
00448   /* Inhibit divide by 0 */
00449   EFM_ASSERT(baudrate);
00450 
00451   /*
00452    * We want to use integer division to avoid forcing in float division
00453    * utils, and yet keep rounding effect errors to a minimum.
00454    *
00455    * CLKDIV in synchronous mode is given by:
00456    *
00457    * CLKDIV = 256 * (fHFPERCLK/(2 * br) - 1)
00458    * or
00459    * CLKDIV = (256 * fHFPERCLK)/(2 * br) - 256 = (128 * fHFPERCLK)/br - 256
00460    *
00461    * The basic problem with integer division in the above formula is that
00462    * the dividend (128 * fHFPERCLK) may become higher than max 32 bit
00463    * integer. Yet, we want to evaluate dividend first before dividing in
00464    * order to get as small rounding effects as possible. We do not want
00465    * to make too harsh restrictions on max fHFPERCLK value either.
00466    *
00467    * One can possibly factorize 128 and br. However, since the last
00468    * 6 bits of CLKDIV are don't care, we can base our integer arithmetic
00469    * on the below formula without loosing any extra precision:
00470    *
00471    * CLKDIV / 64 = (2 * fHFPERCLK)/br - 4
00472    *
00473    * and calculate 1/64 of CLKDIV first. This allows for fHFPERCLK
00474    * up to 2GHz without overflowing a 32 bit value!
00475    */
00476 
00477   /* HFPERCLK used to clock all USART/UART peripheral modules */
00478   if (!refFreq)
00479   {
00480     refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00481   }
00482 
00483   /* Calculate and set CLKDIV with fractional bits */
00484   clkdiv  = 2 * refFreq;
00485   clkdiv += baudrate - 1;
00486   clkdiv /= baudrate;
00487   clkdiv -= 4;
00488   clkdiv *= 64;
00489   /* Make sure we don't use fractional bits by rounding CLKDIV */
00490   /* up (and thus reducing baudrate, not increasing baudrate above */
00491   /* specified value). */
00492   clkdiv += 0xc0;
00493   clkdiv &= 0xffffff00;
00494 
00495   /* Verify that resulting clock divider is within limits */
00496   EFM_ASSERT(clkdiv <= _USART_CLKDIV_MASK);
00497 
00498   /* If EFM_ASSERT is not enabled, make sure we don't write to reserved bits */
00499   clkdiv &= _USART_CLKDIV_DIV_MASK;
00500 
00501   usart->CLKDIV = clkdiv;
00502 }
00503 
00504 
00505 /***************************************************************************/
00520 void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable)
00521 {
00522   uint32_t tmp;
00523 
00524   /* Make sure the module exists on the selected chip */
00525   EFM_ASSERT( USART_REF_VALID(usart)
00526               || USARTRF_REF_VALID(usart)
00527               || UART_REF_VALID(usart) );
00528 
00529   /* Disable as specified */
00530   tmp        = ~((uint32_t) (enable));
00531   tmp       &= _USART_CMD_RXEN_MASK | _USART_CMD_TXEN_MASK;
00532   usart->CMD = tmp << 1;
00533 
00534   /* Enable as specified */
00535   usart->CMD = (uint32_t) (enable);
00536 }
00537 
00538 
00539 /***************************************************************************/
00562 void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init)
00563 {
00564   /* Make sure the module exists on the selected chip */
00565   EFM_ASSERT( USART_REF_VALID(usart)
00566               || USARTRF_REF_VALID(usart)
00567               || UART_REF_VALID(usart) );
00568 
00569   /* Init USART registers to HW reset state. */
00570   USART_Reset(usart);
00571 
00572 #if defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
00573   /* Disable majority vote if specified. */
00574   if (init->mvdis)
00575   {
00576     usart->CTRL |= USART_CTRL_MVDIS;
00577   }
00578 
00579   /* Configure PRS input mode. */
00580   if (init->prsRxEnable)
00581   {
00582     usart->INPUT = (uint32_t) init->prsRxCh | USART_INPUT_RXPRS;
00583   }
00584 #endif
00585 
00586   /* Configure databits, stopbits and parity */
00587   usart->FRAME = (uint32_t) (init->databits) |
00588                  (uint32_t) (init->stopbits) |
00589                  (uint32_t) (init->parity);
00590 
00591   /* Configure baudrate */
00592   USART_BaudrateAsyncSet(usart, init->refFreq, init->baudrate, init->oversampling);
00593 
00594   /* Finally enable (as specified) */
00595   usart->CMD = (uint32_t) (init->enable);
00596 }
00597 
00598 
00599 /***************************************************************************/
00623 void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init)
00624 {
00625   /* Make sure the module exists on the selected chip */
00626   EFM_ASSERT( USART_REF_VALID(usart) || USARTRF_REF_VALID(usart) );
00627 
00628   /* Init USART registers to HW reset state. */
00629   USART_Reset(usart);
00630 
00631   /* Set bits for synchronous mode */
00632   usart->CTRL |= (USART_CTRL_SYNC) |
00633                  ((uint32_t) init->clockMode) |
00634                  (init->msbf ? USART_CTRL_MSBF : 0);
00635 
00636 #if defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN)
00637   usart->CTRL |= (init->prsRxEnable ? USART_INPUT_RXPRS : 0) |
00638                  (init->autoTx      ? USART_CTRL_AUTOTX : 0);
00639 #endif
00640 
00641   /* Configure databits, leave stopbits and parity at reset default (not used) */
00642   usart->FRAME = ((uint32_t) (init->databits)) |
00643                  (USART_FRAME_STOPBITS_DEFAULT) |
00644                  (USART_FRAME_PARITY_DEFAULT);
00645 
00646   /* Configure baudrate */
00647   USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate);
00648 
00649   /* Finally enable (as specified) */
00650   if (init->master)
00651   {
00652     usart->CMD = USART_CMD_MASTEREN;
00653   }
00654 
00655   usart->CMD = (uint32_t) (init->enable);
00656 }
00657 
00658 
00659 #if defined(USART0) || ((USART_COUNT == 1) && defined(USART1))
00660 /***************************************************************************/
00686 void USART_InitIrDA(const USART_InitIrDA_TypeDef *init)
00687 {
00688   #if (USART_COUNT == 1) && defined(USART1)
00689   USART_TypeDef *usart = USART1;
00690   #else
00691   USART_TypeDef *usart = USART0;
00692   #endif
00693 
00694   /* Init USART as async device */
00695   USART_InitAsync(usart, &(init->async));
00696 
00697   /* Set IrDA modulation to RZI (return-to-zero-inverted) */
00698   usart->CTRL |= USART_CTRL_TXINV;
00699 
00700   /* Invert Rx signal before demodulator if enabled */
00701   if (init->irRxInv)
00702   {
00703     usart->CTRL |= USART_CTRL_RXINV;
00704   }
00705 
00706   /* Configure IrDA */
00707   usart->IRCTRL |= (uint32_t) init->irPw |
00708                    (uint32_t) init->irPrsSel |
00709                    ((uint32_t) init->irFilt << _USART_IRCTRL_IRFILT_SHIFT) |
00710                    ((uint32_t) init->irPrsEn << _USART_IRCTRL_IRPRSEN_SHIFT);
00711 
00712   /* Enable IrDA */
00713   usart->IRCTRL |= USART_IRCTRL_IREN;
00714 }
00715 #endif
00716 
00717 
00718 #if defined(_USART_I2SCTRL_MASK)
00719 /***************************************************************************/
00748 void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init)
00749 {
00750   USART_Enable_TypeDef enable;
00751 
00752   /* Make sure the module exists on the selected chip */
00753   EFM_ASSERT(USART_I2S_VALID(usart));
00754 
00755   /* Override the enable setting. */
00756   enable            = init->sync.enable;
00757   init->sync.enable = usartDisable;
00758 
00759   /* Init USART as a sync device. */
00760   USART_InitSync(usart, &init->sync);
00761 
00762   /* Configure and enable I2CCTRL register acording to selected mode. */
00763   usart->I2SCTRL = ((uint32_t) init->format) |
00764                    ((uint32_t) init->justify) |
00765                    (init->delay    ? USART_I2SCTRL_DELAY    : 0) |
00766                    (init->dmaSplit ? USART_I2SCTRL_DMASPLIT : 0) |
00767                    (init->mono     ? USART_I2SCTRL_MONO     : 0) |
00768                    (USART_I2SCTRL_EN);
00769 
00770   if (enable != usartDisable)
00771   {
00772     USART_Enable(usart, enable);
00773   }
00774 }
00775 #endif
00776 
00777 
00778 /***************************************************************************/
00787 void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init)
00788 {
00789   uint32_t trigctrl;
00790 
00791   /* Clear values that will be reconfigured  */
00792   trigctrl = usart->TRIGCTRL & ~(_USART_TRIGCTRL_RXTEN_MASK |
00793                                  _USART_TRIGCTRL_TXTEN_MASK |
00794 #if defined(USART_TRIGCTRL_AUTOTXTEN)
00795                                  _USART_TRIGCTRL_AUTOTXTEN_MASK |
00796 #endif
00797                                  _USART_TRIGCTRL_TSEL_MASK);
00798 
00799 #if defined(USART_TRIGCTRL_AUTOTXTEN)
00800   if (init->autoTxTriggerEnable)
00801   {
00802     trigctrl |= USART_TRIGCTRL_AUTOTXTEN;
00803   }
00804 #endif
00805   if (init->txTriggerEnable)
00806   {
00807     trigctrl |= USART_TRIGCTRL_TXTEN;
00808   }
00809   if (init->rxTriggerEnable)
00810   {
00811     trigctrl |= USART_TRIGCTRL_RXTEN;
00812   }
00813   trigctrl |= init->prsTriggerChannel;
00814 
00815   /* Enable new configuration */
00816   usart->TRIGCTRL = trigctrl;
00817 }
00818 
00819 
00820 /***************************************************************************/
00827 void USART_Reset(USART_TypeDef *usart)
00828 {
00829   /* Make sure the module exists on the selected chip */
00830   EFM_ASSERT( USART_REF_VALID(usart)
00831               || USARTRF_REF_VALID(usart)
00832               || UART_REF_VALID(usart) );
00833 
00834   /* Make sure disabled first, before resetting other registers */
00835   usart->CMD = USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS |
00836                USART_CMD_RXBLOCKDIS | USART_CMD_TXTRIDIS | USART_CMD_CLEARTX | USART_CMD_CLEARRX;
00837   usart->CTRL     = _USART_CTRL_RESETVALUE;
00838   usart->FRAME    = _USART_FRAME_RESETVALUE;
00839   usart->TRIGCTRL = _USART_TRIGCTRL_RESETVALUE;
00840   usart->CLKDIV   = _USART_CLKDIV_RESETVALUE;
00841   usart->IEN      = _USART_IEN_RESETVALUE;
00842   usart->IFC      = _USART_IFC_MASK;
00843   usart->ROUTE    = _USART_ROUTE_RESETVALUE;
00844 
00845   if (USART_IRDA_VALID(usart))
00846   {
00847     usart->IRCTRL = _USART_IRCTRL_RESETVALUE;
00848   }
00849 
00850 #if defined(_USART_INPUT_RESETVALUE)
00851   usart->INPUT = _USART_INPUT_RESETVALUE;
00852 #endif
00853 
00854 #if defined(_USART_I2SCTRL_RESETVALUE)
00855   if (USART_I2S_VALID(usart))
00856   {
00857     usart->I2SCTRL = _USART_I2SCTRL_RESETVALUE;
00858   }
00859 #endif
00860 }
00861 
00862 
00863 /***************************************************************************/
00887 uint8_t USART_Rx(USART_TypeDef *usart)
00888 {
00889   while (!(usart->STATUS & USART_STATUS_RXDATAV))
00890     ;
00891 
00892   return (uint8_t) (usart->RXDATA);
00893 }
00894 
00895 
00896 /***************************************************************************/
00920 uint16_t USART_RxDouble(USART_TypeDef *usart)
00921 {
00922   while (!(usart->STATUS & USART_STATUS_RXFULL))
00923     ;
00924 
00925   return (uint16_t) (usart->RXDOUBLE);
00926 }
00927 
00928 
00929 /***************************************************************************/
00953 uint32_t USART_RxDoubleExt(USART_TypeDef *usart)
00954 {
00955   while (!(usart->STATUS & USART_STATUS_RXFULL))
00956     ;
00957 
00958   return usart->RXDOUBLEX;
00959 }
00960 
00961 
00962 /***************************************************************************/
00986 uint16_t USART_RxExt(USART_TypeDef *usart)
00987 {
00988   while (!(usart->STATUS & USART_STATUS_RXDATAV))
00989     ;
00990 
00991   return (uint16_t) (usart->RXDATAX);
00992 }
00993 
00994 
00995 /***************************************************************************/
01014 uint8_t USART_SpiTransfer(USART_TypeDef *usart, uint8_t data)
01015 {
01016   while (!(usart->STATUS & USART_STATUS_TXBL))
01017     ;
01018   usart->TXDATA = (uint32_t) data;
01019   while (!(usart->STATUS & USART_STATUS_TXC))
01020     ;
01021   return (uint8_t) (usart->RXDATA);
01022 }
01023 
01024 
01025 /***************************************************************************/
01048 void USART_Tx(USART_TypeDef *usart, uint8_t data)
01049 {
01050   /* Check that transmit buffer is empty */
01051   while (!(usart->STATUS & USART_STATUS_TXBL))
01052     ;
01053   usart->TXDATA = (uint32_t) data;
01054 }
01055 
01056 
01057 /***************************************************************************/
01084 void USART_TxDouble(USART_TypeDef *usart, uint16_t data)
01085 {
01086   /* Check that transmit buffer is empty */
01087   while (!(usart->STATUS & USART_STATUS_TXBL))
01088     ;
01089   usart->TXDOUBLE = (uint32_t) data;
01090 }
01091 
01092 
01093 /***************************************************************************/
01120 void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data)
01121 {
01122   /* Check that transmit buffer is empty */
01123   while (!(usart->STATUS & USART_STATUS_TXBL))
01124     ;
01125   usart->TXDOUBLEX = data;
01126 }
01127 
01128 
01129 /***************************************************************************/
01148 void USART_TxExt(USART_TypeDef *usart, uint16_t data)
01149 {
01150   /* Check that transmit buffer is empty */
01151   while (!(usart->STATUS & USART_STATUS_TXBL))
01152     ;
01153   usart->TXDATAX = (uint32_t) data;
01154 }
01155 
01156 
01159 #endif /* defined(USART_COUNT) && (USART_COUNT > 0) */