Networking Forums  

Go Back   Networking Forums > Networking Newsgroups > Linux Networking

Flow Control on Serial Device

Reply
 
Thread Tools Display Modes
  #1  
Old 04-20-2007, 01:22 PM
Default Flow Control on Serial Device



I have a serial device that is connected to a pc via modem cable (db9f-
db9m straigth-thru).
There is a Windows program that reads from and writes to that device.
Now I want to replace Windows with Linux, so I have to write the
program for myself.
I have traced all data in both directions, but when I write the
initial string to the device, it does not answer.
I found that only 4 lines are being used: RxD (line 2), TxD (line 3),
SG (line 5) and CTS (line 8).
When the Windows program is started, CTS shows -5,35V against SG,
otherwise it shows 0.
It seems that this line is used to control flow.
I tried to set CTS via ioctl without success.
Has somebody an idea, what the underlying protocol might be and how I
could control that line in Linux?PS: If this is not the proper newsgroup,
could someone point me to the correct one?
Paul




Paul Pridt
Reply With Quote
  #2  
Old 04-20-2007, 01:25 PM
Davide Bianchi
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

On 2007-04-20, Paul Pridt <(E-Mail Removed)> wrote:
> I have traced all data in both directions, but when I write the
> initial string to the device, it does not answer.


Evidently you're missing something. Contact the manufacturer of such
thing and ask them for the specifications, note that reverse-engineering
of software is most of the time illegal.

Davide

--
Everyone seems so impatient and angry these days. I think it's because
so many people use Windows at work -- do you think you'd be Politeness
Man after working on Windows 8 hrs. or more?
-- Chip Atkinson
Reply With Quote
  #3  
Old 04-20-2007, 03:41 PM
Dale Dellutri
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

On Fri, 20 Apr 2007 14:22:03 +0200, Paul Pridt <(E-Mail Removed)> wrote:
> I have a serial device that is connected to a pc via modem cable (db9f-
> db9m straigth-thru).
> There is a Windows program that reads from and writes to that device.
> Now I want to replace Windows with Linux, so I have to write the
> program for myself.
> I have traced all data in both directions, but when I write the
> initial string to the device, it does not answer.
> I found that only 4 lines are being used: RxD (line 2), TxD (line 3),
> SG (line 5) and CTS (line 8).
> When the Windows program is started, CTS shows -5,35V against SG,
> otherwise it shows 0.
> It seems that this line is used to control flow.
> I tried to set CTS via ioctl without success.
> Has somebody an idea, what the underlying protocol might be and how I
> could control that line in Linux?PS: If this is not the proper newsgroup,
> could someone point me to the correct one?
> Paul


You've left out a lot of info. You don't tell your level of
expertise with serial communications. You don't say which
program works on your Windows PC. You don't say what you've
tried on the Linux side. You don't say what device you're
trying to talk to.

It looks like you're only measuring the levels of the lines
on one side (the DCE = the PC) of the line. I'd guess that
the other side (the DTE) is asserting RTS, but you're not
raising CTS in response at the right time so that the DTE
doesn't send any data.

(There are many other possibilities: you need a null-modem
(crossover) cable, not a straight-thru; you need a cable
which connects RTS to CTS for each side; you've got one of
the following wrong: transmit/receive speed, parity, data
bit length, stop bit length; and more.)

My suggestion: get ckermit for your Linux distro and try
to use it to send/receive. Also buy the book "Using
C-Kermit", 2nd ed. It has Appendix II "A Condensed Guide
to Serial Communications", a valuable resource. It also
has Appendix III "UNIX C-Kermit".

