public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* RE: [ECOS]  Re: Half Duplex RS485
@ 2008-01-25  4:16 wangcui
  2008-01-26 20:41 ` Laurie Gellatly
  2008-01-27  4:52 ` [ECOS] Uart missing chars when in Release Laurie Gellatly
  0 siblings, 2 replies; 25+ messages in thread
From: wangcui @ 2008-01-25  4:16 UTC (permalink / raw)
  To: Laurie Gellatly, Grant Edwards, ecos-discuss

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 4736 bytes --]



Here is the patch, shows all modifications in my working folder.
Acutally, I did more than FIFO stuff, I also made it support 2 diffent 16x5x chips on my target(different register-offset-step), and something else.

BTW, I prefer to solve half-duplex problem on hardware level, which avoid lots of effort on software level.

> From: laurie.gellatly@netic.com
> To: iucgnaw@msn.com; grante@visi.com; ecos-discuss@sources.redhat.com
> Subject: RE: [ECOS] Re: Half Duplex RS485
> Date: Fri, 25 Jan 2008 12:59:54 +1100
>
> Hi Wang,
> I'd be interested to see what you had to modify to make the FIFO work.
>
> The eCos source does not know about the fractional divider.
> Did you enable fix that as well?
>
> ...Laurie:{)
>
> -----Original Message-----
> From: wangcui [mailto:iucgnaw@msn.com]
> Sent: Friday, 25 January 2008 12:33 PM
> To: Laurie Gellatly; Grant Edwards; ecos-discuss@sources.redhat.com
> Subject: RE: [ECOS] Re: Half Duplex RS485
>
>
>
> Just FYI, the LPC2XXX's UART0 is not fully functional. So when the 16x5x
> serial driver check FIFO(in serial_config_port()), it will fail, thus FIFO
> is disabled for UART0. But UART1 works fine.
>
> To resolve it, I have to modified 16x5x driver code, force enable FIFO for
> UART0 and UART1.
>
>> From: laurie.gellatly@netic.com
>> To: grante@visi.com; ecos-discuss@sources.redhat.com
>> Date: Thu, 24 Jan 2008 08:12:17 +1100
>> Subject: RE: [ECOS] Re: Half Duplex RS485
>>
>> Wang/Grant, thanks for the replies.
>>
>>>> My project has RS485 half duplex driven by UART0 of an
>>>> LPC2112. At present I've modified pc_serial_start_xmit and
>>>> pc_serial_stop_xmit to change a pin state so that the same
>>>> wires can be used for transmit and receive.
>>>>
>>>> This does not see to work when the FIFO is enabled.
>>>
>>>Then you probably did it wrong. :)
>>>
>>>I imagine that RTS is shutting off too soon. The problem is
>>>that pc_serial_stop_xmit() is called when the driver has no
>>>more data to send _to_ the UART. That's not when you need to
>>>shut off RTS. You need to shut off RTS when the UART is done
>>>sending data and both the FIFO and shift register are empty.
>>>
>>>You're probably shutting off RTS while the UART still has data
>>>in the tx FIFO and the tx shift register.
>> Funny thing is that it appears that the first part of the
>> transmission is lost.
>>
>>>> Has anyone else done RS485 half duplex?
>>>
>>>Many, many times.
>>>
>>>> Did you modify these routines or write your own?
>>>
>>>I usually pick a UART that supports half-duplex operation, and
>>>then just enabled that feature in the UART. [I use a custom
>>>eCos serial driver that supports quite a few more advanced UART
>>>features than the standard driver (e.g. flow control,
>>>half-duplex, inter-byte timeouts, 9-bit modes, FIFO control,
>>>etc.).
>>>
>>>If you don't have a proper UART, you need to enable the tx
>>>shift register empty interrupt and use that to trigger code
>>>that de-asserts RTS. If you're using a broken UART that
>>>doesn't have a tx shift register empty interrupt, then you'll
>>>have to poll for the tx shift register empty status. If you're
>>>using a really broken UART that doesn't have a _working_
>>>shift-register empty status[1], then you may have to start a
>>>timer that will wake you up at the point in time where RTS
>>>needs to be changed.
>>>
>>>> Did you get the FIFO to work?
>>>
>>>When there was one, yes.
>>>
>>>
>>>[1] There are broken UARTs (including a few PC chipsets) whose
>>> shift-register empty bit gets set _before_ the stop bit has
>>> been sent. In that case, you may need to use some sort of
>>> time-delay to wait until after the stop bit has been sent
>>> to toggle RTS. On a properly implimented RS-485 bus, there
>>> should be pull-up and pull-down resisters so that the bus
>>> idles in the mark state (same value as a stop bit), but to
>>> be on the safe side you should leave the bus driver on
>>> until after the stop bit has been sent.
>>
>> Grant, do you know if the LPC series have 'broken' UARTS?
>> Specifically LPC2212 and LPC2103?
>> U0TSR looks promising as an indication of when the bits
>> 'have left the building' - is it accurate or do I
>> need to add a time delay?
>>
>> Really appreciate the help. ...Laurie:{)
>>
>> --
>> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
>> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>>
>
> _________________________________________________________________
> ÌìÁ¹ÁË£¬ÌíÒÂÁË£¬ÐĶ¯ÁË£¬¡°Æß¼þ¡±ÁË
> http://get.live.cn
>

_________________________________________________________________
MSN ÖÐÎÄÍø£¬×îÐÂʱÉÐÉú»î×ÊѶ£¬°×Áì¾Û¼¯ÃÅ»§¡£
http://cn.msn.com

[-- Attachment #2: 16x5x.patch --]
[-- Type: text/plain, Size: 10771 bytes --]

diff -r -u5 -N -x CVS /cygdrive/z/Share/Resource/eCos/anoncvs/ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c /cygdrive/d/work/dev/ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
--- /cygdrive/z/Share/Resource/eCos/anoncvs/ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c	2007-06-22 19:41:49.000000000 +0800
+++ /cygdrive/d/work/dev/ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c	2008-01-25 11:47:46.232562700 +0800
@@ -62,15 +62,18 @@
 #include <cyg/hal/hal_io.h>
 
 // Only compile driver if an inline file with driver details was selected.
 #ifdef CYGDAT_IO_SERIAL_GENERIC_16X5X_INL
 
-#ifndef CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP
-#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 1
-#endif
-
-#define SER_REG(_x_) ((_x_)*CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP)
+//here we use a 'step' variable to indicate the address delta between a 16X5X channel's registers
+//user should new a variable named 'step' and set appropriate value before access 16X5X's register.
+//For example:
+//{
+//  int step = ser_chan->step;
+//  HAL_WRITE_UINT8(base+REG_thr, c);
+//}
+#define SER_REG(_x_) ((_x_)*step)
 
 // Receive control Registers
 #define REG_rhr SER_REG(0)    // Receive holding register
 #define REG_isr SER_REG(2)    // Interrupt status register
 #define REG_lsr SER_REG(5)    // Line status register
@@ -180,10 +183,15 @@
 // selec_baud[] must be define by the client
 
 typedef struct pc_serial_info {
     cyg_addrword_t base;
     int            int_num;
+    int            int_prio;
+    int            step;
+    int            baud_num;
+    int           *select_baud;
+    int          (*baud_generator)(unsigned int baud);
     cyg_interrupt  serial_interrupt;
     cyg_handle_t   serial_interrupt_handle;
 #ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
     enum {
         sNone = 0,
@@ -233,12 +241,17 @@
 serial_config_port(serial_channel *chan, 
                    cyg_serial_info_t *new_config, bool init)
 {
     pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
     cyg_addrword_t base = ser_chan->base;
-    unsigned short baud_divisor = select_baud[new_config->baud];
+    int step = ser_chan->step;
+    unsigned short baud_divisor;
     unsigned char _lcr, _ier;
+    
+    if (new_config->baud >= ser_chan->baud_num) return false;  // Invalid configuration
+
+    baud_divisor = ser_chan->select_baud[new_config->baud];
     if (baud_divisor == 0) return false;  // Invalid configuration
 
     // Disable port interrupts while changing hardware
     HAL_READ_UINT8(base+REG_ier, _ier);
     HAL_WRITE_UINT8(base+REG_ier, 0);
@@ -253,21 +266,22 @@
     if (init) {
 #ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
         unsigned char _fcr_thresh;
         cyg_uint8 b;
 
-        /* First, find out what kind of device it is. */
-        ser_chan->deviceType = sNone;
-        HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP); // enable loopback mode
-        HAL_READ_UINT8(base+REG_msr, b);         
-        if (0 == (b & 0xF0)) {   // see if MSR had CD, RI, DSR or CTS set
-            HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP|MCR_DTR|MCR_RTS);
-            HAL_READ_UINT8(base+REG_msr, b);
-            if (0xF0 != (b & 0xF0))  // check that all of CD,RI,DSR and CTS set
-                ser_chan->deviceType = s8250;
+        if (ser_chan->deviceType == sNone) {
+            /* First, find out what kind of device it is. */
+            HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP); // enable loopback mode
+            HAL_READ_UINT8(base+REG_msr, b);         
+            if (0 == (b & 0xF0)) {   // see if MSR had CD, RI, DSR or CTS set
+                HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP|MCR_DTR|MCR_RTS);
+                HAL_READ_UINT8(base+REG_msr, b);
+                if (0xF0 != (b & 0xF0))  // check that all of CD,RI,DSR and CTS set
+                    ser_chan->deviceType = s8250;
+            }
+            HAL_WRITE_UINT8(base+REG_mcr, 0); // disable loopback mode
         }
-        HAL_WRITE_UINT8(base+REG_mcr, 0); // disable loopback mode
 
         if (ser_chan->deviceType == s8250) {
             // Check for a scratch register; scratch register 
             // indicates 16450 or above.
             HAL_WRITE_UINT8(base+REG_scr, 0x55);
@@ -308,10 +322,11 @@
               CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE;
             // Enable and clear FIFO
             HAL_WRITE_UINT8(base+REG_fcr, _fcr_thresh); 
         }
         else {
+            CYG_FAIL("Can't enable FIFO on this device.");
             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;
@@ -348,36 +363,39 @@
 
 #ifdef CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR
     // Fill in baud rate table - used for platforms where this cannot
     // be determined statically
     int baud_idx, baud_val;
-    if (select_baud[0] == 9999) {
+
+    if (ser_chan->select_baud[0] == 9999) {
+        CYG_ASSERTC(ser_chan->baud_generator != NULL);
+
         // Table not yet initialized
         // Assumes that 'select_baud' looks like this:
         //   static int select_baud[] = {
         //       9999,  -- marker
         //       50,    -- first baud rate
         //       110,   -- second baud rate
         // etc.
-        for (baud_idx = 1;  baud_idx < sizeof(select_baud)/sizeof(select_baud[0]);  baud_idx++) {
-            baud_val = CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR(select_baud[baud_idx]);
-            select_baud[baud_idx] = baud_val;
+        for (baud_idx = 1;  baud_idx < ser_chan->baud_num;  baud_idx++) {
+            baud_val = ser_chan->baud_generator(ser_chan->select_baud[baud_idx]);
+            ser_chan->select_baud[baud_idx] = baud_val;
         }
-        select_baud[0] = 0;
+        ser_chan->select_baud[0] = 0;
     }
 #endif
 
 #ifdef CYGDBG_IO_INIT
-    diag_printf("16x5x SERIAL init - dev: %x.%d\n", 
-                ser_chan->base, ser_chan->int_num);
+    diag_printf("16x5x SERIAL init - dev: base=%x.step=%d.int_num=%d\n", 
+                ser_chan->base, ser_chan->step, ser_chan->int_num);
 #endif
     // Really only required for interrupt driven devices
     (chan->callbacks->serial_init)(chan);
 
     if (chan->out_cbuf.len != 0) {
         cyg_drv_interrupt_create(ser_chan->int_num,
-                                 CYG_IO_SERIAL_GENERIC_16X5X_INT_PRIORITY,
+                                 ser_chan->int_prio == -1 ? CYG_IO_SERIAL_GENERIC_16X5X_INT_PRIORITY : ser_chan->int_prio,
                                  (cyg_addrword_t)chan,
                                  pc_serial_ISR,
                                  pc_serial_DSR,
                                  &ser_chan->serial_interrupt_handle,
                                  &ser_chan->serial_interrupt);
@@ -409,10 +427,11 @@
 #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;
+    int step = ser_chan->step;
 
 #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;
@@ -436,10 +455,11 @@
 {
     unsigned char c;
     cyg_uint8 _lsr;
     pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
     cyg_addrword_t base = ser_chan->base;
+    int step = ser_chan->step;
 
     // Wait for char
     do {
         HAL_READ_UINT8(base+REG_lsr, _lsr);
     } while ((_lsr & LSR_RSR) == 0);
@@ -469,10 +489,11 @@
     case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
       {
           cyg_uint8 _mcr;
           pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
           cyg_addrword_t base = ser_chan->base;
+          int step = ser_chan->step;
           cyg_uint32 *f = (cyg_uint32 *)xbuf;
           unsigned char mask=0;
           if ( *len < sizeof(*f) )
               return -EINVAL;
           
@@ -509,26 +530,34 @@
 static void
 pc_serial_start_xmit(serial_channel *chan)
 {
     pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
     cyg_addrword_t base = ser_chan->base;
-    cyg_uint8 _ier;
+    int step = ser_chan->step;
+    cyg_uint8 _ier, _lsr;
     
     HAL_READ_UINT8(base+REG_ier, _ier);
     _ier |= IER_XMT;                    // Enable xmit interrupt
     HAL_WRITE_UINT8(base+REG_ier, _ier);
 #ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME
-    (chan->callbacks->xmt_char)(chan);
+    //some chip(at least LPC2XXX's embedded DUART) may not generate ISR_Tx interrupt after enable IER_XMT,
+    //so we try transmitting here to trigger the ISR_Tx intertupt.
+    HAL_READ_UINT8(base+REG_lsr, _lsr);
+    if ((_lsr & LSR_THE)) {
+        // transmitter holding register ready
+        (chan->callbacks->xmt_char)(chan);
+    }
 #endif
 }
 
 // Disable the transmitter on the device
 static void 
 pc_serial_stop_xmit(serial_channel *chan)
 {
     pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
     cyg_addrword_t base = ser_chan->base;
+    int step = ser_chan->step;
     cyg_uint8 _ier;
 
     HAL_READ_UINT8(base+REG_ier, _ier);
     _ier &= ~IER_XMT;                   // Disable xmit interrupt
     HAL_WRITE_UINT8(base+REG_ier, _ier);
@@ -550,10 +579,11 @@
 pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
 {
     serial_channel *chan = (serial_channel *)data;
     pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
     cyg_addrword_t base = ser_chan->base;
+    int step = ser_chan->step;
     cyg_uint8 _isr;
 
     // Check if we have an interrupt pending - note that the interrupt
     // is pending of the low bit of the isr is *0*, not 1.
     HAL_READ_UINT8(base+REG_isr, _isr);
@@ -645,14 +675,16 @@
                 }
             }
             break;
 #endif
         default:
-            // Yes, this assertion may well not be visible. *But*
-            // if debugging, we may still successfully hit a breakpoint
-            // on cyg_assert_fail, which _is_ useful
-            CYG_FAIL("unhandled serial interrupt state");
+            #if 0
+            //some chip(at least Philips SC16C2550B) may generate a interrupt without valid source,
+            //so we print a error message rather than die here.
+            diag_printf("unhandled serial interrupt state""\r\n");
+            #endif
+            break;
         }
 
         HAL_READ_UINT8(base+REG_isr, _isr);
     } // while
 

[-- Attachment #3: Type: text/plain, Size: 148 bytes --]

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Half Duplex RS485
  2008-01-25  4:16 [ECOS] Re: Half Duplex RS485 wangcui
@ 2008-01-26 20:41 ` Laurie Gellatly
  2008-01-28 10:34   ` wangcui
  2008-01-27  4:52 ` [ECOS] Uart missing chars when in Release Laurie Gellatly
  1 sibling, 1 reply; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-26 20:41 UTC (permalink / raw)
  To: ecos-discuss

Hi Wang,
I've been looking through the patch you sent.
I don't see any change to the FIFO handling unless you mean where
it figures out the deviceType?

			...Laurie:{)

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS] Uart missing chars when in Release
  2008-01-25  4:16 [ECOS] Re: Half Duplex RS485 wangcui
  2008-01-26 20:41 ` Laurie Gellatly
@ 2008-01-27  4:52 ` Laurie Gellatly
  2008-01-27  5:14   ` [ECOS] " Grant Edwards
  1 sibling, 1 reply; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-27  4:52 UTC (permalink / raw)
  To: ecos-discuss

Hi All,
I have an LPC2112 UART0 running at 117K (2112 does not have the 
fractional divider, 2112/01 does).

I'm sending it 100 characters (1 to 100) at that baud 
and printing out the characters after they have all arrived.

I get consistently 100 chars arriving when the app is run in RAM under
debug in eclipse. When running the Release code from flash, about 
30% of the  time I get less than 100. By less I mean up to 14 characters
less. The missing characters are typically together in 1 or 2 
bursts.

I can't spot what is making the difference. I've checked the ecc files
and made then as close as possible. I have noticed, that for some
strange reason, telling eCos to disable the FIFO seems to help though 
its does not seem to set it up or make use of it.

Any suggestions on what to try next?

Thanks			...Laurie:{)



-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Uart missing chars when in Release
  2008-01-27  4:52 ` [ECOS] Uart missing chars when in Release Laurie Gellatly
@ 2008-01-27  5:14   ` Grant Edwards
  2008-01-27  6:46     ` Laurie Gellatly
  0 siblings, 1 reply; 25+ messages in thread
From: Grant Edwards @ 2008-01-27  5:14 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-27, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

> I have an LPC2112 UART0 running at 117K (2112 does not have
> the fractional divider, 2112/01 does).
>
> I'm sending it 100 characters (1 to 100) at that baud and
> printing out the characters after they have all arrived.

Arrived where?  Sending from where?

Is eCos running on both the sending and receiving device? Are
the "missing" caracters actually on the wire or not? (That
would tell you whether it's the sender's fault or the
receiver's fault).

> I get consistently 100 chars arriving when the app is run in
> RAM under debug in eclipse. When running the Release code from
> flash, about 30% of the time I get less than 100. By less I
> mean up to 14 characters less. The missing characters are
> typically together in 1 or 2 bursts.
>
> I can't spot what is making the difference.

I'm not familiar with your platform, but on many platforms
running from flash can be much, much slower than running from
RAM -- in some cases up to maybe 8-10X slower, but 4X slower is
more typical.  Flash often has much slower access times that
RAM and is often narrower than RAM.  2X bus cycles with 4X
access time can add up pretty fast.

> I've checked the ecc files and made then as close as possible.
> I have noticed, that for some strange reason, telling eCos to
> disable the FIFO seems to help though its does not seem to set
> it up or make use of it.
>
> Any suggestions on what to try next?

Are you seeing rx overrun errors?  If the rx end is running too
slowly for the data rate, you would see rx overrun errors.

-- 
Grant Edwards                   grante             Yow!  What UNIVERSE is
                                  at               this, please??
                               visi.com            


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Uart missing chars when in Release
  2008-01-27  5:14   ` [ECOS] " Grant Edwards
@ 2008-01-27  6:46     ` Laurie Gellatly
  2008-01-27  9:54       ` Grant Edwards
  0 siblings, 1 reply; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-27  6:46 UTC (permalink / raw)
  To: Grant Edwards, ecos-discuss

Hi Grant,
>> I have an LPC2112 UART0 running at 117K (2112 does not have
>> the fractional divider, 2112/01 does).
>>
>> I'm sending it 100 characters (1 to 100) at that baud and
>> printing out the characters after they have all arrived.

>Arrived where?  Sending from where?
Coming from a LPC2103 not running eCos.

>Is eCos running on both the sending and receiving device? Are
>the "missing" caracters actually on the wire or not? (That
>would tell you whether it's the sender's fault or the
>receiver's fault).
The missing chars are on the wire - I've snooped them.

>> I get consistently 100 chars arriving when the app is run in
>> RAM under debug in eclipse. When running the Release code from
>> flash, about 30% of the time I get less than 100. By less I
>> mean up to 14 characters less. The missing characters are
>> typically together in 1 or 2 bursts.
>>
>> I can't spot what is making the difference.

>I'm not familiar with your platform, but on many platforms
>running from flash can be much, much slower than running from
>RAM -- in some cases up to maybe 8-10X slower, but 4X slower is
>more typical.  Flash often has much slower access times that
>RAM and is often narrower than RAM.  2X bus cycles with 4X
>access time can add up pretty fast.

The same platform also runs an Ethernet interface without problems.
10Mbit is quite a bit faster than 115K baud so I feel I can
probably discount that.

>Are you seeing rx overrun errors?  If the rx end is running too
>slowly for the data rate, you would see rx overrun errors.

From what I've read, the OE gets cleared on each read of RBR.
How can I check on this? Is there a counter of OE and other errors
kept in eCos that I can access?

Thanks			...Laurie:{)

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Uart missing chars when in Release
  2008-01-27  6:46     ` Laurie Gellatly
@ 2008-01-27  9:54       ` Grant Edwards
  2008-01-27 11:20         ` Laurie Gellatly
  0 siblings, 1 reply; 25+ messages in thread
From: Grant Edwards @ 2008-01-27  9:54 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-27, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

> The missing chars are on the wire - I've snooped them.

So the receiver is at fault.

>> I'm not familiar with your platform, but on many platforms
>> running from flash can be much, much slower than running from
>> RAM -- in some cases up to maybe 8-10X slower, but 4X slower
>> is more typical.  Flash often has much slower access times
>> that RAM and is often narrower than RAM.  2X bus cycles with
>> 4X access time can add up pretty fast.
>
> The same platform also runs an Ethernet interface without
> problems. 10Mbit is quite a bit faster than 115K baud so I
> feel I can probably discount that.

At 117Kbps with no fifo, you have to service a receive
interrupt at a 11.7KHz or you lose bytes.  That means you've
got to have an interrupt latency less than 85us.

The Ethernet interface only produces an interrupt once per
frame. I'd be surprised if you're transferring more than a
hundred frames per second. The Ethernet interface probabably
also has a buffer queue.  That means that the Ethernet
interface can tolerate an interrupt latency 10-20X larger than
the serial interface can tolerate.  The Ethernet service
routine also probably produces a pretty long interrupt latency
while its DSR is running.  (It's probably the DSR latency that
matters rather than the ISR latency.)

Does it stop dropping bytes at lower baud rates?

Does it stop dropping bytes if there is no Ethernet traffic?

Running from flash is almost certainly slower, and I'd wager
that it increases the interrupt latency beyond what can be
tolerated by the serial interface's interrupt frequency.

>> Are you seeing rx overrun errors?  If the rx end is running
>> too slowly for the data rate, you would see rx overrun errors.
>
> From what I've read, the OE gets cleared on each read of RBR.
> How can I check on this? Is there a counter of OE and other
> errors kept in eCos that I can access?

You've got the source code, you tell me.  -- I don't know what
low-level driver you're using. If it doesn't have an OE
counter, you can add one: it's only a couple lines of code.

You could also add a line of code to the serial driver's DSR
that toggles a spare port pin.  Then watch that pin while it's
receiving data.  That should give a pretty good idea if
interrupt latency is the problem. 

-- 
Grant



-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Uart missing chars when in Release
  2008-01-27  9:54       ` Grant Edwards
@ 2008-01-27 11:20         ` Laurie Gellatly
  2008-01-27 15:55           ` Grant Edwards
  0 siblings, 1 reply; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-27 11:20 UTC (permalink / raw)
  To: ecos-discuss

Hi Grant,
>> The missing chars are on the wire - I've snooped them.

>So the receiver is at fault.
Definitely.

>>> I'm not familiar with your platform, but on many platforms
>>> running from flash can be much, much slower than running from
>>> RAM -- in some cases up to maybe 8-10X slower, but 4X slower
>>> is more typical.  Flash often has much slower access times
>>> that RAM and is often narrower than RAM.  2X bus cycles with
>>> 4X access time can add up pretty fast.
>>
>> The same platform also runs an Ethernet interface without
>> problems. 10Mbit is quite a bit faster than 115K baud so I
>> feel I can probably discount that.

>At 117Kbps with no fifo, you have to service a receive
>interrupt at a 11.7KHz or you lose bytes.  That means you've
>got to have an interrupt latency less than 85us.
So I modified ser_16X5X.c to read FIFO threshold (1,4,8 or 14)
characters worth when an RDA interrupt occurs.
With it set to 8 that should give 8 times as long to service
the interrupt. 

>The Ethernet interface only produces an interrupt once per
>frame. I'd be surprised if you're transferring more than a
>hundred frames per second. The Ethernet interface probabably
>also has a buffer queue.  That means that the Ethernet
>interface can tolerate an interrupt latency 10-20X larger than
>the serial interface can tolerate.  The Ethernet service
>routine also probably produces a pretty long interrupt latency
>while its DSR is running.  (It's probably the DSR latency that
>matters rather than the ISR latency.)
Hmm, unfortunately that sounds right.

>Does it stop dropping bytes at lower baud rates?
Try that next.

>Does it stop dropping bytes if there is no Ethernet traffic?
Tried that. No difference.

>Running from flash is almost certainly slower, and I'd wager
>that it increases the interrupt latency beyond what can be
>tolerated by the serial interface's interrupt frequency.
Maybe I should copy ISR or DSR to internal RAM or flash?

>>> Are you seeing rx overrun errors?  If the rx end is running
>>> too slowly for the data rate, you would see rx overrun errors.
>>
>> From what I've read, the OE gets cleared on each read of RBR.
>> How can I check on this? Is there a counter of OE and other
>> errors kept in eCos that I can access?

>You've got the source code, you tell me.  -- I don't know what
>low-level driver you're using. If it doesn't have an OE
>counter, you can add one: it's only a couple lines of code.
Counted the errors - none were shown.

Thanks again for the help.            ...Laurie:{)


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Uart missing chars when in Release
  2008-01-27 11:20         ` Laurie Gellatly
@ 2008-01-27 15:55           ` Grant Edwards
  2008-01-28  0:11             ` Laurie Gellatly
  0 siblings, 1 reply; 25+ messages in thread
From: Grant Edwards @ 2008-01-27 15:55 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-27, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

>>At 117Kbps with no fifo, you have to service a receive
>>interrupt at a 11.7KHz or you lose bytes.  That means you've
>>got to have an interrupt latency less than 85us.
>
> So I modified ser_16X5X.c to read FIFO threshold (1,4,8 or 14)
> characters worth when an RDA interrupt occurs.

What was it doing?  The correct thing to do is to read all the
available characters each time an rx interrupt occurs.

> With it set to 8 that should give 8 times as long to service
> the interrupt. 

Correct.  If you're using a 16 byte fifo, you should have up to
(16-threshold) byte times to respond to an interrupt.


>>Does it stop dropping bytes at lower baud rates?
>
> Try that next.

If the problem goes a way an lower baud rates, that would be an
important clue.

>>Does it stop dropping bytes if there is no Ethernet traffic?
>
> Tried that. No difference.

What other interrupt sources are active?  I wouldn't think the
timer tick would be an issue...

>>Running from flash is almost certainly slower, and I'd wager
>>that it increases the interrupt latency beyond what can be
>>tolerated by the serial interface's interrupt frequency.
>
> Maybe I should copy ISR or DSR to internal RAM or flash?

If it's a latency problem, you'd probably need to copy all ISRs
and DSRs to RAM (as well as any long-running functions called
by either of those).

>>> From what I've read, the OE gets cleared on each read of RBR.
>>> How can I check on this? Is there a counter of OE and other
>>> errors kept in eCos that I can access?
>
>>You've got the source code, you tell me.  -- I don't know what
>>low-level driver you're using. If it doesn't have an OE
>>counter, you can add one: it's only a couple lines of code.
>
> Counted the errors - none were shown.

If there aren't any receive overrun errors, then interrupt
latency isn't the problem.  There weren't any rx errors of any
sort (parity, framing, etc.)?

-- 
Grant Edwards                   grante             Yow!  Where's th' DAFFY
                                  at               DUCK EXHIBIT??
                               visi.com            


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Uart missing chars when in Release
  2008-01-27 15:55           ` Grant Edwards
@ 2008-01-28  0:11             ` Laurie Gellatly
  2008-01-28  2:37               ` Grant Edwards
  0 siblings, 1 reply; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-28  0:11 UTC (permalink / raw)
  To: Grant Edwards, ecos-discuss

Hi Grant,
> >>At 117Kbps with no fifo, you have to service a receive
> >>interrupt at a 11.7KHz or you lose bytes.  That means you've
> >>got to have an interrupt latency less than 85us.
> >
> > So I modified ser_16X5X.c to read FIFO threshold (1,4,8 or 14)
> > characters worth when an RDA interrupt occurs.
> 
> What was it doing?  The correct thing to do is to read all the
> available characters each time an rx interrupt occurs.
In the switch statement the (RDA)ISR_Rx case simply fell through 
to the (CTI) ISR_RxTO case and a single character was read from RHR.

> > With it set to 8 that should give 8 times as long to service
> > the interrupt. 
> 
> Correct.  If you're using a 16 byte fifo, you should have up to
> (16-threshold) byte times to respond to an interrupt.
I'm using 8 at present so I have an additional 8 char times (to make
16 in the FIFO) to service the first 8.
> 
> >>Does it stop dropping bytes at lower baud rates?
> >
> > Try that next.
> 
> If the problem goes a way an lower baud rates, that would be an
> important clue.
> 
> >>Does it stop dropping bytes if there is no Ethernet traffic?
> >
> > Tried that. No difference.
> 
> What other interrupt sources are active?  I wouldn't think the
> timer tick would be an issue...
> 
> >>Running from flash is almost certainly slower, and I'd wager
> >>that it increases the interrupt latency beyond what can be
> >>tolerated by the serial interface's interrupt frequency.
> >
> > Maybe I should copy ISR or DSR to internal RAM or flash?
> 
> If it's a latency problem, you'd probably need to copy all ISRs
> and DSRs to RAM (as well as any long-running functions called
> by either of those).
> 
> >>> From what I've read, the OE gets cleared on each read of RBR.
> >>> How can I check on this? Is there a counter of OE and other
> >>> errors kept in eCos that I can access?
> >
> >>You've got the source code, you tell me.  -- I don't know what
> >>low-level driver you're using. If it doesn't have an OE
> >>counter, you can add one: it's only a couple lines of code.
Its using the generic serial driver from devs/serial/generic/16x5x
> > Counted the errors - none were shown.
> 
> If there aren't any receive overrun errors, then interrupt
> latency isn't the problem.  There weren't any rx errors of any
> sort (parity, framing, etc.)?

Yeah, I thought this was strange as well. After I slept on it I
found that the Rx Line Status Interrupt was not enabled.... 
Now I see I'm getting OE.

		...Laurie:{)



-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Uart missing chars when in Release
  2008-01-28  0:11             ` Laurie Gellatly
@ 2008-01-28  2:37               ` Grant Edwards
  2008-01-28  5:53                 ` Laurie Gellatly
  0 siblings, 1 reply; 25+ messages in thread
From: Grant Edwards @ 2008-01-28  2:37 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-28, Laurie Gellatly <laurie.gellatly@netic.com> wrote:
> Hi Grant,
>> >>At 117Kbps with no fifo, you have to service a receive
>> >>interrupt at a 11.7KHz or you lose bytes.  That means you've
>> >>got to have an interrupt latency less than 85us.
>> >
>> > So I modified ser_16X5X.c to read FIFO threshold (1,4,8 or 14)
>> > characters worth when an RDA interrupt occurs.
>> 
>> What was it doing?  The correct thing to do is to read all the
>> available characters each time an rx interrupt occurs.
>
> In the switch statement the (RDA)ISR_Rx case simply fell through 
> to the (CTI) ISR_RxTO case and a single character was read from RHR.

That's wrong.  It should continue to read bytes from RHR as
long as the status register says there is receive data
available.  What you describe isn't what's in my snapthost
snapshot of ser_16x5x.c.  The code I'm looking at is right: in
the Rx/RxTO case, there's a loop that reads all of the data
from the receive fifo.  My snapshot is proably a couple years
old, and it's doing the right thing.  Where did you get the
broken file?

>> If there aren't any receive overrun errors, then interrupt
>> latency isn't the problem.  There weren't any rx errors of any
>> sort (parity, framing, etc.)?
>
> Yeah, I thought this was strange as well. After I slept on it
> I found that the Rx Line Status Interrupt was not enabled.... 
> Now I see I'm getting OE.

It sounds like you've somehow gotten ahold of a broken serial
driver code.  I checked CVS, and it's got the right code in it.
I've checked all the versions back for 4 years, and they all
have a loop that will read all available rx data whenever
there's an interrupt.  Are you sure you have driver code that
only reads a single byte?

You shouldn't have had to do anything other than enble the
fifo.  The code that's in CVS is correct.

-- 
Grant




-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Uart missing chars when in Release
  2008-01-28  2:37               ` Grant Edwards
@ 2008-01-28  5:53                 ` Laurie Gellatly
  2008-01-28 15:58                   ` Grant Edwards
  0 siblings, 1 reply; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-28  5:53 UTC (permalink / raw)
  To: ecos-discuss

Hi Grant,
Reading the LPC manual I thought that just looping thru reading
as many chars as were available could (if a new char arrived
while looping) remove a newly arrived OE. The original code loops
reading the LSR to check for any chars available which also clears 
any OE that might have happened after the original interrupt and
while you were looping. I changed the RDA case to just read a 
threshold full (not touching LSR) so that it would preserve the 
error till interrupts were enabled again.
I can see I misunderstood you. I checked out a
fresh copy via CVS and ser_16x5x.c is what I started from.

I just changed the BCFG for the RAM bank to be make accessing RAM as 
slow as the flash. Running the test again did produce just a few errors.
RAM is normally 15ns and flash 70ns on my board.

I then slowed comms to 9600 baud and that works perfectly with code
running from flash.

So, how would you approach this now?

Thanks			...Laurie:{)

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Half Duplex RS485
  2008-01-26 20:41 ` Laurie Gellatly
@ 2008-01-28 10:34   ` wangcui
  0 siblings, 0 replies; 25+ messages in thread
From: wangcui @ 2008-01-28 10:34 UTC (permalink / raw)
  To: Laurie Gellatly, ecos-discuss

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 1116 bytes --]


Sorry for late reply.
Yes, when I specify appropriate deviceType in serial-channel-instance, the driver code will not check chip and just enable it.
So I explictly set deviceType for LPC2XXX's UART0, and intialize UART1 and other channels(of SC16C550) as before, then all channels works well with FIFO enabled.


> From: laurie.gellatly@netic.com
> To: ecos-discuss@sources.redhat.com
> Date: Sun, 27 Jan 2008 07:40:53 +1100
> Subject: RE: [ECOS] Re: Half Duplex RS485
>
> Hi Wang,
> I've been looking through the patch you sent.
> I don't see any change to the FIFO handling unless you mean where
> it figures out the deviceType?
>
> ...Laurie:{)
>
> --
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>

_________________________________________________________________
ÊÖ»úÒ²ÄÜÉÏ MSN ÁÄÌìÁË£¬¿ìÀ´ÊÔÊÔ°É£¡
http://mobile.msn.com.cn/

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Uart missing chars when in Release
  2008-01-28  5:53                 ` Laurie Gellatly
@ 2008-01-28 15:58                   ` Grant Edwards
  2008-01-28 20:40                     ` Grant Edwards
  0 siblings, 1 reply; 25+ messages in thread
From: Grant Edwards @ 2008-01-28 15:58 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-28, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

> Reading the LPC manual I thought that just looping thru reading
> as many chars as were available could (if a new char arrived
> while looping) remove a newly arrived OE.

It would.  If you want to detect overrun errors, you have to
check the OE bit every time the LSR is read.

> The original code loops reading the LSR to check for any chars
> available which also clears any OE that might have happened
> after the original interrupt and while you were looping.

I see.

> I changed the RDA case to just read a threshold full (not
> touching LSR) so that it would preserve the error till
> interrupts were enabled again. I can see I misunderstood you.
> I checked out a fresh copy via CVS and ser_16x5x.c is what I
> started from.

Sorry about the misunderstanding.

> I just changed the BCFG for the RAM bank to be make accessing
> RAM as slow as the flash. Running the test again did produce
> just a few errors. RAM is normally 15ns and flash 70ns on my
> board.
>
> I then slowed comms to 9600 baud and that works perfectly with
> code running from flash.

I'd say it's definitely an interrupt latency issue.

> So, how would you approach this now?

With a threshold of 8, that shuold give you almost 700us to
respond to an interrupt.

The first step is to find out why interrupts or DSRs are being
disabled for so long.  It's probably a DSR that's running
longer than 700us.  If that's so, you need to figure out what
DSR is running longer than that and speed it up.  Locating all
the ISRs and DSRs in RAM appears to be one solution.  It would
be instructive to know which DSR is taking too long.

The way I usually do that is to instrument all the DSRs so that
they set a spare port pin high at entry and low at exit.

Then you hook a scope or logic analyzer up to the spare port
pins and see where the problem is.

Once you know where the problem is, you can break the culprit
up into a state machine that runs for a little while
(performing part of the work), then reschedules itself (which
will let other DSRs run) and exits.

-- 
Grant Edwards                   grante             Yow! Was my SOY LOAF left
                                  at               out in th'RAIN?  It tastes
                               visi.com            REAL GOOD!!


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Uart missing chars when in Release
  2008-01-28 15:58                   ` Grant Edwards
@ 2008-01-28 20:40                     ` Grant Edwards
  2008-01-29 23:35                       ` Byron Jacquot
  2008-02-06  9:35                       ` Laurie Gellatly
  0 siblings, 2 replies; 25+ messages in thread
From: Grant Edwards @ 2008-01-28 20:40 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-28, Grant Edwards <grante@visi.com> wrote:

> The way I usually do that is to instrument all the DSRs so that
> they set a spare port pin high at entry and low at exit.

Though I usually just put instrumentation code into individual
DSR's, you could probably accomplish the same thing by adding
some code the the DSR dispatcher that sets/clears port pins
when dispatching DSRs.  You could also do the same thing with
ISRs.

-- 
Grant Edwards                   grante             Yow! TAILFINS!! ... click
                                  at               ...
                               visi.com            


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Uart missing chars when in Release
  2008-01-28 20:40                     ` Grant Edwards
@ 2008-01-29 23:35                       ` Byron Jacquot
  2008-02-06  9:35                       ` Laurie Gellatly
  1 sibling, 0 replies; 25+ messages in thread
From: Byron Jacquot @ 2008-01-29 23:35 UTC (permalink / raw)
  To: ecos-discuss

>
>> The way I usually do that is to instrument all the DSRs so that
>> they set a spare port pin high at entry and low at exit.
>
>Though I usually just put instrumentation code into individual
>DSR's, you could probably accomplish the same thing by adding
>some code the the DSR dispatcher that sets/clears port pins
>when dispatching DSRs.  You could also do the same thing with
>ISRs.

I've seen dropped RX characters on the LPC2292.  

The default 16x5x driver does some register probing to try to figure out
which specific device it's got.  However, on the LPC, one of those tests
was failing, so it was deciding that it was a simpleminded UART, and not
enabling the RX FIFO.

There was a fix posted on this list last week - look at the " Half
Duplex RS485" thread.

Byron Jacquot

--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Uart missing chars when in Release
  2008-01-28 20:40                     ` Grant Edwards
  2008-01-29 23:35                       ` Byron Jacquot
@ 2008-02-06  9:35                       ` Laurie Gellatly
  2008-02-06 15:25                         ` Grant Edwards
  1 sibling, 1 reply; 25+ messages in thread
From: Laurie Gellatly @ 2008-02-06  9:35 UTC (permalink / raw)
  To: ecos-discuss

Hi Grant,
A small update on this subject.
I found I did not have any optimisation on in the release version.
When I added -Os or -O3 most of the problems disappeared.
I'm planning to try to isolate which section of code makes the
difference and then look at optimising how it works.


Thanks again.			...Laurie:{)

> -----Original Message-----
> From: ecos-discuss-owner@ecos.sourceware.org
> [mailto:ecos-discuss-owner@ecos.sourceware.org]On Behalf Of Grant
> Edwards
> Sent: Tuesday, 29 January 2008 5:36 AM
> To: ecos-discuss@sources.redhat.com
> Subject: [ECOS] Re: Uart missing chars when in Release
> 
> 
> On 2008-01-28, Grant Edwards <grante@visi.com> wrote:
> 
> > The way I usually do that is to instrument all the DSRs so that
> > they set a spare port pin high at entry and low at exit.
> 
> Though I usually just put instrumentation code into individual
> DSR's, you could probably accomplish the same thing by adding
> some code the the DSR dispatcher that sets/clears port pins
> when dispatching DSRs.  You could also do the same thing with
> ISRs.
> 
> -- 
> Grant Edwards                   grante             Yow! 
> TAILFINS!! ... click
>                                   at               ...
>                                visi.com            
> 
> 
> -- 
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
> 

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Uart missing chars when in Release
  2008-02-06  9:35                       ` Laurie Gellatly
@ 2008-02-06 15:25                         ` Grant Edwards
  0 siblings, 0 replies; 25+ messages in thread
From: Grant Edwards @ 2008-02-06 15:25 UTC (permalink / raw)
  To: ecos-discuss

On 2008-02-06, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

> A small update on this subject. I found I did not have any
> optimisation on in the release version. When I added -Os or
> -O3 most of the problems disappeared. I'm planning to try to
> isolate which section of code makes the difference and then
> look at optimising how it works.

You might want to do some size/performance measurements with
different optimization switches.  On some of the platforms I
use, -O3 code is a lot bigger than -O2 and not measurably
faster.  I've also seen projects where -O2 is both smaller and
faster than -Os.

-- 
Grant Edwards                   grante             Yow! DIDI ... is that a
                                  at               MARTIAN name, or, are we
                               visi.com            in ISRAEL?


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Half Duplex RS485
  2008-01-25  1:33       ` wangcui
@ 2008-01-25  2:00         ` Laurie Gellatly
  0 siblings, 0 replies; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-25  2:00 UTC (permalink / raw)
  To: wangcui, Grant Edwards, ecos-discuss

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; 	charset="gb2312", Size: 4079 bytes --]

Hi Wang,
I'd be interested to see what you had to modify to make the FIFO work.

The eCos source does not know about the fractional divider.
Did you enable fix that as well?

			...Laurie:{)

-----Original Message-----
From: wangcui [mailto:iucgnaw@msn.com]
Sent: Friday, 25 January 2008 12:33 PM
To: Laurie Gellatly; Grant Edwards; ecos-discuss@sources.redhat.com
Subject: RE: [ECOS] Re: Half Duplex RS485



Just FYI, the LPC2XXX's UART0 is not fully functional. So when the 16x5x
serial driver check FIFO(in serial_config_port()), it will fail, thus FIFO
is disabled for UART0. But UART1 works fine.

To resolve it, I have to modified 16x5x driver code, force enable FIFO for
UART0 and UART1.

> From: laurie.gellatly@netic.com
> To: grante@visi.com; ecos-discuss@sources.redhat.com
> Date: Thu, 24 Jan 2008 08:12:17 +1100
> Subject: RE: [ECOS] Re: Half Duplex RS485
>
> Wang/Grant, thanks for the replies.
>
>>> My project has RS485 half duplex driven by UART0 of an
>>> LPC2112. At present I've modified pc_serial_start_xmit and
>>> pc_serial_stop_xmit to change a pin state so that the same
>>> wires can be used for transmit and receive.
>>>
>>> This does not see to work when the FIFO is enabled.
>>
>>Then you probably did it wrong. :)
>>
>>I imagine that RTS is shutting off too soon. The problem is
>>that pc_serial_stop_xmit() is called when the driver has no
>>more data to send _to_ the UART. That's not when you need to
>>shut off RTS. You need to shut off RTS when the UART is done
>>sending data and both the FIFO and shift register are empty.
>>
>>You're probably shutting off RTS while the UART still has data
>>in the tx FIFO and the tx shift register.
> Funny thing is that it appears that the first part of the
> transmission is lost.
>
>>> Has anyone else done RS485 half duplex?
>>
>>Many, many times.
>>
>>> Did you modify these routines or write your own?
>>
>>I usually pick a UART that supports half-duplex operation, and
>>then just enabled that feature in the UART. [I use a custom
>>eCos serial driver that supports quite a few more advanced UART
>>features than the standard driver (e.g. flow control,
>>half-duplex, inter-byte timeouts, 9-bit modes, FIFO control,
>>etc.).
>>
>>If you don't have a proper UART, you need to enable the tx
>>shift register empty interrupt and use that to trigger code
>>that de-asserts RTS. If you're using a broken UART that
>>doesn't have a tx shift register empty interrupt, then you'll
>>have to poll for the tx shift register empty status. If you're
>>using a really broken UART that doesn't have a _working_
>>shift-register empty status[1], then you may have to start a
>>timer that will wake you up at the point in time where RTS
>>needs to be changed.
>>
>>> Did you get the FIFO to work?
>>
>>When there was one, yes.
>>
>>
>>[1] There are broken UARTs (including a few PC chipsets) whose
>> shift-register empty bit gets set _before_ the stop bit has
>> been sent. In that case, you may need to use some sort of
>> time-delay to wait until after the stop bit has been sent
>> to toggle RTS. On a properly implimented RS-485 bus, there
>> should be pull-up and pull-down resisters so that the bus
>> idles in the mark state (same value as a stop bit), but to
>> be on the safe side you should leave the bus driver on
>> until after the stop bit has been sent.
>
> Grant, do you know if the LPC series have 'broken' UARTS?
> Specifically LPC2212 and LPC2103?
> U0TSR looks promising as an indication of when the bits
> 'have left the building' - is it accurate or do I
> need to add a time delay?
>
> Really appreciate the help. ...Laurie:{)
>
> --
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>

_________________________________________________________________
ÌìÁ¹ÁË£¬ÌíÒÂÁË£¬ÐĶ¯ÁË£¬¡°Æß¼þ¡±ÁË
http://get.live.cn


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Half Duplex RS485
  2008-01-23 21:12     ` Laurie Gellatly
  2008-01-23 22:03       ` Grant Edwards
@ 2008-01-25  1:33       ` wangcui
  2008-01-25  2:00         ` Laurie Gellatly
  1 sibling, 1 reply; 25+ messages in thread
From: wangcui @ 2008-01-25  1:33 UTC (permalink / raw)
  To: Laurie Gellatly, Grant Edwards, ecos-discuss

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 3670 bytes --]


Just FYI, the LPC2XXX's UART0 is not fully functional. So when the 16x5x serial driver check FIFO(in serial_config_port()), it will fail, thus FIFO is disabled for UART0. But UART1 works fine.

To resolve it, I have to modified 16x5x driver code, force enable FIFO for UART0 and UART1.

> From: laurie.gellatly@netic.com
> To: grante@visi.com; ecos-discuss@sources.redhat.com
> Date: Thu, 24 Jan 2008 08:12:17 +1100
> Subject: RE: [ECOS] Re: Half Duplex RS485
>
> Wang/Grant, thanks for the replies.
>
>>> My project has RS485 half duplex driven by UART0 of an
>>> LPC2112. At present I've modified pc_serial_start_xmit and
>>> pc_serial_stop_xmit to change a pin state so that the same
>>> wires can be used for transmit and receive.
>>>
>>> This does not see to work when the FIFO is enabled.
>>
>>Then you probably did it wrong. :)
>>
>>I imagine that RTS is shutting off too soon. The problem is
>>that pc_serial_stop_xmit() is called when the driver has no
>>more data to send _to_ the UART. That's not when you need to
>>shut off RTS. You need to shut off RTS when the UART is done
>>sending data and both the FIFO and shift register are empty.
>>
>>You're probably shutting off RTS while the UART still has data
>>in the tx FIFO and the tx shift register.
> Funny thing is that it appears that the first part of the
> transmission is lost.
>
>>> Has anyone else done RS485 half duplex?
>>
>>Many, many times.
>>
>>> Did you modify these routines or write your own?
>>
>>I usually pick a UART that supports half-duplex operation, and
>>then just enabled that feature in the UART. [I use a custom
>>eCos serial driver that supports quite a few more advanced UART
>>features than the standard driver (e.g. flow control,
>>half-duplex, inter-byte timeouts, 9-bit modes, FIFO control,
>>etc.).
>>
>>If you don't have a proper UART, you need to enable the tx
>>shift register empty interrupt and use that to trigger code
>>that de-asserts RTS. If you're using a broken UART that
>>doesn't have a tx shift register empty interrupt, then you'll
>>have to poll for the tx shift register empty status. If you're
>>using a really broken UART that doesn't have a _working_
>>shift-register empty status[1], then you may have to start a
>>timer that will wake you up at the point in time where RTS
>>needs to be changed.
>>
>>> Did you get the FIFO to work?
>>
>>When there was one, yes.
>>
>>
>>[1] There are broken UARTs (including a few PC chipsets) whose
>> shift-register empty bit gets set _before_ the stop bit has
>> been sent. In that case, you may need to use some sort of
>> time-delay to wait until after the stop bit has been sent
>> to toggle RTS. On a properly implimented RS-485 bus, there
>> should be pull-up and pull-down resisters so that the bus
>> idles in the mark state (same value as a stop bit), but to
>> be on the safe side you should leave the bus driver on
>> until after the stop bit has been sent.
>
> Grant, do you know if the LPC series have 'broken' UARTS?
> Specifically LPC2212 and LPC2103?
> U0TSR looks promising as an indication of when the bits
> 'have left the building' - is it accurate or do I
> need to add a time delay?
>
> Really appreciate the help. ...Laurie:{)
>
> --
> Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
> and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
>

_________________________________________________________________
ÌìÁ¹ÁË£¬ÌíÒÂÁË£¬ÐĶ¯ÁË£¬¡°Æß¼þ¡±ÁË 
http://get.live.cn

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Half Duplex RS485
  2008-01-23 23:06         ` Laurie Gellatly
  2008-01-23 23:44           ` Grant Edwards
@ 2008-01-24  9:02           ` Daniel Néri
  1 sibling, 0 replies; 25+ messages in thread
From: Daniel Néri @ 2008-01-24  9:02 UTC (permalink / raw)
  To: ecos-discuss

"Laurie Gellatly" <laurie.gellatly@netic.com> writes:

> When you include the ppp package it forces you to have flow control
> on ALL serial lines and I don't want that on the 485 line.

No, it just enables flow control by default on all serial ports. You can
change it for individual ports in your application, using
cyg_io_set_config.

Or change the default to "NONE" for all ports via
CYGDAT_IO_SERIAL_FLOW_CONTROL_DEFAULT (pppd will enable it on its own
serial device, unless you tell it not to)

> Looks like I'll have to try to carve out ppp_chat and make it into its
> own package without the flow control requirement unless you have a
> better alternative?

Actually the requirement is on the flow control support code. There is
no requirement on flow control being enabled for the serial device used
by pppd (and it works pretty well when disabled too).


Regards,
-- 
Daniel Néri <daniel.neri@sigicom.se>
Sigicom AB, Stockholm, Sweden


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Half Duplex RS485
  2008-01-23 23:06         ` Laurie Gellatly
@ 2008-01-23 23:44           ` Grant Edwards
  2008-01-24  9:02           ` Daniel Néri
  1 sibling, 0 replies; 25+ messages in thread
From: Grant Edwards @ 2008-01-23 23:44 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-23, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

>>> Funny thing is that it appears that the first part of the 
>>> transmission is lost.
>
>>Ah. 
>
>>If you look at io/serial.c, you can see that the serial_write()
>>function calls start_xmit() _after_ it's done filling up the
>>UART's tx fifo (the UART will start sending when the first byte
>>is written to the tx fifo).  RTS needs to be asserted before
>>any data is written to the tx fifo.  That means that
>>start_xmit() is being called too late: the first byte is
>>already on it's way out of the UART before start_xmit() is
>>called.


> Did not see that xmit happened after the FIFO was filled. I
> have to flip a bit before the transmit and clear it when done.
> So I'm thinking that setting the bit before the cyg_io_write
> in application code would be OK and clear it (after waiting
> for TEMT plus maybe a small delay) in xmit_stop might work for
> me. I always write a complete message so as long as stop_xmit
> happens fairly soon after the last bit has gone then I'll be
> ready to receive the response.

stop_xmit doesn't happen after the last bit is gone.  It
happens a long, long time before that.

stop_xmit() is called when the last byte has been transferred
from the serial driver's buffer into the UART's tx fifo.  At
the point in time when stop_xmit() is called, there's still up
to an entire fifo's worth (somewhere from 8 to 4K bytes
depending on the UART) of transmit data still waiting to be
sent.  It could happen many seconds before the last bit has
gone.  At 9600 baud with a 1K tx fifo, it would get called
about one second before the last bit is gone (assuming the tx
message didn't fit entirely within the tx fifo).

Despite it's name, stop_xmit() has nothing to do with the UART
stopping transmission.  It is called to shut off the tx
interrupt that requests additional tx data from the serial
driver's transmit buffer.  It is called when the upper level
serial driver has no more bytes to send.  The UART might still
have plenty of bytes waiting to be sent.  stop_xmit() is not
all that useful in determining when the UART has finished
sending bits down the wire.  There's no point in polling for tx
empty until stop_xmit() has been called, but there can be a
very long time between stop_xmit() and the transmission being
completed.  You need to be prepared to poll for an entire tx
fifo's worth of time.

> Possibly part of my problem stems from having two serial
> lines.

I wouldn't think so.  The ports should operate independently.
If they don't, then I'd say the low-level driver is broken.

> One for 485 and the other for 232. The 232 serial line uses
> ppp_chat to conduct a simple exchange. When you include the
> ppp package it forces you to have flow control on ALL serial
> lines and I don't want that on the 485 line.

It sounds to me like the PPP package is broken if it's mucking
about with serial ports on which you're not using PPP.

> Looks like I'll have to try to carve out ppp_chat and make it 
> into its own package without the flow control requirement 
> unless you have a better alternative?

I've never looked at the PPP stuff, and I don't know how flow
control works in the standard serial driver.  In my serial
driver, flow control is configurable on a per-port basis at run
time by the application and is implemented by either the UART
itself or by the low-level driver in the case of UARTs that
don't do flow control in hardware.

-- 
Grant Edwards                   grante             Yow! PEGGY FLEMMING is
                                  at               stealing BASKET BALLS to
                               visi.com            feed the babies in VERMONT.


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Half Duplex RS485
  2008-01-23 22:03       ` Grant Edwards
@ 2008-01-23 23:06         ` Laurie Gellatly
  2008-01-23 23:44           ` Grant Edwards
  2008-01-24  9:02           ` Daniel Néri
  0 siblings, 2 replies; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-23 23:06 UTC (permalink / raw)
  To: Grant Edwards, ecos-discuss


Grant,

>>>I imagine that RTS is shutting off too soon.  The problem is
>>>that pc_serial_stop_xmit() is called when the driver has no
>>>more data to send _to_ the UART.  That's not when you need to
>>>shut off RTS.  You need to shut off RTS when the UART is done
>>>sending data and both the FIFO and shift register are empty.
>>>
>>>You're probably shutting off RTS while the UART still has data
>>>in the tx FIFO and the tx shift register.
>> 
>> Funny thing is that it appears that the first part of the 
>> transmission is lost.

>Ah. 

>If you look at io/serial.c, you can see that the serial_write()
>function calls start_xmit() _after_ it's done filling up the
>UART's tx fifo (the UART will start sending when the first byte
>is written to the tx fifo).  RTS needs to be asserted before
>any data is written to the tx fifo.  That means that
>start_xmit() is being called too late: the first byte is
>already on it's way out of the UART before start_xmit() is
>called.  If your protocol allows it, adding an extra "idle"
>byte to the beginning of the message will probably fix that.

>Off the top of my head, here are a couple other options:

> 1) Add code to the low-level driver's putc() method that
>    asserts RTS _before_ it transfers the byte to the UART tx
>    fifo.

> 2) Add another driver hook that is called by serial_write()
>    before it fills the tx fifo.

> 3) Always leave the UART in a mode where the transmit logic is
>    disabled until it's enabled by a call to start_xmit(). IOW,
>    when the last bit it in a transmission has been sent not
>    only do you de-assert RTS, you also shut off the UART's
>    transmit hw so that the next time somebody fills up the tx
>    fifo nothing goes out until start_xmit() is called.

