[comp.sys.sun] Sun serial port communication problem

quasar@ctt.bellcore.com (Laurence R. Brothers) (02/14/89)

OK, here's my problem. USA4SUN hasn't gotten back to me yet, so....

I'm writing a little application to read stuff coming in over my sun's
serial port (Sun-4/260, though it shouldn't make much difference).

Since I don't yet have the OGM (Obsolete Garbagey Machine) that will be
supplying the RS232 chatter, I'm faking it by connecting a null modem from
ttya to ttyb, writing to a, and reading from b.

My test reader just does an open on /dev/ttyb and sits there busy-waiting,
copying anything it reads to stdout. To write to ttya, I just either cat a
file into the device, or open it for writing from a toy program.

The problem is that my reader reads garbage. I mean, I get maybe half the
catted file more or less OK, (for some reason, all the end-of-line
characters get doubled), but after the file has been sent, the reader
still manages to get junk coming in. By junk, I don't mean just random
characters, but a sort of cuisinarted version of the original file, like
there's some buffer somewhere which is getting cycled through with
dissociated press.

If I cat from the keyboard into the ttya device, the result is even worse
-- the first line gets sent OK, the second is typically garbled, and the
third is totally scrambled.

I've tried a large variety of things. For example, removing the getty on
tty's a and b (yes, I reran init), doing reads and writes instead of
getc's and putc's, doing fgets's instead of getc's, setting
setbuf(stream,0) on a file pointer gotten from the device's file
descriptor, putting usleeps in both the writer and reader, etc. etc.  etc.

I suspect either some sort of timing problem, or some fundamental mistake
in trying to read and write these devices.

Can someone take pity on a poor AI hacker who doesn't even know the pins
in an RS232 plug by heart... (sob)?

	    Laurence R. Brothers (quasar@ctt.bellcore.com)
Bellcore -- Computer Technology Transfer -- Expert Systems Development

dan@watson.bbn.com (02/23/89)

I've never tried to connect two serial ports together on Suns, but I can
give some general UNIX advice about connecting two tty ports together:

First, make sure those getty processes really went away when you wanted
them to.  Do "ps ax" and make sure there are no processes living on ttya
or ttyb, particularly processes named '-'.  They can cause intermittent
failures if they are still hanging around.

But your real problem is probably the tty modes.  The tty drivers are
capable of doing quite complicated things to the characters they send and
receive, and you don't want them to do any of that.  I did

	stty everything >/dev/ttya

on my Sun-3/50 running 3.5, to see what the default modes were, and the
result would not be good for your application: both echo and -nl appeared.
This sounds like it's the real problem.  The doubling of your newline
characters implies that -nl, called CRMOD at the programming level, is set
on both ttys.  So when you write an LF to one tty, CR-LF goes out on the
wire.  The reader sees CR-LF and turns it into LF-LF.  The repeating
garbage sounds like echo is turned on.  Actually, if you've got echo
turned on at both ttys, I'm not sure why your reader would ever stop
reading :-).  But you want to turn it off.

To do all this, use ioctl(2) to do a TIOCSETP as described in tty(4).  To
play it safe, do a TIOCGETP first to fill in the structure, then change
the bits you need to change and do TIOCSETP of the result.  Here is an
*untested* example:

	#include <sgtty.h>
	...
	struct sgttyb ttymodes;
	...
	/* Assume infd is the file descriptor being read */
	if (ioctl(infd, TIOCGETP, &ttymodes) == -1)
		perror("Error getting modes");
	ttymodes.sg_flags = RAW|TANDEM;
	if (ioctl(infd, TIOCSETP, &ttymodes) == -1)
		perror("Error setting modes");
	...	

In this example I've turned on raw mode, which is about as close to zero
processing by the driver as you can get.  All 8 bits will come through
uninterpreted.  And I turned on TANDEM, on the assumption that you want
the Sun to send ctrl-S/ctrl-Q characters back to the OGM if there's a
problem keeping up.  (Caveat: I don't know for sure that TANDEM works when
RAW is set...)  I also implicitly turned off things like CRMOD, ECHO, line
editing characters, etc. none of which you want.  If you want parity
checked/produced, turn on CBREAK instead of RAW.

You can also do this kind of thing at the shell level by using the stty
command; this is useful for your fake writer.  Example:
	(stty 9600 raw; cat a-file) >/dev/ttya
That sets the speed to 9600 baud and turns on raw mode.

Disclaimer: The details may not be quite right.  But it should get you
pointed in the right direction.

	Dan Franklin

dik@uva.UUCP (Casper H.S. Dik) (02/28/89)

quasar@ctt.bellcore.com (Laurence R. Brothers) writes:
>I'm writing a little application to read stuff coming in over my sun's
>serial port (Sun-4/260, though it shouldn't make much difference).
>
>Since I don't yet have the OGM (Obsolete Garbagey Machine) that will be
>supplying the RS232 chatter, I'm faking it by connecting a null modem from
>ttya to ttyb, writing to a, and reading from b.

This is what I think happens:

You write a character to a
It travels to b

It gets echoed by the tty driver at b. (and read by your program)

It travels back to a

It gets echoed by the tty driver listening to port a

It gets back to b. (read again by your program)

... ad infinitum

So switching of echoing on port a and b should do the trick.

This also accounts for doubled line-terminators.  If you output a newline
on port a it gets converted to nl-cr on output.  Port b then finds two
line terminators.

Your best bet is raw & noecho.

Hope this helps,
--cd

Casper H.S. Dik
University of Amsterdam     |		      dik@uva.uucp
The Netherlands             |                 ...!uunet!mcvax!uva!dik

tpc@bnr-fos.uucp (Tom Chmara) (03/04/89)

quasar@ctt.bellcore.com (Laurence R. Brothers) writes:
>My test reader just does an open on /dev/ttyb and sits there busy-waiting,
>copying anything it reads to stdout. To write to ttya, I just either cat a
>file into the device, or open it for writing from a toy program.
>
>The problem is that my reader reads garbage....

Sounds like a problem I had at one point.  The problem turned out to be
that I hadn't turned off echo on the ports; each character was echoed by
the terminal driver, and was then looped back into the driver, which took
it as more input... (on top, of course, of the input I was already
squirting into the port, and output from any shell or application with
which I was communicating).  And you're right --- the garbage looks
"familiar", because what you'd really expected to say (and any output from
your input) IS in the text; it's just buried in gibberish...

Sorry about the delay in getting this out (and that it's a posted
message); our mail feed has been refusing to talk with us lately, and
though I think I have it working, I'm trying this means just in case...

	---tpc---

Tom Chmara			UUCP:  ..utgpu!bnr-vpa!bnr-fos!tpc
BNR Ltd.  			BITNET: TPC@BNR.CA