--
Dale Dellutri <(E-Mail Removed)> (lose the Q's)
Reply With Quote
  #4  
Old 04-20-2007, 03:56 PM
Floyd L. Davidson
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

"Paul Pridt" <(E-Mail Removed)> wrote:
>I have a serial device that is connected to a pc via modem cable (db9f-
>db9m straigth-thru).
>
>There is a Windows program that reads from and writes to that device.


Are you using the exact same cable for the Linux system that you
do for the Windows system? Are you absolutely sure that is
indeed a straight through cable? If it is some type of Null
Modem, there could be a lot of confusion...

>Now I want to replace Windows with Linux, so I have to write the
>program for myself.
>I have traced all data in both directions, but when I write the
>initial string to the device, it does not answer.


I'm not sure what you mean by "trace all data in both directions"
means. If you have access to an RS-232 data analyzer, that is
going to be *very* useful. Tell me how you are tracing data!

>I found that only 4 lines are being used: RxD (line 2), TxD (line 3),
>SG (line 5) and CTS (line 8).


That does *not* match RS-232. In the chart below, the PC serial
port is a DTE (for Data Terminal Equipment) and the remote
serial device is a DCE (for Data Communications Equipment).

PIN DTE FUNCTION NAME DTE DIRECTION
1 Frame Ground FG
2 Transmit Data TxD output
3 Receive Data RxD input
4 Request to Send RTS output
5 Clear to Send CTS input
6 Data Set Ready DSR input
7 Signal Ground SG
8 Carrier Detect DCD input

20 Data Terminal Ready DTR output
22 Ring Indicator RI input

The above is virtually guaranteed to be the way your PC's serial
port is wired. Your device may or may not be wired exactly the
same, or with appropriate wires reversed (TxD and RxD, for
example) for proper operation, which would be true of a DCE. If
the device is wired as a DTE, then the cable used must be a Null
Modem, and if the device is wired as a DCE then the cable must
be straight through.

>When the Windows program is started, CTS shows -5,35V against SG,
>otherwise it shows 0.


That cannot be a valid assumption on which pins are which.
First, pin 5 is not signal ground on your PC, and is very
unlikely to be on your device either. Second, RS-232 lines are
either a negative voltage or a positive voltage in respect to
ground, and are *never* idle at 0 volts. They have to be more
than +3 to be considered positive (not asserted) and more than
-3 to be considered negative (asserted). When between those
values the signal condition is undefined.

Generally on computers the RS232 pins are driven with +/- 12 volt
supplies, but technically can be (and must work with) signals as
great as +/- 15 volts. Voltage regulation is not required, and
actual values might vary even on the same equipment.

>It seems that this line is used to control flow.


Hardware flow control exists on at least two levels, one as an
indication that the device is turned on and ready to work, and
the other as an indication that individual characters can or
cannot be sent. The exact way that is done can vary (and is
usually different than what RS-232 was actually intended to do).

Generally the DTR signal is asserted on one side and is
connected to DSR on the other. It may also be connected to
DCD and CTS, thus indicating that data transmission can begin.
Sometimes CTS and RTS are strapped together on each end and
connected to DCD on the opposite end. All of those configurations
allow more or less ability to determine the ready state of the
remote device.

Another way is to connect DTR on one end to the opposite DSR and
DCD to indicate the device is available. Then CTS and RTS are
crossconnected between devices to permit character by character
hardware flow control.

>I tried to set CTS via ioctl without success.


Good trick, given that it is an input not an output, eh! :-)
You can monitor CTS, but you cannot set it. RTS is the output,
which you can set or clear.

But generally speaking, you don't want to do that. If you
properly configure your serial port, the device driver can and
will control RTS.

>Has somebody an idea, what the underlying protocol might be and how I
>could control that line in Linux?PS: If this is not the proper newsgroup,
>could someone point me to the correct one?


Welllll... Post your code for opening and configuring the
serial port. Try to cut it down to the simplest, shortest
program that you can. Maybe even just snippets with code
to open and configure a port; though if you can do it nicely the
best would be a short program that compiles and shoud send
one command and receive a response from the device.

Serial port programming is not really hard as such, but it is
extremely confusing. Hence experience counts much more than
smarts. Virtually nobody gets it right on their own the first
time, and everyone uses good references to keep track of how to
do it.

First, the Linux HOWTO for serial programming is filled with
errors and the program examples are loaded with bugs, so it is
an interesting read for the experienced, and a horrible
reference for newbies. Avoid it.

The number one reference you want is "Serial Programming Guide
for POSIX Operating Systems" by Michael Sweet at,

http://www.easysw.com/~mike/serial/

There are probably a number of good examples of serial port
programming available. One is to get the source code for
/minicom/, and see how they did it. A production program is
necessarily a bit convoluted, but you can eventually track down
how to do almost anything.

I have a few simpler examples posted on my web page, which might
be useful too. There are multiple examples of how to write a
simple terminal program (similar to the examples in the Linux
HOWTO for serial programming, except hopefully with fewer gross
errors, but unfortunately still with some unexplained "weird
stuff").

http://web.newsguy.com/floyd_davidson/code/terminal/

And some generic examples of diddling with ioctl's and serial
ports,

http://web.newsguy.com/floyd_davidson/code/rs232/

--
Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) (E-Mail Removed)
Reply With Quote
  #5  
Old 04-20-2007, 04:55 PM
Unruh
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