>Number 1) is probably the simplest.
    
Did not see that xmit happened after the FIFO was filled.
I have to flip a bit before the transmit and clear it when done.
So I'm thinking that setting the bit before the cyg_io_write in
application code would be OK and clear it (after waiting for TEMT
plus maybe a small delay) in xmit_stop might work for me.
I always write a complete message so as long as stop_xmit happens
fairly soon after the last bit has gone then I'll be ready to receive 
the response.

Possibly part of my problem stems from having two serial lines.
One for 485 and the other for 232.
The 232 serial line uses ppp_chat to conduct a simple exchange.
When you include the ppp package it forces you to have flow control
on ALL serial lines and I don't want that on the 485 line.

Looks like I'll have to try to carve out ppp_chat and make it 
into its own package without the flow control requirement 
unless you have a better alternative?

Thanks again. 			...Laurie:{)

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Half Duplex RS485
  2008-01-23 21:12     ` Laurie Gellatly
@ 2008-01-23 22:03       ` Grant Edwards
  2008-01-23 23:06         ` Laurie Gellatly
  2008-01-25  1:33       ` wangcui
  1 sibling, 1 reply; 25+ messages in thread
From: Grant Edwards @ 2008-01-23 22:03 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-23, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

>>I imagine that RTS is shutting off too soon.  The problem is
>>that pc_serial_stop_xmit() is called when the driver has no
>>more data to send _to_ the UART.  That's not when you need to
>>shut off RTS.  You need to shut off RTS when the UART is done
>>sending data and both the FIFO and shift register are empty.
>>
>>You're probably shutting off RTS while the UART still has data
>>in the tx FIFO and the tx shift register.
> 
> Funny thing is that it appears that the first part of the 
> transmission is lost.

