io-char and RS485 trouble

Hi,

I have some problem with io-char low level control fonction in RS485 serial
communication

I want to use a RS485 serial interface controlled by an 8250’s UART on QNX
6.2.
I use this script to control RTS signal and write data :


int fd;
int iReg;
char data[DATA_SIZE];

fd = open("/dev/ser2", O_RDWR); // Open device (speed 9600 Bds)

iReg = _CTL_RTS_CHG | _CTL_RTS; // Set RTS to 1
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

write( fd, data, DATA_SIZE); // Send Data

// Wait until all output has been transmitted to device
devctl(__fildes, DCMD_CHR_TCDRAIN, NULL, 0, NULL);

iReg = _CTL_RTS_CHG; // Set RTS to 0
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

close (fd); // Close device



I tested it and I observed two behaviors :
. if DATA_SIZE > 2 : It work !!!
. if DATA_SIZE <= 2 : There is some problem. All data aren’t
transmitted.

After having examined devc-ser820 source (DDK QNX 6.2) and io-char library
source (QNX 6.1A on cvs.qnx.com), I think I find a trouble on io-char
library. On file ‘io_devctl.c’, line 22 :
The test for beginning to test the 8250 LSR_TSRE bit on a drain request is

if(bup->cnt) {
// Start Waiting …
}

In the case of a small writing request (DATA_SIZE <= 2), when we call devctl
with TCDRAIN request, soft FIFO is empty, but hardware FIFO isn’t and all
data aren’t transmitted or serialized. Unfortunately, with this test, 8250
LSR_TSRE bit is never tested. So the drain function does not work properly.
This problem can be more serious if UART transmit FIFO is larger or if
interface speed is faster.


Do you think I do a mistake, or is it really a bug ?
Any information you can provide will be greatly appreciated. Thanks


KUBIT Stéphane

“PAYRE serge” <spayre@centralp.fr> wrote in message
news:b4nle0$7ub$1@inn.qnx.com

Hi,

I have some problem with io-char low level control fonction in RS485
serial
communication

I want to use a RS485 serial interface controlled by an 8250’s UART on QNX
6.2.
I use this script to control RTS signal and write data :


int fd;
int iReg;
char data[DATA_SIZE];

fd = open("/dev/ser2", O_RDWR); // Open device (speed 9600 Bds)

iReg = _CTL_RTS_CHG | _CTL_RTS; // Set RTS to 1
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

write( fd, data, DATA_SIZE); // Send Data

// Wait until all output has been transmitted to device
devctl(__fildes, DCMD_CHR_TCDRAIN, NULL, 0, NULL);

iReg = _CTL_RTS_CHG; // Set RTS to 0
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

close (fd); // Close device



I tested it and I observed two behaviors :
. if DATA_SIZE > 2 : It work !!!
. if DATA_SIZE <= 2 : There is some problem. All data aren’t
transmitted.

After having examined devc-ser820 source (DDK QNX 6.2) and io-char library
source (QNX 6.1A on cvs.qnx.com), I think I find a trouble on io-char
library. On file ‘io_devctl.c’, line 22 :
The test for beginning to test the 8250 LSR_TSRE bit on a drain request is

if(bup->cnt) {
// Start Waiting …
}

In the case of a small writing request (DATA_SIZE <= 2), when we call
devctl
with TCDRAIN request, soft FIFO is empty, but hardware FIFO isn’t and all
data aren’t transmitted or serialized. Unfortunately, with this test, 8250
LSR_TSRE bit is never tested. So the drain function does not work
properly.
This problem can be more serious if UART transmit FIFO is larger or if
interface speed is faster.


Do you think I do a mistake, or is it really a bug ?

Without looking into the source my first impression is the way you are
dealing with this is really not safe.

First the time between the drain and setting RTS to 0 will vary depending on
CPU load and could in fact be very long. So long that other machine will
assume they can transmit but the bus will still be held. That could be work
around in the protocol but is usually a pain to deal with.

I don’t have the doc in front of me but I don’t beleive DCMD_CHR_TCDRAIN
will garanty that all data are out of he serial chip,wich is different then
empty buffer.

In my experience the best solution is often to customize devc-ser and add
control from RTS inside ISR.

Any information you can provide will be greatly appreciated. Thanks


KUBIT Stéphane
\

Good time of day!

I had about the same problem and moreover was limited by strict time
constraints (~100 mks for RTS manipulation). The only solution I found (and
it really works!) was writing custom driver consisting of ISR & high
priority thread. I even had to thread’s priority over network driver,
because it sometimes gave ms-s delays.

Good luck.

Dmitry.

Mario Charest wrote:
"PAYRE serge" <> wrote in message
news:b4nle0$7ub$<1@inn.qnx.com>...
Hi,

I have some problem with io-char low level control fonction in RS485

serial
communication

I want to use a RS485 serial interface controlled by an 8250’s UART on QNX
6.2.
I use this script to control RTS signal and write data :


int fd;
int iReg;
char data[DATA_SIZE];

fd = open("/dev/ser2", O_RDWR); // Open device (speed 9600 Bds)

iReg = _CTL_RTS_CHG | _CTL_RTS; // Set RTS to 1
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

write( fd, data, DATA_SIZE); // Send Data

