RTS signal and uart2 init


Recommended Posts

Armbianmonitor:

Hi all,

I need to enable rts/cts on my OrangePi Zero with Armbian buster with Linux 5.4.26-sunxi installed.
I added the "param_uart2_rtscts=1" (I'm using /dev/ttyS2) to the /boot/armbianEnv.txt file

 

On mi code I use this initialization of the port.

xxxxx.c_cflag |=
        port_parity |
        port_bits |
        port_stop |
        CLOCAL |
        CRTSCTS |
        CREAD;

 

Not only rts/cts but also the tx and rx pin aren't working now.

Has anyone managed to enable the port on this board? Am I doing something wrong?

Link to post
Share on other sites
Armbian is a community driven open source project. Do you like to contribute your code?

I found this in boot:

 

Applying kernel provided DT overlay sun8i-h3-usbhost2.dtbo
504 bytes read in 5 ms (97.7 KiB/s)
Applying kernel provided DT overlay sun8i-h3-usbhost3.dtbo
502 bytes read in 5 ms (97.7 KiB/s)
Applying kernel provided DT overlay sun8i-h3-uart2.dtbo
502 bytes read in 5 ms (97.7 KiB/s)
Applying kernel provided DT overlay sun8i-h3-uart3.dtbo
4155 bytes read in 5 ms (811.5 KiB/s)
Applying kernel provided DT fixup script (sun8i-h3-fixup.scr)
## Executing script at 44000000
libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND
libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND

## Loading init Ramdisk from Legacy Image at 43300000 ...
   Image Name:   uInitrd
   Image Type:   ARM Linux RAMDisk Image (gzip compressed)
   Data Size:    7347265 Bytes = 7 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK

 

what can be the cause of this error? 
 

Link to post
Share on other sites

UART2 with TX/RX should work out of the box if you enable the "uart2" overlay in armbianEnv.txt. I see you also have uart3 activated, afaik this port is not routed out on a OPZ.
RTS/CTS for UART2 is missing at the moment, but you can add it to the device tree manually. Create the file "uart2_rtscts_fix.dts" in your home folder:

/dts-v1/;
/plugin/;

/ {
	compatible = "allwinner,sun8i-h3";

	fragment@0 {
		target = <&pio>;
		__overlay__ {
			uart2_rts_cts: uart2_rts_cts {
				pins = "PA2", "PA3";
				function = "uart2";
			};
		};
	};
};

Then run this to compile and add the custom overlay it to the device tree:

armbian-add-overlay uart2_rtscts_fix.dts

You need to keep param_uart2_rtscts=1, and on the next reboot, the error should be gone.

 

Edit: Oh and systemd likes to start a getty shell on all serial ports, so you may need to kill that service to make the port usable:

systemctl stop serial-getty@ttyS2.service

 

Link to post
Share on other sites

thank you yoq,

i did all what you said, but the serial works until i add param_uart2_rtscts=1 in the armbianEnv.txt file:

 

verbosity=1
logo=disabled
console=serial
disp_mode=1920x1080p60
overlay_prefix=sun8i-h3
overlays=uart2 usbhost2 usbhost3
rootdev=UUID=48c1e88a-b408-42ec-9d6c-9aaacd147312
rootfstype=ext4
user_overlays=uart2_rtscts_fix
param_uart2_rtscts=1
usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

 

Link to post
Share on other sites
25 minutes ago, garinus said:

but the serial works until i add param_uart2_rtscts=1 in the armbianEnv.txt file:

This thread reveal some bug present in fixup scripts that were not be updated since introduction of 5.x.y :

 

I've done some fixes and committed this morning.

You can either wait for new images, or build yourself a new image, or try to fix the sun8i-h3-fixup.scr yourself manually.

Link to post
Share on other sites

Hi,

thanks Martin.

I built the last image. There aren't errors on boot and the ttS2 now works when I add the param param_uart2_rtscts=1.  I have still some problems on rts. 

The signal is high until I open the serial connection, then goes low for all the time the serial stay open and then it become high when I close the serial connection. 

I made several tries with all the settings I know. 

The simplest metod to test it is using tio: tio /dev/ttyS2 -f hard-b 115200

With -f none (no hardwae flow control) the serial has the same behaviour.

Link to post
Share on other sites

Yes, the goal is to use a 485 tranceiver directly, without acting at high level on RTS pin. Now I use ioctl to verify the finish of the tx and i change the state of the pin. This works in 99% of cases except when the cpu is doing something and there is a delay before the change of the signal.

 

I'm having diffculties in applying the patch because i'm a noob in git and kernel compiling. 

 

Please correct me if I do something wrong:

 

put the file .patch in the folder build/cache/sources/linux-mainline/orange-pi-5.5

 

launch the command git apply rs485-8250_dw.patch

error: patch failed: drivers/tty/serial/8250/8250.h:136
error: drivers/tty/serial/8250/8250.h: patch does not apply
error: patch failed: drivers/tty/serial/8250/8250_dw.c:637
error: drivers/tty/serial/8250/8250_dw.c: patch does not apply

 

then if the apply goes well launch 

compile.sh in /build

 

I'm doing something wrong that i receive this errors?

Link to post
Share on other sites
On 4/3/2020 at 8:26 AM, martinayotte said:

This patch will add RS485 emulation ...

 

Hello, I need RS485 half-duplex too.

I applied the patch, but behaviour is the same. RTS goes down when transmition started ang goes up only when application closed.

Maybe I missed how to turn ON the emulation mode?

Any advice please

thanks

Link to post
Share on other sites
15 hours ago, mycnc said:

Maybe I missed how to turn ON the emulation mode?

After having built a kernel with the above patch to get half-duplex emulation, you also need to initialize the port with proper flags, with either "-i" or not, depending of ActiveHigh or ActiveLow output.

 



#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <linux/serial.h>
#include <sys/ioctl.h>


void init_port(char *port, int rts_state) {
    struct serial_rs485 rs485conf = {0};
    struct termios tty;    

    int fd = open(port, O_RDWR);
    if (fd < 0) {
        printf("ERROR! Open() failed \r\n");
    }

    rs485conf.flags = SER_RS485_ENABLED;
    if (rts_state == 0)
        rs485conf.flags |= SER_RS485_RTS_ON_SEND;
    else
        rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
    if (ioctl(fd, TIOCSRS485, &rs485conf) < 0) {
        printf("ERROR! ioctl settings update failed \r\n");
    }

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
    }
    cfsetospeed(&tty, (speed_t)115200);
    cfsetispeed(&tty, (speed_t)115200);

    tty.c_cflag |= (CLOCAL | CREAD);    /* ignore modem controls */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */
    
    /* setup for non-canonical mode */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;

    /* fetch bytes as they become available */
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 1;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
    }
    
    if (close(fd) < 0) {
        /* Error handling. See errno. */
        printf("ERROR! Close() failed \r\n");
    }
}
    

