ser_avr.c

Go to the documentation of this file.
00001 
00042 #include "hw/hw_ser.h"  /* Required for bus macros overrides */
00043 #include "hw/hw_cpu.h"  /* CLOCK_FREQ */
00044 
00045 #include "cfg/cfg_ser.h"
00046 
00047 #include <cfg/macros.h> /* DIV_ROUND */
00048 #include <cfg/debug.h>
00049 
00050 #include <drv/ser.h>
00051 #include <drv/ser_p.h>
00052 #include <drv/timer.h>
00053 
00054 #include <struct/fifobuf.h>
00055 
00056 #include <avr/io.h>
00057 
00058 #if defined(__AVR_LIBC_VERSION__) && (__AVR_LIBC_VERSION__ >= 10400UL)
00059     #include <avr/interrupt.h>
00060 #else
00061     #include <avr/signal.h>
00062 #endif
00063 
00064 
00065 #if !CONFIG_SER_HWHANDSHAKE
00066 
00070     #define RTS_ON      do {} while (0)
00071     #define RTS_OFF     do {} while (0)
00072     #define IS_CTS_ON   true
00073     #define EIMSKF_CTS  0 
00074     /*\}*/
00075 #endif
00076 
00077 #if CPU_AVR_ATMEGA1281
00078     #define BIT_RXCIE0 RXCIE0
00079     #define BIT_RXEN0  RXEN0
00080     #define BIT_TXEN0  TXEN0
00081     #define BIT_UDRIE0 UDRIE0
00082 
00083     #define BIT_RXCIE1 RXCIE1
00084     #define BIT_RXEN1  RXEN1
00085     #define BIT_TXEN1  TXEN1
00086     #define BIT_UDRIE1 UDRIE1
00087 #else
00088     #define BIT_RXCIE0 RXCIE
00089     #define BIT_RXEN0  RXEN
00090     #define BIT_TXEN0  TXEN
00091     #define BIT_UDRIE0 UDRIE
00092 
00093     #define BIT_RXCIE1 RXCIE
00094     #define BIT_RXEN1  RXEN
00095     #define BIT_TXEN1  TXEN
00096     #define BIT_UDRIE1 UDRIE
00097 #endif
00098 
00099 
00120 #ifndef SER_UART0_BUS_TXINIT
00121 
00127     #define SER_UART0_BUS_TXINIT do { \
00128         UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
00129     } while (0)
00130 #endif
00131 
00132 #ifndef SER_UART0_BUS_TXBEGIN
00133 
00139     #define SER_UART0_BUS_TXBEGIN do { \
00140         UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
00141     } while (0)
00142 #endif
00143 
00144 #ifndef SER_UART0_BUS_TXCHAR
00145 
00148     #define SER_UART0_BUS_TXCHAR(c) do { \
00149         UDR0 = (c); \
00150     } while (0)
00151 #endif
00152 
00153 #ifndef SER_UART0_BUS_TXEND
00154 
00161     #define SER_UART0_BUS_TXEND do { \
00162         UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
00163     } while (0)
00164 #endif
00165 
00166 #ifndef SER_UART0_BUS_TXOFF
00167 
00174     #ifdef __doxygen__
00175     #define SER_UART0_BUS_TXOFF
00176     #endif
00177 #endif
00178 
00179 #ifndef SER_UART1_BUS_TXINIT
00180 
00181     #define SER_UART1_BUS_TXINIT do { \
00182         UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
00183     } while (0)
00184 #endif
00185 #ifndef SER_UART1_BUS_TXBEGIN
00186 
00187     #define SER_UART1_BUS_TXBEGIN do { \
00188         UCSR1B = BV(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
00189     } while (0)
00190 #endif
00191 #ifndef SER_UART1_BUS_TXCHAR
00192 
00193     #define SER_UART1_BUS_TXCHAR(c) do { \
00194         UDR1 = (c); \
00195     } while (0)
00196 #endif
00197 #ifndef SER_UART1_BUS_TXEND
00198 
00199     #define SER_UART1_BUS_TXEND do { \
00200         UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
00201     } while (0)
00202 #endif
00203 #ifndef SER_UART1_BUS_TXOFF
00204 
00209     #ifdef __doxygen__
00210     #define SER_UART1_BUS_TXOFF
00211     #endif
00212 #endif
00213 /*\}*/
00214 
00215 
00224 #ifndef SER_SPI_BUS_TXINIT
00225 
00229     #define SER_SPI_BUS_TXINIT
00230 #endif
00231 
00232 #ifndef SER_SPI_BUS_TXCLOSE
00233 
00237     #define SER_SPI_BUS_TXCLOSE
00238 #endif
00239 /*\}*/
00240 
00241 
00242 /* SPI port and pin configuration */
00243 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA1281
00244     #define SPI_PORT      PORTB
00245     #define SPI_DDR       DDRB
00246     #define SPI_SS_BIT    PB0
00247     #define SPI_SCK_BIT   PB1
00248     #define SPI_MOSI_BIT  PB2
00249     #define SPI_MISO_BIT  PB3
00250 #elif CPU_AVR_ATMEGA8
00251     #define SPI_PORT      PORTB
00252     #define SPI_DDR       DDRB
00253     #define SPI_SS_BIT    PB2
00254     #define SPI_SCK_BIT   PB5
00255     #define SPI_MOSI_BIT  PB3
00256     #define SPI_MISO_BIT  PB4
00257 #else
00258     #error Unknown architecture
00259 #endif
00260 
00261 /* USART register definitions */
00262 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281
00263     #define AVR_HAS_UART1 1
00264 #elif CPU_AVR_ATMEGA8
00265     #define AVR_HAS_UART1 0
00266     #define UCSR0A UCSRA
00267     #define UCSR0B UCSRB
00268     #define UCSR0C UCSRC
00269     #define UDR0   UDR
00270     #define UBRR0L UBRRL
00271     #define UBRR0H UBRRH
00272     #define SIG_UART0_DATA SIG_UART_DATA
00273     #define SIG_UART0_RECV SIG_UART_RECV
00274     #define SIG_UART0_TRANS SIG_UART_TRANS
00275 #elif CPU_AVR_ATMEGA103
00276     #define AVR_HAS_UART1 0
00277     #define UCSR0B UCR
00278     #define UDR0   UDR
00279     #define UCSR0A USR
00280     #define UBRR0L UBRR
00281     #define SIG_UART0_DATA SIG_UART_DATA
00282     #define SIG_UART0_RECV SIG_UART_RECV
00283     #define SIG_UART0_TRANS SIG_UART_TRANS
00284 #else
00285     #error Unknown architecture
00286 #endif
00287 
00288 
00299 #if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE
00300     #define SER_STROBE_ON    do {/*nop*/} while(0)
00301     #define SER_STROBE_OFF   do {/*nop*/} while(0)
00302     #define SER_STROBE_INIT  do {/*nop*/} while(0)
00303 #endif
00304 
00305 
00306 /* From the high-level serial driver */
00307 extern struct Serial *ser_handles[SER_CNT];
00308 
00309 /* TX and RX buffers */
00310 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
00311 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
00312 #if AVR_HAS_UART1
00313     static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
00314     static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
00315 #endif
00316 static unsigned char spi_txbuffer[CONFIG_SPI_TXBUFSIZE];
00317 static unsigned char spi_rxbuffer[CONFIG_SPI_RXBUFSIZE];
00318 
00319 
00336 struct AvrSerial
00337 {
00338     struct SerialHardware hw;
00339     volatile bool sending;
00340 };
00341 
00342 
00343 
00344 /*
00345  * Callbacks
00346  */
00347 static void uart0_init(
00348     UNUSED_ARG(struct SerialHardware *, _hw),
00349     UNUSED_ARG(struct Serial *, ser))
00350 {
00351     SER_UART0_BUS_TXINIT;
00352     RTS_ON;
00353     SER_STROBE_INIT;
00354 }
00355 
00356 static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00357 {
00358     UCSR0B = 0;
00359 }
00360 
00361 static void uart0_enabletxirq(struct SerialHardware *_hw)
00362 {
00363     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00364 
00365     /*
00366      * WARNING: racy code here!  The tx interrupt sets hw->sending to false
00367      * when it runs with an empty fifo.  The order of statements in the
00368      * if-block matters.
00369      */
00370     if (!hw->sending)
00371     {
00372         hw->sending = true;
00373         SER_UART0_BUS_TXBEGIN;
00374     }
00375 }
00376 
00377 static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00378 {
00379     /* Compute baud-rate period */
00380     uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
00381 
00382 #if !CPU_AVR_ATMEGA103
00383     UBRR0H = (period) >> 8;
00384 #endif
00385     UBRR0L = (period);
00386 
00387     //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);)
00388 }
00389 
00390 static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
00391 {
00392 #if !CPU_AVR_ATMEGA103
00393     UCSR0C = (UCSR0C & ~(BV(UPM01) | BV(UPM00))) | ((parity) << UPM00);
00394 #endif
00395 }
00396 
00397 #if AVR_HAS_UART1
00398 
00399 static void uart1_init(
00400     UNUSED_ARG(struct SerialHardware *, _hw),
00401     UNUSED_ARG(struct Serial *, ser))
00402 {
00403     SER_UART1_BUS_TXINIT;
00404     RTS_ON;
00405     SER_STROBE_INIT;
00406 }
00407 
00408 static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00409 {
00410     UCSR1B = 0;
00411 }
00412 
00413 static void uart1_enabletxirq(struct SerialHardware *_hw)
00414 {
00415     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00416 
00417     /*
00418      * WARNING: racy code here!  The tx interrupt
00419      * sets hw->sending to false when it runs with
00420      * an empty fifo.  The order of the statements
00421      * in the if-block matters.
00422      */
00423     if (!hw->sending)
00424     {
00425         hw->sending = true;
00426         SER_UART1_BUS_TXBEGIN;
00427     }
00428 }
00429 
00430 static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00431 {
00432     /* Compute baud-rate period */
00433     uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
00434 
00435     UBRR1H = (period) >> 8;
00436     UBRR1L = (period);
00437 
00438     //DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);)
00439 }
00440 
00441 static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
00442 {
00443     UCSR1C = (UCSR1C & ~(BV(UPM11) | BV(UPM10))) | ((parity) << UPM10);
00444 }
00445 
00446 #endif // AVR_HAS_UART1
00447 
00448 static void spi_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser))
00449 {
00450     /*
00451      * Set MOSI and SCK ports out, MISO in.
00452      *
00453      * The ATmega64/128 datasheet explicitly states that the input/output
00454      * state of the SPI pins is not significant, as when the SPI is
00455      * active the I/O port are overrided.
00456      * This is *blatantly FALSE*.
00457      *
00458      * Moreover, the MISO pin on the board_kc *must* be in high impedance
00459      * state even when the SPI is off, because the line is wired together
00460      * with the KBus serial RX, and the transmitter of the slave boards
00461      * would be unable to drive the line.
00462      */
00463     ATOMIC(SPI_DDR |= (BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT)));
00464 
00465     /*
00466      * If the SPI master mode is activated and the SS pin is in input and tied low,
00467      * the SPI hardware will automatically switch to slave mode!
00468      * For proper communication this pins should therefore be:
00469      * - as output
00470      * - as input but tied high forever!
00471      * This driver set the pin as output.
00472      */
00473     #warning SPI SS pin set as output for proper operation, check schematics for possible conflicts.
00474     ATOMIC(SPI_DDR |= BV(SPI_SS_BIT));
00475 
00476     ATOMIC(SPI_DDR &= ~BV(SPI_MISO_BIT));
00477     /* Enable SPI, IRQ on, Master */
00478     SPCR = BV(SPE) | BV(SPIE) | BV(MSTR);
00479 
00480     /* Set data order */
00481     #if CONFIG_SPI_DATA_ORDER == SER_LSB_FIRST
00482         SPCR |= BV(DORD);
00483     #endif
00484 
00485     /* Set SPI clock rate */
00486     #if CONFIG_SPI_CLOCK_DIV == 128
00487         SPCR |= (BV(SPR1) | BV(SPR0));
00488     #elif (CONFIG_SPI_CLOCK_DIV == 64 || CONFIG_SPI_CLOCK_DIV == 32)
00489         SPCR |= BV(SPR1);
00490     #elif (CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 8)
00491         SPCR |= BV(SPR0);
00492     #elif (CONFIG_SPI_CLOCK_DIV == 4 || CONFIG_SPI_CLOCK_DIV == 2)
00493         // SPR0 & SDPR1 both at 0
00494     #else
00495         #error Unsupported SPI clock division factor.
00496     #endif
00497 
00498     /* Set SPI2X bit (spi double frequency) */
00499     #if (CONFIG_SPI_CLOCK_DIV == 128 || CONFIG_SPI_CLOCK_DIV == 64 \
00500       || CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 4)
00501         SPSR &= ~BV(SPI2X);
00502     #elif (CONFIG_SPI_CLOCK_DIV == 32 || CONFIG_SPI_CLOCK_DIV == 8 || CONFIG_SPI_CLOCK_DIV == 2)
00503         SPSR |= BV(SPI2X);
00504     #else
00505         #error Unsupported SPI clock division factor.
00506     #endif
00507 
00508     /* Set clock polarity */
00509     #if CONFIG_SPI_CLOCK_POL == 1
00510         SPCR |= BV(CPOL);
00511     #endif
00512 
00513     /* Set clock phase */
00514     #if CONFIG_SPI_CLOCK_PHASE == 1
00515         SPCR |= BV(CPHA);
00516     #endif
00517     SER_SPI_BUS_TXINIT;
00518 
00519     SER_STROBE_INIT;
00520 }
00521 
00522 static void spi_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00523 {
00524     SPCR = 0;
00525 
00526     SER_SPI_BUS_TXCLOSE;
00527 
00528     /* Set all pins as inputs */
00529     ATOMIC(SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT) | BV(SPI_SS_BIT)));
00530 }
00531 
00532 static void spi_starttx(struct SerialHardware *_hw)
00533 {
00534     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00535 
00536     cpu_flags_t flags;
00537     IRQ_SAVE_DISABLE(flags);
00538 
00539     /* Send data only if the SPI is not already transmitting */
00540     if (!hw->sending && !fifo_isempty(&ser_handles[SER_SPI]->txfifo))
00541     {
00542         hw->sending = true;
00543         SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
00544     }
00545 
00546     IRQ_RESTORE(flags);
00547 }
00548 
00549 static void spi_setbaudrate(
00550     UNUSED_ARG(struct SerialHardware *, _hw),
00551     UNUSED_ARG(unsigned long, rate))
00552 {
00553     // nop
00554 }
00555 
00556 static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity))
00557 {
00558     // nop
00559 }
00560 
00561 static bool tx_sending(struct SerialHardware* _hw)
00562 {
00563     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00564     return hw->sending;
00565 }
00566 
00567 
00568 
00569 // FIXME: move into compiler.h?  Ditch?
00570 #if COMPILER_C99
00571     #define C99INIT(name,val) .name = val
00572 #elif defined(__GNUC__)
00573     #define C99INIT(name,val) name: val
00574 #else
00575     #warning No designated initializers, double check your code
00576     #define C99INIT(name,val) (val)
00577 #endif
00578 
00579 /*
00580  * High-level interface data structures
00581  */
00582 static const struct SerialHardwareVT UART0_VT =
00583 {
00584     C99INIT(init, uart0_init),
00585     C99INIT(cleanup, uart0_cleanup),
00586     C99INIT(setBaudrate, uart0_setbaudrate),
00587     C99INIT(setParity, uart0_setparity),
00588     C99INIT(txStart, uart0_enabletxirq),
00589     C99INIT(txSending, tx_sending),
00590 };
00591 
00592 #if AVR_HAS_UART1
00593 static const struct SerialHardwareVT UART1_VT =
00594 {
00595     C99INIT(init, uart1_init),
00596     C99INIT(cleanup, uart1_cleanup),
00597     C99INIT(setBaudrate, uart1_setbaudrate),
00598     C99INIT(setParity, uart1_setparity),
00599     C99INIT(txStart, uart1_enabletxirq),
00600     C99INIT(txSending, tx_sending),
00601 };
00602 #endif // AVR_HAS_UART1
00603 
00604 static const struct SerialHardwareVT SPI_VT =
00605 {
00606     C99INIT(init, spi_init),
00607     C99INIT(cleanup, spi_cleanup),
00608     C99INIT(setBaudrate, spi_setbaudrate),
00609     C99INIT(setParity, spi_setparity),
00610     C99INIT(txStart, spi_starttx),
00611     C99INIT(txSending, tx_sending),
00612 };
00613 
00614 static struct AvrSerial UARTDescs[SER_CNT] =
00615 {
00616     {
00617         C99INIT(hw, ) {
00618             C99INIT(table, &UART0_VT),
00619             C99INIT(txbuffer, uart0_txbuffer),
00620             C99INIT(rxbuffer, uart0_rxbuffer),
00621             C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
00622             C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
00623         },
00624         C99INIT(sending, false),
00625     },
00626 #if AVR_HAS_UART1
00627     {
00628         C99INIT(hw, ) {
00629             C99INIT(table, &UART1_VT),
00630             C99INIT(txbuffer, uart1_txbuffer),
00631             C99INIT(rxbuffer, uart1_rxbuffer),
00632             C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
00633             C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
00634         },
00635         C99INIT(sending, false),
00636     },
00637 #endif
00638     {
00639         C99INIT(hw, ) {
00640             C99INIT(table, &SPI_VT),
00641             C99INIT(txbuffer, spi_txbuffer),
00642             C99INIT(rxbuffer, spi_rxbuffer),
00643             C99INIT(txbuffer_size, sizeof(spi_txbuffer)),
00644             C99INIT(rxbuffer_size, sizeof(spi_rxbuffer)),
00645         },
00646         C99INIT(sending, false),
00647     }
00648 };
00649 
00650 struct SerialHardware *ser_hw_getdesc(int unit)
00651 {
00652     ASSERT(unit < SER_CNT);
00653     return &UARTDescs[unit].hw;
00654 }
00655 
00656 
00657 /*
00658  * Interrupt handlers
00659  */
00660 
00661 #if CONFIG_SER_HWHANDSHAKE
00662 
00664 SIGNAL(SIG_CTS)
00665 {
00666     // Re-enable UDR empty interrupt and TX, then disable CTS interrupt
00667     UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
00668     EIMSK &= ~EIMSKF_CTS;
00669 }
00670 
00671 #endif // CONFIG_SER_HWHANDSHAKE
00672 
00673 
00677 SIGNAL(USART0_UDRE_vect)
00678 {
00679     SER_STROBE_ON;
00680 
00681     struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
00682 
00683     if (fifo_isempty(txfifo))
00684     {
00685         SER_UART0_BUS_TXEND;
00686 #ifndef SER_UART0_BUS_TXOFF
00687         UARTDescs[SER_UART0].sending = false;
00688 #endif
00689     }
00690 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
00691     else if (!IS_CTS_ON)
00692     {
00693         // Disable rx interrupt and tx, enable CTS interrupt
00694         // UNTESTED
00695         UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
00696         EIFR |= EIMSKF_CTS;
00697         EIMSK |= EIMSKF_CTS;
00698     }
00699 #endif
00700     else
00701     {
00702         char c = fifo_pop(txfifo);
00703         SER_UART0_BUS_TXCHAR(c);
00704     }
00705 
00706     SER_STROBE_OFF;
00707 }
00708 
00709 #ifdef SER_UART0_BUS_TXOFF
00710 
00725 SIGNAL(SIG_UART0_TRANS)
00726 {
00727     SER_STROBE_ON;
00728 
00729     struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
00730     if (fifo_isempty(txfifo))
00731     {
00732         SER_UART0_BUS_TXOFF;
00733         UARTDescs[SER_UART0].sending = false;
00734     }
00735     else
00736         UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
00737 
00738     SER_STROBE_OFF;
00739 }
00740 #endif /* SER_UART0_BUS_TXOFF */
00741 
00742 
00743 #if AVR_HAS_UART1
00744 
00748 SIGNAL(USART1_UDRE_vect)
00749 {
00750     SER_STROBE_ON;
00751 
00752     struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
00753 
00754     if (fifo_isempty(txfifo))
00755     {
00756         SER_UART1_BUS_TXEND;
00757 #ifndef SER_UART1_BUS_TXOFF
00758         UARTDescs[SER_UART1].sending = false;
00759 #endif
00760     }
00761 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
00762     else if (!IS_CTS_ON)
00763     {
00764         // Disable rx interrupt and tx, enable CTS interrupt
00765         // UNTESTED
00766         UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
00767         EIFR |= EIMSKF_CTS;
00768         EIMSK |= EIMSKF_CTS;
00769     }
00770 #endif
00771     else
00772     {
00773         char c = fifo_pop(txfifo);
00774         SER_UART1_BUS_TXCHAR(c);
00775     }
00776 
00777     SER_STROBE_OFF;
00778 }
00779 
00780 #ifdef SER_UART1_BUS_TXOFF
00781 
00786 SIGNAL(SIG_UART1_TRANS)
00787 {
00788     SER_STROBE_ON;
00789 
00790     struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
00791     if (fifo_isempty(txfifo))
00792     {
00793         SER_UART1_BUS_TXOFF;
00794         UARTDescs[SER_UART1].sending = false;
00795     }
00796     else
00797         UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
00798 
00799     SER_STROBE_OFF;
00800 }
00801 #endif /* SER_UART1_BUS_TXOFF */
00802 
00803 #endif // AVR_HAS_UART1
00804 
00805 
00821 SIGNAL(USART0_RX_vect)
00822 {
00823     SER_STROBE_ON;
00824 
00825     /* Disable Recv complete IRQ */
00826     //UCSR0B &= ~BV(RXCIE);
00827     //IRQ_ENABLE;
00828 
00829     /* Should be read before UDR */
00830     ser_handles[SER_UART0]->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00831 
00832     /* To clear the RXC flag we must _always_ read the UDR even when we're
00833      * not going to accept the incoming data, otherwise a new interrupt
00834      * will occur once the handler terminates.
00835      */
00836     char c = UDR0;
00837     struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART0]->rxfifo;
00838 
00839     if (fifo_isfull(rxfifo))
00840         ser_handles[SER_UART0]->status |= SERRF_RXFIFOOVERRUN;
00841     else
00842     {
00843         fifo_push(rxfifo, c);
00844 #if CONFIG_SER_HWHANDSHAKE
00845         if (fifo_isfull(rxfifo))
00846             RTS_OFF;
00847 #endif
00848     }
00849 
00850     /* Reenable receive complete int */
00851     //IRQ_DISABLE;
00852     //UCSR0B |= BV(RXCIE);
00853 
00854     SER_STROBE_OFF;
00855 }
00856 
00857 
00858 #if AVR_HAS_UART1
00859 
00871 SIGNAL(USART1_RX_vect)
00872 {
00873     SER_STROBE_ON;
00874 
00875     /* Disable Recv complete IRQ */
00876     //UCSR1B &= ~BV(RXCIE);
00877     //IRQ_ENABLE;
00878 
00879     /* Should be read before UDR */
00880     ser_handles[SER_UART1]->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00881 
00882     /* To avoid an IRQ storm, we must _always_ read the UDR even when we're
00883      * not going to accept the incoming data
00884      */
00885     char c = UDR1;
00886     struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART1]->rxfifo;
00887     //ASSERT_VALID_FIFO(rxfifo);
00888 
00889     if (UNLIKELY(fifo_isfull(rxfifo)))
00890         ser_handles[SER_UART1]->status |= SERRF_RXFIFOOVERRUN;
00891     else
00892     {
00893         fifo_push(rxfifo, c);
00894 #if CONFIG_SER_HWHANDSHAKE
00895         if (fifo_isfull(rxfifo))
00896             RTS_OFF;
00897 #endif
00898     }
00899     /* Re-enable receive complete int */
00900     //IRQ_DISABLE;
00901     //UCSR1B |= BV(RXCIE);
00902 
00903     SER_STROBE_OFF;
00904 }
00905 
00906 #endif // AVR_HAS_UART1
00907 
00908 
00912 SIGNAL(SIG_SPI)
00913 {
00914     SER_STROBE_ON;
00915 
00916     /* Read incoming byte. */
00917     if (!fifo_isfull(&ser_handles[SER_SPI]->rxfifo))
00918         fifo_push(&ser_handles[SER_SPI]->rxfifo, SPDR);
00919     /*
00920      * FIXME
00921     else
00922         ser_handles[SER_SPI]->status |= SERRF_RXFIFOOVERRUN;
00923     */
00924 
00925     /* Send */
00926     if (!fifo_isempty(&ser_handles[SER_SPI]->txfifo))
00927         SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
00928     else
00929         UARTDescs[SER_SPI].sending = false;
00930 
00931     SER_STROBE_OFF;
00932 }