Verdin imx8mp rs485 RTS configuration

Hello, all,

I’m trying to use the Verdin i.MX8M-plus RS-485 interface. I faced an issues with the configuration of RTS/DE signal. The default configuration of UART1 supports rs485-rts-active-low. My board uses rs485-rts-active-high, since RS-485 transceiver requires a high-level to enable the transmitter.

I’ve placed the following code in my device tree file in order to set:

  • pull down on RTS/DE pin;
  • active-high RTS/DE;

&pinctrl_uart1 {

fsl,pins =

	<MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX		0x1c4>,	/* SODIMM 129 */

	<MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX		0x1c4>,	/* SODIMM 131 */

	<MX8MP_IOMUXC_SAI2_TXFS__UART1_DCE_CTS		0x0c4>;	/* SODIMM 133 */

};

&uart1 {

status = "okay";

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_uart1>;

linux,rs485-enabled-at-boot-time;

rs485-rts-active-high;

rs485-rx-during-tx;

};

The device tree file is compiled and loaded properly. Other functions, like LEDs and GPIOs works fine, but the behavior of RTS/DE is as active-low.

The SODIMM 133 is low in uboot. Once the kernel start to boot it becomes high and remains high. This is very sensitive situation for my device, because that means the RS-485 transmitter will be in enabled all of the time during boot and the RS-485 bus will be blocked, or worse - fake data will be transmitted.

When I execute the tests, described here:

the result is as for active low RTS/DE. The signal remains high and goes low for ~300us during transmission. After that goes to high again.

If I run minicom, the behavior of RTS/DE changes. The RTS/DE remains low. If RS-485 mode is enabled in minicom serial options, ports works as expected - RTS/DE becomes active high and I can establish bidirectional communication.

Once I quit minicom, RTS/DE switches to active-low behavior again and remains high.

Please provide some hints how to fix this.

With kind regards,
Ivan

Verdin iMX8M-plus QL 1GB IT, v1.1A
Custom Yocto build, BSP 7.5.0
Custom carrier board

Hi, I’m the Toradex AI Assistant.

I might make mistakes or occasionally get you wrong. Our support team will step in if needed.


RS-485 Configuration Issue Analysis

Based on your description, you’re experiencing a common issue with RS-485 configuration on the Verdin i.MX8M Plus. The problem appears to be related to how the kernel handles the RS-485 RTS control signal polarity and timing.

Device Tree Configuration Review

Your device tree configuration looks mostly correct for enabling RS-485 mode(1). However, there are a few points to consider:

  1. Pin Configuration: You’re using SODIMM 133 (SAI2_TXFS) as the RTS/CTS signal, which should work for RS-485 direction control(1).

  2. RS-485 Properties: The properties you’re using are correct according to the documentation(1):

    • linux,rs485-enabled-at-boot-time
    • rs485-rts-active-high
    • rs485-rx-during-tx

Potential Solutions

1. Verify Kernel Support

The i.MX 8M Plus UART block has built-in support for RS-485 auto RTS control(1). Make sure your BSP 7.5.0 kernel properly supports these device tree properties.

2. Check RTS Pin Configuration

According to the documentation, on Toradex carrier boards, the following flags should typically be used(1):

/* Enable RS485 mode: */
rs485conf.flags |= SER_RS485_ENABLED;

/* or, set logical level for RTS pin equal to 0 when sending: */
rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

/* Set logical level for RTS pin equal to 1 after sending: */
rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;

/* Enable receiver during sending, required for i.MX devices */
rs485conf.flags |= SER_RS485_RX_DURING_TX;

3. Alternative GPIO-based Approach

If the built-in RS-485 support isn’t working as expected, you might need to consider using a GPIO-based approach for RTS control(2). This would involve:

  • Configuring the RTS pin as a GPIO instead of UART RTS
  • Using rts-gpios property in the device tree
  • Managing the GPIO state in software

4. Userspace Configuration

You can also try configuring RS-485 mode from userspace using ioctl calls(1). The behavior you observe with minicom suggests that proper userspace configuration might resolve the issue.

Boot-time Behavior