// Wait until all output has been transmitted to device
devctl(__fildes, DCMD_CHR_TCDRAIN, NULL, 0, NULL);

iReg = _CTL_RTS_CHG; // Set RTS to 0
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

close (fd); // Close device



I tested it and I observed two behaviors :
. if DATA_SIZE > 2 : It work !!!
. if DATA_SIZE <= 2 : There is some problem. All data aren’t
transmitted.

After having examined devc-ser820 source (DDK QNX 6.2) and io-char library
source (QNX 6.1A on cvs.qnx.com), I think I find a trouble on io-char
library. On file ‘io_devctl.c’, line 22 :
The test for beginning to test the 8250 LSR_TSRE bit on a drain request is

if(bup->cnt) {
// Start Waiting …
}

In the case of a small writing request (DATA_SIZE <= 2), when we call

devctl
with TCDRAIN request, soft FIFO is empty, but hardware FIFO isn't and all
data aren't transmitted or serialized. Unfortunately, with this test, 8250
LSR_TSRE bit is never tested. So the drain function does not work
properly.
This problem can be more serious if UART transmit FIFO is larger or if
interface speed is faster.
\
\
Do you think I do a mistake, or is it really a bug ?
Without looking into the source my first impression is the way you are
dealing with this is really not safe.

First the time between the drain and setting RTS to 0 will vary depending on
CPU load and could in fact be very long. So long that other machine will
assume they can transmit but the bus will still be held. That could be work
around in the protocol but is usually a pain to deal with.

I don’t have the doc in front of me but I don’t beleive DCMD_CHR_TCDRAIN
will garanty that all data are out of he serial chip,wich is different then
empty buffer.

In my experience the best solution is often to customize devc-ser and add
control from RTS inside ISR.


In fact - the older UARTs do not give any interrupt that tells you when the last bit of the last character has left the transmitter. They interrupt when the transmit buffer is free. In a UART with a large buffer, there may be many characters and bits of a character still in the buffer when the transmitt interrupt is received. Some of the latter UARTs can be programmed to tri-state the transmatter after all bits are out, so this may be helpful if you have one of them. A possibility (assuming half duplex mode) is to read transmitted data back. When you see your last character, you know that everyone else on the line has as well. You also may get feedback on line noise this way.

On the otherhand, I ususally use a 232 - 485 converter. No worries about line turn arround and protection from high voltage spikes as a bonus.

Dave


Any information you can provide will be greatly appreciated.  Thanks
\
\
KUBIT Stéphane
\
\
\
\



Hi Stephane,

Right, written like that the test seems not very correct but I wonder if
I didn’t hear talking about this problem yet.
Try to search through the newgroup, I think the related article is quite
old.

I looked at the drain_check() func in tto.c (devc-ser8250) I own, and
the code is a bit different:


if (dev->tty.waiting_drain && (bup->cnt == 0) &&
(in8(port[REG_LS]) & LSR_TSRE)) return 1;

What I don’t understand is that drain_check() is in io-char.h so it
should be called by io-char library for that purpose because this func
is very specific to the chip you use.

This code is the one I sent to Pascal Rouchouse.

That’s said, as you read in the other answers, talking with an equipment
cause some other difficulties as you should be in listen mode within 1
or 2 ms. So you have to modify RTS in the ISR, but that’s a different
problem.

Alain.

PAYRE serge a écrit:

Hi,

I have some problem with io-char low level control fonction in RS485 serial
communication

I want to use a RS485 serial interface controlled by an 8250’s UART on QNX
6.2.
I use this script to control RTS signal and write data :


int fd;
int iReg;
char data[DATA_SIZE];

fd = open("/dev/ser2", O_RDWR); // Open device (speed 9600 Bds)

iReg = _CTL_RTS_CHG | _CTL_RTS; // Set RTS to 1
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

write( fd, data, DATA_SIZE); // Send Data

// Wait until all output has been transmitted to device
devctl(__fildes, DCMD_CHR_TCDRAIN, NULL, 0, NULL);

iReg = _CTL_RTS_CHG; // Set RTS to 0
devctl (fd, DCMD_CHR_SERCTL, & iReg, sizeof(iReg), NULL);

close (fd); // Close device



I tested it and I observed two behaviors :
. if DATA_SIZE > 2 : It work !!!
. if DATA_SIZE <= 2 : There is some problem. All data aren’t
transmitted.

After having examined devc-ser820 source (DDK QNX 6.2) and io-char library
source (QNX 6.1A on cvs.qnx.com), I think I find a trouble on io-char
library. On file ‘io_devctl.c’, line 22 :
The test for beginning to test the 8250 LSR_TSRE bit on a drain request is

if(bup->cnt) {
// Start Waiting …
}

In the case of a small writing request (DATA_SIZE <= 2), when we call devctl
with TCDRAIN request, soft FIFO is empty, but hardware FIFO isn’t and all
data aren’t transmitted or serialized. Unfortunately, with this test, 8250
LSR_TSRE bit is never tested. So the drain function does not work properly.
This problem can be more serious if UART transmit FIFO is larger or if
interface speed is faster.


Do you think I do a mistake, or is it really a bug ?
Any information you can provide will be greatly appreciated. Thanks


KUBIT Stéphane


\