Colibri i.MX8DX - Configure Device Tree for RS-485 and GPIO RTS

Good morning,

I am using a Yocto build using kernel colibri-imx8x 5.15.148-6.4.0+git.284966e8d6ee
I have been trying to configure lpuart1 for RS-485 half duplex

	fsl,pins =  <IMX8QXP_UART1_RX_ADMA_UART1_RX             0x00000020>,
				<IMX8QXP_UART1_TX_ADMA_UART1_TX              0x00000020>,
				<IMX8QXP_SCU_GPIO0_00_LSIO_GPIO2_IO03       	 0x00000020>;		/* SODIMM  144 */
    };

  • I have removed the pin conflict of SODIMM 144
&lpuart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
	rts-gpios = <&lsio_gpio2 3 GPIO_ACTIVE_HIGH>;
	rs485-rts-delay = <0 0>;
	linux,rs485-enabled-at-boot-time;
    status= "okay";
};
  • When I build and run the code, pin 144 is always high when transmitting. It never transitions low.
  • I rebuilt a new image with libgpiod and gpio tools and issued gpioinfo. It indicates that SODIMM_144 is configured as an input

Can someone assist on how to configure SODIMM_144 as an output for the data enable (RTS) for RS-485 as described above?

image

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


:handshake:

To configure SODIMM 144 as an output for the RTS signal in RS-485 mode, you need to ensure that the pin is correctly muxed and configured in the device tree. Here are the steps to achieve this:

  1. Pin Multiplexing Configuration:
    Ensure that the pin is correctly muxed as a GPIO in the pinctrl node. Your current configuration seems correct, but let’s double-check it:

    pinctrl_uart1: uart1grp {
        fsl,pins = <IMX8QXP_UART1_RX_ADMA_UART1_RX 0x00000020>,
                   <IMX8QXP_UART1_TX_ADMA_UART1_TX 0x00000020>,
                   <IMX8QXP_SCU_GPIO0_00_LSIO_GPIO2_IO03 0x00000020>; /* SODIMM 144 */
    };
    
  2. UART Configuration:
    Ensure that the UART node is correctly configured to use the RTS pin for RS-485:

    &lpuart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1>;
        rts-gpios = <&lsio_gpio2 3 GPIO_ACTIVE_HIGH>;
        rs485-rts-delay = <0 0>;
        linux,rs485-enabled-at-boot-time;
        status = "okay";
    };
    
  3. GPIO Configuration:
    Ensure that the GPIO is correctly configured as an output. You can add a GPIO configuration node to explicitly set the direction of the GPIO:

    &lsio_gpio2 {
        gpio-controller;
        #gpio-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpio2>;
        status = "okay";
    };
    
    pinctrl_gpio2: gpio2grp {
        fsl,pins = <IMX8QXP_SCU_GPIO0_00_LSIO_GPIO2_IO03 0x00000020>;
    };
    
  4. Device Tree Overlay:
    If you are using a device tree overlay, ensure that the overlay is correctly applied and does not conflict with other configurations.

  5. Rebuild and Deploy:
    Rebuild your device tree and deploy it to the target device. Ensure that the new device tree is being used by the kernel.

hey @cowboydan,

Looking at the device tree for the SODIMM 144 pin and imx8 colibri, this pin is to be used in SCFW, so I don’t believe its a good choice for your RTS if other pins are available.

    /*
   1      * This pin is used in the SCFW as a UART. Using it from
   2      * Linux would require rewritting the SCFW board file.
   3      */
   4     pinctrl_hog_scfw: hogscfwgrp {
   5         fsl,pins = <IMX8QXP_SCU_GPIO0_00_LSIO_GPIO2_IO03        0x20>;      /* SODIMM 144 */
   6     };

And looking at the RS485 device tree bindings yaml, I see rs485 as being built in half duplex. So when you enable at boot, this should indicate the half duplex.

-Eric

1 Like

Hi @eric.tx ,

Understood and agree re: pin 144. We do not need that pin and I have resolved that conflict.

Do you or does anybody know just for proof-of-concept if Toradex has an example demo for use with the Colibri Evaluation board that exercises its RS-485 connection?

Hey @cowboydan,

I don’t have a Toradex demo example for rs485 readily available, but I did find another resolved ticket with a script inside that appears to be working from the customers perspective.

-Eric

Hi @eric.tx

UPDATE Ultimately we ended up implementing our own userspace client that uses the Linux DT Binding for RS-485 so that it has control over the RTS/DE with much faster response time than using GPIO from userspace.

Thanks for your help!

Hey @cowboydan,

Thanks for the update. And I’m glad you have a fast solution!

-Eric

Hey @cowboydan
Just curious…so you abandoned the rts control built into the serial drivers and now just use the rx/tx functionality there coupled with a userspace client to toggle the gpio when applicable?

Hey @DaveM
The reverse - we abandoned user-mode GPIO control of RTS (latency ~4msec after end of transmission before RTS was de-asserted) to the native control of RTS build into the drivers (latency ~tens of microseconds). The problem was a collision with the client reply whilst our RTS was enabled and the data not being received. We couldn’t live with a workaround of a “pause” period between transmit/receive, so the native driver control of RTS seems to work well for us.

Ah…when you said “userspace client”, I leapt to “toggle gpio”, “sent data”, “toggle gpio”, “receive data”. Tough timing there :wink:

So your pin config for that signal connected to your 485 driver is _RTS or is it _GPIO? I’m interpreting your comment above as you’ve changed to “native” _RTS, thus having uart-has-rtscts in the device tree (as opposed to having rts-gpios in there?)

Correct. We are using a GPIO pin configured as RTS, but not through the GPIO API if that makes sense. (Not sure I have the right vocabulary words).

1 Like