-/**
+/*!
* \file
* <!--
* Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
+ * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * This file is part of DevLib - See devlib/README for information.
* -->
*
* \version $Id$
/*
* $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"
#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
/*!
- * 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)
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);
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);
RTS_OFF;
#endif
}
+ /* Reenable receive complete int */
+ UCSR0B |= BV(RXCIE);
}
#endif /* !__AVR_ATmega103__ */
/* 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;
}
{
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,
.enabletxirq = uart0_enabletxirq,
};
-static const struct SerialHardwareVT UART1_VT =
+static const struct SerialHardwareVT UART1_VT =
{
.init = uart1_init,
.cleanup = uart1_cleanup,
.enabletxirq = uart1_enabletxirq,
};
-static const struct SerialHardwareVT SPI_VT =
+static const struct SerialHardwareVT SPI_VT =
{
.init = spi_init,
.cleanup = spi_cleanup,
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)