garinus Posted March 30, 2020 Posted March 30, 2020 Armbianmonitor: http://ix.io/2fZx 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? 0 Quote
garinus Posted March 30, 2020 Author Posted March 30, 2020 I'm trying to debug it using the oscilloscope, and I see that the TX signal is not initialized to 3v3 when I add the "param_uart2_rtscts=1" in the armbianEnv.txt file. If I do not edit the armbianEnv file, the board initializes correctly the TX and RX signals. 0 Quote
garinus Posted March 30, 2020 Author Posted March 30, 2020 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 44000000libfdt 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? 0 Quote
yoq Posted March 31, 2020 Posted March 31, 2020 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 0 Quote
garinus Posted April 1, 2020 Author Posted April 1, 2020 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 0 Quote
martinayotte Posted April 1, 2020 Posted April 1, 2020 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. 1 Quote
garinus Posted April 3, 2020 Author Posted April 3, 2020 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. 0 Quote
martinayotte Posted April 3, 2020 Posted April 3, 2020 3 hours ago, garinus said: I have still some problems on rts. 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 0 Quote
garinus Posted April 3, 2020 Author Posted April 3, 2020 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? 0 Quote
martinayotte Posted April 3, 2020 Posted April 3, 2020 Using Armbian build scripts, the patch should be placed into build/patch/kernel/sunxi-dev, then start the build. You can look at build/output/debug/patching.log to see if it been applied properly ... 0 Quote
mycnc Posted April 17, 2020 Posted April 17, 2020 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 0 Quote
martinayotte Posted April 18, 2020 Posted April 18, 2020 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; } 0 Quote
iqbal Posted August 20, 2020 Posted August 20, 2020 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 0 Quote
Werner Posted August 20, 2020 Posted August 20, 2020 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 0 Quote
martinayotte Posted August 20, 2020 Posted August 20, 2020 7 hours ago, iqbal said: I got an error compiling your patch My patch was working with <=5.7.y, but not anymore with >=5.8.y due to someone else patch been mainlined . I'm still investigating how to make it work again and/or make the someone else patch working as my previous one ... 0 Quote
rrp Posted October 26, 2021 Posted October 26, 2021 On 8/20/2020 at 12:26 PM, martinayotte said: I'm still investigating how to make it work again and/or make the someone else patch working as my previous one ... Hi, do you update/fix rs485-8250 patch for current kernel (5.10)? 0 Quote
martinayotte Posted November 1, 2021 Posted November 1, 2021 On 10/26/2021 at 4:45 AM, rrp said: do you update/fix rs485-8250 patch for current kernel (5.10)? I don't know ... I've worked on this since almost a year ... 0 Quote
rrp Posted November 21, 2021 Posted November 21, 2021 On 11/1/2021 at 6:51 PM, martinayotte said: I don't know ... I've worked on this since almost a year ... So ... I was trying to look too. Looks like this patch (series) make mess with your rs485-8250 patch, but don't enable software emulated rs485 for dw variant nor provide own workaround for chips without "end transmit" interrupt. I created minimal patch for add this workaround (from your patch) to current kernel: diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 9c00d7504..bc8cd87ee 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -469,6 +469,10 @@ static int dw8250_probe(struct platform_device *pdev) p->set_ldisc = dw8250_set_ldisc; p->set_termios = dw8250_set_termios; + p->rs485_config = serial8250_em485_config; + up->rs485_start_tx = serial8250_em485_start_tx; + up->rs485_stop_tx = serial8250_em485_stop_tx; + p->membase = devm_ioremap(dev, regs->start, resource_size(regs)); if (!p->membase) return -ENOMEM; diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index be779eb9e..c9f5b626e 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1541,8 +1541,14 @@ static inline void __stop_tx(struct uart_8250_port *p) * shift register are empty. It is for device driver to enable * interrupt on TEMT. */ - if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) - return; + //if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) + // return; + // TODO: use if / while variant depending on the support / not support interrupt ... + // TODO: or provide different serial8250_stop_tx for chips without interrupt + while ((lsr & BOTH_EMPTY) != BOTH_EMPTY) { + lsr = serial_in(p, UART_LSR); + cpu_relax(); + } __stop_tx_rs485(p); } This is more "dirty hack" than "good patch" (always use "no interrupt" approach - see todo note in code), but it's work for me (at least for now, more tests shortly). 0 Quote
MastinZgZ Posted November 22, 2021 Posted November 22, 2021 Hi @rrp ! I have a similar problem I want to try your patch , but i dont know how to apply .¿ Any guide or help? Thanks! 0 Quote
erazor Posted February 2, 2022 Posted February 2, 2022 Attached is a git diff, which includes 2 patches: rs485-8250_dw.patch - manually merged for 5.13.3 [PATCH] tty: 8250_of: Use software emulated RS485 direction control @ 2019-09-13 5:01 Heiko Schocher As you can see it's for the current/latest armbian kernel version 5.13.3 . I haven't re-applied the patch to see if patching works but with these changes RS485 works great for me on my NanoPI Neo. I don't use any additional ENV-vars for booting, but this DTS:: /dts-v1/; /plugin/; / { compatible = "allwinner,sun8i-h3"; fragment@0 { target = <&uart2>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; linux,rs485-enabled-at-boot-time; rs485-rts-active-low; //rs485-rx-during-tx; rts-gpios = <&pio 0 2 1>; status = "okay"; }; }; }; This took me 3 days but I wouldn't get it running without this forum. Thanks Armbian Team! rs485-8250_dw-8250_of.patch 1 Quote
MastinZgZ Posted July 11, 2023 Posted July 11, 2023 Hello! How y can try to apply this patch? Thanks! Luis 0 Quote
Recommended Posts
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.