ser_avr.c

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