stevend
Posts: 441
Joined: Fri Oct 11, 2013 12:28 pm

Serial port configuration for RS-485

Thu Aug 26, 2021 8:07 am

I'm looking to use several of the Pi's serial ports in two modes (selectable at runtime, not just at boot):
a) Basic full-duplex serial, with RTS effectively a GPIO line used as an output
b) RS-485 style modes, where the RTS line is used to enable the transmitter (automatically from the driver)

The final application will be written in C/C++.

I've not managed to find definitive answers to all my questions on setup; my initial presumption is that devicetree is the way to go for pin/function assignment (although I've got no problem with setting things up via code if that's preferable, and I'm happy with using termios/ioctl for serial management; it's just some of the detail that eludes me!).

1. Assigning pins:
a) Looking at the 'standard' device tree overlays, it appears that when enabled uart0 and uart1 just use TxD, RxD, while uart2..uart5 'grab' TxD, RxD, CTS, RTS (source: https://github.com/raspberrypi/firmware ... ays/README and https://github.com/raspberrypi/linux/tr ... s/overlays).
I don't particularly want the CTS pin to be associated with the serial port; the requirement is to use it as an independent signal (output which rarely changed, so doesn't matter if it needs an ioctl() or similar)
What is the best way to exclude CTS from serial port operations, and be able to treat it as a simple output?
(Note: I can't afford to 'waste' the CTS pin by not using it at all).
b) Is there any underlying reason why RTS could not be enabled on uart0 or uart1?

2. I've found a good explanation of using RS-485 mode:
https://www.kernel.org/doc/html/latest/ ... rs485.html
Is this supported in the Pi's serial drivers?

3. When not in RS-485 mode, it appears that the RTS pin can remain associated with the serial port, controlled thus:
https://www.xanthium.in/Controlling-RTS ... t-in-Linux
Is this supported in the Pi's serial drivers?

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Serial port configuration for RS-485

Thu Aug 26, 2021 8:15 am

[ Moved to Interfacing ]

stevend
Posts: 441
Joined: Fri Oct 11, 2013 12:28 pm

Re: Serial port configuration for RS-485

Fri Aug 27, 2021 2:25 pm

PhilE wrote:
Thu Aug 26, 2021 8:15 am
[ Moved to Interfacing ]
Is that implying that device tree-related tweaks aren't the solution? (Which is my initial assumption)

User avatar
rpdom
Posts: 19280
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Serial port configuration for RS-485

Fri Aug 27, 2021 2:51 pm

stevend wrote:
Fri Aug 27, 2021 2:25 pm
PhilE wrote:
Thu Aug 26, 2021 8:15 am
[ Moved to Interfacing ]
Is that implying that device tree-related tweaks aren't the solution? (Which is my initial assumption)
No, that is saying that this subject is better discussed in the "Interfacing" sub-forum. You are more likely to get a good answer there.
Unreadable squiggle

trejan
Posts: 3850
Joined: Tue Jul 02, 2019 2:28 pm

Re: Serial port configuration for RS-485

Fri Aug 27, 2021 3:00 pm

You can use just 1 handshaking line but actually setting it via the overlay will be a hassle. It assumes the CTS and RTS lines are a single unit so you can't easily turn on just one of them. The easy but hacky way is to twiddle the registers directly to reconfigure it to how you want.

User avatar
scruss
Posts: 4485
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: Serial port configuration for RS-485

Fri Aug 27, 2021 4:03 pm

If you're used to Windows-style COM ports where (mis)using serial control lines as GPIO is a thing, and a thing that happens in near real-time, you might find Linux's "when I feel like getting round to it" serial ioctls a bit of a drag
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.
Pronouns: he/him

stevend
Posts: 441
Joined: Fri Oct 11, 2013 12:28 pm

Re: Serial port configuration for RS-485

Wed Sep 08, 2021 4:50 pm

rpdom wrote:
Fri Aug 27, 2021 2:51 pm
stevend wrote:
Fri Aug 27, 2021 2:25 pm
PhilE wrote:
Thu Aug 26, 2021 8:15 am
[ Moved to Interfacing ]
Is that implying that device tree-related tweaks aren't the solution? (Which is my initial assumption)
No, that is saying that this subject is better discussed in the "Interfacing" sub-forum. You are more likely to get a good answer there.
Glad that was confirmed; I've been able to set up the port using a modified overlay:

Code: Select all

/dts-v1/;
/plugin/;

/* 
	Overlay to enable UART4 TxD, RxD and RTS
	
	Pin functions appear in the gpio listing
	However - looks as if driver doesn't support automatic RTS control
*/
/* Essentially uart4-overlay.dts with CTS pin deleted */

/*
   Enable /dev/ttyAMAx RTS signal on 26/40-pin GPIO header
   Header connections:
		Transmit - GPIO8  - Pin 24
		Receive -  GPIO9  - Pin 11 - pull high
		RTS 	-  GPIO11 - Pin 23 - pull low (to reflect hardware polarity)
*/

/ {
    compatible = "brcm,bcm2711";


	fragment@0 {
		target = <&uart4>;
		__overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&uart4_pins>;
			status = "okay";
		};
	};

	fragment@1 {
		target = <&uart4_pins>;
		__overlay__ {
			brcm,pins = <8 9 11>;
			brcm,pull = <0 2 1>;
		};
	};
};
However.... it appears that the UART driver doesn't support the RS-485-related ioctl() - returns error 25. (RPi OS, kernel 5.10.17 on a Pi 4).

The low-level driver is presumably this one: https://github.com/raspberrypi/linux/bl ... ba-pl011.c (even though some of the early comments are inconsistent with the hardware, there are some familiar names posting changes).

Bit surprised that RS-485 type communication isn't fully supported; it's quite a common interface in industrial applications, even now.

So I guess it's over to writing software to manage RTS - not the end of the world, since I don't need to go fast (rarely more than 19200 baud!). Not sure yet whether to adopt a "bare metal" approach, rather than use the OS for as much as possible, since the application has a fair amount of multitasking.

Incidentally, uart4 was assigned to /dev/ttyAMA1, rather than the /dev/ttyAMA3 I was expecting - presumably because uarts 1 and 2 aren't assigned. Is it possible to assign a specific device name to a uart, regardless of which other uarts are enabled?

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4260
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Serial port configuration for RS-485

Wed Sep 08, 2021 6:34 pm

Is it possible to assign a specific device name to a uart, regardless of which other uarts are enabled?
No - the driver allocates them sequentially in the order the device nodes are processed.

Return to “Interfacing (DSI, CSI, I2C, etc.)”