All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Christian Magnusson" <mag@mag.cx>
To: linux-serial@vger.kernel.org
Subject: Auto RS485 half-duplex control
Date: Sun, 3 Jan 2010 14:15:37 +0100	[thread overview]
Message-ID: <001801ca8c76$d7654bd0$862fe370$@cx> (raw)


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
 

             reply	other threads:[~2010-01-03 13:15 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-03 13:15 Christian Magnusson [this message]
2010-01-24 16:06 ` Auto RS485 half-duplex control Matthias Fuchs

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='001801ca8c76$d7654bd0$862fe370$@cx' \
    --to=mag@mag.cx \
    --cc=linux-serial@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.