changeset 2124:272d1110cda1

* 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).
author asl
date Wed, 08 Feb 2006 10:28:04 +0000
parents 7af5a98be12b
children fae1320c2db8
files packages/devs/serial/generic/16x5x/current/ChangeLog packages/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
diffstat 3 files changed, 49 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/serial/generic/16x5x/current/ChangeLog
+++ b/packages/devs/serial/generic/16x5x/current/ChangeLog
@@ -1,10 +1,22 @@
+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): 
-	Allow platform to define CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR if the
-	baud rate clock (values) cannot be known at compile time.  In this case,
-	the baud rate generator values are provided by platform specific code,
-	computed when the device is first initialized.
+	Allow platform to define CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR 
+	if the baud rate clock (values) cannot be known at compile time.  In 
+	this case, the baud rate generator values are provided by platform 
+	specific code, computed when the device is first initialized.
 
 2003-07-16  Jonathan Larmour  <jifl@eCosCentric.com>
 
--- a/packages/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl
+++ b/packages/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl
@@ -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 {
--- a/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
+++ b/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
@@ -33,9 +33,6 @@
 //
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
@@ -194,6 +191,8 @@ typedef struct pc_serial_info {
         s16550,
         s16550a
     } deviceType;
+    unsigned tx_fifo_size;
+    volatile unsigned tx_fifo_avail;
 #endif
 } pc_serial_info;
 
@@ -304,10 +303,17 @@ serial_config_port(serial_channel *chan,
                 _fcr_thresh=FCR_RT14; break;
             }
             _fcr_thresh|=FCR_FE|FCR_CRF|FCR_CTF;
-            HAL_WRITE_UINT8(base+REG_fcr, _fcr_thresh); // Enable and clear FIFO
+            ser_chan->tx_fifo_size = 
+              CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE;
+            // Enable and clear FIFO
+            HAL_WRITE_UINT8(base+REG_fcr, _fcr_thresh); 
         }
-        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;
@@ -395,16 +401,26 @@ pc_serial_lookup(struct cyg_devtab_entry
 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;
 }
@@ -549,6 +565,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;