Issues with serial - Linux

I’ve written an application which deals with NMEA sentences for my 5HZ GPS module.

It worked for a while, but now it doesn’t.

When I run the GPS module through Minicom I receive the correct results:

$GPVTG,51.99,T,,M,0.48,N,0.88,K,A*05                                            
$GPGGA,133837.000,5130.9991,N,00232.4986,W,1,7,1.01,68.2,M,48.9,M,,*72          
$GPRMC,133837.000,A,5130.9991,N,00232.4986,W,0.53,51.99,170409,,,A*47           
$GPVTG,51.99,T,,M,0.53,N,0.97,K,A*01                                            
$GPGGA,133837.200,5130.9991,N,00232.4985,W,1,7,1.01,68.2,M,48.9,M,,*73          
$GPRMC,133837.200,A,5130.9991,N,00232.4985,W,0.51,51.99,170409,,,A*44           
$GPVTG,51.99,T,,M,0.51,N,0.94,K,A*00                                            
$GPGGA,133837.400,5130.9991,N,00232.4985,W,1,7,1.01,68.2,M,48.9,M,,*75          
$GPGSA,A,3,08,04,25,02,10,24,13,,,,,,1.37,1.01,0.92*00                          
$GPGSV,3,1,11,07,61,116,,25,54,073,19,02,48,240,35,13,45,065,18*70              
$GPGSV,3,2,11,08,39,175,17,10,38,296,39,04,29,193,25,23,14,070,*72              
$GPGSV,3,3,11,24,11,324,21,16,10,027,,29,09,321,*48                             
$GPRMC,133837.400,A,5130.9991,N,00232.4985,W,0.60,51.99,170409,,,A*40           
$GPVTG,51.99,T,,M,0.60,N,1.11,K,A*0E

So I’m happy that everything is working correctly from the GPS module to the end of the serial cable.

However when I run it on my development board, I receive mostly garbage.

fORGSV,;.:,qs.q0nvr,��i+�7�5sn�v7<>1<,:=-3{r.2;-2<-9,OXRMSn1;6�99n<84,I,=1sA
6W�GS��s<sl31n2sn9p<0w2.,r;,19�397,����v-8:n�rs<*�w
$GPRMC,134911.600,A,5130.9997,N,00232.5056,W,0.00,51.99,170409,,,A*46
$GPVTG,51.99,T,,M,0.00,N,0.00,K,A*09
$GPGGA,134911.800,5130.9997,N,00232.5056,W,1,7,1.22,66.2,M,48.9,M,,*74
$GPRMC,134911.800,A,5130.9997,N,00232.5056,W,0.00,51.99,170409,,,A*48
$GPVTG,51.99,T,,M,0.00,N,0.00,K,A*09
&GtggE,n&ڊ�v���t,Ol&d����fv.006&�����b���f�f��nv7$v6.2lD,<<.=,M,,.7e       9
�4GROOAlssv�srn6�8l=9;8.999?-O,8prs25rw�nW-q,7n1n:rn�R.�~O�vz>{.].nj7BC#�V 7
RG�O�V<3l3n11,3s.11,�7�nn2{<r9n{9?l22nsR-0x��K%OOC!YV��]Cn334{1r�5p0,I,53s�?

I wouldn’t mind so much if it printed garbage ALL the time, but it doesn’t.

Every now and again it churns out perfectly viable data.

I am running Linux and a bare-bones system i.e. compiled kernel and Busybox on my Olimex EP9302.

Does anyone have any ideas to poke me in the right direction, for I’m all out!

Make sure all of your timings are right, CPU Frequency, multipliers, bus speeds, etc. Also make sure that your serial settings are correct.

That shouldn’t have anything to do with it.

If you look at the center of the received junk you’ll see that occasionally it prints perfectly.

It’s annoying because this has been working for weeks and now it’s not.

Same kernel, same rootfs, same application.

I have been playing around with the getty settings in /etc/inittab, but to no avail.

I’ve tried each of these:

console::respawn:/sbin/getty -L 38400 /dev/ttyAM1 vt100

console::once:/sbin/getty -L 38400 /dev/ttyAM1 vt100
console::once:/sbin/getty -L 38400 /dev/ttyAM1 vt102

getty -L -n 38400 /dev/ttyAM1 vt100
getty -L -l /home/username/null_login 38400 /dev/ttyAM1 vt102

Some work better than others, some do not work at all.

As I say, it’s very annoying because all this worked not long ago and I can’t think what I might have changed to upset it.

That looks more like an electrical problem to me — a noisy connection, or a wire that’s come loose but still capacitively couples just well enough to get through most of the time. If you look at some of the only-partly-garbled lines, you’ll see that the displayed data is often only 1 or 2 bits flipped from the correct data, which really suggests a signal-integrity problem more than a software problem.

If there are no pauses in transmission, line noise can cause async NRZ serial to lose frame sync for a while, interpreting the stop and start bits as part of the data, and vise versa. That kind of looks like it’s happening here. Another possibility is that the baud rates at either end are not exactly the same (either because an oscillator is drifting or your baudrate generator can’t exactly hit the specified frequency). Async serial can tolerate some mismatch in the baud rate, but only a certain amount— it’s pretty easy to calculate the amount, but if your signal is noisy (or slew-rate-limited or band-limited) then the two problems can compound each other.

I think the problem lies on a buffer overrun, if you have not programmed RTS/CTS handshake. You could change the terminal attributes, with the attached code as an esqueleton (the CRTSCTS deals with hardware handshake)

void initComSMS()

{

struct termios oldtio,newtio;

fdSMS = open(DEVICE, O_RDWR | O_NOCTTY );

if (fdSMS <0)

{

// perror(DEVICE);

syslog(LOG_ERR,“Error opening %s\n”,DEVICE);

exit(-1);

}

tcgetattr(fdSMS,&oldtio); /* save current port settings */

bzero(&newtio, sizeof(newtio));

newtio.c_cflag = B19200 | CS8 | CRTSCTS | CLOCAL | CREAD;

newtio.c_iflag = IGNPAR;

newtio.c_oflag = 0;

/* set input mode (non-canonical, no echo,…) */

newtio.c_lflag = 0;

newtio.c_cc[VTIME] = 10; /* inter-character timer unused */

newtio.c_cc[VMIN] = 0; /* blocking read until 1 chars received */

tcflush(fdSMS, TCIFLUSH);

tcsetattr(fdSMS,TCSANOW,&newtio);

telefono[0] = 0;

msgSMS[0] = 0;

syslog(LOG_DEBUG,“Port %s initialized\n”,DEVICE);

}