Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading raw bytes from a serial port

I'm trying to read raw bytes from a serial port sent by a IEC 870-5-101 win32 protocol simulator with a program written in C running on Linux 32bit.

It's working fine for byte values like 0x00 - 0x7F. But for values beginning from 0x80 to 0xAF the high bit is wrong, e.g.:

0x7F -> 0x7F //correct
0x18 -> 0x18 //correct
0x79 -> 0x79 //correct
0x80 -> 0x00 //wrong
0xAF -> 0x2F //wrong
0xFF -> 0x7F //wrong

After digging around for two days now, I have no idea, what's causing this.

This is my config of the serial port:

    cfsetispeed(&config, B9600);
    cfsetospeed(&config, B9600);

    config.c_cflag |= (CLOCAL | CREAD);

    config.c_cflag &= ~CSIZE;                               /* Mask the character size bits */
    config.c_cflag |= (PARENB | CS8);                       /* Parity bit Select 8 data bits */

    config.c_cflag &= ~(PARODD | CSTOPB);                   /* even parity, 1 stop bit */


    config.c_cflag |= CRTSCTS;                              /*enable RTS/CTS flow control - linux only supports rts/cts*/


    config.c_iflag &= ~(IXON | IXOFF | IXANY);              /*disable software flow control*/ 

    config.c_oflag &= ~OPOST;                               /* enable raw output */
    config.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);      /* enable raw input */

    config.c_iflag &= ~(INPCK | PARMRK);                    /* DANGEROUS no parity check*/
    config.c_iflag |= ISTRIP;                               /* strip parity bits */
    config.c_iflag |= IGNPAR;                               /* DANGEROUS ignore parity errors*/

    config.c_cc[VTIME] = 1;                                 /*timeout to read a character in tenth of a second*/

I'm reading from the serial port with:

*bytesread = read((int) fd, in_buf, BytesToRead);

Right after this operation "in_buf" contains the wrong byte, so I guess there's something wrong with my config, which is a port from a win32 DCB structure.

Thanks for any ideas!

like image 980
punischdude Avatar asked Dec 22 '11 15:12

punischdude


1 Answers

Based on your examples, only the 8th bit (the high bit) is wrong, and it's wrong by being always 0. You are setting ISTRIP in your line discipline on the Linux side, and that would cause this. ISTRIP does not, as the comment in the C code claims, strip parity bits. It strips the 8th data bit.

If ISTRIP is set, valid input bytes shall first be stripped to seven bits; otherwise, all eight bits shall be processed. IEEE Std 1003.1, 2004 Edition, chapter 11, General Terminal Interface

like image 56
MetaEd Avatar answered Sep 27 '22 17:09

MetaEd