ser_avr.c

Go to the documentation of this file.
00001 
00064 #include <drv/ser.h>
00065 #include <drv/ser_p.h>
00066 
00067 #include <hw_ser.h>  /* Required for bus macros overrides */
00068 #include <hw_cpu.h>  /* CLOCK_FREQ */
00069 #include <appconfig.h>
00070 
00071 #include <cfg/macros.h> /* DIV_ROUND */
00072 #include <cfg/debug.h>
00073 #include <drv/timer.h>
00074 #include <mware/fifobuf.h>
00075 
00076 #include <avr/io.h>
00077 #if defined(__AVR_LIBC_VERSION__) && (__AVR_LIBC_VERSION__ >= 10400UL)
00078     #include <avr/interrupt.h>
00079 #else
00080     #include <avr/signal.h>
00081 #endif
00082 
00083 
00084 #if !CONFIG_SER_HWHANDSHAKE
00085 
00089     #define RTS_ON      do {} while (0)
00090     #define RTS_OFF     do {} while (0)
00091     #define IS_CTS_ON   true
00092     #define EIMSKF_CTS  0 
00093     /*\}*/
00094 #endif
00095 
00096 #if CPU_AVR_ATMEGA1281
00097     #define BIT_RXCIE0 RXCIE0
00098     #define BIT_RXEN0  RXEN0
00099     #define BIT_TXEN0  TXEN0
00100     #define BIT_UDRIE0 UDRIE0
00101 
00102     #define BIT_RXCIE1 RXCIE1
00103     #define BIT_RXEN1  RXEN1
00104     #define BIT_TXEN1  TXEN1
00105     #define BIT_UDRIE1 UDRIE1
00106 #else
00107     #define BIT_RXCIE0 RXCIE
00108     #define BIT_RXEN0  RXEN
00109     #define BIT_TXEN0  TXEN
00110     #define BIT_UDRIE0 UDRIE
00111 
00112     #define BIT_RXCIE1 RXCIE
00113     #define BIT_RXEN1  RXEN
00114     #define BIT_TXEN1  TXEN
00115     #define BIT_UDRIE1 UDRIE
00116 #endif
00117 
00118 
00139 #ifndef SER_UART0_BUS_TXINIT
00140 
00146     #define SER_UART0_BUS_TXINIT do { \
00147         UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
00148     } while (0)
00149 #endif
00150 
00151 #ifndef SER_UART0_BUS_TXBEGIN
00152 
00158     #define SER_UART0_BUS_TXBEGIN do { \
00159         UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
00160     } while (0)
00161 #endif
00162 
00163 #ifndef SER_UART0_BUS_TXCHAR
00164 
00167     #define SER_UART0_BUS_TXCHAR(c) do { \
00168         UDR0 = (c); \
00169     } while (0)
00170 #endif
00171 
00172 #ifndef SER_UART0_BUS_TXEND
00173 
00180     #define SER_UART0_BUS_TXEND do { \
00181         UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
00182     } while (0)
00183 #endif
00184 
00185 #ifndef SER_UART0_BUS_TXOFF
00186 
00193     #ifdef __doxygen__
00194     #define SER_UART0_BUS_TXOFF
00195     #endif
00196 #endif
00197 
00198 #ifndef SER_UART1_BUS_TXINIT
00199 
00200     #define SER_UART1_BUS_TXINIT do { \
00201         UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
00202     } while (0)
00203 #endif
00204 #ifndef SER_UART1_BUS_TXBEGIN
00205 
00206     #define SER_UART1_BUS_TXBEGIN do { \
00207         UCSR1B = BV(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
00208     } while (0)
00209 #endif
00210 #ifndef SER_UART1_BUS_TXCHAR
00211 
00212     #define SER_UART1_BUS_TXCHAR(c) do { \
00213         UDR1 = (c); \
00214     } while (0)
00215 #endif
00216 #ifndef SER_UART1_BUS_TXEND
00217 
00218     #define SER_UART1_BUS_TXEND do { \
00219         UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
00220     } while (0)
00221 #endif
00222 #ifndef SER_UART1_BUS_TXOFF
00223 
00228     #ifdef __doxygen__
00229     #define SER_UART1_BUS_TXOFF
00230     #endif
00231 #endif
00232 /*\}*/
00233 
00234 
00243 #ifndef SER_SPI_BUS_TXINIT
00244 
00248     #define SER_SPI_BUS_TXINIT
00249 #endif
00250 
00251 #ifndef SER_SPI_BUS_TXCLOSE
00252 
00256     #define SER_SPI_BUS_TXCLOSE
00257 #endif
00258 /*\}*/
00259 
00260 
00261 /* SPI port and pin configuration */
00262 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA1281
00263     #define SPI_PORT      PORTB
00264     #define SPI_DDR       DDRB
00265     #define SPI_SS_BIT    PB0
00266     #define SPI_SCK_BIT   PB1
00267     #define SPI_MOSI_BIT  PB2
00268     #define SPI_MISO_BIT  PB3
00269 #elif CPU_AVR_ATMEGA8
00270     #define SPI_PORT      PORTB
00271     #define SPI_DDR       DDRB
00272     #define SPI_SS_BIT    PB2
00273     #define SPI_SCK_BIT   PB5
00274     #define SPI_MOSI_BIT  PB3
00275     #define SPI_MISO_BIT  PB4
00276 #else
00277     #error Unknown architecture
00278 #endif
00279 
00280 /* USART register definitions */
00281 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281
00282     #define AVR_HAS_UART1 1
00283 #elif CPU_AVR_ATMEGA8
00284     #define AVR_HAS_UART1 0
00285     #define UCSR0A UCSRA
00286     #define UCSR0B UCSRB
00287     #define UCSR0C UCSRC
00288     #define UDR0   UDR
00289     #define UBRR0L UBRRL
00290     #define UBRR0H UBRRH
00291     #define SIG_UART0_DATA SIG_UART_DATA
00292     #define SIG_UART0_RECV SIG_UART_RECV
00293     #define SIG_UART0_TRANS SIG_UART_TRANS
00294 #elif CPU_AVR_ATMEGA103
00295     #define AVR_HAS_UART1 0
00296     #define UCSR0B UCR
00297     #define UDR0   UDR
00298     #define UCSR0A USR
00299     #define UBRR0L UBRR
00300     #define SIG_UART0_DATA SIG_UART_DATA
00301     #define SIG_UART0_RECV SIG_UART_RECV
00302     #define SIG_UART0_TRANS SIG_UART_TRANS
00303 #else
00304     #error Unknown architecture
00305 #endif
00306 
00307 
00318 #if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE
00319     #define SER_STROBE_ON    do {/*nop*/} while(0)
00320     #define SER_STROBE_OFF   do {/*nop*/} while(0)
00321     #define SER_STROBE_INIT  do {/*nop*/} while(0)
00322 #endif
00323 
00324 
00325 /* From the high-level serial driver */
00326 extern struct Serial ser_handles[SER_CNT];
00327 
00328 /* TX and RX buffers */
00329 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
00330 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
00331 #if AVR_HAS_UART1
00332     static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
00333     static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
00334 #endif
00335 static unsigned char spi_txbuffer[CONFIG_SPI_TXBUFSIZE];
00336 static unsigned char spi_rxbuffer[CONFIG_SPI_RXBUFSIZE];
00337 
00338 
00355 struct AvrSerial
00356 {
00357     struct SerialHardware hw;
00358     volatile bool sending;
00359 };
00360 
00361 
00362 /*
00363  * These are to trick GCC into *not* using absolute addressing mode
00364  * when accessing ser_handles, which is very expensive.
00365  *
00366  * Accessing through these pointers generates much shorter
00367  * (and hopefully faster) code.
00368  */
00369 struct Serial *ser_uart0 = &ser_handles[SER_UART0];
00370 #if AVR_HAS_UART1
00371 struct Serial *ser_uart1 = &ser_handles[SER_UART1];
00372 #endif
00373 struct Serial *ser_spi = &ser_handles[SER_SPI];
00374 
00375 
00376 
00377 /*
00378  * Callbacks
00379  */
00380 static void uart0_init(
00381     UNUSED_ARG(struct SerialHardware *, _hw),
00382     UNUSED_ARG(struct Serial *, ser))
00383 {
00384     SER_UART0_BUS_TXINIT;
00385     RTS_ON;
00386     SER_STROBE_INIT;
00387 }
00388 
00389 static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00390 {
00391     UCSR0B = 0;
00392 }
00393 
00394 static void uart0_enabletxirq(struct SerialHardware *_hw)
00395 {
00396     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00397 
00398     /*
00399      * WARNING: racy code here!  The tx interrupt sets hw->sending to false
00400      * when it runs with an empty fifo.  The order of statements in the
00401      * if-block matters.
00402      */
00403     if (!hw->sending)
00404     {
00405         hw->sending = true;
00406         SER_UART0_BUS_TXBEGIN;
00407     }
00408 }
00409 
00410 static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00411 {
00412     /* Compute baud-rate period */
00413     uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
00414 
00415 #if !CPU_AVR_ATMEGA103
00416     UBRR0H = (period) >> 8;
00417 #endif
00418     UBRR0L = (period);
00419 
00420     //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);)
00421 }
00422 
00423 static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
00424 {
00425 #if !CPU_AVR_ATMEGA103
00426     UCSR0C = (UCSR0C & ~(BV(UPM01) | BV(UPM00))) | ((parity) << UPM00);
00427 #endif
00428 }
00429 
00430 #if AVR_HAS_UART1
00431 
00432 static void uart1_init(
00433     UNUSED_ARG(struct SerialHardware *, _hw),
00434     UNUSED_ARG(struct Serial *, ser))
00435 {
00436     SER_UART1_BUS_TXINIT;
00437     RTS_ON;
00438     SER_STROBE_INIT;
00439 }
00440 
00441 static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00442 {
00443     UCSR1B = 0;
00444 }
00445 
00446 static void uart1_enabletxirq(struct SerialHardware *_hw)
00447 {
00448     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00449 
00450     /*
00451      * WARNING: racy code here!  The tx interrupt
00452      * sets hw->sending to false when it runs with
00453      * an empty fifo.  The order of the statements
00454      * in the if-block matters.
00455      */
00456     if (!hw->sending)
00457     {
00458         hw->sending = true;
00459         SER_UART1_BUS_TXBEGIN;
00460     }
00461 }
00462 
00463 static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
00464 {
00465     /* Compute baud-rate period */
00466     uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1;
00467 
00468     UBRR1H = (period) >> 8;
00469     UBRR1L = (period);
00470 
00471     //DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);)
00472 }
00473 
00474 static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
00475 {
00476     UCSR1C = (UCSR1C & ~(BV(UPM11) | BV(UPM10))) | ((parity) << UPM10);
00477 }
00478 
00479 #endif // AVR_HAS_UART1
00480 
00481 static void spi_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser))
00482 {
00483     /*
00484      * Set MOSI and SCK ports out, MISO in.
00485      *
00486      * The ATmega64/128 datasheet explicitly states that the input/output
00487      * state of the SPI pins is not significant, as when the SPI is
00488      * active the I/O port are overrided.
00489      * This is *blatantly FALSE*.
00490      *
00491      * Moreover, the MISO pin on the board_kc *must* be in high impedance
00492      * state even when the SPI is off, because the line is wired together
00493      * with the KBus serial RX, and the transmitter of the slave boards
00494      * would be unable to drive the line.
00495      */
00496     ATOMIC(SPI_DDR |= (BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT)));
00497 
00498     /*
00499      * If the SPI master mode is activated and the SS pin is in input and tied low,
00500      * the SPI hardware will automatically switch to slave mode!
00501      * For proper communication this pins should therefore be:
00502      * - as output
00503      * - as input but tied high forever!
00504      * This driver set the pin as output.
00505      */
00506     #warning SPI SS pin set as output for proper operation, check schematics for possible conflicts.
00507     ATOMIC(SPI_DDR |= BV(SPI_SS_BIT));
00508 
00509     ATOMIC(SPI_DDR &= ~BV(SPI_MISO_BIT));
00510     /* Enable SPI, IRQ on, Master */
00511     SPCR = BV(SPE) | BV(SPIE) | BV(MSTR);
00512 
00513     /* Set data order */
00514     #if CONFIG_SPI_DATA_ORDER == SER_LSB_FIRST
00515         SPCR |= BV(DORD);
00516     #endif
00517 
00518     /* Set SPI clock rate */
00519     #if CONFIG_SPI_CLOCK_DIV == 128
00520         SPCR |= (BV(SPR1) | BV(SPR0));
00521     #elif (CONFIG_SPI_CLOCK_DIV == 64 || CONFIG_SPI_CLOCK_DIV == 32)
00522         SPCR |= BV(SPR1);
00523     #elif (CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 8)
00524         SPCR |= BV(SPR0);
00525     #elif (CONFIG_SPI_CLOCK_DIV == 4 || CONFIG_SPI_CLOCK_DIV == 2)
00526         // SPR0 & SDPR1 both at 0
00527     #else
00528         #error Unsupported SPI clock division factor.
00529     #endif
00530 
00531     /* Set SPI2X bit (spi double frequency) */
00532     #if (CONFIG_SPI_CLOCK_DIV == 128 || CONFIG_SPI_CLOCK_DIV == 64 \
00533       || CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 4)
00534         SPSR &= ~BV(SPI2X);
00535     #elif (CONFIG_SPI_CLOCK_DIV == 32 || CONFIG_SPI_CLOCK_DIV == 8 || CONFIG_SPI_CLOCK_DIV == 2)
00536         SPSR |= BV(SPI2X);
00537     #else
00538         #error Unsupported SPI clock division factor.
00539     #endif
00540 
00541     /* Set clock polarity */
00542     #if CONFIG_SPI_CLOCK_POL == 1
00543         SPCR |= BV(CPOL);
00544     #endif
00545 
00546     /* Set clock phase */
00547     #if CONFIG_SPI_CLOCK_PHASE == 1
00548         SPCR |= BV(CPHA);
00549     #endif
00550     SER_SPI_BUS_TXINIT;
00551 
00552     SER_STROBE_INIT;
00553 }
00554 
00555 static void spi_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
00556 {
00557     SPCR = 0;
00558 
00559     SER_SPI_BUS_TXCLOSE;
00560 
00561     /* Set all pins as inputs */
00562     ATOMIC(SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT) | BV(SPI_SS_BIT)));
00563 }
00564 
00565 static void spi_starttx(struct SerialHardware *_hw)
00566 {
00567     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00568 
00569     cpuflags_t flags;
00570     IRQ_SAVE_DISABLE(flags);
00571 
00572     /* Send data only if the SPI is not already transmitting */
00573     if (!hw->sending && !fifo_isempty(&ser_spi->txfifo))
00574     {
00575         hw->sending = true;
00576         SPDR = fifo_pop(&ser_spi->txfifo);
00577     }
00578 
00579     IRQ_RESTORE(flags);
00580 }
00581 
00582 static void spi_setbaudrate(
00583     UNUSED_ARG(struct SerialHardware *, _hw),
00584     UNUSED_ARG(unsigned long, rate))
00585 {
00586     // nop
00587 }
00588 
00589 static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity))
00590 {
00591     // nop
00592 }
00593 
00594 static bool tx_sending(struct SerialHardware* _hw)
00595 {
00596     struct AvrSerial *hw = (struct AvrSerial *)_hw;
00597     return hw->sending;
00598 }
00599 
00600 
00601 
00602 // FIXME: move into compiler.h?  Ditch?
00603 #if COMPILER_C99
00604     #define C99INIT(name,val) .name = val
00605 #elif defined(__GNUC__)
00606     #define C99INIT(name,val) name: val
00607 #else
00608     #warning No designated initializers, double check your code
00609     #define C99INIT(name,val) (val)
00610 #endif
00611 
00612 /*
00613  * High-level interface data structures
00614  */
00615 static const struct SerialHardwareVT UART0_VT =
00616 {
00617     C99INIT(init, uart0_init),
00618     C99INIT(cleanup, uart0_cleanup),
00619     C99INIT(setBaudrate, uart0_setbaudrate),
00620     C99INIT(setParity, uart0_setparity),
00621     C99INIT(txStart, uart0_enabletxirq),
00622     C99INIT(txSending, tx_sending),
00623 };
00624 
00625 #if AVR_HAS_UART1
00626 static const struct SerialHardwareVT UART1_VT =
00627 {
00628     C99INIT(init, uart1_init),
00629     C99INIT(cleanup, uart1_cleanup),
00630     C99INIT(setBaudrate, uart1_setbaudrate),
00631     C99INIT(setParity, uart1_setparity),
00632     C99INIT(txStart, uart1_enabletxirq),
00633     C99INIT(txSending, tx_sending),
00634 };
00635 #endif // AVR_HAS_UART1
00636 
00637 static const struct SerialHardwareVT SPI_VT =
00638 {
00639     C99INIT(init, spi_init),
00640     C99INIT(cleanup, spi_cleanup),
00641     C99INIT(setBaudrate, spi_setbaudrate),
00642     C99INIT(setParity, spi_setparity),
00643     C99INIT(txStart, spi_starttx),
00644     C99INIT(txSending, tx_sending),
00645 };
00646 
00647 static struct AvrSerial UARTDescs[SER_CNT] =
00648 {
00649     {
00650         C99INIT(hw, ) {
00651             C99INIT(table, &UART0_VT),
00652             C99INIT(txbuffer, uart0_txbuffer),
00653             C99INIT(rxbuffer, uart0_rxbuffer),
00654             C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
00655             C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
00656         },
00657         C99INIT(sending, false),
00658     },
00659 #if AVR_HAS_UART1
00660     {
00661         C99INIT(hw, ) {
00662             C99INIT(table, &UART1_VT),
00663             C99INIT(txbuffer, uart1_txbuffer),
00664             C99INIT(rxbuffer, uart1_rxbuffer),
00665             C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
00666             C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
00667         },
00668         C99INIT(sending, false),
00669     },
00670 #endif
00671     {
00672         C99INIT(hw, ) {
00673             C99INIT(table, &SPI_VT),
00674             C99INIT(txbuffer, spi_txbuffer),
00675             C99INIT(rxbuffer, spi_rxbuffer),
00676             C99INIT(txbuffer_size, sizeof(spi_txbuffer)),
00677             C99INIT(rxbuffer_size, sizeof(spi_rxbuffer)),
00678         },
00679         C99INIT(sending, false),
00680     }
00681 };
00682 
00683 struct SerialHardware *ser_hw_getdesc(int unit)
00684 {
00685     ASSERT(unit < SER_CNT);
00686     return &UARTDescs[unit].hw;
00687 }
00688 
00689 
00690 /*
00691  * Interrupt handlers
00692  */
00693 
00694 #if CONFIG_SER_HWHANDSHAKE
00695 
00697 SIGNAL(SIG_CTS)
00698 {
00699     // Re-enable UDR empty interrupt and TX, then disable CTS interrupt
00700     UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
00701     EIMSK &= ~EIMSKF_CTS;
00702 }
00703 
00704 #endif // CONFIG_SER_HWHANDSHAKE
00705 
00706 
00710 SIGNAL(USART0_UDRE_vect)
00711 {
00712     SER_STROBE_ON;
00713 
00714     struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
00715 
00716     if (fifo_isempty(txfifo))
00717     {
00718         SER_UART0_BUS_TXEND;
00719 #ifndef SER_UART0_BUS_TXOFF
00720         UARTDescs[SER_UART0].sending = false;
00721 #endif
00722     }
00723 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
00724     else if (!IS_CTS_ON)
00725     {
00726         // Disable rx interrupt and tx, enable CTS interrupt
00727         // UNTESTED
00728         UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
00729         EIFR |= EIMSKF_CTS;
00730         EIMSK |= EIMSKF_CTS;
00731     }
00732 #endif
00733     else
00734     {
00735         char c = fifo_pop(txfifo);
00736         SER_UART0_BUS_TXCHAR(c);
00737     }
00738 
00739     SER_STROBE_OFF;
00740 }
00741 
00742 #ifdef SER_UART0_BUS_TXOFF
00743 
00758 SIGNAL(SIG_UART0_TRANS)
00759 {
00760     SER_STROBE_ON;
00761 
00762     struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
00763     if (fifo_isempty(txfifo))
00764     {
00765         SER_UART0_BUS_TXOFF;
00766         UARTDescs[SER_UART0].sending = false;
00767     }
00768     else
00769         UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
00770 
00771     SER_STROBE_OFF;
00772 }
00773 #endif /* SER_UART0_BUS_TXOFF */
00774 
00775 
00776 #if AVR_HAS_UART1
00777 
00781 SIGNAL(USART1_UDRE_vect)
00782 {
00783     SER_STROBE_ON;
00784 
00785     struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
00786 
00787     if (fifo_isempty(txfifo))
00788     {
00789         SER_UART1_BUS_TXEND;
00790 #ifndef SER_UART1_BUS_TXOFF
00791         UARTDescs[SER_UART1].sending = false;
00792 #endif
00793     }
00794 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
00795     else if (!IS_CTS_ON)
00796     {
00797         // Disable rx interrupt and tx, enable CTS interrupt
00798         // UNTESTED
00799         UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
00800         EIFR |= EIMSKF_CTS;
00801         EIMSK |= EIMSKF_CTS;
00802     }
00803 #endif
00804     else
00805     {
00806         char c = fifo_pop(txfifo);
00807         SER_UART1_BUS_TXCHAR(c);
00808     }
00809 
00810     SER_STROBE_OFF;
00811 }
00812 
00813 #ifdef SER_UART1_BUS_TXOFF
00814 
00819 SIGNAL(SIG_UART1_TRANS)
00820 {
00821     SER_STROBE_ON;
00822 
00823     struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
00824     if (fifo_isempty(txfifo))
00825     {
00826         SER_UART1_BUS_TXOFF;
00827         UARTDescs[SER_UART1].sending = false;
00828     }
00829     else
00830         UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
00831 
00832     SER_STROBE_OFF;
00833 }
00834 #endif /* SER_UART1_BUS_TXOFF */
00835 
00836 #endif // AVR_HAS_UART1
00837 
00838 
00854 SIGNAL(USART0_RX_vect)
00855 {
00856     SER_STROBE_ON;
00857 
00858     /* Disable Recv complete IRQ */
00859     //UCSR0B &= ~BV(RXCIE);
00860     //IRQ_ENABLE;
00861 
00862     /* Should be read before UDR */
00863     ser_uart0->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00864 
00865     /* To clear the RXC flag we must _always_ read the UDR even when we're
00866      * not going to accept the incoming data, otherwise a new interrupt
00867      * will occur once the handler terminates.
00868      */
00869     char c = UDR0;
00870     struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo;
00871 
00872     if (fifo_isfull(rxfifo))
00873         ser_uart0->status |= SERRF_RXFIFOOVERRUN;
00874     else
00875     {
00876         fifo_push(rxfifo, c);
00877 #if CONFIG_SER_HWHANDSHAKE
00878         if (fifo_isfull(rxfifo))
00879             RTS_OFF;
00880 #endif
00881     }
00882 
00883     /* Reenable receive complete int */
00884     //IRQ_DISABLE;
00885     //UCSR0B |= BV(RXCIE);
00886 
00887     SER_STROBE_OFF;
00888 }
00889 
00890 
00891 #if AVR_HAS_UART1
00892 
00904 SIGNAL(USART1_RX_vect)
00905 {
00906     SER_STROBE_ON;
00907 
00908     /* Disable Recv complete IRQ */
00909     //UCSR1B &= ~BV(RXCIE);
00910     //IRQ_ENABLE;
00911 
00912     /* Should be read before UDR */
00913     ser_uart1->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
00914 
00915     /* To avoid an IRQ storm, we must _always_ read the UDR even when we're
00916      * not going to accept the incoming data
00917      */
00918     char c = UDR1;
00919     struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo;
00920     //ASSERT_VALID_FIFO(rxfifo);
00921 
00922     if (UNLIKELY(fifo_isfull(rxfifo)))
00923         ser_uart1->status |= SERRF_RXFIFOOVERRUN;
00924     else
00925     {
00926         fifo_push(rxfifo, c);
00927 #if CONFIG_SER_HWHANDSHAKE
00928         if (fifo_isfull(rxfifo))
00929             RTS_OFF;
00930 #endif
00931     }
00932     /* Re-enable receive complete int */
00933     //IRQ_DISABLE;
00934     //UCSR1B |= BV(RXCIE);
00935 
00936     SER_STROBE_OFF;
00937 }
00938 
00939 #endif // AVR_HAS_UART1
00940 
00941 
00945 SIGNAL(SIG_SPI)
00946 {
00947     SER_STROBE_ON;
00948 
00949     /* Read incoming byte. */
00950     if (!fifo_isfull(&ser_spi->rxfifo))
00951         fifo_push(&ser_spi->rxfifo, SPDR);
00952     /*
00953      * FIXME
00954     else
00955         ser_spi->status |= SERRF_RXFIFOOVERRUN;
00956     */
00957 
00958     /* Send */
00959     if (!fifo_isempty(&ser_spi->txfifo))
00960         SPDR = fifo_pop(&ser_spi->txfifo);
00961     else
00962         UARTDescs[SER_SPI].sending = false;
00963 
00964     SER_STROBE_OFF;
00965 }