Ah. 

If you look at io/serial.c, you can see that the serial_write()
function calls start_xmit() _after_ it's done filling up the
UART's tx fifo (the UART will start sending when the first byte
is written to the tx fifo).  RTS needs to be asserted before
any data is written to the tx fifo.  That means that
start_xmit() is being called too late: the first byte is
already on it's way out of the UART before start_xmit() is
called.  If your protocol allows it, adding an extra "idle"
byte to the beginning of the message will probably fix that.

Off the top of my head, here are a couple other options:

 1) Add code to the low-level driver's putc() method that
    asserts RTS _before_ it transfers the byte to the UART tx
    fifo.

 2) Add another driver hook that is called by serial_write()
    before it fills the tx fifo.

 3) Always leave the UART in a mode where the transmit logic is
    disabled until it's enabled by a call to start_xmit(). IOW,
    when the last bit it in a transmission has been sent not
    only do you de-assert RTS, you also shut off the UART's
    transmit hw so that the next time somebody fills up the tx
    fifo nothing goes out until start_xmit() is called.

Number 1) is probably the simplest.
    
> Grant, do you know if the LPC series have 'broken' UARTS?
> Specifically LPC2212 and LPC2103? U0TSR looks promising as an
> indication of when the bits 'have left the building' - is it
> accurate or do I need to add a time delay?