int main(int argc, char *argv[]) {
    if (argc > 1) {
        if (strcmp(argv[1], "-i") == 0) {
            printf("inverted port = %s\n", argv[2]);
            init_port(argv[2], 1);
        }
        else {
            printf("port = %s\n", argv[1]);
            init_port(argv[1], 0);
        }
    }
    else {
        printf("usage :   rs485-init <port>\n example : rs485-init /dev/ttyS1\n");
    }
    return 0;
}

 

Link to post
Share on other sites
On 4/3/2020 at 7:26 PM, martinayotte said:

Are you wish to use RTS as RS485 HalfDuplex control pin ?

In such case, you will need another patch since the dw8250 driver doesn't support it.

This patch will add RS485 emulation ...

 

rs485-8250_dw.patch 12.08 kB · 30 downloads

I got an error compiling your patch

 

Processing file /home/pacol/build/patch/kernel/sunxi-dev/rs485-8250_dw.patch
1 out of 1 hunk FAILED -- saving rejects to file include/linux/serial_8250.h.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250.h.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250_omap.c.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250_core.c.rej
4 out of 8 hunks FAILED -- saving rejects to file drivers/tty/serial/8250/8250_port.c.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250_of.c.rej
 

Link to post
Share on other sites
45 minutes ago, iqbal said:

I got an error compiling your patch

 

Processing file /home/pacol/build/patch/kernel/sunxi-dev/rs485-8250_dw.patch
1 out of 1 hunk FAILED -- saving rejects to file include/linux/serial_8250.h.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250.h.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250_omap.c.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250_core.c.rej
4 out of 8 hunks FAILED -- saving rejects to file drivers/tty/serial/8250/8250_port.c.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/tty/serial/8250/8250_of.c.rej
 

 

Quote

sunxi-dev

wrong kernel version. Try legacy

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...