linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Auto RS485 half-duplex control
@ 2010-01-03 13:15 Christian Magnusson
  2010-01-24 16:06 ` Matthias Fuchs
  0 siblings, 1 reply; 2+ messages in thread
From: Christian Magnusson @ 2010-01-03 13:15 UTC (permalink / raw)
  To: linux-serial


I have searched in the lists for some kernel support to control the RTS-pin
while sending characters to through an external RS232->RS485 adapter.
The RS485 device I’m writing to, respond with an answer within approximately
2ms after my last sent character, and therefore I need to release the
RTS-pin before that.
If not, the returning characters will be unreadable due to the
send-collision.

Will this feature be implemented in the i386 arch (as it is for chris), or
is there any reason to never include it in the future?

/Christian



Right now I have implemented the feature in my application with pretty good
result, but I don’t like the busy-while loop I need to do.
This is a part from my code where I write to the serial-device

        COM_set_RTS(in->file_descriptor, 1); // Tell RS485 converter to
activate TX-pin
        i = COM_write(tmp, size, in);
#ifdef HAVE_TIOCSERGETLSR
        // 79 bytes takes 180.88ms to send  (2.2896ms / char at 4800 baud)
        // (2.289*4800 = 10990)
        if(i == 0) {
            signed int lsr;
            int loops = 0;
            int pre_sleep = ((size*10990)/COM_BaudRate(in->baud)) - 1;
            if(pre_sleep > 3) {
                // Sleep most of the time before the busy-while loop.
                LEVEL_DEFAULT("Pre-sleep %d ms (%d baud)\n", pre_sleep,
COM_BaudRate(in->baud));
                UT_delay(pre_sleep);
            }
            gettimeofday(&tv2, NULL);
            do {
                /* Busy while loop until transmit buffer is empty */
                loops++;
                rc = ioctl(in->file_descriptor, TIOCSERGETLSR, &lsr);
                if(rc < 0) {
                    LEVEL_CALL("TIOCSERGETLSR failed\n");
                    break;
                }
                if(lsr & TIOCSER_TEMT) {
                    /* Transmitter empty */
                    break;
                }
                gettimeofday(&tv2, NULL);
                timersub(&tv2, &tv_start, &diff);
                if(diff.tv_sec != 0) {
                    LEVEL_DEFAULT("TEMT never set within 1 sec\n");
                    break;
                }
            } while(1);

            // tcdrain should return at once after all chars have been sent
            if((rc = tcdrain(in->file_descriptor)) < 0) {
                LEVEL_DEFAULT("drain failed rc=%d\n", rc);
            }
            gettimeofday(&tv_end, NULL);
            timersub(&tv_end, &tv_start, &diff);
            LEVEL_CALL("%d chars sent after %d.%06ld secs (%d loops +
tcdrain)\n", size, diff.tv_sec, diff.tv_usec, loops);
            // 27.5ms - 27.7ms for 12 chars.
            // Waiting for TIOCSER_TEMT is reliable & tcdrain return at once
            // Consumes some CPU-time in the busy-while loop though.
        }
#else
        if(i == 0) {
            // If all bytes were written, then wait until all bytes are sent
            // Seem to wait about 3ms after last char is sent, and that's
too long delay
            if((rc = tcdrain(in->file_descriptor)) < 0) {
                LEVEL_DEFAULT("drain failed rc=%d\n", rc);
            }
        }

        gettimeofday(&tv2, NULL);
        timersub(&tv2, &tv_start, &diff);
        // 28.6-32.8ms for 12 chars  (tcdrain is not very reliable)
        LEVEL_CALL("%d chars sent after %d.%06ld secs (called tcdrain)\n",
size, diff.tv_sec, diff.tv_usec);

#endif

        // Tell RS485 converter to deactivate TX-pin
        COM_set_RTS(in->file_descriptor, 0);
    }



 

__________ Information from ESET NOD32 Antivirus, version of virus signature
database 4738 (20100102) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com
 

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

end of thread, other threads:[~2010-01-24 16:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-03 13:15 Auto RS485 half-duplex control Christian Magnusson
2010-01-24 16:06 ` Matthias Fuchs

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 NNTP newsgroup(s).