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 Im 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 dont 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
next 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 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).