Update isr name.
[bertos.git] / bertos / cpu / avr / drv / ser_avr.c
index f37841c6aa7d3212acf020927f47d79edba92c7a..066444822abd40d669fc62ebf41de772ea207af3 100644 (file)
  * the GNU General Public License.
  *
  * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
+ * Copyright 2000 Bernie Innocenti <bernie@codewiz.org>
  *
  * -->
  *
- * \brief AVR UART and SPI I/O driver
- *
- * Rationale for project_ks hardware.
- *
- * The serial 0 on the board_kf board is used to communicate with the
- * smart card, which has the TX and RX lines connected together. To
- * allow the smart card to drive the RX line of the CPU the CPU TX has
- * to be in a high impedance state.
- * Whenever a transmission is done and there is nothing more to send
- * the transmitter is turn off. The output pin is held in input with
- * pull-up enabled, to avoid capturing noise from the nearby RX line.
- *
- * The line on the KBus port must keep sending data, even when
- * there is nothing to transmit, because a burst data transfer
- * generates noise on the audio channels.
- * This is accomplished using the multiprocessor mode of the
- * ATmega64/128 serial.
- *
- * The receiver keeps the MPCM bit always on. When useful data
- * is trasmitted the address bit is set. The receiver hardware
- * consider the frame as address info and receive it.
- * When useless fill bytes are sent the address bit is cleared
- * and the receiver will ignore them, avoiding useless triggering
- * of RXC interrupt.
+ * \brief AVR UART and SPI I/O driver (Implementation)
  *
  * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \author Bernie Innocenti <bernie@codewiz.org>
  * \author Stefano Fedrigo <aleph@develer.com>
  */
 
-#include "hw_ser.h"  /* Required for bus macros overrides */
-#include "hw_cpu.h"  /* CLOCK_FREQ */
+#include "hw/hw_ser.h"  /* Required for bus macros overrides */
+#include "hw/hw_cpu.h"  /* CLOCK_FREQ */
 
-#include <cfg/cfg_ser.h>
+#include "cfg/cfg_ser.h"
 
 #include <cfg/macros.h> /* DIV_ROUND */
 #include <cfg/debug.h>
@@ -73,7 +51,7 @@
 #include <drv/ser_p.h>
 #include <drv/timer.h>
 
-#include <mware/fifobuf.h>
+#include <struct/fifobuf.h>
 
 #include <avr/io.h>
 
 
 
 /* From the high-level serial driver */
-extern struct Serial ser_handles[SER_CNT];
+extern struct Serial *ser_handles[SER_CNT];
 
 /* TX and RX buffers */
 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
@@ -362,20 +340,6 @@ struct AvrSerial
 };
 
 
-/*
- * These are to trick GCC into *not* using absolute addressing mode
- * when accessing ser_handles, which is very expensive.
- *
- * Accessing through these pointers generates much shorter
- * (and hopefully faster) code.
- */
-struct Serial *ser_uart0 = &ser_handles[SER_UART0];
-#if AVR_HAS_UART1
-struct Serial *ser_uart1 = &ser_handles[SER_UART1];
-#endif
-struct Serial *ser_spi = &ser_handles[SER_SPI];
-
-
 
 /*
  * Callbacks
@@ -569,14 +533,14 @@ static void spi_starttx(struct SerialHardware *_hw)
 {
        struct AvrSerial *hw = (struct AvrSerial *)_hw;
 
-       cpuflags_t flags;
+       cpu_flags_t flags;
        IRQ_SAVE_DISABLE(flags);
 
        /* Send data only if the SPI is not already transmitting */
-       if (!hw->sending && !fifo_isempty(&ser_spi->txfifo))
+       if (!hw->sending && !fifo_isempty(&ser_handles[SER_SPI]->txfifo))
        {
                hw->sending = true;
-               SPDR = fifo_pop(&ser_spi->txfifo);
+               SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
        }
 
        IRQ_RESTORE(flags);
@@ -700,7 +664,7 @@ struct SerialHardware *ser_hw_getdesc(int unit)
 SIGNAL(SIG_CTS)
 {
        // Re-enable UDR empty interrupt and TX, then disable CTS interrupt
-       UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
+       UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0);
        EIMSK &= ~EIMSKF_CTS;
 }
 
@@ -714,7 +678,7 @@ SIGNAL(USART0_UDRE_vect)
 {
        SER_STROBE_ON;
 
-       struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
+       struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
 
        if (fifo_isempty(txfifo))
        {
@@ -728,7 +692,7 @@ SIGNAL(USART0_UDRE_vect)
        {
                // Disable rx interrupt and tx, enable CTS interrupt
                // UNTESTED
-               UCSR0B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
+               UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0);
                EIFR |= EIMSKF_CTS;
                EIMSK |= EIMSKF_CTS;
        }
@@ -762,14 +726,14 @@ SIGNAL(SIG_UART0_TRANS)
 {
        SER_STROBE_ON;
 
-       struct FIFOBuffer * const txfifo = &ser_uart0->txfifo;
+       struct FIFOBuffer * const txfifo = &ser_handles[SER_UART0]->txfifo;
        if (fifo_isempty(txfifo))
        {
                SER_UART0_BUS_TXOFF;
                UARTDescs[SER_UART0].sending = false;
        }
        else
-               UCSR0B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
+               UCSR0B = BV(BIT_RXCIE0) | BV(BIT_UDRIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0);
 
        SER_STROBE_OFF;
 }
@@ -785,7 +749,7 @@ SIGNAL(USART1_UDRE_vect)
 {
        SER_STROBE_ON;
 
-       struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
+       struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
 
        if (fifo_isempty(txfifo))
        {
@@ -799,7 +763,7 @@ SIGNAL(USART1_UDRE_vect)
        {
                // Disable rx interrupt and tx, enable CTS interrupt
                // UNTESTED
-               UCSR1B = BV(RXCIE) | BV(RXEN) | BV(TXEN);
+               UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1);
                EIFR |= EIMSKF_CTS;
                EIMSK |= EIMSKF_CTS;
        }
@@ -819,18 +783,18 @@ SIGNAL(USART1_UDRE_vect)
  *
  * \sa port 0 TX complete handler.
  */
-SIGNAL(SIG_UART1_TRANS)
+SIGNAL(USART1_TX_vect)
 {
        SER_STROBE_ON;
 
-       struct FIFOBuffer * const txfifo = &ser_uart1->txfifo;
+       struct FIFOBuffer * const txfifo = &ser_handles[SER_UART1]->txfifo;
        if (fifo_isempty(txfifo))
        {
                SER_UART1_BUS_TXOFF;
                UARTDescs[SER_UART1].sending = false;
        }
        else
-               UCSR1B = BV(RXCIE) | BV(UDRIE) | BV(RXEN) | BV(TXEN);
+               UCSR1B = BV(BIT_RXCIE1) | BV(BIT_UDRIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1);
 
        SER_STROBE_OFF;
 }
@@ -863,17 +827,17 @@ SIGNAL(USART0_RX_vect)
        //IRQ_ENABLE;
 
        /* Should be read before UDR */
-       ser_uart0->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+       ser_handles[SER_UART0]->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
 
        /* To clear the RXC flag we must _always_ read the UDR even when we're
         * not going to accept the incoming data, otherwise a new interrupt
         * will occur once the handler terminates.
         */
        char c = UDR0;
-       struct FIFOBuffer * const rxfifo = &ser_uart0->rxfifo;
+       struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART0]->rxfifo;
 
        if (fifo_isfull(rxfifo))
-               ser_uart0->status |= SERRF_RXFIFOOVERRUN;
+               ser_handles[SER_UART0]->status |= SERRF_RXFIFOOVERRUN;
        else
        {
                fifo_push(rxfifo, c);
@@ -913,17 +877,17 @@ SIGNAL(USART1_RX_vect)
        //IRQ_ENABLE;
 
        /* Should be read before UDR */
-       ser_uart1->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
+       ser_handles[SER_UART1]->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
 
        /* To avoid an IRQ storm, we must _always_ read the UDR even when we're
         * not going to accept the incoming data
         */
        char c = UDR1;
-       struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo;
+       struct FIFOBuffer * const rxfifo = &ser_handles[SER_UART1]->rxfifo;
        //ASSERT_VALID_FIFO(rxfifo);
 
        if (UNLIKELY(fifo_isfull(rxfifo)))
-               ser_uart1->status |= SERRF_RXFIFOOVERRUN;
+               ser_handles[SER_UART1]->status |= SERRF_RXFIFOOVERRUN;
        else
        {
                fifo_push(rxfifo, c);
@@ -950,17 +914,17 @@ SIGNAL(SIG_SPI)
        SER_STROBE_ON;
 
        /* Read incoming byte. */
-       if (!fifo_isfull(&ser_spi->rxfifo))
-               fifo_push(&ser_spi->rxfifo, SPDR);
+       if (!fifo_isfull(&ser_handles[SER_SPI]->rxfifo))
+               fifo_push(&ser_handles[SER_SPI]->rxfifo, SPDR);
        /*
         * FIXME
        else
-               ser_spi->status |= SERRF_RXFIFOOVERRUN;
+               ser_handles[SER_SPI]->status |= SERRF_RXFIFOOVERRUN;
        */
 
        /* Send */
-       if (!fifo_isempty(&ser_spi->txfifo))
-               SPDR = fifo_pop(&ser_spi->txfifo);
+       if (!fifo_isempty(&ser_handles[SER_SPI]->txfifo))
+               SPDR = fifo_pop(&ser_handles[SER_SPI]->txfifo);
        else
                UARTDescs[SER_SPI].sending = false;