2

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?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Rajesh D
  • 63
  • 3
  • 1
    Where are you sending from and where to? (and which software do you use to send/receive) – Simon Doppler Mar 18 '22 at 09:41
  • @SimonDoppler from processor (NXP6ULL) to serial port .. – Rajesh D Mar 18 '22 at 09:44
  • On which side is the wrong byte present? On the embedded processor or your development machine? – Simon Doppler Mar 18 '22 at 09:47
  • What @SimonDoppler means: do you have a terminal(emulator) at the receiving end of the line? – wildplasser Mar 18 '22 at 09:51
  • @simon-doppler while receving im using docklight(software) then i receving extra byte 0d before 0a – Rajesh D Mar 18 '22 at 09:51
  • You should probably check the parameters in Docklight, it may add the byte as part of the data reception process (most terminal emulators do something like this, where they will convert the host's CR/LF combination to the combination to use on the serial line). – Simon Doppler Mar 18 '22 at 09:54
  • If you are working in embedded world, I'm almost sure you might have a logic analyzer. First thing to check what is actually sent. By looking into your code I tend to think it's your terminal (or whatever software you're using on the receiver side) that adds extra staff to try to be compliant with whatever they think is right in regards to CFLR. Also, move away from Windows if you are working in embedded field - you will surprised how much headache you will solve by this. – Andrejs Cainikovs Mar 18 '22 at 18:58

2 Answers2

3

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, which is typically enabled by default).

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 (such as the ONLCR attribute), 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.

sawdust
  • 16,103
  • 3
  • 40
  • 50
2

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.

Dominique
  • 16,450
  • 15
  • 56
  • 112
  • 2
    0a is LF, 0d is CR – stark Mar 18 '22 at 10:54
  • there is no newline in ASCII. LF means scroll the paper by one line, CR means move the print carriage to the left margin. A newline to an old ASCII teletype sent both plus 3 NULs to give them time to complete, so 5 bytes. Windows got it down to 2 bytes. – stark Mar 18 '22 at 11:01