The following code configures UART port.
const char *UART2_path="/dev/ttymxc2";
int UART2;
void UART2_open(const char *UART2_path)
{
int flags = O_RDWR | O_NOCTTY ;
UART2 = open(UART2_path,flags);
tcgetattr(UART2, &ttyurt); //Get the current attributes of the serial port //
//Setting baud rate (input and output)
cfsetispeed(&ttyurt, B115200);
cfsetospeed(&ttyurt, B115200);
ttyurt.c_cflag &= ~PARENB; // Disables the Parity Enable bit(PARENB) //
ttyurt.c_cflag &= ~CSTOPB; // Clear CSTOPB, configuring 1 stop bit //
ttyurt.c_cflag &= ~CSIZE; // Using mask to clear data size setting //
ttyurt.c_cflag |= CS8; // Set 8 data bits //
ttyurt.c_cflag &= ~CRTSCTS; // Disable Hardware Flow Control //
tcsetattr(UART2, TCSANOW, &ttyurt); // Write the configuration to the termios structure//
tcflush(UART2, TCIFLUSH);
}
---------
--------
--------
buffer[8]={0x1f,0x0a,0x1a,0x89,0x85,0xbf,0x36,0x40};
write(UART2,&buffer,strlen(buffer));//sending on uart
expected output==>1f0a8985bf3640
actual output ==>1f0d0a8985bf3640
I'm able to send data, but for some reason 0x0A
sent characters are received as 0x0D 0x0A
. I'm fairly sure something in this port configuration is doing this.
extra byte 0d
before 0a
?
CodePudding user response:
You seem to be another victim of UNIX/Linux versus Windows "newline"/"line feed" handling: UNIX/Linux uses single character, like 0A
(line feed) or 0D
(newline) for going to another line, while Windows uses a combination 0D0A
, so most probably you have some program that converts your "I-believe-the-data-to-be-UNIX-like" into "Windows-like".
That might go far: I had the situation where UNIX files were sent to a Windows computer, and the user was using a Windows file viewer to see the content of the files, and it was the file viewer itself which was doing that conversion. Therefore I advise you to check all intermediate programs.
CodePudding user response:
writting 0D 0A insted of 0A when I tried to write into uart
That appears to caused by a termios (mis)configuration that is inappropriate for your situation. The termios layer is capable of translating/expanding each occurrence of \n
to \r\n
for output (i.e. the ONLCR attribute).
The following code configures UART port.
Your program accesses a serial terminal (i.e. /dev/tty...) rather than a "UART port". There are several layers of processing in between your program and the UART hardware. See Linux serial drivers
Your initialization code is properly implemented (i.e. per Setting Terminal Modes Properly), but it is just the bare minimum that sets only the serial line parameters to 115200 8N1 and no HW flow control. Absolutely no other termios attributes are specified, which means that your program will use whatever previous (random?) settings, and may occasionally misbehave.
The most important consideration when using a serial terminal and termios configuration is determining whether the data should be handled in canonical (as lines of text) or non-canonical (aka raw or binary) mode. Canonical mode provides additional processing to facilitate the reading/writing of text as lines, delimited by End-of-Line characters. Otherwise syscalls are performed for an arbitrary number of bytes. See this answer for more details.
Your output data appears to be not (ASCII) text, so presumably you want to use non-canonical (aka raw) mode. For raw output, your program should specify:
ttyurt.c_oflag &= ~OPOST;
This will inhibit any data conversion on output by termios.
But your termios initialization is also incomplete for reading.
For a proper and concise termios initialization for non-canonical mode, see this answer.
If instead you need canonical mode, then refer to this answer.