Move buffer handling in chip-specific driver.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 6 Sep 2004 21:40:50 +0000 (21:40 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 6 Sep 2004 21:40:50 +0000 (21:40 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@187 38d2e660-2303-0410-9eaa-f027e97ec537

drv/ser.c
drv/ser.h
drv/ser_avr.c
drv/ser_p.h

index 9e7e96d6d9592b6268fe2760e7456ab94b95f8b5..663366753d72ef5ce29e772fc83e78cd29c6ff58 100755 (executable)
--- a/drv/ser.c
+++ b/drv/ser.c
@@ -28,6 +28,9 @@
 
 /*#*
  *#* $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
  *#*
@@ -105,6 +108,7 @@ struct Serial ser_handles[SER_CNT];
  */
 int ser_putchar(int c, struct Serial *port)
 {
+       //ASSERT_VALID_FIFO(&port->txfifo);
        if (fifo_isfull_locked(&port->txfifo))
        {
 #if CONFIG_SER_TXTIMEOUT != -1
@@ -179,7 +183,7 @@ int ser_getchar(struct Serial *port)
         * 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;
 }
 
@@ -195,7 +199,7 @@ int ser_getchar_nowait(struct Serial *port)
                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);
 }
 
 
@@ -420,11 +424,12 @@ struct Serial *ser_open(unsigned int unit)
 
        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 */
index 918e7a76c825e4062705759c990e6a2ce067e7da..6dddd282d2b9a2464dff78dad521cc245de8eeb3 100755 (executable)
--- a/drv/ser.h
+++ b/drv/ser.h
@@ -14,6 +14,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.12  2004/09/06 21:40:50  bernie
+ *#* Move buffer handling in chip-specific driver.
+ *#*
  *#* Revision 1.11  2004/08/25 14:12:08  rasky
  *#* Aggiornato il comment block dei log RCS
  *#*
@@ -139,7 +142,7 @@ struct Serial
        DB(bool is_open;)
 
        /*!
-        * \name FIFO transmit and receive buffers.
+        * \name Transmit and receive FIFOs.
         *
         * Declared volatile because handled asinchronously by interrupts.
         *
@@ -147,8 +150,6 @@ struct Serial
         */
        FIFOBuffer txfifo;
        FIFOBuffer rxfifo;
-       unsigned char txbuffer[CONFIG_SER_TXBUFSIZE];
-       unsigned char rxbuffer[CONFIG_SER_RXBUFSIZE];
        /* \} */
 
 #if CONFIG_SER_RXTIMEOUT != -1
index 0841c68ff49cc9c51eed63c3d68b14dc95cde245..a1d8519227624e15c806121c05dc5e16d36be312 100755 (executable)
@@ -38,6 +38,9 @@
 
 /*#*
  *#* $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
@@ -496,17 +509,35 @@ static const struct SerialHardwareVT SPI_VT =
 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,
        }
 };
@@ -676,14 +707,20 @@ SIGNAL(SIG_UART1_TRANS)
  * 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);
@@ -707,7 +744,8 @@ SIGNAL(SIG_UART0_RECV)
        }
 
        /* Reenable receive complete int */
-       UCSR0B |= BV(RXCIE);
+       //DISABLE_INTS;
+       //UCSR0B |= BV(RXCIE);
 
        SER_STROBE_OFF;
 }
@@ -723,14 +761,16 @@ SIGNAL(SIG_UART0_RECV)
  * 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);
@@ -740,8 +780,9 @@ SIGNAL(SIG_UART1_RECV)
         */
        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
        {
@@ -752,7 +793,7 @@ SIGNAL(SIG_UART1_RECV)
 #endif
        }
        /* Reenable receive complete int */
-       UCSR1B |= BV(RXCIE);
+       //UCSR1B |= BV(RXCIE);
 
        SER_STROBE_OFF;
 }
index 025d79f26e24ed049ea798784505aacfc3ec7874..9e5b9701f7dc355edc70178add54a5a9a71a2d6d 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.5  2004/09/06 21:40:50  bernie
+ *#* Move buffer handling in chip-specific driver.
+ *#*
  *#* Revision 1.4  2004/08/25 14:12:08  rasky
  *#* Aggiornato il comment block dei log RCS
  *#*
@@ -44,6 +47,10 @@ struct SerialHardwareVT
 struct SerialHardware
 {
        const struct SerialHardwareVT* table;
+       unsigned char *txbuffer;
+       unsigned char *rxbuffer;
+       size_t         txbuffer_size;
+       size_t         rxbuffer_size;
 };
 
 struct SerialHardware* ser_hw_getdesc(int unit);