IRQ_GETSTATE(): New macro; Rename IRQ macros for consistency.
[bertos.git] / drv / ser_avr.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
6  * This file is part of DevLib - See devlib/README for information.
7  * -->
8  *
9  * \brief AVR UART and SPI I/O driver
10  *
11  * Rationale for project_ks hardware.
12  *
13  * The serial 0 on the board_kf board is used to communicate with the
14  * smart card, which has the TX and RX lines connected together. To
15  * allow the smart card to drive the RX line of the CPU the CPU TX has
16  * to be in a high impedance state.
17  * Whenever a transmission is done and there is nothing more to send
18  * the transmitter is turn off. The output pin is held in input with
19  * pull-up enabled, to avoid capturing noise from the nearby RX line.
20  *
21  * The line on the KBus port must keep sending data, even when
22  * there is nothing to transmit, because a burst data transfer
23  * generates noise on the audio channels.
24  * This is accomplished using the multiprocessor mode of the
25  * ATmega64/128 serial.
26  *
27  * The receiver keeps the MPCM bit always on. When useful data
28  * is trasmitted the address bit is set. The receiver hardware
29  * consider the frame as address info and receive it.
30  * When useless fill bytes are sent the address bit is cleared
31  * and the receiver will ignore them, avoiding useless triggering
32  * of RXC interrupt.
33  *
34  * \version $Id$
35  * \author Bernardo Innocenti <bernie@develer.com>
36  * \author Stefano Fedrigo <aleph@develer.com>
37  */
38
39 /*#*
40  *#* $Log$
41  *#* Revision 1.15  2004/09/14 21:05:36  bernie
42  *#* Use debug.h instead of kdebug.h; Use new AVR pin names; Spelling fixes.
43  *#*
44  *#* Revision 1.14  2004/09/06 21:50:00  bernie
45  *#* Spelling fixes.
46  *#*
47  *#* Revision 1.13  2004/09/06 21:40:50  bernie
48  *#* Move buffer handling in chip-specific driver.
49  *#*
50  *#* Revision 1.12  2004/08/29 22:06:10  bernie
51  *#* Fix a bug in the (unused) RTS/CTS code; Clarify documentation.
52  *#*
53  *#* Revision 1.10  2004/08/10 06:30:41  bernie
54  *#* Major redesign of serial bus policy handling.
55  *#*
56  *#* Revision 1.9  2004/08/02 20:20:29  aleph
57  *#* Merge from project_ks
58  *#*
59  *#* Revision 1.8  2004/07/29 22:57:09  bernie
60  *#* Several tweaks to reduce code size on ATmega8.
61  *#*
62  *#* Revision 1.7  2004/07/18 21:54:23  bernie
63  *#* Add ATmega8 support.
64  *#*
65  *#* Revision 1.5  2004/06/27 15:25:40  aleph
66  *#* Add missing callbacks for SPI;
67  *#* Change UNUSED() macro to new version with two args;
68  *#* Use TX line filling only on the correct KBUS serial port;
69  *#* Fix nasty IRQ disabling bug in recv complete hander for port 1.
70  *#*
71  *#* Revision 1.4  2004/06/03 11:27:09  bernie
72  *#* Add dual-license information.
73  *#*
74  *#* Revision 1.3  2004/06/02 21:35:24  aleph
75  *#* Serial enhancements: interruptible receive handler and 8 bit serial status for AVR; remove volatile attribute to FIFOBuffer, useless for new fifobuf routens
76  *#*
77  *#* Revision 1.2  2004/05/23 18:21:53  bernie
78  *#* Trim CVS logs and cleanup header info.
79  *#*
80  *#*/
81
82 #include "ser.h"
83 #include "ser_p.h"
84 #include "config.h"
85 #include "hw.h"  /* Required for bus macros overrides */
86
87 #include <debug.h>
88 #include <drv/timer.h>
89 #include <mware/fifobuf.h>
90
91 #include <avr/signal.h>
92
93
94 /*!
95  * \name Hardware handshake (RTS/CTS).
96  * \{
97  */
98 #ifndef RTS_ON
99 #define RTS_ON      do {} while (0)
100 #endif
101 #ifndef RTS_OFF
102 #define RTS_OFF     do {} while (0)
103 #endif
104 #ifndef IS_CTS_ON
105 #define IS_CTS_ON   true
106 #endif
107 #ifndef EIMSKB_CTS
108 #define EIMSKB_CTS  0 /*!< Dummy value, must be overridden */
109 #endif
110 /*\}*/
111
112
113 /*!
114  * \name Overridable serial bus hooks
115  *
116  * These can be redefined in hw.h to implement
117  * special bus policies such as half-duplex, 485, etc.
118  *
119  *
120  * \code
121  *  TXBEGIN      TXCHAR      TXEND  TXOFF
122  *    |   __________|__________ |     |
123  *    |   |   |   |   |   |   | |     |
124  *    v   v   v   v   v   v   v v     v
125  * ______  __  __  __  __  __  __  ________________
126  *       \/  \/  \/  \/  \/  \/  \/
127  * ______/\__/\__/\__/\__/\__/\__/
128  *
129  * \endcode
130  *
131  * \{
132  */
133 #ifndef SER_UART0_BUS_TXINIT
134         /*!
135          * Default TXINIT macro - invoked in uart0_init()
136          *
137          * - Enable both the receiver and the transmitter
138          * - Enable only the RX complete interrupt
139          */
140         #define SER_UART0_BUS_TXINIT do { \
141                 UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN); \
142         } while (0)
143 #endif
144
145 #ifndef SER_UART0_BUS_TXBEGIN
146         /*!
147          * Invoked before starting a transmission
148          *
149          * - Enable both the receiver and the transmitter
150          * - Enable both the RX complete and UDR empty interrupts
151          */
152         #define SER_UART0_BUS_TXBEGIN do { \
153                 UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); \
154         } while (0)
155 #endif
156
157 #ifndef SER_UART0_BUS_TXCHAR
158         /*!
159          * Invoked to send one character.
160          */
161         #define SER_UART0_BUS_TXCHAR(c) do { \
162                 UDR0 = (c); \
163         } while (0)
164 #endif
165
166 #ifndef SER_UART0_BUS_TXEND
167         /*!
168          * Invoked as soon as the txfifo becomes empty
169          *
170          * - Keep both the receiver and the transmitter enabled
171          * - Keep the RX complete interrupt enabled
172          * - Disable the UDR empty interrupt
173          */
174         #define SER_UART0_BUS_TXEND do { \
175                 UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN); \
176         } while (0)
177 #endif
178
179 #ifndef SER_UART0_BUS_TXOFF
180         /*!
181          * \def SER_UART0_BUS_TXOFF
182          *
183          * Invoked after the last character has been transmitted
184          *
185          * The default is no action.
186          */
187 #endif
188
189 #ifndef SER_UART1_BUS_TXINIT
190         /*! \sa SER_UART0_BUS_TXINIT */
191         #define SER_UART1_BUS_TXINIT do { \
192                 UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN); \
193         } while (0)
194 #endif
195 #ifndef SER_UART1_BUS_TXBEGIN
196         /*! \sa SER_UART0_BUS_TXBEGIN */
197         #define SER_UART1_BUS_TXBEGIN do { \
198                 UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN); \
199         } while (0)
200 #endif
201 #ifndef SER_UART1_BUS_TXCHAR
202         /*! \sa SER_UART0_BUS_TXCHAR */
203         #define SER_UART1_BUS_TXCHAR(c) do { \
204                 UDR1 = (c); \
205         } while (0)
206 #endif
207 #ifndef SER_UART1_BUS_TXEND
208         /*! \sa SER_UART0_BUS_TXEND */
209         #define SER_UART1_BUS_TXEND do { \
210                 UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN); \
211         } while (0)
212 #endif
213 #ifndef SER_UART1_BUS_TXOFF
214         /*!
215          * \def SER_UART1_BUS_TXOFF
216          *
217          * \see SER_UART0_BUS_TXOFF
218          */
219 #endif
220 /*\}*/
221
222
223 /* SPI port and pin configuration */
224 #define SPI_PORT      PORTB
225 #define SPI_DDR       DDRB
226 #define SPI_SCK_BIT   PB1
227 #define SPI_MOSI_BIT  PB2
228 #define SPI_MISO_BIT  PB3
229
230 /* USART registers definitions */
231 #if defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
232         #define AVR_HAS_UART1 1
233 #elif defined(__AVR_ATmega8__)
234         #define AVR_HAS_UART1 0
235         #define UCSR0A UCSRA
236         #define UCSR0B UCSRB
237         #define UCSR0C UCSRC
238         #define UDR0   UDR
239         #define UBRR0L UBRRL
240         #define UBRR0H UBRRH
241         #define SIG_UART0_DATA SIG_UART_DATA
242         #define SIG_UART0_RECV SIG_UART_RECV
243 #elif defined(__AVR_ATmega103__)
244         #define AVR_HAS_UART1 0
245         #define UCSR0B UCR
246         #define UDR0   UDR
247         #define UCSR0A USR
248         #define UBRR0L UBRR
249         #define SIG_UART0_DATA SIG_UART_DATA
250         #define SIG_UART0_RECV SIG_UART_RECV
251 #else
252         #error Unknown architecture
253 #endif
254
255
256 /*!
257  * \def CONFIG_SER_STROBE
258  *
259  * This is a debug facility that can be used to
260  * monitor SER interrupt activity on an external pin.
261  *
262  * To use strobes, redefine the macros SER_STROBE_ON,
263  * SER_STROBE_OFF and SER_STROBE_INIT and set
264  * CONFIG_SER_STROBE to 1.
265  */
266 #if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE
267         #define SER_STROBE_ON    do {/*nop*/} while(0)
268         #define SER_STROBE_OFF   do {/*nop*/} while(0)
269         #define SER_STROBE_INIT  do {/*nop*/} while(0)
270 #endif
271
272
273 /* From the high-level serial driver */
274 extern struct Serial ser_handles[SER_CNT];
275
276 /* TX and RX buffers */
277 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
278 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
279 #if AVR_HAS_UART1
280         static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
281         static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
282 #endif
283 static unsigned char spi_txbuffer[CONFIG_SPI_TXBUFSIZE];
284 static unsigned char spi_rxbuffer[CONFIG_SPI_RXBUFSIZE];
285
286
287 /*!
288  * Internal hardware state structure
289  *
290  * The \a sending variable is true while the transmission
291  * interrupt is retriggering itself.
292  *
293  * For the USARTs the \a sending flag is useful for taking specific
294  * actions before sending a burst of data, at the start of a trasmission
295  * but not before every char sent.
296  *
297  * For the SPI, this flag is necessary because the SPI sends and receives
298  * bytes at the same time and the SPI IRQ is unique for send/receive.
299  * The only way to start transmission is to write data in SPDR (this
300  * is done by spi_starttx()). We do this *only* if a transfer is
301  * not already started.
302  */
303 struct AvrSerial
304 {
305         struct SerialHardware hw;
306         volatile bool sending;
307 };
308
309
310 /*
311  * These are to trick GCC into *not* using
312  * absolute addressing mode when accessing
313  * ser_handles, which is very expensive.
314  *
315  * Accessing through these pointers generates
316  * much shorter (and hopefully faster) code.
317  */
318 struct Serial *ser_uart0 = &ser_handles[SER_UART0];
319 #if AVR_HAS_UART1
320 struct Serial *ser_uart1 = &ser_handles[SER_UART1];
321 #endif
322 struct Serial *ser_spi = &ser_handles[SER_SPI];
323
324
325
326 /*
327  * Callbacks
328  */
329 static void uart0_init(UNUSED(struct SerialHardware *, _hw), UNUSED(struct Serial *, ser))
330 {
331         SER_UART0_BUS_TXINIT;
332         RTS_ON;
333 }
334
335 static void uart0_cleanup(UNUSED(struct SerialHardware *, _hw))
336 {
337         UCSR0B = 0;
338 }
339
340 static void uart0_enabletxirq(struct SerialHardware *_hw)
341 {
342         struct AvrSerial *hw = (struct AvrSerial *)_hw;
343
344         /*
345          * WARNING: racy code here!  The tx interrupt
346          * sets hw->sending to false when it runs with
347          * an empty fifo.  The order of the statements
348          * in the if-block matters.
349          */
350         if (!hw->sending)
351         {
352                 hw->sending = true;
353                 SER_UART0_BUS_TXBEGIN;
354         }
355 }
356
357 static void uart0_setbaudrate(UNUSED(struct SerialHardware *, _hw), unsigned long rate)
358 {
359         /* Compute baud-rate period */
360         uint16_t period = (((CLOCK_FREQ / 16UL) + (rate / 2)) / rate) - 1;
361
362 #ifndef __AVR_ATmega103__
363         UBRR0H = (period) >> 8;
364 #endif
365         UBRR0L = (period);
366
367         //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);)
368 }
369
370 static void uart0_setparity(UNUSED(struct SerialHardware *, _hw), int parity)
371 {
372 #ifndef __AVR_ATmega103__
373         UCSR0C |= (parity) << UPM0;
374 #endif
375 }
376
377 #if AVR_HAS_UART1
378
379 static void uart1_init(UNUSED(struct SerialHardware *, _hw), UNUSED(struct Serial *, ser))
380 {
381         SER_UART1_BUS_TXINIT;
382         RTS_ON;
383         SER_STROBE_INIT;
384 }
385
386 static void uart1_cleanup(UNUSED(struct SerialHardware *, _hw))
387 {
388         UCSR1B = 0;
389 }
390
391 static void uart1_enabletxirq(struct SerialHardware *_hw)
392 {
393         struct AvrSerial *hw = (struct AvrSerial *)_hw;
394
395         /*
396          * WARNING: racy code here!  The tx interrupt
397          * sets hw->sending to false when it runs with
398          * an empty fifo.  The order of the statements
399          * in the if-block matters.
400          */
401         if (!hw->sending)
402         {
403                 hw->sending = true;
404                 SER_UART1_BUS_TXBEGIN;
405         }
406 }
407
408 static void uart1_setbaudrate(UNUSED(struct SerialHardware *, _hw), unsigned long rate)
409 {
410         /* Compute baud-rate period */
411         uint16_t period = (((CLOCK_FREQ / 16UL) + (rate / 2)) / rate) - 1;
412
413         UBRR1H = (period) >> 8;
414         UBRR1L = (period);
415
416         //DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);)
417 }
418
419 static void uart1_setparity(UNUSED(struct SerialHardware *, _hw), int parity)
420 {
421         UCSR1C |= (parity) << UPM0;
422 }
423
424 #endif // AVR_HAS_UART1
425
426 static void spi_init(UNUSED(struct SerialHardware *, _hw), UNUSED(struct Serial *, ser))
427 {
428         /*
429          * Set MOSI and SCK ports out, MISO in.
430          *
431          * The ATmega64/128 datasheet explicitly states that the input/output
432          * state of the SPI pins is not significant, as when the SPI is
433          * active the I/O port are overrided.
434          * This is *blatantly FALSE*.
435          *
436          * Moreover, the MISO pin on the board_kc *must* be in high impedance
437          * state even when the SPI is off, because the line is wired together
438          * with the KBus serial RX, and the transmitter of the slave boards
439          * would be unable to drive the line.
440          */
441         SPI_DDR |= BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT);
442         SPI_DDR &= ~BV(SPI_MISO_BIT);
443         /* Enable SPI, IRQ on, Master, CPU_CLOCK/16 */
444         SPCR = BV(SPE) | BV(SPIE) | BV(MSTR) | BV(SPR0);
445 }
446
447 static void spi_cleanup(UNUSED(struct SerialHardware *, _hw))
448 {
449         SPCR = 0;
450         /* Set all pins as inputs */
451         SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT));
452 }
453
454 static void spi_starttx(struct SerialHardware *_hw)
455 {
456         struct AvrSerial *hw = (struct AvrSerial *)_hw;
457
458         cpuflags_t flags;
459         DISABLE_IRQSAVE(flags);
460
461         /* Send data only if the SPI is not already transmitting */
462         if (!hw->sending && !fifo_isempty(&ser_spi->txfifo))
463         {
464                 hw->sending = true;
465                 SPDR = fifo_pop(&ser_spi->txfifo);
466         }
467
468         ENABLE_IRQRESTORE(flags);
469 }
470
471 static void spi_setbaudrate(UNUSED(struct SerialHardware *, _hw), UNUSED(unsigned long, rate))
472 {
473         // nop
474 }
475
476 static void spi_setparity(UNUSED(struct SerialHardware *, _hw), UNUSED(int, parity))
477 {
478         // nop
479 }
480
481
482
483 /*
484  * High-level interface data structures
485  */
486 static const struct SerialHardwareVT UART0_VT =
487 {
488         .init = uart0_init,
489         .cleanup = uart0_cleanup,
490         .setbaudrate = uart0_setbaudrate,
491         .setparity = uart0_setparity,
492         .enabletxirq = uart0_enabletxirq,
493 };
494
495 #if AVR_HAS_UART1
496 static const struct SerialHardwareVT UART1_VT =
497 {
498         .init = uart1_init,
499         .cleanup = uart1_cleanup,
500         .setbaudrate = uart1_setbaudrate,
501         .setparity = uart1_setparity,
502         .enabletxirq = uart1_enabletxirq,
503 };
504 #endif // AVR_HAS_UART1
505
506 static const struct SerialHardwareVT SPI_VT =
507 {
508         .init = spi_init,
509         .cleanup = spi_cleanup,
510         .setbaudrate = spi_setbaudrate,
511         .setparity = spi_setparity,
512         .enabletxirq = spi_starttx,
513 };
514
515 static struct AvrSerial UARTDescs[SER_CNT] =
516 {
517         {
518                 .hw = {
519                         .table = &UART0_VT,
520                         .txbuffer = uart0_txbuffer,
521                         .rxbuffer = uart0_rxbuffer,
522                         .txbuffer_size = CONFIG_UART0_TXBUFSIZE,
523                         .rxbuffer_size = CONFIG_UART0_RXBUFSIZE,
524                 },
525                 .sending = false,
526         },
527 #if AVR_HAS_UART1
528         {
529                 .hw = {
530                         .table = &UART1_VT,
531                         .txbuffer = uart1_txbuffer,
532                         .rxbuffer = uart1_rxbuffer,
533                         .txbuffer_size = CONFIG_UART1_TXBUFSIZE,
534                         .rxbuffer_size = CONFIG_UART1_RXBUFSIZE,
535                 },
536                 .sending = false,
537         },
538 #endif
539         {
540                 .hw = {
541                         .table = &SPI_VT,
542                         .txbuffer = spi_txbuffer,
543                         .rxbuffer = spi_rxbuffer,
544                         .txbuffer_size = CONFIG_SPI_TXBUFSIZE,
545                         .rxbuffer_size = CONFIG_SPI_RXBUFSIZE,
546                 },
547                 .sending = false,
548         }
549 };
550
551 struct SerialHardware* ser_hw_getdesc(int unit)
552 {
553         ASSERT(unit < SER_CNT);
554         return &UARTDescs[unit].hw;
555 }
556
557
558
559 /*
560  * Interrupt handlers
561  */
562
563 #if CONFIG_SER_HWHANDSHAKE
564
565 //! This interrupt is triggered when the CTS line goes high
566 SIGNAL(SIG_CTS)
567 {
568         // Re-enable UDR empty interrupt and TX, then disable CTS interrupt
569         UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
570         cbi(EIMSK, EIMSKB_CTS);
571 }
572
573 #endif // CONFIG_SER_HWHANDSHAKE
574
575
576 /*!
577  * Serial 0 TX interrupt handler
578  */
579 SIGNAL(SIG_UART0_DATA)
580 {
581         SER_STROBE_ON;
582
583         struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
584
585         if (fifo_isempty(txfifo))
586         {
587                 SER_UART0_BUS_TXEND;
588 #ifndef SER_UART0_BUS_TXOFF
589                 UARTDescs[SER_UART0].sending = false;
590 #endif
591         }
592 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
593         else if (!IS_CTS_ON)
594         {
595                 // Disable rx interrupt and tx, enable CTS interrupt
596                 // UNTESTED
597                 UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
598                 sbi(EIFR, EIMSKB_CTS);
599                 sbi(EIMSK, EIMSKB_CTS);
600         }
601 #endif
602         else
603         {
604                 char c = fifo_pop(txfifo);
605                 SER_UART0_BUS_TXCHAR(c);
606         }
607
608         SER_STROBE_OFF;
609 }
610
611 #ifdef SER_UART0_BUS_TXOFF
612 /*!
613  * Serial port 0 TX complete interrupt handler.
614  *
615  * This IRQ is usually disabled.  The UDR-empty interrupt
616  * enables it when there's no more data to transmit.
617  * We need to wait until the last character has been
618  * transmitted before switching the 485 transceiver to
619  * receive mode.
620  *
621  * The txfifo might have been refilled by putchar() while
622  * we were waiting for the transmission complete interrupt.
623  * In this case, we must restart the UDR empty interrupt,
624  * otherwise we'd stop the serial port with some data
625  * still pending in the buffer.
626  */
627 SIGNAL(SIG_UART0_TRANS)
628 {
629         SER_STROBE_ON;
630
631         struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
632         if (fifo_isempty(txfifo))
633         {
634                 SER_UART0_BUS_TXOFF;
635                 UARTDescs[SER_UART0].sending = false;
636         }
637         else
638                 UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
639
640         SER_STROBE_OFF;
641 }
642 #endif /* SER_UART0_BUS_TXOFF */
643
644
645 #if AVR_HAS_UART1
646
647 /*!
648  * Serial 1 TX interrupt handler
649  */
650 SIGNAL(SIG_UART1_DATA)
651 {
652         SER_STROBE_ON;
653
654         struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
655
656         if (fifo_isempty(txfifo))
657         {
658                 SER_UART1_BUS_TXEND;
659 #ifndef SER_UART1_BUS_TXOFF
660                 UARTDescs[SER_UART1].sending = false;
661 #endif
662         }
663 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
664         else if (!IS_CTS_ON)
665         {
666                 // Disable rx interrupt and tx, enable CTS interrupt
667                 // UNTESTED
668                 UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
669                 sbi(EIFR, EIMSKB_CTS);
670                 sbi(EIMSK, EIMSKB_CTS);
671         }
672 #endif
673         else
674         {
675                 char c = fifo_pop(txfifo);
676                 SER_UART1_BUS_TXCHAR(c);
677         }
678
679         SER_STROBE_OFF;
680 }
681
682 #ifdef SER_UART1_BUS_TXOFF
683 /*!
684  * Serial port 1 TX complete interrupt handler.
685  *
686  * \sa port 0 TX complete handler.
687  */
688 SIGNAL(SIG_UART1_TRANS)
689 {
690         SER_STROBE_ON;
691
692         struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
693         if (fifo_isempty(txfifo))
694         {
695                 SER_UART1_BUS_TXOFF;
696                 UARTDescs[SER_UART1].sending = false;
697         }
698         else
699                 UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
700
701         SER_STROBE_OFF;
702 }
703 #endif /* SER_UART1_BUS_TXOFF */
704
705 #endif // AVR_HAS_UART1
706
707
708 /*!
709  * Serial 0 RX complete interrupt handler.
710  *
711  * This handler is interruptible.
712  * Interrupt are reenabled as soon as recv complete interrupt is
713  * disabled. Using INTERRUPT() is troublesome when the serial
714  * is heavily loaded, because an interrupt could be retriggered
715  * when executing the handler prologue before RXCIE is disabled.
716  *
717  * \note The code that re-enables interrupts is commented out
718  *       because in some nasty cases the interrupt is retriggered.
719  *       This is probably due to the RXC flag being set before
720  *       RXCIE is cleared.  Unfortunately the RXC flag is read-only
721  *       and can't be cleared by code.
722  */
723 SIGNAL(SIG_UART0_RECV)
724 {
725         SER_STROBE_ON;
726
727         /* Disable Recv complete IRQ */
728         //UCSR0B &= ~BV(RXCIE);
729         //ENABLE_INTS;
730
731         /* Should be read before UDR */
732         ser_uart0->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
733
734         /* To clear the RXC flag we must _always_ read the UDR even when we're
735          * not going to accept the incoming data, otherwise a new interrupt
736          * will occur once the handler terminates.
737          */
738         char c = UDR0;
739         struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo;
740
741         if (fifo_isfull(rxfifo))
742                 ser_uart0->status |= SERRF_RXFIFOOVERRUN;
743         else
744         {
745                 fifo_push(rxfifo, c);
746 #if CONFIG_SER_HWHANDSHAKE
747                 if (fifo_isfull(rxfifo))
748                         RTS_OFF;
749 #endif
750         }
751
752         /* Reenable receive complete int */
753         //DISABLE_INTS;
754         //UCSR0B |= BV(RXCIE);
755
756         SER_STROBE_OFF;
757 }
758
759
760 #if AVR_HAS_UART1
761
762 /*!
763  * Serial 1 RX complete interrupt handler.
764  *
765  * This handler is interruptible.
766  * Interrupt are reenabled as soon as recv complete interrupt is
767  * disabled. Using INTERRUPT() is troublesome when the serial
768  * is heavily loaded, because an interrupt could be retriggered
769  * when executing the handler prologue before RXCIE is disabled.
770  *
771  * \see SIGNAL(SIG_UART0_RECV)
772  */
773 SIGNAL(SIG_UART1_RECV)
774 {
775         SER_STROBE_ON;
776
777         /* Disable Recv complete IRQ */
778         //UCSR1B &= ~BV(RXCIE);
779         //ENABLE_INTS;
780
781         /* Should be read before UDR */
782         ser_uart1->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
783
784         /* To avoid an IRQ storm, we must _always_ read the UDR even when we're
785          * not going to accept the incoming data
786          */
787         char c = UDR1;
788         struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo;
789         //ASSERT_VALID_FIFO(rxfifo);
790
791         if (UNLIKELY(fifo_isfull(rxfifo)))
792                 ser_uart1->status |= SERRF_RXFIFOOVERRUN;
793         else
794         {
795                 fifo_push(rxfifo, c);
796 #if CONFIG_SER_HWHANDSHAKE
797                 if (fifo_isfull(rxfifo))
798                         RTS_OFF;
799 #endif
800         }
801         /* Re-enable receive complete int */
802         //UCSR1B |= BV(RXCIE);
803
804         SER_STROBE_OFF;
805 }
806
807 #endif // AVR_HAS_UART1
808
809
810 /*!
811  * SPI interrupt handler
812  */
813 SIGNAL(SIG_SPI)
814 {
815         /* Read incoming byte. */
816         if (!fifo_isfull(&ser_spi->rxfifo))
817                 fifo_push(&ser_spi->rxfifo, SPDR);
818         /*
819          * FIXME
820         else
821                 ser_spi->status |= SERRF_RXFIFOOVERRUN;
822         */
823
824         /* Send */
825         if (!fifo_isempty(&ser_spi->txfifo))
826                 SPDR = fifo_pop(&ser_spi->txfifo);
827         else
828                 UARTDescs[SER_SPI].sending = false;
829 }