I don't know -- I've never worked with the LPC parts.  The vast
majority of the the parts I've used have been OK (many don't
provide an interrupt, but at least the status bit worked
correctly when polled).  IIRC, the ones that I had problems
with were a UART in one of Motorola's old uControllers (don't
remember which one, but it was from about 10-15 years ago) and
a couple different PC motherboard chipsets.

At one point I modified the Linux PC UART driver to support
half-duplex operation, but it never worked reliably, so I just
gave up and bought serial cards that had UARTs which supported
half-duplex mode.  Now that I think about it, I also built a
little 9-pin pass-through dongle with a one-shot in it that
controlled RTS.  It worked pretty well also (for the one baud
rate it was designed for), but since the first bit was usually
mangled, it only worked on protocols where the messages had
training preambles.

-- 
Grant Edwards                   grante             Yow! We are now enjoying
                                  at               total mutual interaction in
                               visi.com            an imaginary hot tub ...


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [ECOS]  Re: Half Duplex RS485
  2008-01-23 16:34   ` [ECOS] " Grant Edwards
@ 2008-01-23 21:12     ` Laurie Gellatly
  2008-01-23 22:03       ` Grant Edwards
  2008-01-25  1:33       ` wangcui
  0 siblings, 2 replies; 25+ messages in thread
