UART w RTS/CTS does not receive correctly

Started by igi, July 02, 2020, 11:32:28 AM

Previous topic - Next topic

igi

Hello,
I use the A20 board revision I (I tried also revision E with the same result).
I am using uart3 with hardware flow control RTS/CTS. There is used this OS:
Debian GNU/Linux 8 (jessie)
Linux 10-0-1-32 3.4.103-00033-g9a1cd03-dirty #29 SMP PREEMPT Tue Apr 5 08:21:20 EEST 2016 armv7l GNU/Linux
Transmitting works fine. Receiving also works but sometimes nothing is received, sometimes there are missing bytes - most of the time first 2B are missed, sometimes the received message is fine. I tried direct reading via command
cat /dev/ttyS1
and I also tried reading in my C program with the same result. I tried a lot of possible configuration of VMIN, VTIME and the other flags. It is probably SW problem because when I enable ECHO, I get every time the correct message back to my transmitting device. I tried messages with and also without \r and \n. My current code looks something like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


static struct termios oldterminfo;

void closeserial(int fd) {
    tcsetattr(fd, TCSANOW, &oldterminfo);
    if (close(fd) < 0)
        perror("closeserial()");
}

int openserial(char *devicename) {
    int fd;
    struct termios attr;

    if ((fd = open(devicename, O_RDWR)) == -1) {
        perror("openserial(): open()");
        return 0;
    }
    if (tcgetattr(fd, &oldterminfo) == -1) {
        perror("openserial(): tcgetattr()");
        return 0;
    }
    attr = oldterminfo;
   cfsetispeed(&attr, B115200);
    cfsetospeed(&attr, B115200);
   
    //attr.c_oflag = 0;
    attr.c_cc[VMIN] = 1;
   attr.c_cc[VTIME] = 0;
   
      
   attr.c_cflag &= ~PARENB;// without parity
   attr.c_cflag &= ~CSTOPB;// just one stop bit
    attr.c_cflag &= ~CSIZE;
    attr.c_cflag |= CS8;
    attr.c_cflag |= (CREAD);
   attr.c_cflag |= CRTSCTS;
   
    attr.c_lflag &= ~(ICANON | ECHOE | ISIG);
   //attr.c_lflag |= ECHO;
    //attr.c_iflag &= ~(IXON | IXOFF | IXANY | IGNCR | ICRNL);
    //attr.c_oflag &= ~OPOST;
   

    if (tcflush(fd, TCIOFLUSH) == -1) {
        perror("openserial(): tcflush()");
        return 0;
    }
    if (tcsetattr(fd, TCSANOW, &attr) == -1) {
        perror("initserial(): tcsetattr()");
        return 0;
    }


    return fd;
}


int main() {
    int fd;
    char *serialdev = "/dev/ttyS1";

    fd = openserial(serialdev);
    if (!fd) {
        fprintf(stderr, "Error while initializing %s.\n", serialdev);
        return 1;
    }
   
    char readBuf[256];
    memset(readBuf, '\0', sizeof (readBuf));

    // Read bytes. The behaviour of read() (e.g. does it block?,
    // how long does it block for?) depends on the configuration
    // settings above, specifically VMIN and VTIME
   
    int n, i, j;
    for (i = 0; i < 4; i++) {
      
        n = read(fd, readBuf, sizeof (readBuf));
        if (n > 0) {
           
         for(j = 0; j < n; j++) {
            printf("%X ", readBuf[j]);
        }
      printf("\n");
    }

    closeserial(fd);
    return 0;
}

olimex


Brian

If you use uart without transceivers you have to terminate RTS, CTS lines with resistors 1K to ground.

igi

The cable is about 30cm long. I think there is not any interference/disturbance because what I wrote before - if I turn on echo, a message is correctly sent back to transmitting device. It means that at least a HW receiver in the Olimex received the correct data.
What do you mean by "uart without transceivers" ? I use Olimex and USB/UART interface connected to PC. Both devices have RTS/CTS pins. So I connected them directly RTS=>CTS, CTS=>RTS.
I guess it is a SW problem. Maybe in driver or wrong settings somwhere...

JohnS

Have you got a getty or the like also using that port?

You will lose chars if so!

John

igi

Yes, there was the mistake! Thank you for the help. :)

JohnS