Davide Bianchi <(E-Mail Removed)> writes:

>On 2007-04-20, Paul Pridt <(E-Mail Removed)> wrote:
>> I have traced all data in both directions, but when I write the
>> initial string to the device, it does not answer.


>Evidently you're missing something. Contact the manufacturer of such
>thing and ask them for the specifications, note that reverse-engineering
>of software is most of the time illegal.


Reverse engineering is never illegal unless you have signed a contract in
which you have bound yourself not to reverse engineer.

(Under the MDCA reverse engineering may be illegal in the USA if it is a
copy protection scheme that you are reverse engineering).

Reply With Quote
  #6  
Old 04-20-2007, 06:31 PM
Paul Pridt
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

I use exactly the same cable as with the windows program. It is a
straight-thru cable. I had cut it and reconnected with 2 sniffer ends and
used linux/logserial to log all data. As I can see exactly the same data
as it is shown in Windows, speed, parity etc seem to be ok.
Btw I did started as sniffer with a windows machine and got the same result.
A db-9 cable is being used. I can disconnect all lines but 2,3,5,8 and it
works in Windows as before.
Obviously the device is wired as DCE.
I also tried to set RTS on and off via ioctl, no result.
When I set hardware flow on, nothing happens, the program appearently waits
for response that never comes.
Somebody asked about my knowledge level in serial programming: once I wrote
a serial device monitor for a specific device in C, so I do have some,
problably not very deep knowledge.
This device now does provide some measurement values over a rs232 interface.
Again, I want to use C.

Paul

"Floyd L. Davidson" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> "Paul Pridt" <(E-Mail Removed)> wrote:
>>I have a serial device that is connected to a pc via modem cable (db9f-
>>db9m straigth-thru).
>>
>>There is a Windows program that reads from and writes to that device.

>
> Are you using the exact same cable for the Linux system that you
> do for the Windows system? Are you absolutely sure that is
> indeed a straight through cable? If it is some type of Null
> Modem, there could be a lot of confusion...
>
>>Now I want to replace Windows with Linux, so I have to write the
>>program for myself.
>>I have traced all data in both directions, but when I write the
>>initial string to the device, it does not answer.

>
> I'm not sure what you mean by "trace all data in both directions"
> means. If you have access to an RS-232 data analyzer, that is
> going to be *very* useful. Tell me how you are tracing data!
>
>>I found that only 4 lines are being used: RxD (line 2), TxD (line 3),
>>SG (line 5) and CTS (line 8).

>
> That does *not* match RS-232. In the chart below, the PC serial
> port is a DTE (for Data Terminal Equipment) and the remote
> serial device is a DCE (for Data Communications Equipment).
>
> PIN DTE FUNCTION NAME DTE DIRECTION
> 1 Frame Ground FG
> 2 Transmit Data TxD output
> 3 Receive Data RxD input
> 4 Request to Send RTS output
> 5 Clear to Send CTS input
> 6 Data Set Ready DSR input
> 7 Signal Ground SG
> 8 Carrier Detect DCD input
>
> 20 Data Terminal Ready DTR output
> 22 Ring Indicator RI input
>
> The above is virtually guaranteed to be the way your PC's serial
> port is wired. Your device may or may not be wired exactly the
> same, or with appropriate wires reversed (TxD and RxD, for
> example) for proper operation, which would be true of a DCE. If
> the device is wired as a DTE, then the cable used must be a Null
> Modem, and if the device is wired as a DCE then the cable must
> be straight through.
>
>>When the Windows program is started, CTS shows -5,35V against SG,
>>otherwise it shows 0.

>
> That cannot be a valid assumption on which pins are which.
> First, pin 5 is not signal ground on your PC, and is very
> unlikely to be on your device either. Second, RS-232 lines are
> either a negative voltage or a positive voltage in respect to
> ground, and are *never* idle at 0 volts. They have to be more
> than +3 to be considered positive (not asserted) and more than
> -3 to be considered negative (asserted). When between those
> values the signal condition is undefined.
>
> Generally on computers the RS232 pins are driven with +/- 12 volt
> supplies, but technically can be (and must work with) signals as
> great as +/- 15 volts. Voltage regulation is not required, and
> actual values might vary even on the same equipment.
>
>>It seems that this line is used to control flow.

