Update the interrupt signal to new style.
[bertos.git] / bertos / cpu / avr / drv / ser_avr.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2003, 2004, 2010 Develer S.r.l. (http://www.develer.com/)
30  * Copyright 2000 Bernie Innocenti <bernie@codewiz.org>
31  *
32  * -->
33  *
34  * \brief AVR UART and SPI I/O driver (Implementation)
35  *
36  * \author Bernie Innocenti <bernie@codewiz.org>
37  * \author Stefano Fedrigo <aleph@develer.com>
38  * \author Luca Ottaviano <lottaviano@develer.com>
39  */
40
41 #include "hw/hw_ser.h"  /* Required for bus macros overrides */
42 #include <hw/hw_cpufreq.h>  /* CPU_FREQ */
43
44 #include "cfg/cfg_ser.h"
45
46 #include <cfg/macros.h> /* DIV_ROUND */
47 #include <cfg/debug.h>
48 #include <cfg/cfg_arch.h> // ARCH_NIGHTTEST
49
50 #include <drv/ser.h>
51 #include <drv/ser_p.h>
52 #include <drv/timer.h>
53
54 #include <struct/fifobuf.h>
55
56 #include <avr/io.h>
57
58 #if defined(__AVR_LIBC_VERSION__) && (__AVR_LIBC_VERSION__ >= 10400UL)
59         #include <avr/interrupt.h>
60 #else
61         #include <avr/signal.h>
62 #endif
63
64
65 #if !CONFIG_SER_HWHANDSHAKE
66         /**
67          * \name Hardware handshake (RTS/CTS).
68          * \{
69          */
70         #define RTS_ON      do {} while (0)
71         #define RTS_OFF     do {} while (0)
72         #define IS_CTS_ON   true
73         #define EIMSKF_CTS  0 /**< Dummy value, must be overridden */
74         /*\}*/
75 #endif
76
77 #if CPU_AVR_ATMEGA1281
78         #define BIT_RXCIE0 RXCIE0
79         #define BIT_RXEN0  RXEN0
80         #define BIT_TXEN0  TXEN0
81         #define BIT_UDRIE0 UDRIE0
82
83         #define BIT_RXCIE1 RXCIE1
84         #define BIT_RXEN1  RXEN1
85         #define BIT_TXEN1  TXEN1
86         #define BIT_UDRIE1 UDRIE1
87 #elif CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P
88         #define BIT_RXCIE0 RXCIE0
89         #define BIT_RXEN0  RXEN0
90         #define BIT_TXEN0  TXEN0
91         #define BIT_UDRIE0 UDRIE0
92
93         #define BIT_RXCIE1 RXCIE0
94         #define BIT_RXEN1  RXEN0
95         #define BIT_TXEN1  TXEN0
96         #define BIT_UDRIE1 UDRIE0
97 #else
98         #define BIT_RXCIE0 RXCIE
99         #define BIT_RXEN0  RXEN
100         #define BIT_TXEN0  TXEN
101         #define BIT_UDRIE0 UDRIE
102
103         #define BIT_RXCIE1 RXCIE
104         #define BIT_RXEN1  RXEN
105         #define BIT_TXEN1  TXEN
106         #define BIT_UDRIE1 UDRIE
107 #endif
108
109
110 /**
111  * \name Overridable serial bus hooks
112  *
113  * These can be redefined in hw.h to implement
114  * special bus policies such as half-duplex, 485, etc.
115  *
116  *
117  * \code
118  *  TXBEGIN      TXCHAR      TXEND  TXOFF
119  *    |   __________|__________ |     |
120  *    |   |   |   |   |   |   | |     |
121  *    v   v   v   v   v   v   v v     v
122  * ______  __  __  __  __  __  __  ________________
123  *       \/  \/  \/  \/  \/  \/  \/
124  * ______/\__/\__/\__/\__/\__/\__/
125  *
126  * \endcode
127  *
128  * \{
129  */
130 #ifndef SER_UART0_BUS_TXINIT
131         /**
132          * Default TXINIT macro - invoked in uart0_init()
133          *
134          * - Enable both the receiver and the transmitter
135          * - Enable only the RX complete interrupt
136          */
137         #define SER_UART0_BUS_TXINIT do { \
138                 UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
139         } while (0)
140 #endif
141
142 #ifndef SER_UART0_BUS_TXBEGIN
143         /**
144          * Invoked before starting a transmission
145          *
146          * - Enable both the receiver and the transmitter
147          * - Enable both the RX complete and UDR empty interrupts
148          */
149         #define SER_UART0_BUS_TXBEGIN do { \
150                 UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
151         } while (0)
152 #endif
153
154 #ifndef SER_UART0_BUS_TXCHAR
155         /**
156          * Invoked to send one character.
157          */
158         #define SER_UART0_BUS_TXCHAR(c) do { \
159                 UDR0 = (c); \
160         } while (0)
161 #endif
162
163 #ifndef SER_UART0_BUS_TXEND
164         /**
165          * Invoked as soon as the txfifo becomes empty
166          *
167          * - Keep both the receiver and the transmitter enabled
168          * - Keep the RX complete interrupt enabled
169          * - Disable the UDR empty interrupt
170          */
171         #define SER_UART0_BUS_TXEND do { \
172                 UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \
173         } while (0)
174 #endif
175
176 #ifndef SER_UART0_BUS_TXOFF
177         /**
178          * \def SER_UART0_BUS_TXOFF
179          *
180          * Invoked after the last character has been transmitted
181          *
182          * The default is no action.
183          */
184         #ifdef __doxygen__
185         #define SER_UART0_BUS_TXOFF
186         #endif
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(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
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(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
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(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); \
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         #ifdef __doxygen__
220         #define SER_UART1_BUS_TXOFF
221         #endif
222 #endif
223 /*\}*/
224
225
226 /**
227  * \name Overridable SPI hooks
228  *
229  * These can be redefined in hw.h to implement
230  * special bus policies such as slave select pin handling, etc.
231  *
232  * \{
233  */
234 #ifndef SER_SPI_BUS_TXINIT
235         /**
236          * Default TXINIT macro - invoked in spi_init()
237          * The default is no action.
238          */
239         #define SER_SPI_BUS_TXINIT
240 #endif
241
242 #ifndef SER_SPI_BUS_TXCLOSE
243         /**
244          * Invoked after the last character has been transmitted.
245          * The default is no action.
246          */
247         #define SER_SPI_BUS_TXCLOSE
248 #endif
249 /*\}*/
250
251
252 /* SPI port and pin configuration */
253 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA1281
254         #define SPI_PORT      PORTB
255         #define SPI_DDR       DDRB
256         #define SPI_SS_BIT    PB0
257         #define SPI_SCK_BIT   PB1
258         #define SPI_MOSI_BIT  PB2
259         #define SPI_MISO_BIT  PB3
260 // TODO: these bits are the same as ATMEGA8 but the defines in avr-gcc are different.
261 // They should be the same!
262 #elif CPU_AVR_ATMEGA328P
263         #define SPI_PORT      PORTB
264         #define SPI_DDR       DDRB
265         #define SPI_SS_BIT    PORTB2
266         #define SPI_SCK_BIT   PORTB5
267         #define SPI_MOSI_BIT  PORTB3
268         #define SPI_MISO_BIT  PORTB4
269 #elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA168
270         #define SPI_PORT      PORTB
271         #define SPI_DDR       DDRB
272         #define SPI_SS_BIT    PB2
273         #define SPI_SCK_BIT   PB5
274         #define SPI_MOSI_BIT  PB3
275         #define SPI_MISO_BIT  PB4
276 #else
277         #error Unknown architecture
278 #endif
279
280 /* USART register definitions */
281 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281
282         #define AVR_HAS_UART1 1
283 #elif CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P
284         #define AVR_HAS_UART1 0
285         #define USART0_UDRE_vect USART_UDRE_vect
286         #define USART0_RX_vect USART_RX_vect
287         #define USART0_TX_vect USART_TX_vect
288 #elif CPU_AVR_ATMEGA8
289         #define AVR_HAS_UART1 0
290         #define UCSR0A UCSRA
291         #define UCSR0B UCSRB
292         #define UCSR0C UCSRC
293         #define UDR0   UDR
294         #define UBRR0L UBRRL
295         #define UBRR0H UBRRH
296         #define USART0_UDRE_vect USART_UDRE_vect
297         #define USART0_RX_vect USART_RX_vect
298         #define USART0_TX_vect USART_TX_vect
299 #elif CPU_AVR_ATMEGA103
300         #define AVR_HAS_UART1 0
301         #define UCSR0B UCR
302         #define UDR0   UDR
303         #define UCSR0A USR
304         #define UBRR0L UBRR
305         #define USART0_UDRE_vect USART_UDRE_vect
306         #define USART0_RX_vect USART_RX_vect
307         #define USART0_TX_vect USART_TX_vect
308 #else
309         #error Unknown architecture
310 #endif
311
312
313 /* From the high-level serial driver */
314 extern struct Serial *ser_handles[SER_CNT];
315
316 /* TX and RX buffers */
317 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
318 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
319 #if AVR_HAS_UART1
320         static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
321         static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
322 #endif
323 static unsigned char spi_txbuffer[CONFIG_SPI_TXBUFSIZE];
324 static unsigned char spi_rxbuffer[CONFIG_SPI_RXBUFSIZE];
325
326
327 /**
328  * Internal hardware state structure
329  *
330  * The \a sending variable is true while the transmission
331  * interrupt is retriggering itself.
332  *
333  * For the USARTs the \a sending flag is useful for taking specific
334  * actions before sending a burst of data, at the start of a trasmission
335  * but not before every char sent.
336  *
337  * For the SPI, this flag is necessary because the SPI sends and receives
338  * bytes at the same time and the SPI IRQ is unique for send/receive.
339  * The only way to start transmission is to write data in SPDR (this
340  * is done by spi_starttx()). We do this *only* if a transfer is
341  * not already started.
342  */
343 struct AvrSerial
344 {
345         struct SerialHardware hw;
346         volatile bool sending;
347 };
348
349
350
351 /*
352  * Callbacks
353  */
354 static void uart0_init(
355         UNUSED_ARG(struct SerialHardware *, _hw),
356         UNUSED_ARG(struct Serial *, ser))
357 {
358         SER_UART0_BUS_TXINIT;
359         RTS_ON;
360         SER_STROBE_INIT;
361 }
362
363 static void uart0_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
364 {
365         UCSR0B = 0;
366 }
367
368 static void uart0_enabletxirq(struct SerialHardware *_hw)
369 {
370         struct AvrSerial *hw = (struct AvrSerial *)_hw;
371
372         /*
373          * WARNING: racy code here!  The tx interrupt sets hw->sending to false
374          * when it runs with an empty fifo.  The order of statements in the
375          * if-block matters.
376          */
377         if (!hw->sending)
378         {
379                 hw->sending = true;
380                 SER_UART0_BUS_TXBEGIN;
381         }
382 }
383
384 static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
385 {
386         /* Compute baud-rate period */
387         uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1;
388
389 #if !CPU_AVR_ATMEGA103
390         UBRR0H = (period) >> 8;
391 #endif
392         UBRR0L = (period);
393
394         //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);)
395 }
396
397 static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
398 {
399 #if !CPU_AVR_ATMEGA103
400         UCSR0C = (UCSR0C & ~(BV(UPM01) | BV(UPM00))) | ((parity) << UPM00);
401 #endif
402 }
403
404 #if AVR_HAS_UART1
405
406 static void uart1_init(
407         UNUSED_ARG(struct SerialHardware *, _hw),
408         UNUSED_ARG(struct Serial *, ser))
409 {
410         SER_UART1_BUS_TXINIT;
411         RTS_ON;
412         SER_STROBE_INIT;
413 }
414
415 static void uart1_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
416 {
417         UCSR1B = 0;
418 }
419
420 static void uart1_enabletxirq(struct SerialHardware *_hw)
421 {
422         struct AvrSerial *hw = (struct AvrSerial *)_hw;
423
424         /*
425          * WARNING: racy code here!  The tx interrupt
426          * sets hw->sending to false when it runs with
427          * an empty fifo.  The order of the statements
428          * in the if-block matters.
429          */
430         if (!hw->sending)
431         {
432                 hw->sending = true;
433                 SER_UART1_BUS_TXBEGIN;
434         }
435 }
436
437 static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
438 {
439         /* Compute baud-rate period */
440         uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1;
441
442         UBRR1H = (period) >> 8;
443         UBRR1L = (period);
444
445         //DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);)
446 }
447
448 static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
449 {
450         UCSR1C = (UCSR1C & ~(BV(UPM11) | BV(UPM10))) | ((parity) << UPM10);
451 }
452
453 #endif // AVR_HAS_UART1
454
455 static void spi_init(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(struct Serial *, ser))
456 {
457         /*
458          * Set MOSI and SCK ports out, MISO in.
459          *
460          * The ATmega64/128 datasheet explicitly states that the input/output
461          * state of the SPI pins is not significant, as when the SPI is
462          * active the I/O port are overrided.
463          * This is *blatantly FALSE*.
464          *
465          * Moreover, the MISO pin on the board_kc *must* be in high impedance
466          * state even when the SPI is off, because the line is wired together
467          * with the KBus serial RX, and the transmitter of the slave boards
468          * would be unable to drive the line.
469          */
470         ATOMIC(SPI_DDR |= (BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT)));
471
472         /*
473          * If the SPI master mode is activated and the SS pin is in input and tied low,
474          * the SPI hardware will automatically switch to slave mode!
475          * For proper communication this pins should therefore be:
476          * - as output
477          * - as input but tied high forever!
478          * This driver set the pin as output.
479          */
480         #warning FIXME:SPI SS pin set as output for proper operation, check schematics for possible conflicts.
481         ATOMIC(SPI_DDR |= BV(SPI_SS_BIT));
482
483         ATOMIC(SPI_DDR &= ~BV(SPI_MISO_BIT));
484         /* Enable SPI, IRQ on, Master */
485         SPCR = BV(SPE) | BV(SPIE) | BV(MSTR);
486
487         /* Set data order */
488         #if CONFIG_SPI_DATA_ORDER == SER_LSB_FIRST
489                 SPCR |= BV(DORD);
490         #endif
491
492         /* Set SPI clock rate */
493         #if CONFIG_SPI_CLOCK_DIV == 128
494                 SPCR |= (BV(SPR1) | BV(SPR0));
495         #elif (CONFIG_SPI_CLOCK_DIV == 64 || CONFIG_SPI_CLOCK_DIV == 32)
496                 SPCR |= BV(SPR1);
497         #elif (CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 8)
498                 SPCR |= BV(SPR0);
499         #elif (CONFIG_SPI_CLOCK_DIV == 4 || CONFIG_SPI_CLOCK_DIV == 2)
500                 // SPR0 & SDPR1 both at 0
501         #else
502                 #error Unsupported SPI clock division factor.
503         #endif
504
505         /* Set SPI2X bit (spi double frequency) */
506         #if (CONFIG_SPI_CLOCK_DIV == 128 || CONFIG_SPI_CLOCK_DIV == 64 \
507           || CONFIG_SPI_CLOCK_DIV == 16 || CONFIG_SPI_CLOCK_DIV == 4)
508                 SPSR &= ~BV(SPI2X);
509         #elif (CONFIG_SPI_CLOCK_DIV == 32 || CONFIG_SPI_CLOCK_DIV == 8 || CONFIG_SPI_CLOCK_DIV == 2)
510                 SPSR |= BV(SPI2X);
511         #else
512                 #error Unsupported SPI clock division factor.
513         #endif
514
515         /* Set clock polarity */
516         #if CONFIG_SPI_CLOCK_POL == 1
517                 SPCR |= BV(CPOL);
518         #endif
519
520         /* Set clock phase */
521         #if CONFIG_SPI_CLOCK_PHASE == 1
522                 SPCR |= BV(CPHA);
523         #endif
524         SER_SPI_BUS_TXINIT;
525
526         SER_STROBE_INIT;
527 }
528
529 static void spi_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
530 {
531         SPCR = 0;
532
533         SER_SPI_BUS_TXCLOSE;
534
535         /* Set all pins as inputs */
536         ATOMIC(SPI_DDR &= ~(BV(SPI_MISO_BIT) | BV(SPI_MOSI_BIT) | BV(SPI_SCK_BIT) | BV(SPI_SS_BIT)));
537 }
538
539 static void spi_starttx(struct SerialHardware *_hw)
540 {
541         struct AvrSerial *hw = (struct AvrSerial *)_hw;
542
543         cpu_flags_t flags;
544         IRQ_SAVE_DISABLE(flags);
545
546         /* Send data only if the SPI is not already transmitting */
547         if (!hw->sending && !fifo_isempty(&ser_handles[SER_SPI]->txfifo))
548         {
549                 hw->sending = true;
550                 SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
551         }
552
553         IRQ_RESTORE(flags);
554 }
555
556 static void spi_setbaudrate(
557         UNUSED_ARG(struct SerialHardware *, _hw),
558         UNUSED_ARG(unsigned long, rate))
559 {
560         // nop
561 }
562
563 static void spi_setparity(UNUSED_ARG(struct SerialHardware *, _hw), UNUSED_ARG(int, parity))
564 {
565         // nop
566 }
567
568 static bool tx_sending(struct SerialHardware* _hw)
569 {
570         struct AvrSerial *hw = (struct AvrSerial *)_hw;
571         return hw->sending;
572 }
573
574
575
576 // FIXME: move into compiler.h?  Ditch?
577 #if COMPILER_C99
578         #define C99INIT(name,val) .name = val
579 #elif defined(__GNUC__)
580         #define C99INIT(name,val) name: val
581 #else
582         #warning No designated initializers, double check your code
583         #define C99INIT(name,val) (val)
584 #endif
585
586 /*
587  * High-level interface data structures
588  */
589 static const struct SerialHardwareVT UART0_VT =
590 {
591         C99INIT(init, uart0_init),
592         C99INIT(cleanup, uart0_cleanup),
593         C99INIT(setBaudrate, uart0_setbaudrate),
594         C99INIT(setParity, uart0_setparity),
595         C99INIT(txStart, uart0_enabletxirq),
596         C99INIT(txSending, tx_sending),
597 };
598
599 #if AVR_HAS_UART1
600 static const struct SerialHardwareVT UART1_VT =
601 {
602         C99INIT(init, uart1_init),
603         C99INIT(cleanup, uart1_cleanup),
604         C99INIT(setBaudrate, uart1_setbaudrate),
605         C99INIT(setParity, uart1_setparity),
606         C99INIT(txStart, uart1_enabletxirq),
607         C99INIT(txSending, tx_sending),
608 };
609 #endif // AVR_HAS_UART1
610
611 static const struct SerialHardwareVT SPI_VT =
612 {
613         C99INIT(init, spi_init),
614         C99INIT(cleanup, spi_cleanup),
615         C99INIT(setBaudrate, spi_setbaudrate),
616         C99INIT(setParity, spi_setparity),
617         C99INIT(txStart, spi_starttx),
618         C99INIT(txSending, tx_sending),
619 };
620
621 static struct AvrSerial UARTDescs[SER_CNT] =
622 {
623         {
624                 C99INIT(hw, /**/) {
625                         C99INIT(table, &UART0_VT),
626                         C99INIT(txbuffer, uart0_txbuffer),
627                         C99INIT(rxbuffer, uart0_rxbuffer),
628                         C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
629                         C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
630                 },
631                 C99INIT(sending, false),
632         },
633 #if AVR_HAS_UART1
634         {
635                 C99INIT(hw, /**/) {
636                         C99INIT(table, &UART1_VT),
637                         C99INIT(txbuffer, uart1_txbuffer),
638                         C99INIT(rxbuffer, uart1_rxbuffer),
639                         C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
640                         C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
641                 },
642                 C99INIT(sending, false),
643         },
644 #endif
645         {
646                 C99INIT(hw, /**/) {
647                         C99INIT(table, &SPI_VT),
648                         C99INIT(txbuffer, spi_txbuffer),
649                         C99INIT(rxbuffer, spi_rxbuffer),
650                         C99INIT(txbuffer_size, sizeof(spi_txbuffer)),
651                         C99INIT(rxbuffer_size, sizeof(spi_rxbuffer)),
652                 },
653                 C99INIT(sending, false),
654         }
655 };
656
657 struct SerialHardware *ser_hw_getdesc(int unit)
658 {
659         ASSERT(unit < SER_CNT);
660         return &UARTDescs[unit].hw;
661 }
662
663
664 /*
665  * Interrupt handlers
666  */
667
668 #if CONFIG_SER_HWHANDSHAKE
669
670 /// This interrupt is triggered when the CTS line goes high
671 DECLARE_ISR(SIG_CTS)
672 {
673         // Re-enable UDR empty interrupt and TX, then disable CTS interrupt
674         UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0);
675         EIMSK &= ~EIMSKF_CTS;
676 }
677
678 #endif // CONFIG_SER_HWHANDSHAKE
679
680
681 /**
682  * Serial 0 TX interrupt handler
683  */
684 DECLARE_ISR(USART0_UDRE_vect)
685 {
686         SER_STROBE_ON;
687
688         struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
689
690         if (fifo_isempty(txfifo))
691         {
692                 SER_UART0_BUS_TXEND;
693 #ifndef SER_UART0_BUS_TXOFF
694                 UARTDescs[SER_UART0].sending = false;
695 #endif
696         }
697 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
698         else if (!IS_CTS_ON)
699         {
700                 // Disable rx interrupt and tx, enable CTS interrupt
701                 // UNTESTED
702                 UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0);
703                 EIFR |= EIMSKF_CTS;
704                 EIMSK |= EIMSKF_CTS;
705         }
706 #endif
707         else
708         {
709                 char c = fifo_pop(txfifo);
710                 SER_UART0_BUS_TXCHAR(c);
711         }
712
713         SER_STROBE_OFF;
714 }
715
716 #ifdef SER_UART0_BUS_TXOFF
717 /**
718  * Serial port 0 TX complete interrupt handler.
719  *
720  * This IRQ is usually disabled.  The UDR-empty interrupt
721  * enables it when there's no more data to transmit.
722  * We need to wait until the last character has been
723  * transmitted before switching the 485 transceiver to
724  * receive mode.
725  *
726  * The txfifo might have been refilled by putchar() while
727  * we were waiting for the transmission complete interrupt.
728  * In this case, we must restart the UDR empty interrupt,
729  * otherwise we'd stop the serial port with some data
730  * still pending in the buffer.
731  */
732 DECLARE_ISR(USART0_TX_vect)
733 {
734         SER_STROBE_ON;
735
736         struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
737         if (fifo_isempty(txfifo))
738         {
739                 SER_UART0_BUS_TXOFF;
740                 UARTDescs[SER_UART0].sending = false;
741         }
742         else
743                 UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0);
744
745         SER_STROBE_OFF;
746 }
747 #endif /* SER_UART0_BUS_TXOFF */
748
749
750 #if AVR_HAS_UART1
751
752 /**
753  * Serial 1 TX interrupt handler
754  */
755 DECLARE_ISR(USART1_UDRE_vect)
756 {
757         SER_STROBE_ON;
758
759         struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
760
761         if (fifo_isempty(txfifo))
762         {
763                 SER_UART1_BUS_TXEND;
764 #ifndef SER_UART1_BUS_TXOFF
765                 UARTDescs[SER_UART1].sending = false;
766 #endif
767         }
768 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103
769         else if (!IS_CTS_ON)
770         {
771                 // Disable rx interrupt and tx, enable CTS interrupt
772                 // UNTESTED
773                 UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1);
774                 EIFR |= EIMSKF_CTS;
775                 EIMSK |= EIMSKF_CTS;
776         }
777 #endif
778         else
779         {
780                 char c = fifo_pop(txfifo);
781                 SER_UART1_BUS_TXCHAR(c);
782         }
783
784         SER_STROBE_OFF;
785 }
786
787 #ifdef SER_UART1_BUS_TXOFF
788 /**
789  * Serial port 1 TX complete interrupt handler.
790  *
791  * \sa port 0 TX complete handler.
792  */
793 DECLARE_ISR(USART1_TX_vect)
794 {
795         SER_STROBE_ON;
796
797         struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
798         if (fifo_isempty(txfifo))
799         {
800                 SER_UART1_BUS_TXOFF;
801                 UARTDescs[SER_UART1].sending = false;
802         }
803         else
804                 UCSR1B = BV(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1);
805
806         SER_STROBE_OFF;
807 }
808 #endif /* SER_UART1_BUS_TXOFF */
809
810 #endif // AVR_HAS_UART1
811
812
813 /**
814  * Serial 0 RX complete interrupt handler.
815  *
816  * This handler is interruptible.
817  * Interrupt are reenabled as soon as recv complete interrupt is
818  * disabled. Using INTERRUPT() is troublesome when the serial
819  * is heavily loaded, because an interrupt could be retriggered
820  * when executing the handler prologue before RXCIE is disabled.
821  *
822  * \note The code that re-enables interrupts is commented out
823  *       because in some nasty cases the interrupt is retriggered.
824  *       This is probably due to the RXC flag being set before
825  *       RXCIE is cleared.  Unfortunately the RXC flag is read-only
826  *       and can't be cleared by code.
827  */
828 DECLARE_ISR(USART0_RX_vect)
829 {
830         SER_STROBE_ON;
831
832         /* Disable Recv complete IRQ */
833         //UCSR0B &= ~BV(RXCIE);
834         //IRQ_ENABLE;
835
836         /* Should be read before UDR */
837         ser_handles[SER_UART0]->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
838
839         /* To clear the RXC flag we must _always_ read the UDR even when we're
840          * not going to accept the incoming data, otherwise a new interrupt
841          * will occur once the handler terminates.
842          */
843         char c = UDR0;
844         struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART0]->rxfifo;
845
846         if (fifo_isfull(rxfifo))
847                 ser_handles[SER_UART0]->status |= SERRF_RXFIFOOVERRUN;
848         else
849         {
850                 fifo_push(rxfifo, c);
851 #if CONFIG_SER_HWHANDSHAKE
852                 if (fifo_isfull(rxfifo))
853                         RTS_OFF;
854 #endif
855         }
856
857         /* Reenable receive complete int */
858         //IRQ_DISABLE;
859         //UCSR0B |= BV(RXCIE);
860
861         SER_STROBE_OFF;
862 }
863
864
865 #if AVR_HAS_UART1
866
867 /**
868  * Serial 1 RX complete interrupt handler.
869  *
870  * This handler is interruptible.
871  * Interrupt are reenabled as soon as recv complete interrupt is
872  * disabled. Using INTERRUPT() is troublesome when the serial
873  * is heavily loaded, because an interrupt could be retriggered
874  * when executing the handler prologue before RXCIE is disabled.
875  *
876  * \see DECLARE_ISR(USART1_RX_vect)
877  */
878 DECLARE_ISR(USART1_RX_vect)
879 {
880         SER_STROBE_ON;
881
882         /* Disable Recv complete IRQ */
883         //UCSR1B &= ~BV(RXCIE);
884         //IRQ_ENABLE;
885
886         /* Should be read before UDR */
887         ser_handles[SER_UART1]->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
888
889         /* To avoid an IRQ storm, we must _always_ read the UDR even when we're
890          * not going to accept the incoming data
891          */
892         char c = UDR1;
893         struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART1]->rxfifo;
894         //ASSERT_VALID_FIFO(rxfifo);
895
896         if (UNLIKELY(fifo_isfull(rxfifo)))
897                 ser_handles[SER_UART1]->status |= SERRF_RXFIFOOVERRUN;
898         else
899         {
900                 fifo_push(rxfifo, c);
901 #if CONFIG_SER_HWHANDSHAKE
902                 if (fifo_isfull(rxfifo))
903                         RTS_OFF;
904 #endif
905         }
906         /* Re-enable receive complete int */
907         //IRQ_DISABLE;
908         //UCSR1B |= BV(RXCIE);
909
910         SER_STROBE_OFF;
911 }
912
913 #endif // AVR_HAS_UART1
914
915
916 /**
917  * SPI interrupt handler
918  */
919 DECLARE_ISR(SPI_STC_vect)
920 {
921         SER_STROBE_ON;
922
923         /* Read incoming byte. */
924         if (!fifo_isfull(&ser_handles[SER_SPI]->rxfifo))
925                 fifo_push(&ser_handles[SER_SPI]->rxfifo, SPDR);
926         /*
927          * FIXME
928         else
929                 ser_handles[SER_SPI]->status |= SERRF_RXFIFOOVERRUN;
930         */
931
932         /* Send */
933         if (!fifo_isempty(&ser_handles[SER_SPI]->txfifo))
934                 SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
935         else
936                 UARTDescs[SER_SPI].sending = false;
937
938         SER_STROBE_OFF;
939 }