Reputation: 623
Below are Serial Communication Port Settings
1. BaudRate: 19200
2. Parity: Even
3. StopBits: 1
The transmitter sends few bytes of data: 0x5A 0xA5 0xAA
Receiver is written in C on Linux using termios serial API
I am able to receive the first byte 0x5A correctly but the byte 0xA5 is received as 0x25 and 0xAA is received as 0x2A i.e. the 8th bit of each byte is set to 0...why ?
Below is the C (OS: Linux) code extract for setting the serial port settings on receiver application:
void *threadRecv(void *arg)
{
char *portName = (char *)arg;
char ch;
struct termios portSettings;
//fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY);
fd = open(portName, O_RDONLY | O_NOCTTY);
close(fd);
fd = open(portName, O_RDONLY | O_NOCTTY);
if(fd == -1)
{
printf("Error opening port: %s", portName);
pthread_exit("Exiting thread");
}
cfsetispeed(&portSettings, B19200);
//Parity
portSettings.c_cflag &= ~PARENB;
portSettings.c_cflag |= PARENB;
portSettings.c_cflag &= ~PARODD;
//Stop Bit
portSettings.c_cflag &= ~CSTOPB;
//Data Size: 8bits
portSettings.c_cflag &= ~CSIZE;
portSettings.c_cflag |= CS8;
portSettings.c_cflag |= CREAD;
portSettings.c_cflag |= CLOCAL;
portSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
portSettings.c_iflag |= (INPCK);
portSettings.c_oflag &= ~OPOST; //For RAW I/P
portSettings.c_cc[VMIN] = 77;
portSettings.c_cc[VTIME] = 0;
if(tcsetattr(fd, TCSANOW, &portSettings) == -1)
{
printf("Error setting port: %s", portName);
pthread_exit("Exiting thread");
}
while(1)
{
//Recv Logic
}
}
Upvotes: 0
Views: 484
Reputation: 17047
While your code follows the preferred practice of bit-wise modifying the terms of the termios structure, your program is missing the salient initialization of the structure by calling tcgetattr(fd, &portSettings)
.
If the garbage values in the uninitialized termios stucture has the iflag.ISTRIP
enabled, then that could explain the results you see.
Since your code only does minimal modification of the iflag
bits, it should have a statement similar to what the cfmakeraw()
does:
portSettings.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
See Serial Programming Guide for POSIX Operating Systems.
portSettings.c_cc[VMIN] = 77;
portSettings.c_cc[VTIME] = 0;
This is a problematic configuration if message frame synchronization is ever lost. Specifying a nonzero VTIME would be a safety measure that would permit recovery as long as you have proper hunt logic for re-achieving message synchronization.
BTW raw (aka non-canonical) I/O is typically 8 bits with no parity. Eight bits with parity is an unusual configuration. Are you trying to emulate receiving 9-bit character frames (i.e. 9N1)?
Upvotes: 1