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 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.