>
> Hardware flow control exists on at least two levels, one as an
> indication that the device is turned on and ready to work, and
> the other as an indication that individual characters can or
> cannot be sent. The exact way that is done can vary (and is
> usually different than what RS-232 was actually intended to do).
>
> Generally the DTR signal is asserted on one side and is
> connected to DSR on the other. It may also be connected to
> DCD and CTS, thus indicating that data transmission can begin.
> Sometimes CTS and RTS are strapped together on each end and
> connected to DCD on the opposite end. All of those configurations
> allow more or less ability to determine the ready state of the
> remote device.
>
> Another way is to connect DTR on one end to the opposite DSR and
> DCD to indicate the device is available. Then CTS and RTS are
> crossconnected between devices to permit character by character
> hardware flow control.
>
>>I tried to set CTS via ioctl without success.

>
> Good trick, given that it is an input not an output, eh! :-)
> You can monitor CTS, but you cannot set it. RTS is the output,
> which you can set or clear.
>
> But generally speaking, you don't want to do that. If you
> properly configure your serial port, the device driver can and
> will control RTS.
>
>>Has somebody an idea, what the underlying protocol might be and how I
>>could control that line in Linux?PS: If this is not the proper newsgroup,
>>could someone point me to the correct one?

>
> Welllll... Post your code for opening and configuring the
> serial port. Try to cut it down to the simplest, shortest
> program that you can. Maybe even just snippets with code
> to open and configure a port; though if you can do it nicely the
> best would be a short program that compiles and shoud send
> one command and receive a response from the device.
>
> Serial port programming is not really hard as such, but it is
> extremely confusing. Hence experience counts much more than
> smarts. Virtually nobody gets it right on their own the first
> time, and everyone uses good references to keep track of how to
> do it.
>
> First, the Linux HOWTO for serial programming is filled with
> errors and the program examples are loaded with bugs, so it is
> an interesting read for the experienced, and a horrible
> reference for newbies. Avoid it.
>
> The number one reference you want is "Serial Programming Guide
> for POSIX Operating Systems" by Michael Sweet at,
>
> http://www.easysw.com/~mike/serial/
>
> There are probably a number of good examples of serial port
> programming available. One is to get the source code for
> /minicom/, and see how they did it. A production program is
> necessarily a bit convoluted, but you can eventually track down
> how to do almost anything.
>
> I have a few simpler examples posted on my web page, which might
> be useful too. There are multiple examples of how to write a
> simple terminal program (similar to the examples in the Linux
> HOWTO for serial programming, except hopefully with fewer gross
> errors, but unfortunately still with some unexplained "weird
> stuff").
>
> http://web.newsguy.com/floyd_davidson/code/terminal/
>
> And some generic examples of diddling with ioctl's and serial
> ports,
>
> http://web.newsguy.com/floyd_davidson/code/rs232/
>
> --
> Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
> Ukpeagvik (Barrow, Alaska) (E-Mail Removed)



Reply With Quote
  #7  
Old 04-20-2007, 07:04 PM
Floyd L. Davidson
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

"Paul Pridt" <(E-Mail Removed)> wrote:
>I use exactly the same cable as with the windows program. It is a
>straight-thru cable. I had cut it and reconnected with 2 sniffer ends and
>used linux/logserial to log all data. As I can see exactly the same data
>as it is shown in Windows, speed, parity etc seem to be ok.
>Btw I did started as sniffer with a windows machine and got the same result.
>A db-9 cable is being used. I can disconnect all lines but 2,3,5,8 and it
>works in Windows as before.


Okay. First, I was thinking in 25 pin connector terms, and you
are using 9 pin connectors. My fault.

DB25 DB9
PIN PIN FUNCTION NAME
1 Frame Ground FG
2 3 Transmit Data TxD
3 2 Receive Data RxD
4 7 Request to Send RTS
5 8 Clear to Send CTS
6 6 Data Set Ready DSR
7 5 Signal Ground SG
8 1 Carrier Detect DCD

20 4 Data Terminal Ready DTR
22 9 Ring Indicator RI

Hence, with that, your pin statements do make more sense, though
there is still the problem with showing 0 volts. It is possible
that your device is trying to use -5v for mark and 0 volts for
space... which often enough works even if it is an abomination.

With that configuration, connecting only 4 lines, you can't
really do hardware flow control in the way the device driver
will assume if it is used.

It appears as if the RTS/CTS line is sourced at the device
(RTS), and your program would sense (the CTS) that line to
determine the state of the device. I guess one would assume
that data should only be sent if it is asserted. Or at least
that is a good starting point, and something you can verify
relatively easy.

There is code for sensing CTS in the RS-232 examples that I
cited in the previous article, which you can use as a mind
refresher if needed. It would appear that you have done that
sort of thing previously, so it will all make sense quickly.

>Obviously the device is wired as DCE.
>I also tried to set RTS on and off via ioctl, no result.


If what I suspect above is true, there would be no effect from
changing RTS states.

>When I set hardware flow on, nothing happens, the program appearently waits
>for response that never comes.


And that would also happen.

>Somebody asked about my knowledge level in serial programming: once I wrote
>a serial device monitor for a specific device in C, so I do have some,
>problably not very deep knowledge.


That is definitely a good start. I was assuming just about
that. Otherwise you would not have been playing with ioctl
calls! (And of course if you had lots of experience, you
wouldn't have even bothered with that.)

>This device now does provide some measurement values over a rs232 interface.
>Again, I want to use C.


Here's where we're at, I think:

>> Welllll... Post your code for opening and configuring the
>> serial port. Try to cut it down to the simplest, shortest
>> program that you can. Maybe even just snippets with code
>> to open and configure a port; though if you can do it nicely the
>> best would be a short program that compiles and shoud send
>> one command and receive a response from the device.


I think we might be back to this. A lot of what you are
probably doing depends on what examples you used to develop your
code, and much of what is available on the net comes from the
LINUX Howto, which means much of it is riddled with errors.

I can go through your code and determine if it actually is doing
what you want it to, and probably point out any weird
possibilities that would cause strange results.

--
Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) (E-Mail Removed)
Reply With Quote
  #8  
Old 04-21-2007, 04:50 PM
Paul Pridt
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

Floyd,

I re-engineered my cable and connected line 7 (RTS) also.
So the cable now looks like that:
2,3,5,7 and 8 are straight-thru. On the PC-side 6 and 4 are connected (did
not make any difference).
The sniffer ends are connected to 2 and 3 respectively and to 5.
Then I repeated all the tests and noted down the measurements as follows:

W WA WT LS0 LUSB

2 -7,1 -7,1 -7,2 -6,4 -7,2
3 0 -5,3 -5,3 0 -6,9
7 0 -5,3 +5,9 0 -7,3
8 -7,1 -7,1 -7,1 -6,7 -7,2

That means:
W Windows only (no application started)
WA Windows application program (provided with the device)
WT Windows perminal program
LS0 Linux ttyS0
LUSB Linux ttyUSB0

In all cases the same cable and hardware was used with the following
exception:
in Linux ttyS0 did not work at all (the sniffer program did not even see the
initial character string sent)
and I have to use an usb-serial adapter, while the Windows application
program runs on com1 only.
In Windows only the application program provided with the device works.
Interesting is that when I use the Windows terminal program to send the
initial character string line 7 shows +5,9 V,
but there is no response from the device either.
In Linux I made the same test with my application program and serlook.
In both cases the sniffer program sees the initial character string but no
response.
These are the relevant parts of my program:

fd = open(tty, O_RDWR | O_NOCTTY | O_NDELAY);

tcgetattr(fd,&oldtio);
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = CLOCAL | CREAD | CS8;
newtio.c_iflag = 0;
newtio.c_cc[VMIN]=0;
newtio.c_cc[VTIME]=0;
cfsetospeed(&newtio, BAUDRATE);
cfsetispeed(&newtio, BAUDRATE);
tcflush(fd, TCIOFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
fcntl(fd, F_SETOWN, getpid());

ioctl(fd,TIOCMGET,&status);
status |= TIOCM_RTS;
ioctl(fd,TIOCMSET,&status);
write(fd,"UUUUU\xFF\xFF\x01\x5b\x8f\x00\x5A\x07\x0 1\x33\x00\x00\x95",18);

I hope this all is readable to you.
Thank you very much for your effort.

Paul


"Floyd L. Davidson" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> "Paul Pridt" <(E-Mail Removed)> wrote:
>>I use exactly the same cable as with the windows program. It is a
>>straight-thru cable. I had cut it and reconnected with 2 sniffer ends and
>>used linux/logserial to log all data. As I can see exactly the same data
>>as it is shown in Windows, speed, parity etc seem to be ok.
>>Btw I did started as sniffer with a windows machine and got the same
>>result.
>>A db-9 cable is being used. I can disconnect all lines but 2,3,5,8 and it
>>works in Windows as before.

>
> Okay. First, I was thinking in 25 pin connector terms, and you
> are using 9 pin connectors. My fault.
>
> DB25 DB9
> PIN PIN FUNCTION NAME
> 1 Frame Ground FG
> 2 3 Transmit Data TxD
> 3 2 Receive Data RxD
> 4 7 Request to Send RTS
> 5 8 Clear to Send CTS
> 6 6 Data Set Ready DSR
> 7 5 Signal Ground SG
> 8 1 Carrier Detect DCD
>
> 20 4 Data Terminal Ready DTR
> 22 9 Ring Indicator RI
>
> Hence, with that, your pin statements do make more sense, though
> there is still the problem with showing 0 volts. It is possible
> that your device is trying to use -5v for mark and 0 volts for
> space... which often enough works even if it is an abomination.
>
> With that configuration, connecting only 4 lines, you can't
> really do hardware flow control in the way the device driver
> will assume if it is used.
>
> It appears as if the RTS/CTS line is sourced at the device
> (RTS), and your program would sense (the CTS) that line to
> determine the state of the device. I guess one would assume
> that data should only be sent if it is asserted. Or at least
> that is a good starting point, and something you can verify
> relatively easy.
>
> There is code for sensing CTS in the RS-232 examples that I
> cited in the previous article, which you can use as a mind
> refresher if needed. It would appear that you have done that
> sort of thing previously, so it will all make sense quickly.
>
>>Obviously the device is wired as DCE.
>>I also tried to set RTS on and off via ioctl, no result.

>
> If what I suspect above is true, there would be no effect from
> changing RTS states.
>
>>When I set hardware flow on, nothing happens, the program appearently
>>waits
>>for response that never comes.

>
> And that would also happen.
>
>>Somebody asked about my knowledge level in serial programming: once I
>>wrote
>>a serial device monitor for a specific device in C, so I do have some,
>>problably not very deep knowledge.

>
> That is definitely a good start. I was assuming just about
> that. Otherwise you would not have been playing with ioctl
> calls! (And of course if you had lots of experience, you
> wouldn't have even bothered with that.)
>
>>This device now does provide some measurement values over a rs232
>>interface.
>>Again, I want to use C.

>
> Here's where we're at, I think:
>
>>> Welllll... Post your code for opening and configuring the
>>> serial port. Try to cut it down to the simplest, shortest
>>> program that you can. Maybe even just snippets with code
>>> to open and configure a port; though if you can do it nicely the
>>> best would be a short program that compiles and shoud send
>>> one command and receive a response from the device.

>
> I think we might be back to this. A lot of what you are
> probably doing depends on what examples you used to develop your
> code, and much of what is available on the net comes from the
> LINUX Howto, which means much of it is riddled with errors.
>
> I can go through your code and determine if it actually is doing
> what you want it to, and probably point out any weird
> possibilities that would cause strange results.
>
> --
> Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
> Ukpeagvik (Barrow, Alaska) (E-Mail Removed)



Reply With Quote
  #9  
Old 04-22-2007, 06:05 PM
Floyd L. Davidson
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

"Paul Pridt" <(E-Mail Removed)> wrote:
>Floyd,
>
>I re-engineered my cable and connected line 7 (RTS) also.
>So the cable now looks like that:
>2,3,5,7 and 8 are straight-thru. On the PC-side 6 and 4 are connected (did
>not make any difference).
>The sniffer ends are connected to 2 and 3 respectively and to 5.
>Then I repeated all the tests and noted down the measurements as follows:
>
> W WA WT LS0 LUSB
>
>2 -7,1 -7,1 -7,2 -6,4 -7,2
>3 0 -5,3 -5,3 0 -6,9
>7 0 -5,3 +5,9 0 -7,3
>8 -7,1 -7,1 -7,1 -6,7 -7,2
>
>That means:
>W Windows only (no application started)


Note the 0 voltage on pins that are sourced by the PC. That
means your serial port is not active... and is not putting any
"signal" on those pins yet.

>WA Windows application program (provided with the device)


Incidentally, I don't believe the voltages are calibrated! I'll bet
you anything that what shows up there as -5 is more like -12. And
your remote device isn't actually -7, but more like -15.

>WT Windows perminal program


Note the similarity to WA, which is exactly what it should be.

>LS0 Linux ttyS0


This is the same as W, with no signal at all from the PC. The
serial port is not enabled. What happens if you run

/sbin/setserial /dev/ttyS0

>LUSB Linux ttyUSB0


The USB to serial port converter always has the RS232 port
enabled.

>In all cases the same cable and hardware was used with the following
>exception:
>in Linux ttyS0 did not work at all (the sniffer program did not even see the
>initial character string sent)


The voltages shown above indicate that it is not enabled, so that
fits. Serial ports may not be enabled in your kernel???

>and I have to use an usb-serial adapter, while the Windows application
>program runs on com1 only.
>In Windows only the application program provided with the device works.
>Interesting is that when I use the Windows terminal program to send the
>initial character string line 7 shows +5,9 V,
>but there is no response from the device either.


That is the RTS line sourced by the PC. It is difficult to know
what response there should be from the device.

Typically the common usage today would be that if RTS is
asserted, the remote device will send data if it wants to and if
RTS is not asserted the device will not send data even if it
wants to. The same effect, in the opposite direction, would be
true of CTS.

So you would not see anything happen when RTS is asserted
_unless_ it just happens that the device has data ready to send
(and of course full hardware flow control is enabled, so that it
was inhibited from sending until RTS was asserted).

It doesn't appear that the RTS line is actually being used.

And I have a sneaking suspician that CTS is not being used for
flow control as such. If you watch pin 8 for awhile when the
Window application is running, does it ever flip to a positive
voltage, even for a moment? If not, they might be using it as
merely the equivalent of DTR, to indicate that the device is
ready.

If that is the case, you could strap pin 8 to the DCD input on
pin 1 and cause the programming task to be easier...

>In Linux I made the same test with my application program and serlook.
>In both cases the sniffer program sees the initial character string but no
>response.


Your serial port is not enabled.

>These are the relevant parts of my program:


Unfortunately, that does not include many relevant parts! Don't
make any attempt to edit on a line per line basis. Grab the entire
function, because you probably have all sorts of odd things that
have effects you aren't aware of...

> fd = open(tty, O_RDWR | O_NOCTTY | O_NDELAY);


Use O_NONBLOCK rather than O_NDELAY, just to make it more
portable. They are precisely the same on Linux but might be
different on other unix OS's.

But here we don't have any error checking, so there is no way to
tell of the call to open() failed or succeeded. If your serial
port is not enabled in the kernel, it failed and that would
cause exactly the symptoms you describe.

Also, you are not re-enabling O_NONBLOCK, which is going to make
reading data from this serial port a bit complicated.

> tcgetattr(fd,&oldtio);


There is no point in saving the original configuration.

> bzero(&newtio, sizeof(newtio));


Use memset() instead of bzero().

> newtio.c_cflag = CLOCAL | CREAD | CS8;


That is good, but you also probably want a few others,

newtio.c_iflag = (IGNBRK | IGNPAR);

> newtio.c_iflag = 0;
> newtio.c_cc[VMIN]=0;
> newtio.c_cc[VTIME]=0;


Note that you have already zeroed the entire struct, and
these are redundant.

Also, I would not recomment setting both VMIN and VTIME elements
of the c_cc array to zero.

The easiest way to read data from a serial port is with blocking
i/o, and then with one of VMIN/VTIME set to 0 and the other to 1,
depending on the desired effects.

If they are both set to 0, a call to read() will always return
immediately. If VMIN is 1 and VTIME is 0, the call to read()
block forever or until there is at least 1 byte of data or a
interupt signal is received. If VTIME is 1 and VMIN is 0, the
call to read() will return if data is available or will block
for 1/10th of a second before returning with no data.

One of the significant effects of the above is that if each
call to read() can block, the process very nicely gives up its
time slice and does not become a CPU hog. (If you use nonblocking
i/o in a tight loop you'll beat the CPU to death at the needless
expense of every other process running.)

If you set VTIME to 0, then read() should only be called after
the select() function has determined that there is data
available.

> cfsetospeed(&newtio, BAUDRATE);
> cfsetispeed(&newtio, BAUDRATE);
> tcflush(fd, TCIOFLUSH);
> tcsetattr(fd,TCSANOW,&newtio);


That needs to have error checking added to make sure that it has
done something. (No error does not mean that it necessarily did
what you wanted, but an error means it didn't do anything.)

> fcntl(fd, F_SETOWN, getpid());
>
> ioctl(fd,TIOCMGET,&status);
> status |= TIOCM_RTS;
> ioctl(fd,TIOCMSET,&status);
> write(fd,"UUUUU\xFF\xFF\x01\x5b\x8f\x00\x5A\x07\x0 1\x33\x00\x00\x95",18);
>
>I hope this all is readable to you.
>Thank you very much for your effort.


No problem... other than I haven't been doing much of this in
the last few years, so I'm a bit dull sometimes and miss obvious
things.

--
Floyd L. Davidson <http://www.apaflo.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) (E-Mail Removed)
Reply With Quote
  #10  
Old 04-22-2007, 07:24 PM
David M
Guest
 
Posts: n/a
Default Re: Flow Control on Serial Device

On Sat, 21 Apr 2007 17:50:25 +0200, Paul Pridt rearranged some electrons
to form:

Here's a bit of code that works for me.
I am not using flow control, in this particular application, the PC
serial port is talking to a 68HC11 microcontroller.

YMMV.

#include <termios.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

/*********** open_com_port *****************************
* opens com port
* port = char string defining what to open (ie. /dev/ttyxx)
* fd = resulting file descriptor
* returns: 0 (OK) non-zero (error)
* ************************************************** **/
int open_com_port(char *port, int *fd)
{
*fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);
if (*fd < 0)
return (*fd); /* bad fd, so return non-zero */
else
{
/* make fd non-blocking */
fcntl(*fd, F_SETFL, FNDELAY);
}
return 0;
}

/*********** init_com_port *****************************
* sets up com port
* port = COMx (DOS) or file descriptor of open com port (LINUX)
* baud = 300,1200,2400,4800,9600
* length = 5,6,7,8
* stop = 1,2
* parity = 0 (none) 1 (odd) 2 (even)
* sets it up for raw non canonical input
* returns 0 (OK) non-zero (error)
* Also sets xmitdelay to an appropriate value based on baud rate
************************************************** *******/
int init_com_port(int port,int baud,int length,int stop,int parity)
{
extern int xmitdelay;
unsigned int data,temp;
float x;
char tmp[30];
struct termios oldtio, newtio;

/* figure about how many millisec. it will take to send a char */
x = (float)(length+stop+1)*1100.0/(float)baud; /* add 10% for luck */
x++; /* add one just to make sure it's not zero */
xmitdelay = (int) x;

/* retrieve current port settings */
tcgetattr(port, &newtio);
/* get baudrate */
switch (baud) {
case 300: data=B300;
break;
case 1200: data=B1200;
break;
case 2400: data=B2400;
break;
case 4800: data=B4800;
break;
case 9600: data=B9600;
break;
default: return -2;
}
cfsetispeed(&newtio, data); /* sets input & output baud rate in structure */
cfsetospeed(&newtio, data);
newtio.c_cflag &= ~CSIZE; /* mask word size bits */
switch (length) {
case 5: newtio.c_cflag |= CS5;
break;
case 6: newtio.c_cflag |= CS6;
break;
case 7: newtio.c_cflag |= CS7;
break;
case 8: newtio.c_cflag |= CS8;
break;
default: return -3;
}
switch (stop) {
case 1: /* default is 1 SB */
newtio.c_cflag &= ~CSTOPB; /* clear the bit */
break;
case 2: newtio.c_cflag |= CSTOPB; /* set the bit for 2SB */
break;
default: return -3;
}
switch (parity) {
case 0: /* default is none */
newtio.c_cflag &= ~PARENB; /* clear the parity enable bit */
newtio.c_iflag &= ~INPCK;
break;
case 1: newtio.c_cflag |= PARENB; /* odd */
newtio.c_cflag |= PARODD;
break;
case 2: newtio.c_cflag |= PARENB; /* even */
newtio.c_cflag &= ~PARODD;
break;
default: return -4;
}
/* set the values in the termios struct */
newtio.c_cflag |= (CREAD | CLOCAL); /* enable RX*/
newtio.c_cflag &= ~(CRTSCTS); /* HW flow control off */
newtio.c_iflag |= IGNPAR; /* ignore parity errors */
newtio.c_iflag &= ~(IXON | IXOFF | IXANY | INLCR | ICRNL | IUCLC | IMAXBEL); /* switch off other options*/
newtio.c_oflag &= ~(OPOST); /* raw output */
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | ISIG); /* non canonical, no echo */
newtio.c_cc[VMIN] = 0;
newtio.c_cc[VTIME] = 1; /* delay up to (N/10) seconds waiting for char on "read" */

temp = tcsetattr(port, TCSAFLUSH, &newtio);
tcflush(port, TCIOFLUSH);
return (int)temp;
}


Enjoy.


--
David M (dmacchiarolo)
http://home.triad.rr.com/redsled
T/S 53
sled351 Linux 2.4.18-14 has been up 6 days 20:22

Reply With Quote
Reply

Tags
control, device, flow, serial

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT. The time now is 08:46 PM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.