This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Make better use of the 16x5x UART transmit FIFO


       Hello,


I've finally cleaned up my fix for the generic 16x5x UART driver, as
previously mentioned on ecos-discuss.


Best wishes,
  --Daniel


diff -r e8bf60a19428 devs/serial/generic/16x5x/current/ChangeLog
--- a/devs/serial/generic/16x5x/current/ChangeLog	Wed Nov 24 10:24:02 2004 +0000
+++ b/devs/serial/generic/16x5x/current/ChangeLog	Tue Feb  7 12:28:47 2006 +0100
@@ -1,3 +1,15 @@ 2003-09-19  Gary Thomas  <gary@mlbassoc.
+2006-02-07  Daniel Néri  <daniel.neri@sigicom.se>
+
+	* cdl/ser_generic_16x5x.cdl
+	(CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE): New option.
+
+	* src/ser_16x5x.c (serial_config_port, pc_serial_putc,
+	pc_serial_DSR): At TX interrupt, write up to
+	CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE bytes to the transmit
+	FIFO. This makes better use of the FIFO, since the LSR_THE flag
+	resets when the FIFO is non-empty (not when it's full, as this
+	code previously assumed).
+
 2003-09-19  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/ser_16x5x.c (pc_serial_init): 
diff -r e8bf60a19428 devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl
--- a/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl	Wed Nov 24 10:24:02 2004 +0000
+++ b/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl	Tue Feb  7 12:28:47 2006 +0100
@@ -94,6 +94,15 @@ cdl_package CYGPKG_IO_SERIAL_GENERIC_16X
                 the RX interrupt occurs when a FIFO is used. (16550 and
                 above only), this may be after 1, 4, 8 or 14 characters."
         }
+
+	cdl_option CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE {
+	    display       "16x5x TX FIFO size"
+	    flavor        data
+	    default_value 16
+	    description   "
+	        Configures the maximum number of bytes written to the
+	        16x5x UART transmit FIFO when the TX interrupt occurs."
+	}
     }
 	     
     cdl_component CYGPKG_IO_SERIAL_GENERIC_16X5X_OPTIONS {
diff -r e8bf60a19428 devs/serial/generic/16x5x/current/src/ser_16x5x.c
--- a/devs/serial/generic/16x5x/current/src/ser_16x5x.c	Wed Nov 24 10:24:02 2004 +0000
+++ b/devs/serial/generic/16x5x/current/src/ser_16x5x.c	Tue Feb  7 12:28:47 2006 +0100
@@ -212,6 +212,8 @@ typedef struct pc_serial_info {
         s16550,
         s16550a
     } deviceType;
+    unsigned tx_fifo_size;
+    volatile unsigned tx_fifo_avail;
 #endif
 } pc_serial_info;
 
@@ -332,10 +334,15 @@ serial_config_port(serial_channel *chan,
                 _fcr_thresh=FCR_RT14; break;
             }
             _fcr_thresh|=FCR_FE|FCR_CRF|FCR_CTF;
+            ser_chan->tx_fifo_size = CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE;
             HAL_WRITE_UINT8(base+REG_fcr, _fcr_thresh); // Enable and clear FIFO
         }
-        else
+        else {
+            ser_chan->tx_fifo_size = 1;
             HAL_WRITE_UINT8(base+REG_fcr, 0); // make sure it's disabled
+        }
+
+        ser_chan->tx_fifo_avail = ser_chan->tx_fifo_size;
 #endif
         if (chan->out_cbuf.len != 0) {
             _ier = IER_RCV;
@@ -423,16 +430,26 @@ static bool
 static bool
 pc_serial_putc(serial_channel *chan, unsigned char c)
 {
+#ifndef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
     cyg_uint8 _lsr;
+#endif
     pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
     cyg_addrword_t base = ser_chan->base;
 
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+    if (ser_chan->tx_fifo_avail > 0) {
+        HAL_WRITE_UINT8(base+REG_thr, c);
+        --ser_chan->tx_fifo_avail;
+        return true;
+    }
+#else
     HAL_READ_UINT8(base+REG_lsr, _lsr);
     if (_lsr & LSR_THE) {
         // Transmit buffer is empty
         HAL_WRITE_UINT8(base+REG_thr, c);
         return true;
     }
+#endif
     // No space
     return false;
 }
@@ -626,6 +643,9 @@ pc_serial_DSR(cyg_vector_t vector, cyg_u
             break;
         }
         case ISR_Tx:
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+            ser_chan->tx_fifo_avail = ser_chan->tx_fifo_size;
+#endif
             (chan->callbacks->xmt_char)(chan);
             break;
 
-- 
Daniel Néri <daniel.neri@sigicom.se>
Sigicom AB, Stockholm, Sweden

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]