Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C tty/tcsetattrs question

1 view
Skip to first unread message

Manuel Bouyer

unread,
May 26, 2016, 1:31:15 PM5/26/16
to
Hello,
I have a GPS device connected to a serial port. It defaults to 9600bps
NMEA messages, but I need to switch it to 4800bps. There are NMEA
commands for this, and I can properly do this using cu(1).

Now I'm trying to write a program to do this at boot time.
First I need to determine if the GPS is outputting at 4800 or 9600bps
(the CPU may be rebooted, or even powered off wihout resetting the GPS
module).
I wrote the attached C program, but the cfsetspeed() doesn't seem
to have any effect: with the GPS running at 9600bps,
if I start with the tty set to 9600 (for example from a previous
cu(1) run) I get proper NMEA sentences on both check_term() calls,
and if I start with the tty set to 4800 (e.g. from a previous
cu(1) run) I get either nothing or garbage (not getting anything
from the tty is a valid case, as the tty is in canon mode select()
will return a read event only if the serial port got something that
looks like a line).

Does anyone see an obvious error or something I missed ?

--
Manuel Bouyer <bou...@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--
configure_gps.c

David Holland

unread,
May 26, 2016, 11:37:13 PM5/26/16
to
No, but some things to check:

(1) When you have this program change the speed, does the speed change
register? If you call tcgetattr right after, what's the speed
returned? And what do you see if if you use stty?

(2) Is the behavior different if you specify TCSANOW instead of TCSAFLUSH?
(It shouldn't be, but...)

(3) why are you turning on ICANON?

--
David A. Holland
dhol...@netbsd.org

Manuel Bouyer

unread,
May 27, 2016, 4:02:20 AM5/27/16
to
On Fri, May 27, 2016 at 03:37:03AM +0000, David Holland wrote:
> On Thu, May 26, 2016 at 07:30:05PM +0200, Manuel Bouyer wrote:
> > I have a GPS device connected to a serial port. It defaults to 9600bps
> > NMEA messages, but I need to switch it to 4800bps. There are NMEA
> > commands for this, and I can properly do this using cu(1).
> >
> > Now I'm trying to write a program to do this at boot time.
> > First I need to determine if the GPS is outputting at 4800 or 9600bps
> > (the CPU may be rebooted, or even powered off wihout resetting the GPS
> > module).
> > I wrote the attached C program, but the cfsetspeed() doesn't seem
> > to have any effect: with the GPS running at 9600bps,
> > if I start with the tty set to 9600 (for example from a previous
> > cu(1) run) I get proper NMEA sentences on both check_term() calls,
> > and if I start with the tty set to 4800 (e.g. from a previous
> > cu(1) run) I get either nothing or garbage (not getting anything
> > from the tty is a valid case, as the tty is in canon mode select()
> > will return a read event only if the serial port got something that
> > looks like a line).
> >
> > Does anyone see an obvious error or something I missed ?
>
> No, but some things to check:
>
> (1) When you have this program change the speed, does the speed change
> register? If you call tcgetattr right after, what's the speed
> returned? And what do you see if if you use stty?

stty returns the expected speed, so I guess the kernel has the right speed.
But this may be cached somewhere; I'll add some debug printf in the
com driver to make sure.

>
> (2) Is the behavior different if you specify TCSANOW instead of TCSAFLUSH?
> (It shouldn't be, but...)

will try.

>
> (3) why are you turning on ICANON?

Because NMEA is a line-oriented protocol, so having select() wake up when
a whole line is ready to be read is easier to deal with.
But for test I could run with ICANON off.

Manuel Bouyer

unread,
May 27, 2016, 1:23:54 PM5/27/16
to
On Thu, May 26, 2016 at 07:30:05PM +0200, Manuel Bouyer wrote:
> Hello,
> I have a GPS device connected to a serial port. It defaults to 9600bps
> NMEA messages, but I need to switch it to 4800bps. There are NMEA
> commands for this, and I can properly do this using cu(1).
>
> Now I'm trying to write a program to do this at boot time.
> First I need to determine if the GPS is outputting at 4800 or 9600bps
> (the CPU may be rebooted, or even powered off wihout resetting the GPS
> module).
> I wrote the attached C program, but the cfsetspeed() doesn't seem
> to have any effect: with the GPS running at 9600bps,
> if I start with the tty set to 9600 (for example from a previous
> cu(1) run) I get proper NMEA sentences on both check_term() calls,
> and if I start with the tty set to 4800 (e.g. from a previous
> cu(1) run) I get either nothing or garbage (not getting anything
> from the tty is a valid case, as the tty is in canon mode select()
> will return a read event only if the serial port got something that
> looks like a line).
>
> Does anyone see an obvious error or something I missed ?

Ops, I used = where I wanted &=. This resulted in non-wanted flags
in various place, with strange effects. With this fixed the
speed settings have more effects.

Now there are bugs in the driver itself (or in the allwiner serial port)
but this is another problem.
0 new messages