The issue you’re experiencing during boot (RTS staying high) is critical for RS-485 bus integrity. This suggests that the kernel driver might not be properly initializing the RS-485 mode at boot time, despite the linux,rs485-enabled-at-boot-time property.

Recommended Next Steps

  1. Verify BSP Version: Ensure your BSP 7.5.0 includes the latest RS-485 support for i.MX8M Plus
  2. Check Kernel Logs: Look for any RS-485 related messages during boot
  3. Test with Standard Tools: Use the stty command-line utility to verify RS-485 configuration(1):
# stty -F /dev/verdin-uart1 115200
# echo Test > /dev/verdin-uart1
  1. Consider GPIO Alternative: If the hardware RS-485 support continues to cause issues, implementing GPIO-based RTS control might be more reliable for your specific transceiver requirements.

The fact that minicom works correctly suggests the hardware and basic driver support are functional, but there may be an initialization timing or configuration issue specific to the boot-time RS-485 setup.

Best regards,
Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

Hi!
This is a dump of /proc/device-tree:
/proc/device-tree/soc@0/bus@30800000/spba-bus@30800000/serial@30860000:
clock-names
clocks
compatible
dma-names
dmas
interrupts
linux,rs485-enabled-at-boot-time
name
phandle
pinctrl-0
pinctrl-names
reg
rs485-rts-active-high
rs485-rts-active-low

rs485-rx-during-tx
status
uart-has-rtscts

Both rs485-rts-active-high and rs485-rts-active-low exists in dump. Looks like adding rs485-rts-active-high does not overwrite rs485-rts-active-low.
I will rebuild the device tree with explicit /delete-property/ rs485-rts-active-low; and will test again.

Best regards,
Ivan

Hi Ivan,

Excellent Diagnosis!

Your analysis is spot-on. The presence of both rs485-rts-active-high and rs485-rts-active-low properties in the device tree dump indicates that your device tree modification didn’t properly override the default setting(1).

Device Tree Property Override Solution

Your approach using /delete-property/ is the correct method to resolve this conflict(1). When customizing device trees, you need to explicitly remove conflicting properties before adding new ones(2).

Here’s the corrected device tree configuration:

&uart1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
    
    /delete-property/ rs485-rts-active-low;
    
    linux,rs485-enabled-at-boot-time;
    rs485-rts-active-high;
    rs485-rx-during-tx;
};

(1)

Why This Happens

Device tree overlays and modifications work by layering properties(2). When you add rs485-rts-active-high without removing the existing rs485-rts-active-low, both properties coexist in the compiled device tree blob, which can cause undefined behavior in the driver(1).

Verification Steps

After rebuilding and deploying your device tree:

  1. Verify the property removal:

    # ls /proc/device-tree/soc@0/bus@30800000/spba-bus@30800000/serial@30860000/
    

    You should only see rs485-rts-active-high and not rs485-rts-active-low(3).

  2. Test RS-485 behavior: The RTS/DE signal should now properly behave as active-high during transmission(3).

Additional Considerations

Since you’re using a custom carrier board, ensure that your RS-485 transceiver’s DE (Driver Enable) pin is properly connected to SODIMM 133 and that the transceiver expects an active-high signal for transmit enable(4).

Your systematic troubleshooting approach of examining the device tree dump was excellent - this is exactly the kind of verification that helps identify configuration conflicts.

Best regards, Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

Hi, issue is solved.

The problem was both rs485-rts-active-high and rs485-rts-active-low exists simultaneously.

Deleting rs485-rts-active-low solves all issues. RTS/DE pin remains low during boot and acts as expected when tests performed.

Why - setting rs485-rts-active-high does not remove/overwrite rs485-rts-active-low. rs485-rts-active-low is set as part of default Verdin imx8mp (imx8mp-verdin-dev.dtsi) device tree configuration. To change the RTS/DE polarity, rs485-rts-active-low must be deleted explicitly from device tree.

This can not happen in device tree overlay, since device tree overlay does not support delete-property. (DT Overview). Should be done in a device tree file.

Minicom shall not be used for tests, it overwrites the serial port settings and RTS/DE stops working once minicom is closed.

With kind regards,
Ivan

1 Like