X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Favr%2Fdrv%2Fser_avr.c;h=d3cc743d0d6ca0e32d7d492832bccfd301a509b5;hb=2c5f3d04467211d59b9387abe73c1f286ea74806;hp=f37841c6aa7d3212acf020927f47d79edba92c7a;hpb=11da44352fcd4d33b173c976db45293ac1a87cca;p=bertos.git diff --git a/bertos/cpu/avr/drv/ser_avr.c b/bertos/cpu/avr/drv/ser_avr.c index f37841c6..d3cc743d 100644 --- a/bertos/cpu/avr/drv/ser_avr.c +++ b/bertos/cpu/avr/drv/ser_avr.c @@ -27,44 +27,22 @@ * the GNU General Public License. * * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/) - * Copyright 2000 Bernardo Innocenti + * Copyright 2000 Bernie Innocenti * * --> * - * \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 + * + * \author Bernie Innocenti * \author Stefano Fedrigo */ -#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 /* CPU_FREQ */ -#include +#include "cfg/cfg_ser.h" #include /* DIV_ROUND */ #include @@ -73,7 +51,7 @@ #include #include -#include +#include #include @@ -326,7 +304,7 @@ /* 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 @@ -413,7 +377,7 @@ static void uart0_enabletxirq(struct SerialHardware *_hw) static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) { /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; + uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1; #if !CPU_AVR_ATMEGA103 UBRR0H = (period) >> 8; @@ -466,7 +430,7 @@ static void uart1_enabletxirq(struct SerialHardware *_hw) static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) { /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, rate) - 1; + uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1; UBRR1H = (period) >> 8; UBRR1L = (period); @@ -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;