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