From: Laurie Gellatly @ 2008-01-23 21:12 UTC (permalink / raw)
  To: Grant Edwards, ecos-discuss

Wang/Grant, thanks for the replies.

>> My project has RS485 half duplex driven by UART0 of an
>> LPC2112. At present I've modified pc_serial_start_xmit and
>> pc_serial_stop_xmit to change a pin state so that the same
>> wires can be used for transmit and receive.
>>
>> This does not see to work when the FIFO is enabled.
>
>Then you probably did it wrong. :)
>
>I imagine that RTS is shutting off too soon.  The problem is
>that pc_serial_stop_xmit() is called when the driver has no
>more data to send _to_ the UART.  That's not when you need to
>shut off RTS.  You need to shut off RTS when the UART is done
>sending data and both the FIFO and shift register are empty.
>
>You're probably shutting off RTS while the UART still has data
>in the tx FIFO and the tx shift register.
Funny thing is that it appears that the first part of the 
transmission is lost.

>> Has anyone else done RS485 half duplex?
>
>Many, many times.
>
>> Did you modify these routines or write your own?
>
>I usually pick a UART that supports half-duplex operation, and
>then just enabled that feature in the UART.  [I use a custom
>eCos serial driver that supports quite a few more advanced UART
>features than the standard driver (e.g. flow control,
>half-duplex, inter-byte timeouts, 9-bit modes, FIFO control,
>etc.).
>
>If you don't have a proper UART, you need to enable the tx
>shift register empty interrupt and use that to trigger code
>that de-asserts RTS.  If you're using a broken UART that
>doesn't have a tx shift register empty interrupt, then you'll
>have to poll for the tx shift register empty status.  If you're
>using a really broken UART that doesn't have a _working_
>shift-register empty status[1], then you may have to start a
>timer that will wake you up at the point in time where RTS
>needs to be changed.
>
>> Did you get the FIFO to work?
>
>When there was one, yes.
>
>
>[1] There are broken UARTs (including a few PC chipsets) whose
>    shift-register empty bit gets set _before_ the stop bit has
>    been sent.  In that case, you may need to use some sort of
>    time-delay to wait until after the stop bit has been sent
>    to toggle RTS.  On a properly implimented RS-485 bus, there
>    should be pull-up and pull-down resisters so that the bus
>    idles in the mark state (same value as a stop bit), but to
>    be on the safe side you should leave the bus driver on
>    until after the stop bit has been sent.

Grant, do you know if the LPC series have 'broken' UARTS?
Specifically LPC2212 and LPC2103?
U0TSR looks promising as an indication of when the bits
'have left the building' - is it accurate or do I
need to add a time delay?

Really appreciate the help.			...Laurie:{)

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [ECOS]  Re: Half Duplex RS485
  2008-01-22  9:19 ` [ECOS] Half Duplex RS485 Laurie Gellatly
@ 2008-01-23 16:34   ` Grant Edwards
  2008-01-23 21:12     ` Laurie Gellatly
  0 siblings, 1 reply; 25+ messages in thread
From: Grant Edwards @ 2008-01-23 16:34 UTC (permalink / raw)
  To: ecos-discuss

On 2008-01-22, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

> My project has RS485 half duplex driven by UART0 of an
> LPC2112. At present I've modified pc_serial_start_xmit and
> pc_serial_stop_xmit to change a pin state so that the same
> wires can be used for transmit and receive.
>
> This does not see to work when the FIFO is enabled.

Then you probably did it wrong. :)

I imagine that RTS is shutting off too soon.  The problem is
that pc_serial_stop_xmit() is called when the driver has no
more data to send _to_ the UART.  That's not when you need to
shut off RTS.  You need to shut off RTS when the UART is done
sending data and both the FIFO and shift register are empty.

You're probably shutting off RTS while the UART still has data
in the tx FIFO and the tx shift register.

> Has anyone else done RS485 half duplex?

Many, many times.

> Did you modify these routines or write your own?

I usually pick a UART that supports half-duplex operation, and
then just enabled that feature in the UART.  [I use a custom
eCos serial driver that supports quite a few more advanced UART
features than the standard driver (e.g. flow control,
half-duplex, inter-byte timeouts, 9-bit modes, FIFO control,
etc.).

If you don't have a proper UART, you need to enable the tx
shift register empty interrupt and use that to trigger code
that de-asserts RTS.  If you're using a broken UART that
doesn't have a tx shift register empty interrupt, then you'll
have to poll for the tx shift register empty status.  If you're
using a really broken UART that doesn't have a _working_
shift-register empty status[1], then you may have to start a
timer that will wake you up at the point in time where RTS
needs to be changed.

> Did you get the FIFO to work?

When there was one, yes.


[1] There are broken UARTs (including a few PC chipsets) whose
    shift-register empty bit gets set _before_ the stop bit has
    been sent.  In that case, you may need to use some sort of
    time-delay to wait until after the stop bit has been sent
    to toggle RTS.  On a properly implimented RS-485 bus, there
    should be pull-up and pull-down resisters so that the bus
    idles in the mark state (same value as a stop bit), but to
    be on the safe side you should leave the bus driver on
    until after the stop bit has been sent.

-- 
Grant Edwards                   grante             Yow! I'm also against
                                  at               BODY-SURFING!!
                               visi.com            


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2008-02-06 15:25 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-25  4:16 [ECOS] Re: Half Duplex RS485 wangcui
2008-01-26 20:41 ` Laurie Gellatly
2008-01-28 10:34   ` wangcui
2008-01-27  4:52 ` [ECOS] Uart missing chars when in Release Laurie Gellatly
2008-01-27  5:14   ` [ECOS] " Grant Edwards
2008-01-27  6:46     ` Laurie Gellatly
2008-01-27  9:54       ` Grant Edwards
2008-01-27 11:20         ` Laurie Gellatly
2008-01-27 15:55           ` Grant Edwards
2008-01-28  0:11             ` Laurie Gellatly
2008-01-28  2:37               ` Grant Edwards
2008-01-28  5:53                 ` Laurie Gellatly
2008-01-28 15:58                   ` Grant Edwards
2008-01-28 20:40                     ` Grant Edwards
2008-01-29 23:35                       ` Byron Jacquot
2008-02-06  9:35                       ` Laurie Gellatly
2008-02-06 15:25                         ` Grant Edwards
  -- strict thread matches above, loose matches on Subject: below --
2008-01-21 22:04 [ECOS] routing sockets / far end address resolution Daniel Paape
2008-01-22  9:19 ` [ECOS] Half Duplex RS485 Laurie Gellatly
2008-01-23 16:34   ` [ECOS] " Grant Edwards
2008-01-23 21:12     ` Laurie Gellatly
2008-01-23 22:03       ` Grant Edwards
2008-01-23 23:06         ` Laurie Gellatly
2008-01-23 23:44           ` Grant Edwards
2008-01-24  9:02           ` Daniel Néri
2008-01-25  1:33       ` wangcui
2008-01-25  2:00         ` Laurie Gellatly

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).