BeRTOS
ser_xmega.c
Go to the documentation of this file.
00001 
00043 #include "hw/hw_ser.h"     /* Required for bus macros overrides */
00044 #include <hw/hw_cpufreq.h> /* CPU_FREQ */
00045 
00046 #include "cfg/cfg_ser.h"   /* Serialport configuration settings */
00047 
00048 #include <cfg/macros.h>    /* DIV_ROUND */
00049 #include <cfg/debug.h>     /* debug configuration */
00050 
00051 #include <drv/ser.h>
00052 #include <drv/ser_p.h>
00053 #include <drv/timer.h>
00054 
00055 #include <struct/fifobuf.h>
00056 
00057 #include <avr/io.h>        /* AVR IO ports and structures */
00058 #include <avr/interrupt.h> /* AVR Interrupt methods */
00059 
00060 /*
00061  * Scalefactor to use for computing the baudrate
00062  * this scalefactor should be an integer value between -7
00063  * and 7
00064  */
00065 #ifndef USART_SCALE_FACTOR
00066     #define USART_SCALE_FACTOR (-7)
00067 #else
00068     #if USART_SCALE_FACTOR > 7 || USART_SCALE_FACTOR < -7
00069         #error USART_SCALE_FACTOR should be an integer between -7 and 7
00070     #endif
00071 #endif
00072 
00073 /* Helper macros, mostly taken from the Atmel Examples
00074  * Slightly alterd to match the BeRTOS naming convention
00075  */
00076 
00077 /* \brief Set USART baud rate.
00078  *
00079  *  Sets the USART's baud rate register.
00080  *
00081  *  UBRR_Value   : Value written to UBRR
00082  *  ScaleFactor  : Time Base Generator Scale Factor
00083  *
00084  *  Equation for calculation of BSEL value in asynchronous normal speed mode:
00085  *      If ScaleFactor >= 0
00086  *          BSEL = ((I/O clock frequency)/(2^(ScaleFactor)*16*Baudrate))-1
00087  *      If ScaleFactor < 0
00088  *          BSEL = (1/(2^(ScaleFactor)*16))*(((I/O clock frequency)/Baudrate)-1)
00089  *
00090  *  \note See XMEGA manual for equations for calculation of BSEL value in other
00091  *        modes.
00092  *
00093  *  \param _usart          Pointer to the USART module.
00094  *  \param _bselValue      Value to write to BSEL part of Baud control register.
00095  *                         Use uint16_t type.
00096  *  \param _bScaleFactor   USART baud rate scale factor.
00097  *                         Use uint8_t type
00098  */
00099 #define USART_SET_BAUDRATE(_usart, _bselValue, _bScaleFactor)                  \
00100     (_usart)->BAUDCTRLA =(uint8_t)_bselValue;                                           \
00101     (_usart)->BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)
00102 
00103 /* \brief Enable USART receiver.
00104  *
00105  *  \param _usart    Pointer to the USART module
00106  */
00107 #define USART_RX_ENABLE(_usart) ((_usart)->CTRLB |= USART_RXEN_bm)
00108 
00109 /* \brief Disable USART receiver.
00110  *
00111  *  \param _usart Pointer to the USART module.
00112  */
00113 #define USART_RX_DISABLE(_usart) ((_usart)->CTRLB &= ~USART_RXEN_bm)
00114 
00115 /* \brief Enable USART transmitter.
00116  *
00117  *  \param _usart Pointer to the USART module.
00118  */
00119 #define USART_TX_ENABLE(_usart) ((_usart)->CTRLB |= USART_TXEN_bm)
00120 
00121 /* \brief Disable USART transmitter.
00122  *
00123  *  \param _usart Pointer to the USART module.
00124  */
00125 #define USART_TX_DISABLE(_usart) ((_usart)->CTRLB &= ~USART_TXEN_bm)
00126 
00127 /* \brief Set USART RXD interrupt level.
00128  *
00129  *  Sets the interrupt level on RX Complete interrupt.
00130  *
00131  *  \param _usart        Pointer to the USART module.
00132  *  \param _rxdIntLevel  Interrupt level of the RXD interrupt.
00133  *                       Use USART_RXCINTLVL_t type.
00134  */
00135 #define USART_SET_RX_INTERRUPT_LEVEL(_usart, _rxdIntLevel)                      \
00136     ((_usart)->CTRLA = ((_usart)->CTRLA & ~USART_RXCINTLVL_gm) | _rxdIntLevel)
00137 
00138 /* \brief Set USART TXD interrupt level.
00139  *
00140  *  Sets the interrupt level on TX Complete interrupt.
00141  *
00142  *  \param _usart        Pointer to the USART module.
00143  *  \param _txdIntLevel  Interrupt level of the TXD interrupt.
00144  *                       Use USART_TXCINTLVL_t type.
00145  */
00146 #define USART_SET_TX_INTERRUPT_LEVEL(_usart, _txdIntLevel)                      \
00147     (_usart)->CTRLA = ((_usart)->CTRLA & ~USART_TXCINTLVL_gm) | _txdIntLevel
00148 
00149 /* \brief Set USART DRE interrupt level.
00150  *
00151  *  Sets the interrupt level on Data Register interrupt.
00152  *
00153  *  \param _usart        Pointer to the USART module.
00154  *  \param _dreIntLevel  Interrupt level of the DRE interrupt.
00155  *                       Use USART_DREINTLVL_t type.
00156  */
00157 #define USART_SET_DRE_INTERRUPT_LEVEL(_usart, _dreIntLevel)                      \
00158     (_usart)->CTRLA = ((_usart)->CTRLA & ~USART_DREINTLVL_gm) | _dreIntLevel
00159 
00160 /* \brief Set the mode the USART run in.
00161  *
00162  * Set the mode the USART run in. The default mode is asynchronous mode.
00163  *
00164  *  \param  _usart       Pointer to the USART module register section.
00165  *  \param  _usartMode   Selects the USART mode. Use  USART_CMODE_t type.
00166  *
00167  *  USART modes:
00168  *  - 0x0        : Asynchronous mode.
00169  *  - 0x1        : Synchronous mode.
00170  *  - 0x2        : IrDA mode.
00171  *  - 0x3        : Master SPI mode.
00172  */
00173 #define USART_SET_MODE(_usart, _usartMode)                                      \
00174     ((_usart)->CTRLC = ((_usart)->CTRLC & (~USART_CMODE_gm)) | _usartMode)
00175 
00176 /* \brief Check if data register empty flag is set.
00177  *
00178  *  \param _usart      The USART module.
00179  */
00180 #define USART_IS_TX_DATA_REGISTER_EMPTY(_usart) (((_usart)->STATUS & USART_DREIF_bm) != 0)
00181 
00182 /* \brief Put data (5-8 bit character).
00183  *
00184  *  Use the macro USART_IsTXDataRegisterEmpty before using this function to
00185  *  put data to the TX register.
00186  *
00187  *  \param _usart      The USART module.
00188  *  \param _data       The data to send.
00189  */
00190 #define USART_PUT_CHAR(_usart, _data) ((_usart)->DATA = _data)
00191 
00192 /* \brief Checks if the RX complete interrupt flag is set.
00193  *
00194  *   Checks if the RX complete interrupt flag is set.
00195  *
00196  *  \param _usart     The USART module.
00197  */
00198 #define USART_IS_RX_COMPLETE(_usart) (((_usart)->STATUS & USART_RXCIF_bm) != 0)
00199 
00200 /* \brief Get received data (5-8 bit character).
00201  *
00202  *  This macro reads out the RX register.
00203  *  Use the macro USART_RX_Complete to check if anything is received.
00204  *
00205  *  \param _usart     The USART module.
00206  *
00207  *  \retval           Received data.
00208  */
00209 #define USART_GET_CHAR(_usart)  ((_usart)->DATA)
00210 
00211 /* configurable macros */
00212 
00213 #if !CONFIG_SER_HWHANDSHAKE
00214 
00218     #define RTS_ON      do {} while (0)
00219     #define RTS_OFF     do {} while (0)
00220     #define IS_CTS_ON   true
00221     #define EIMSKF_CTS  0 
00222     /*\}*/
00223 #endif
00224 
00225 /*
00226  * \name Overridable serial bus hooks
00227  *
00228  * These can be redefined in hw.h to implement
00229  * special bus policies such as half-duplex, 485, etc.
00230  *
00231  *
00232  * \code
00233  *  TXBEGIN      TXCHAR      TXEND  TXOFF
00234  *    |   __________|__________ |     |
00235  *    |   |   |   |   |   |   | |     |
00236  *    v   v   v   v   v   v   v v     v
00237  * ______  __  __  __  __  __  __  ________________
00238  *       \/  \/  \/  \/  \/  \/  \/
00239  * ______/\__/\__/\__/\__/\__/\__/
00240  *
00241  * \endcode
00242  *
00243  * \{
00244  */
00245 
00246 #ifndef SER_UART_BUS_TXINIT
00247     /*
00248      * Default TXINIT macro - invoked in uart_init()
00249      *
00250      * - Enable both the receiver and the transmitter
00251      * - Enable only the RX complete interrupt
00252      */
00253     #define SER_UART_BUS_TXINIT(_usart) do { \
00254         USART_RX_ENABLE(_usart); \
00255         USART_TX_ENABLE(_usart); \
00256         USART_SET_RX_INTERRUPT_LEVEL(_usart, USART_RXCINTLVL_MED_gc); \
00257     } while (0)
00258 #endif
00259 
00260 #ifndef SER_UART_BUS_TXBEGIN
00261     /*
00262      * Invoked before starting a transmission
00263      *
00264      * - Enable both the receiver and the transmitter
00265      * - Enable both the RX complete and UDR empty interrupts
00266      */
00267     #define SER_UART_BUS_TXBEGIN(_usart) do { \
00268         USART_SET_RX_INTERRUPT_LEVEL(_usart, USART_RXCINTLVL_MED_gc); \
00269         USART_SET_DRE_INTERRUPT_LEVEL(_usart, USART_DREINTLVL_MED_gc);\
00270     } while (0)
00271 #endif
00272 
00273 #ifndef SER_UART_BUS_TXCHAR
00274     /*
00275      * Invoked to send one character.
00276      */
00277     #define SER_UART_BUS_TXCHAR(_usart, c) do { \
00278         USART_PUT_CHAR(_usart, c); \
00279     } while (0)
00280 #endif
00281 
00282 #ifndef SER_UART_BUS_TXEND
00283     /*
00284      * Invoked as soon as the txfifo becomes empty
00285      *
00286      * - Keep both the receiver and the transmitter enabled
00287      * - Keep the RX complete interrupt enabled
00288      * - Disable the UDR empty interrupt
00289      */
00290     #define SER_UART_BUS_TXEND(_usart) do { \
00291         USART_SET_DRE_INTERRUPT_LEVEL(_usart, USART_DREINTLVL_OFF_gc); \
00292     } while (0)
00293 #endif
00294 
00295 #ifndef SER_UART_BUS_TXOFF
00296     /*
00297      * \def SER_UART_BUS_TXOFF
00298      *
00299      * Invoked after the last character has been transmitted
00300      *
00301      * The default is no action.
00302      */
00303     #ifdef __doxygen__
00304     #define SER_UART_BUS_TXOFF(_usart)
00305     #endif
00306 #endif
00307 
00308 /*\}*/
00309 
00310 /* From the high-level serial driver */
00311 extern struct Serial *ser_handles[SER_CNT];
00312 
00313 /* TX and RX buffers */
00314 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
00315 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
00316 static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
00317 static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
00318 #ifdef CPU_AVR_XMEGA_A
00319 static unsigned char uart2_txbuffer[CONFIG_UART2_TXBUFSIZE];
00320 static unsigned char uart2_rxbuffer[CONFIG_UART2_RXBUFSIZE];
00321 static unsigned char uart3_txbuffer[CONFIG_UART3_TXBUFSIZE];
00322 static unsigned char uart3_rxbuffer[CONFIG_UART3_RXBUFSIZE];
00323 static unsigned char uart4_txbuffer[CONFIG_UART4_TXBUFSIZE];
00324 static unsigned char uart4_rxbuffer[CONFIG_UART4_RXBUFSIZE];
00325 #endif
00326 
00327 /*
00328  * Internal hardware state structure
00329  *
00330  * The \a sending variable is true while the transmission
00331  * interrupt is retriggering itself.
00332  *
00333  * the \a usart variable will point to the USART_t structure
00334  * that should be used.
00335  *
00336  * the \a port variable will point to the PORT_t structure
00337  * that should be modified to set the tx pin as an output and the
00338  * rx pin as an input
00339  *
00340  * the \a txpin variable will hold the pinnumber of the pin to use
00341  * as the tx output
00342  *
00343  * the \a rxpin variable will hold the pinnumber of the pin to use
00344  * as the rx input
00345  *
00346  * For the USARTs the \a sending flag is useful for taking specific
00347  * actions before sending a burst of data, at the start of a trasmission
00348  * but not before every char sent.
00349  *
00350  * For the SPI, this flag is necessary because the SPI sends and receives
00351  * bytes at the same time and the SPI IRQ is unique for send/receive.
00352  * The only way to start transmission is to write data in SPDR (this
00353  * is done by spi_starttx()). We do this *only* if a transfer is
00354  * not already started.
00355  */
00356 struct AvrxmegaSerial
00357 {
00358     struct SerialHardware hw;
00359     volatile bool sending;
00360     volatile USART_t* usart;
00361     volatile PORT_t* port;
00362     uint8_t txpin;
00363     uint8_t rxpin;
00364 };
00365 
00366 /*
00367  * Callbacks
00368  * The same callbacks are used for all USARTS.
00369  * By casting the SerialHardware structure to the AvrxmegaSerial
00370  * structure a pointer to the USART_t structure can be obtained,
00371  * to perform the callback for the specific USART.
00372  * This methode might cost some more cpu time, but saves on
00373  * code duplication and code size.
00374  */
00375 
00376 
00377 /*
00378  * \brief Initializes the uart
00379  *
00380  * The TX pin of the uart will be set as an outputpin
00381  * The RX pin of the uart will be set as an inputpin
00382  * The usart will be initialized
00383  * \see SER_UART_BUS_TXINIT
00384  *
00385  * \param _hw struct AvrxmegaSerial
00386  * \param ser Unused
00387  */
00388 static void uart_init(struct SerialHardware * _hw, UNUSED_ARG(struct Serial *, ser))
00389 {
00390     struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00391     //set transmit pin as output
00392     hw->port->DIRSET = BV(hw->txpin);
00393     hw->port->OUTCLR = BV(hw->txpin);
00394     //set receive pin as input
00395     hw->port->DIRCLR = BV(hw->rxpin);
00396     //initialize the USART
00397     SER_UART_BUS_TXINIT(hw->usart);
00398     RTS_ON;
00399     SER_STROBE_INIT;
00400 }
00401 
00402 /*
00403  * \brief Cleans up / Disables the uart
00404  *
00405  * \param _hw struct AvrxmegaSerial
00406  */
00407 static void uart_cleanup(struct SerialHardware * _hw)
00408 {
00409     struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00410     hw->usart->CTRLA = 0;
00411     hw->usart->CTRLB = 0;
00412 }
00413 
00414 /*
00415  * \brief Enableds the TX interrupt
00416  *
00417  * \param _hw struct AvrxmegaSerial
00418  */
00419 static void uart_enabletxirq(struct SerialHardware *_hw)
00420 {
00421     struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00422 
00423     /*
00424      * WARNING: racy code here!  The tx interrupt sets hw->sending to false
00425      * when it runs with an empty fifo.  The order of statements in the
00426      * if-block matters.
00427      */
00428     if (!hw->sending)
00429     {
00430         hw->sending = true;
00431         SER_UART_BUS_TXBEGIN(hw->usart);
00432     }
00433 }
00434 
00435 /*
00436  * \brief  sets the uart to the provided baudrate
00437  *
00438  * For setting the baudrate an scale factor (bscale) and a period
00439  * setting (BSEL) is required.
00440  *
00441  * The scale factor should be privided by defining USART_SCALE_FACTOR
00442  *
00443  * Atmel specifies BSEL for normal speed mode and bscale >= 0 as:
00444  * BSEL = (cpu_freq / ((2^bscale) * 16 * rate)) - 1
00445  * To allow BSEL to be calculated with an power function this can be
00446  * rewriten to:
00447  * BSEL = BSEL = (cpu_freq / ((1 << bscale) * 16 * rate)) - 1
00448  *
00449  * Atmel specifies BSEL for normal speed mode and bscale < 0 as:
00450  * BSEL = (1 / (2^bscale)) * ( (cpu_freq / (16 * rate)) - 1)
00451  * To calculte this float atheritmic is required as the second product will be smaller
00452  * than zero in a lot of cases.
00453  * To allow BSEL to be calculated with interger devision and no power function
00454  * this can be rewriten by folowing simple math rules to:
00455  * BSEL = ((1 << -bscale) * (cpu_freq - (16 * rate)) / (16 * rate)
00456  *
00457  * \param _hw struct AvrxmegaSerial
00458  * \param _rate the required baudrate
00459  *
00460  */
00461 static void uart_setbaudrate(struct SerialHardware * _hw, unsigned long _rate)
00462 {
00463     struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00464     /* Compute baud-rate period, this requires a valid USART_SCALE_FACTOR */
00465     #if USART_SCALE_FACTOR < 0
00466         uint16_t bsel = DIV_ROUND((1 << (-(USART_SCALE_FACTOR))) * (CPU_FREQ - (16 * _rate)), 16 * _rate);
00467     #else
00468         uint16_t bsel = DIV_ROUND(CPU_FREQ, (1 << (USART_SCALE_FACTOR)) * 16 * _rate) - 1;
00469     #endif
00470     USART_SET_BAUDRATE(hw->usart, bsel, USART_SCALE_FACTOR);
00471 }
00472 
00473 /*
00474  * \brief Sets the parity of the uart
00475  *
00476  * \param _hw struct AvrxmegaSerial
00477  * \param _parity the parity to set
00478  */
00479 static void uart_setparity(struct SerialHardware * _hw, int _parity)
00480 {
00481     struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00482     USART_SET_MODE(hw->usart, _parity);
00483 }
00484 
00485 /*
00486  * \brief Returns true if Transmitter is sending
00487  *
00488  * \param _hw struct AvrxmegaSerial
00489  * \return true if transmitter is sending
00490  */
00491 static bool tx_sending(struct SerialHardware* _hw)
00492 {
00493     struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
00494     return hw->sending;
00495 }
00496 
00497 
00498 // FIXME: move into compiler.h?  Ditch?
00499 #if COMPILER_C99
00500     #define C99INIT(name,val) .name = val
00501 #elif defined(__GNUC__)
00502     #define C99INIT(name,val) name: val
00503 #else
00504     #warning No designated initializers, double check your code
00505     #define C99INIT(name,val) (val)
00506 #endif
00507 
00508 /*
00509  * High-level interface data structures
00510  */
00511 static const struct SerialHardwareVT UART_VT =
00512 {
00513     C99INIT(init, uart_init),
00514     C99INIT(cleanup, uart_cleanup),
00515     C99INIT(setBaudrate, uart_setbaudrate),
00516     C99INIT(setParity, uart_setparity),
00517     C99INIT(txStart, uart_enabletxirq),
00518     C99INIT(txSending, tx_sending)
00519 };
00520 
00521 static struct AvrxmegaSerial UARTDescs[SER_CNT] =
00522 {
00523     {
00524         C99INIT(hw, ) {
00525             C99INIT(table, &UART_VT),
00526             C99INIT(txbuffer, uart0_txbuffer),
00527             C99INIT(rxbuffer, uart0_rxbuffer),
00528             C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
00529             C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
00530         },
00531         C99INIT(sending, false),
00532         C99INIT(usart, &USARTC0),
00533         C99INIT(port, &PORTC),
00534         C99INIT(txpin, PIN3_bp),
00535         C99INIT(rxpin, PIN2_bp),
00536     },
00537     {
00538         C99INIT(hw, ) {
00539             C99INIT(table, &UART_VT),
00540             C99INIT(txbuffer, uart1_txbuffer),
00541             C99INIT(rxbuffer, uart1_rxbuffer),
00542             C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
00543             C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
00544         },
00545         C99INIT(sending, false),
00546         C99INIT(usart, &USARTD0),
00547         C99INIT(port, &PORTD),
00548         C99INIT(txpin, PIN3_bp),
00549         C99INIT(rxpin, PIN2_bp),
00550     },
00551 #ifdef CPU_AVR_XMEGA_A
00552     {
00553         C99INIT(hw, ) {
00554             C99INIT(table, &UART_VT),
00555             C99INIT(txbuffer, uart2_txbuffer),
00556             C99INIT(rxbuffer, uart2_rxbuffer),
00557             C99INIT(txbuffer_size, sizeof(uart2_txbuffer)),
00558             C99INIT(rxbuffer_size, sizeof(uart2_rxbuffer)),
00559         },
00560         C99INIT(sending, false),
00561         C99INIT(usart, &USARTC1),
00562         C99INIT(port, &PORTC),
00563         C99INIT(txpin, PIN7_bp),
00564         C99INIT(rxpin, PIN6_bp),
00565     },
00566     {
00567         C99INIT(hw, ) {
00568             C99INIT(table, &UART_VT),
00569             C99INIT(txbuffer, uart3_txbuffer),
00570             C99INIT(rxbuffer, uart3_rxbuffer),
00571             C99INIT(txbuffer_size, sizeof(uart3_txbuffer)),
00572             C99INIT(rxbuffer_size, sizeof(uart3_rxbuffer)),
00573         },
00574         C99INIT(sending, false),
00575         C99INIT(usart, &USARTD1),
00576         C99INIT(port, &PORTD),
00577         C99INIT(txpin, PIN7_bp),
00578         C99INIT(rxpin, PIN6_bp),
00579     },
00580     {
00581         C99INIT(hw, ) {
00582             C99INIT(table, &UART_VT),
00583             C99INIT(txbuffer, uart4_txbuffer),
00584             C99INIT(rxbuffer, uart4_rxbuffer),
00585             C99INIT(txbuffer_size, sizeof(uart4_txbuffer)),
00586             C99INIT(rxbuffer_size, sizeof(uart4_rxbuffer)),
00587         },
00588         C99INIT(sending, false),
00589         C99INIT(usart, &USARTE0),
00590         C99INIT(port, &PORTE),
00591         C99INIT(txpin, PIN3_bp),
00592         C99INIT(rxpin, PIN2_bp),
00593     },
00594 #endif //CPU_AVR_XMEGA_A
00595 };
00596 
00597 struct SerialHardware *ser_hw_getdesc(int unit)
00598 {
00599     ASSERT(unit < SER_CNT);
00600     return &UARTDescs[unit].hw;
00601 }
00602 
00603 
00604 /*
00605  * Interrupt handlers
00606  */
00607 static inline void usart_handleDreInterrupt(uint8_t usartNumber)
00608 {
00609     SER_STROBE_ON;
00610     struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo;
00611     if (fifo_isempty(txfifo))
00612     {
00613         SER_UART_BUS_TXEND(UARTDescs[usartNumber].usart);
00614         #ifndef SER_UART_BUS_TXOFF
00615             UARTDescs[usartNumber].sending = false;
00616         #endif
00617     }
00618     else
00619     {
00620         char c = fifo_pop(txfifo);
00621         SER_UART_BUS_TXCHAR(UARTDescs[usartNumber].usart, c);
00622     }
00623     SER_STROBE_OFF;
00624 }
00625 
00626 #define USART_DRE_INTERRUPT_VECTOR(_vector, _usart)     \
00627 DECLARE_ISR(_vector)                                        \
00628 {                                                           \
00629     usart_handleDreInterrupt( _usart ); \
00630 }
00631 
00632 USART_DRE_INTERRUPT_VECTOR(USARTC0_DRE_vect, SER_UART0)
00633 USART_DRE_INTERRUPT_VECTOR(USARTD0_DRE_vect, SER_UART1)
00634 #ifdef CPU_AVR_XMEGA_A
00635     USART_DRE_INTERRUPT_VECTOR(USARTC1_DRE_vect, SER_UART2)
00636     USART_DRE_INTERRUPT_VECTOR(USARTD1_DRE_VECT, SER_UART3)
00637     USART_DRE_INTERRUPT_VECTOR(USARTE0_DRE_vect, SER_UART4)
00638 #endif
00639 
00640 #ifdef SER_UART_BUS_TXOFF
00641     static inline void USART_handleTXCInterrupt(uint8_t usartNumber)
00642     {
00643         SER_STROBE_ON;
00644         struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo;
00645         if (fifo_isempty(txfifo))
00646         {
00647             SER_UART_BUS_TXOFF(UARTDescs[usartNumber].usart);
00648             UARTDescs[usartNumber].sending = false;
00649         }
00650         else
00651         {
00652             SER_UART_BUS_TXBEGIN(UARTDescs[usartNumber].usart);
00653         }
00654         SER_STROBE_OFF;
00655     }
00656 
00657     /*
00658      * Serial port 0 TX complete interrupt handler.
00659      *
00660      * This IRQ is usually disabled.  The UDR-empty interrupt
00661      * enables it when there's no more data to transmit.
00662      * We need to wait until the last character has been
00663      * transmitted before switching the 485 transceiver to
00664      * receive mode.
00665      *
00666      * The txfifo might have been refilled by putchar() while
00667      * we were waiting for the transmission complete interrupt.
00668      * In this case, we must restart the UDR empty interrupt,
00669      * otherwise we'd stop the serial port with some data
00670      * still pending in the buffer.
00671      */
00672     #define USART_TXC_INTERRUPT_VECTOR(_vector, _usart) \
00673     DECLARE_ISR(_vector)                                \
00674     {                                                   \
00675         USART_handleTXCInterrupt( _usart );             \
00676     }
00677 
00678     USART_TXC_INTERRUPT_VECTOR(USARTC0_TXC_vect, SER_UART0)
00679     USART_TXC_INTERRUPT_VECTOR(USARTD0_TXC_vect, SER_UART1)
00680     #ifdef CPU_AVR_XMEGA_A
00681         USART_TXC_INTERRUPT_VECTOR(USARTC1_TXC_vect, SER_UART2)
00682         USART_TXC_INTERRUPT_VECTOR(USARTD1_TXC_vect, SER_UART3)
00683         USART_TXC_INTERRUPT_VECTOR(USARTE0_TXC_vect, SER_UART4)
00684     #endif /* CPU_AVR_XMEGA_A */
00685 #endif /* SER_UART_BUS_TXOFF */
00686 
00687 /*
00688  * Serial RX complete interrupt handler.
00689  *
00690  * This handler is interruptible.
00691  * Interrupt are reenabled as soon as recv complete interrupt is
00692  * disabled. Using INTERRUPT() is troublesome when the serial
00693  * is heavily loaded, because an interrupt could be retriggered
00694  * when executing the handler prologue before RXCIE is disabled.
00695  */
00696 static inline void USART_handleRXCInterrupt(uint8_t usartNumber)
00697 {
00698     SER_STROBE_ON;
00699     /* read status */
00700     ser_handles[usartNumber]->status |= (UARTDescs[usartNumber].usart)->STATUS & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00701     /* To clear the RXC flag we must _always_ read the UDR even when we're
00702      * not going to accept the incoming data, otherwise a new interrupt
00703      * will occur once the handler terminates.
00704      */
00705     char c = (UARTDescs[usartNumber].usart)->DATA;
00706     struct FIFOBuffer * const rxfifo = &ser_handles[usartNumber]->rxfifo;
00707     if (fifo_isfull(rxfifo))
00708     {
00709         ser_handles[usartNumber]->status |= SERRF_RXFIFOOVERRUN;
00710     }
00711     else
00712     {
00713         fifo_push(rxfifo, c);
00714         #if CONFIG_SER_HWHANDSHAKE
00715             if (fifo_isfull(rxfifo))
00716             {
00717                 RTS_OFF(UARTDescs[usartNumber].usart);
00718             }
00719         #endif
00720     }
00721     SER_STROBE_OFF;
00722 }
00723 
00724 #define USART_RXC_INTERRUPT_VECTOR(_vector, _usart) \
00725 DECLARE_ISR(_vector)                                \
00726 {                                                   \
00727     USART_handleRXCInterrupt( _usart );             \
00728 }
00729 USART_RXC_INTERRUPT_VECTOR(USARTC0_RXC_vect, SER_UART0)
00730 USART_RXC_INTERRUPT_VECTOR(USARTD0_RXC_vect, SER_UART1)
00731 #ifdef CPU_AVR_XMEGA_A
00732     USART_RXC_INTERRUPT_VECTOR(USARTC1_RXC_vect, SER_UART2)
00733     USART_RXC_INTERRUPT_VECTOR(USARTD1_RXC_vect, SER_UART3)
00734     USART_RXC_INTERRUPT_VECTOR(USARTE0_RXC_vect, SER_UART4)
00735 #endif