/*#*
*#* $Log$
+ *#* Revision 1.16 2004/09/06 21:40:50 bernie
+ *#* Move buffer handling in chip-specific driver.
+ *#*
*#* Revision 1.15 2004/08/25 14:12:08 rasky
*#* Aggiornato il comment block dei log RCS
*#*
*/
int ser_putchar(int c, struct Serial *port)
{
+ //ASSERT_VALID_FIFO(&port->txfifo);
if (fifo_isfull_locked(&port->txfifo))
{
#if CONFIG_SER_TXTIMEOUT != -1
* Get a byte from the FIFO (avoiding sign-extension),
* re-enable RTS, then return result.
*/
- result = (int)(unsigned char)fifo_pop(&port->rxfifo);
+ result = (int)(unsigned char)fifo_pop_locked(&port->rxfifo);
return port->status ? EOF : result;
}
return EOF;
/* NOTE: the double cast prevents unwanted sign extension */
- return (int)(unsigned char)fifo_pop(&port->rxfifo);
+ return (int)(unsigned char)fifo_pop_locked(&port->rxfifo);
}
port->unit = unit;
- /* Initialize circular buffer */
- fifo_init(&port->rxfifo, port->rxbuffer, sizeof(port->rxbuffer));
- fifo_init(&port->txfifo, port->txbuffer, sizeof(port->txbuffer));
-
port->hw = ser_hw_getdesc(unit);
+
+ /* Initialize circular buffers */
+ fifo_init(&port->txfifo, port->hw->txbuffer, port->hw->txbuffer_size);
+ fifo_init(&port->rxfifo, port->hw->rxbuffer, port->hw->rxbuffer_size);
+
port->hw->table->init(port->hw, port);
/* Set default values */
/*#*
*#* $Log$
+ *#* Revision 1.13 2004/09/06 21:40:50 bernie
+ *#* Move buffer handling in chip-specific driver.
+ *#*
*#* Revision 1.12 2004/08/29 22:06:10 bernie
*#* Fix a bug in the (unused) RTS/CTS code; Clarify documentation.
*#*
* SER_STROBE_OFF and SER_STROBE_INIT and set
* CONFIG_SER_STROBE to 1.
*/
-#ifndef CONFIG_SER_STROBE
+#if !defined(CONFIG_SER_STROBE) || !CONFIG_SER_STROBE
#define SER_STROBE_ON do {/*nop*/} while(0)
#define SER_STROBE_OFF do {/*nop*/} while(0)
#define SER_STROBE_INIT do {/*nop*/} while(0)
/* From the high-level serial driver */
extern struct Serial ser_handles[SER_CNT];
+/* TX and RX buffers */
+static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
+static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
+#if AVR_HAS_UART1
+ static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
+ static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
+#endif
+static unsigned char spi_txbuffer[CONFIG_SPI_TXBUFSIZE];
+static unsigned char spi_rxbuffer[CONFIG_SPI_RXBUFSIZE];
+
/*!
* Internal hardware state structure
static struct AvrSerial UARTDescs[SER_CNT] =
{
{
- .hw = { .table = &UART0_VT },
+ .hw = {
+ .table = &UART0_VT,
+ .txbuffer = uart0_txbuffer,
+ .rxbuffer = uart0_rxbuffer,
+ .txbuffer_size = CONFIG_UART0_TXBUFSIZE,
+ .rxbuffer_size = CONFIG_UART0_RXBUFSIZE,
+ },
.sending = false,
},
#if AVR_HAS_UART1
{
- .hw = { .table = &UART1_VT },
+ .hw = {
+ .table = &UART1_VT,
+ .txbuffer = uart1_txbuffer,
+ .rxbuffer = uart1_rxbuffer,
+ .txbuffer_size = CONFIG_UART1_TXBUFSIZE,
+ .rxbuffer_size = CONFIG_UART1_RXBUFSIZE,
+ },
.sending = false,
},
#endif
{
- .hw = { .table = &SPI_VT },
+ .hw = {
+ .table = &SPI_VT,
+ .txbuffer = spi_txbuffer,
+ .rxbuffer = spi_rxbuffer,
+ .txbuffer_size = CONFIG_SPI_TXBUFSIZE,
+ .rxbuffer_size = CONFIG_SPI_RXBUFSIZE,
+ },
.sending = false,
}
};
* disabled. Using INTERRUPT() is troublesome when the serial
* is heavily loaded, because an interrupt could be retriggered
* when executing the handler prologue before RXCIE is disabled.
+ *
+ * \note The code that re-enables interrupts is commented out
+ * because in some nasty cases the interrupt is retriggered.
+ * This is probably due to the RXC flag being set before
+ * RXCIE is cleared. Unfortunately the RXC flag is read-only
+ * and can't be cleared by code.
*/
SIGNAL(SIG_UART0_RECV)
{
SER_STROBE_ON;
/* Disable Recv complete IRQ */
- UCSR0B &= ~BV(RXCIE);
- ENABLE_INTS;
+ //UCSR0B &= ~BV(RXCIE);
+ //ENABLE_INTS;
/* Should be read before UDR */
ser_uart0->status |= UCSR0A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
}
/* Reenable receive complete int */
- UCSR0B |= BV(RXCIE);
+ //DISABLE_INTS;
+ //UCSR0B |= BV(RXCIE);
SER_STROBE_OFF;
}
* disabled. Using INTERRUPT() is troublesome when the serial
* is heavily loaded, because an interrupt could be retriggered
* when executing the handler prologue before RXCIE is disabled.
+ *
+ * \see SIGNAL(SIG_UART0_RECV)
*/
SIGNAL(SIG_UART1_RECV)
{
SER_STROBE_ON;
/* Disable Recv complete IRQ */
- UCSR1B &= ~BV(RXCIE);
- ENABLE_INTS;
+ //UCSR1B &= ~BV(RXCIE);
+ //ENABLE_INTS;
/* Should be read before UDR */
ser_uart1->status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
*/
char c = UDR1;
struct FIFOBuffer * const rxfifo = &ser_uart1->rxfifo;
+ //ASSERT_VALID_FIFO(rxfifo);
- if (fifo_isfull(rxfifo))
+ if (UNLIKELY(fifo_isfull(rxfifo)))
ser_uart1->status |= SERRF_RXFIFOOVERRUN;
else
{
#endif
}
/* Reenable receive complete int */
- UCSR1B |= BV(RXCIE);
+ //UCSR1B |= BV(RXCIE);
SER_STROBE_OFF;
}