I'm transmitting data trough the serial port using only the write function. For some reason when I receive this data back \r (0x0d) transforms to \n (0x0a). This is probably due to the termios options I use when opening the port but I can't figure out what I can change.
I wrote code to open a binary image save it's data to a uint8_t array and send the data using the write system call and read it using the read system call.
Both the transmitting port and the receiving port are opened with the same options.
All the bytes that are received only differ on the exact same bytes every time and they are all the \r bytes. No data is being lost.
For some extra context: I'm transmitting data over serial port using 2 arduinos with RX0 connected to TX0 and TX0 connected to RX0. I'm also shorting ground. Basically I'm using the arduinos to separate the TX and RX signals and I'm not really using the actual arduino chip or anything.
I'm allocating the right amount of memory for both the receiving buffer and the transmitting buffer
#include <termios.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
int serialport_init(const char* serialport, int baud) {
struct termios toptions;
int fd;
fd = open(serialport, O_RDWR | O_NONBLOCK);
if (fd == -1) {
return -1;
}
if (tcgetattr(fd, &toptions) < 0) {
return -1;
}
speed_t brate = baud;
brate = B115200;
cfsetispeed(&toptions, brate);
cfsetospeed(&toptions, brate);
// 8N1 - * bits no parity
toptions.c_cflag &= ~PARENB;
toptions.c_cflag &= ~CSTOPB;
toptions.c_cflag &= ~CSIZE;
toptions.c_cflag |= CS8;
toptions.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
toptions.c_oflag &= ~OPOST; // make raw
toptions.c_cc[VMIN] = 0;
toptions.c_cc[VTIME] = 0;
tcsetattr(fd, TCSANOW, &toptions);
if (tcsetattr(fd, TCSAFLUSH, &toptions) < 0) {
return -1;
}
return fd;
}
int serialport_write_bytes(int fd, const uint8_t* bytes, size_t n_bytes) {
ssize_t n;
size_t bytes_written = 0;
while (bytes_written < (size_t)n_bytes) {
n = write(fd, &bytes[bytes_written], n_bytes - bytes_written);
if (n == -1) continue;
if (n == 0) {
continue;
}
bytes_written += n;
printf("wrote total of: %ld bytes n=%ld\n", bytes_written, n);
tcflush(fd, TCIOFLUSH); // Flush port - same result if not used
usleep(10 * 1000); // wait 1 msec try again. Maybe can remove
}
printf("Total bytes written: %ld\n", bytes_written);
return 0;
}
int serialport_read_bytes(int fd, uint8_t* buf, int n_bytes, int millis) {
ssize_t n;
size_t bytes_read = 0;
while (bytes_read < (size_t)n_bytes) {
n = read(fd, &buf[bytes_read], n_bytes - bytes_read);
if (n == -1) return -1; // couldn't read
if (n == 0) {
usleep(millis * 1000); // wait 1 msec try again
continue;
}
printf("read total: %ld bytes\n", bytes_read);
bytes_read += n;
}
printf("Total bytes read: %ld\n", bytes_read);
return 0;
}
I think you need to unset the ICRNL flag as well.
See https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html#fix-ctrl-m
toptions.c_iflag &= ~ICRNL;