How to Define RS485 in Device Tree

Hello ,

Currently I am using a board based on the Col Evaluation v3.2 with a Vybrid VF61. I currently try to get UART1 (RS485 Support) working and I am stuck. I modified the device tree so we use correct pins for this uart. But when I try to communicate with the device we have behind this UART.
We analysed this with an oscilloscope and we can not see PTC4_UART1_RTS signal. (SODIMM_79)

So I guess my device tree configuration is wrong somehow.
I hope someone here can point me in the right direction what I am missing. Here is the pinctrl config for UART 1: (linux kernel ver 4.1.15)

&uart1 {
	status = "okay";
	linux,rs485-enabled-at-boot-time;

};

pinctrl_uart1: uart1grp {
			fsl,pins = <
				VF610_PAD_PTB4__UART1_TX		0x21a2
				VF610_PAD_PTB5__UART1_RX		0x21a1
				VF610_PAD_PTC4__UART1_RTS		0x21a2
				VF610_PAD_PTB7__UART1_CTS         0x21a1
			>;
		};

Code Sample C Code:

#include <stdio.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/serial.h>
#include <asm-generic/ioctls.h> /* TIOCGRS485 + TIOCSRS485 ioctl definitions */
#include <linux/serial.h>

/* Driver-specific ioctls: */
#define TIOCGRS485      0x542E
#define TIOCSRS485      0x542F
 
int main(void) {
         struct serial_rs485 rs485conf;
 
         int fd = open ("/dev/ttyLP1", O_RDWR);
         if (fd < 0) {
                 printf("Error: Can't open: /dev/ttyLP1\n");
         }
 
  
         if (ioctl (fd, TIOCGRS485, &rs485conf) < 0) {
                 printf("Error: TIOCGRS485 ioctl not supported.\n");
         }
 
         /* Enable RS-485 mode: */
         rs485conf.flags |= SER_RS485_ENABLED;
 
         /* Set rts/txen delay before send, if needed: (in microseconds) */
         rs485conf.delay_rts_before_send = 100;
 
         /* Set rts/txen delay after send, if needed: (in microseconds) */
         rs485conf.delay_rts_after_send = 100;
 
         if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
                 printf("Error: TIOCSRS485 ioctl not supported.\n");
         }
 
         fcntl(fd, F_SETFL, 0);
         int n = write(fd, "ABC\r\n", 5);
         if (n < 0) {
                 /* Error handling */
         }
 
         if (close (fd) < 0) {
                 printf("Error: Can't close: /dev/ttyLP1\n");
         }
}

Device tree changes looks good, but did you remove the default GPIO pinmux of these pins here ?

Thanks for your reply!

I have done changes in the vf-colibri.dtsi-File but i still have problem and i can not see signal PTC4__UART1_RTS.

RS485 on UART2 works But we need to use UART1 of our Product.

Is another Device connected to SODIMM_79 (PTC4) ? Do i need to modify Uboot-DT ?!

Many Thanks for your Help

By default all the free pins are pin-muxed as GPIOs. One need to make sure there are no pin conflicts when using them. I tested it at my end, worked as expected.
Below is the diff:

diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index 8392dcd..ad37853 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -168,6 +168,7 @@
 
 &uart1 {
        status = "okay";
+       linux,rs485-enabled-at-boot-time;
 };
 
 &uart2 {
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index d62c4f6..3d8462b 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -189,7 +189,6 @@
                                VF610_PAD_PTA30__GPIO_20        0x22ed
                                VF610_PAD_PTA31__GPIO_21        0x22ed
                                VF610_PAD_PTB6__GPIO_28         0x22ed
-                               VF610_PAD_PTB7__GPIO_29         0x22ed
                                VF610_PAD_PTB12__GPIO_34        0x22ed
                                VF610_PAD_PTB13__GPIO_35        0x22ed
                                VF610_PAD_PTB16__GPIO_38        0x22ed
@@ -200,7 +199,6 @@
                                VF610_PAD_PTC1__GPIO_46         0x22ed
                                VF610_PAD_PTC2__GPIO_47         0x22ed
                                VF610_PAD_PTC3__GPIO_48         0x22ed
-                               VF610_PAD_PTC4__GPIO_49         0x22ed
                                VF610_PAD_PTC5__GPIO_50         0x22ed
                                VF610_PAD_PTC6__GPIO_51         0x22ed
                                VF610_PAD_PTC7__GPIO_52         0x22ed
@@ -364,6 +362,8 @@
                        fsl,pins = <
                                VF610_PAD_PTB4__UART1_TX                0x21a2
                                VF610_PAD_PTB5__UART1_RX                0x21a1
+                               VF610_PAD_PTC4__UART1_RTS               0x21a2
+                               VF610_PAD_PTB7__UART1_CTS               0x21a1
                        >;
                };

it works, many thanks for the great and quick support.

Glad! to hear that.

Hi,

I am using RS485 on UART2 and also defined following configurations into dts file.

> &uart2 {
>     pinctrl-names = "default";
>     pinctrl-0 = <&pinctrl_uart2>;
>     linux,rs485-enabled-at-boot-time; };
> 
>  pinctrl_uart2: uart2grp {
>             fsl,pins = <
>                 VF610_PAD_PTD0__UART2_TX        0x21a2
>                 VF610_PAD_PTD1__UART2_RX        0x21a1
>                 VF610_PAD_PTD2__UART2_RTS       0x21a2
>                 VF610_PAD_PTD3__UART2_CTS       0x21a1
>             >;
>         };

I have also checked with above c code provided to check RS485 connection in which i am getting string ABC on UART2 but not able to transmit any data from UART2.

It means i able to receive data over RS485 UART but not able transmit data from that UART RS485.

Is there any configurations required in UART side to work both RX and TX on RS485 UART?

Regards,
Ritesh Prajapati

Please have a look at this article