X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=drv%2Fser_avr.c;h=9e417cc9b40b4e8b95cfef96b8ff1b2827809e62;hb=afe5d3a9cb767208a58907c42d1f00ab4b9bc755;hp=c3bab672a356e0197e3d4013324d4ea080cea135;hpb=0375780817109b6ab5cd4f36ccf80650b2fe77d5;p=bertos.git diff --git a/drv/ser_avr.c b/drv/ser_avr.c index c3bab672..9e417cc9 100755 --- a/drv/ser_avr.c +++ b/drv/ser_avr.c @@ -1,9 +1,9 @@ -/** +/*! * \file * * * \version $Id$ @@ -15,32 +15,15 @@ /* * $Log$ - * Revision 1.1 2004/05/23 18:10:11 bernie - * Import drv/ modules. - * - * Revision 1.30 2004/05/19 17:06:11 bernie - * Serial TX fill mode - * - * Revision 1.29 2004/05/16 19:16:46 aleph - * Serial always transmitting, first try - * - * Revision 1.28 2004/05/14 12:09:00 aleph - * Fix TX port pull-ups + * Revision 1.4 2004/06/03 11:27:09 bernie + * Add dual-license information. * - * Revision 1.27 2004/05/08 13:56:02 aleph - * Adapt avr serial driver to new design + * Revision 1.3 2004/06/02 21:35:24 aleph + * Serial enhancements: interruptible receive handler and 8 bit serial status for AVR; remove volatile attribute to FIFOBuffer, useless for new fifobuf routens * - * Revision 1.25 2004/04/28 13:42:16 aleph - * Serial port fixes + * Revision 1.2 2004/05/23 18:21:53 bernie + * Trim CVS logs and cleanup header info. * - * Revision 1.24 2004/04/08 14:17:27 bernie - * Change serial to disable TX when not sending data - * - * Revision 1.23 2004/04/03 20:39:41 aleph - * Remove strobe - * - * Revision 1.22 2004/03/29 17:01:02 aleph - * Add function to set serial parity, fix it when ser_open is used */ #include "ser.h" @@ -76,14 +59,14 @@ struct AvrSerial #ifdef __AVR_ATmega103__ /* Macro for ATmega103 compatibility */ - #define UCSR0B UCR - #define UDR0 UDR - #define UCSR0A USR + #define UCSR0B UCR + #define UDR0 UDR + #define UCSR0A USR #define UBRR0L UBRR #else - #define UCR UCSR0B - #define UDR UDR0 - #define USR UCSR0A + #define UCR UCSR0B + #define UDR UDR0 + #define USR UCSR0A #endif @@ -307,7 +290,13 @@ SIGNAL(SIG_UART1_DATA) /*! - * Serial 0 RX complete interrupt handler + * Serial 0 RX complete interrupt handler. + * + * This handler is interruptible. + * Interrupt are reenabled as soon as recv complete interrupt is + * disabled. Using INTERRUPT() is troublesome when the serial + * is heavily loaded, because and interrupt could be retriggered + * when executing the handler prologue before RXCIE is disabled. */ #ifdef __AVR_ATmega103__ SIGNAL(SIG_UART_RECV) @@ -315,6 +304,10 @@ SIGNAL(SIG_UART_RECV) SIGNAL(SIG_UART0_RECV) #endif { + /* Disable Recv complete IRQ */ + UCR &= ~BV(RXCIE); + ENABLE_INTS; + /* Should be read before UDR */ ser_handles[SER_UART0].status |= USR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); @@ -334,14 +327,26 @@ SIGNAL(SIG_UART0_RECV) RTS_OFF; #endif } + /* Reenable receive complete int */ + UCR |= BV(RXCIE); } /*! - * Serial 1 RX complete interrupt handler + * Serial 1 RX complete interrupt handler. + * + * This handler is interruptible. + * Interrupt are reenabled as soon as recv complete interrupt is + * disabled. Using INTERRUPT() is troublesome when the serial + * is heavily loaded, because and interrupt could be retriggered + * when executing the handler prologue before RXCIE is disabled. */ #ifndef __AVR_ATmega103__ SIGNAL(SIG_UART1_RECV) { + /* Disable Recv complete IRQ */ + UCSR0B &= ~BV(RXCIE); + ENABLE_INTS; + /* Should be read before UDR */ ser_handles[SER_UART1].status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR); @@ -360,6 +365,8 @@ SIGNAL(SIG_UART1_RECV) RTS_OFF; #endif } + /* Reenable receive complete int */ + UCSR0B |= BV(RXCIE); } #endif /* !__AVR_ATmega103__ */ @@ -384,7 +391,7 @@ static void spi_starttx(UNUSED(struct SerialHardware *ctx)) /* Send data only if the SPI is not already transmitting */ if (!spi_sending && !fifo_isempty(&ser_handles[SER_SPI].txfifo)) { - SPDR = fifo_pop(&ser_handles[SER_SPI].txfifo); + SPDR = fifo_pop(&ser_handles[SER_SPI].txfifo); spi_sending = true; } @@ -420,12 +427,12 @@ __interrupt void UART_TXC_interrupt(void) { UCSRB &= ~TXCIE; ReceiveMode(); - UCSRB = RXCIE | RXEN | TXEN; //Abilito l'Interrupt in ricezione e RX e TX + UCSRB = RXCIE | RXEN | TXEN; //Abilito l'Interrupt in ricezione e RX e TX } */ -static const struct SerialHardwareVT UART0_VT = +static const struct SerialHardwareVT UART0_VT = { .init = uart0_init, .cleanup = uart0_cleanup, @@ -434,7 +441,7 @@ static const struct SerialHardwareVT UART0_VT = .enabletxirq = uart0_enabletxirq, }; -static const struct SerialHardwareVT UART1_VT = +static const struct SerialHardwareVT UART1_VT = { .init = uart1_init, .cleanup = uart1_cleanup, @@ -443,7 +450,7 @@ static const struct SerialHardwareVT UART1_VT = .enabletxirq = uart1_enabletxirq, }; -static const struct SerialHardwareVT SPI_VT = +static const struct SerialHardwareVT SPI_VT = { .init = spi_init, .cleanup = spi_cleanup, @@ -452,17 +459,17 @@ static const struct SerialHardwareVT SPI_VT = static struct AvrSerial UARTDescs[SER_CNT] = { - { - .hw = { .table = &UART0_VT }, - }, - - { - .hw = { .table = &UART1_VT }, - }, - - { - .hw = { .table = &SPI_VT }, - }, + { + .hw = { .table = &UART0_VT }, + }, + + { + .hw = { .table = &UART1_VT }, + }, + + { + .hw = { .table = &SPI_VT }, + }, }; struct SerialHardware* ser_hw_getdesc(int unit)