Jump to content

Recommended Posts

Posted
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?

Posted

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.

Posted

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? 
 

Posted

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

 

Posted

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

 

Posted
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.

Posted

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.

Posted

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?

Posted

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 ...

Posted
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

Posted
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;
}

 

Posted
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
 

Posted
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

Posted
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 ...

Posted
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)?

Posted
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).

Posted

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

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...
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines