Enabling RS485 on UART_1 for Verdin i.MX8M Plus (Mallow Carrier Board)

Hi, I’m using a Verdin i.MX8M Plus module with a Mallow carrier board, and I want to enable RS485 communication on UART_1.
What changes or configurations are required in the device tree to make this work? Also, which device tree file should I be modifying for this setup?

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

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


Hello! Thank you for your question regarding RS-485 on Verdin i.MX8M Plus with the Mallow carrier board.

1. Device Tree Changes

To enable RS-485 mode on UART_1, you need to update the device tree settings for UART4 (since UART_1 on the Verdin i.MX8M Plus corresponds to UART4 in the pin mapping).

Add or modify the following node in your device tree or device tree overlay:

&uart4 {
    status = "okay";
    linux,rs485-enabled-at-boot-time;
    rs485-rts-active-low;
};
  • linux,rs485-enabled-at-boot-time; enables RS-485 at boot.
  • rs485-rts-active-low; configures the RTS signal polarity, which is the typical setting for RS-485 transceivers.
  • Remove or avoid using rs485-rx-during-tx; unless you specifically need to receive while transmitting, as it can cause echo issues.

For reference:

2. Selecting the Correct Device Tree File

The exact device tree file to modify depends on your BSP version and configuration:

  • For Torizon or Toradex BSP Linux, you typically use a device tree overlay (.dts file which compiles to .dtbo).
  • For Verdin i.MX8M Plus on Mallow, the base device tree is usually:
    imx8mp-verdin-mallow.dts
    
  • If you are using a custom device tree overlay, you can place the above node in your overlay file.

For detailed information on the board and pin assignments:

General Steps:

  1. Create a device tree overlay (recommended for Torizon/Core Linux).
  2. Add the &uart4 node as shown above.
  3. Compile the overlay (dtc) and deploy it according to your platform’s procedure.
  4. Reboot and confirm RS-485 mode is active.

If you need more guidance on compiling and applying these overlays for your current environment, let me know your Linux variant (Torizon or BSP) and version!

Best regards,
Toradex AI Assistant.

Hi @nidhishende I’m facing a similar issue, I’m using a Verdin iMX8M Mini SoM on an Ivy carrier board, and I want Yocto to automatically select the correct device tree (imx8mm-verdin-wifi-ivy.dtb) without having to stop at U-Boot and manually set fdtfile.

My current machine configuration is based on verdin-imx8mm.conf, with this:

#@TYPE: Machine
#@NAME: Toradex Verdin iMX8M Mini
#@SOC: i.MX8MM
#@DESCRIPTION: Machine configuration for Toradex Verdin iMX8M Mini SoM
#@MAINTAINER: Max Krummenacher max.krummenacher@toradex.com

MACHINE_NAME = “Verdin-iMX8MM”

MACHINEOVERRIDES =. “tdx:mx8:mx8m:mx8mm:”

MACHINE_EXTRA_RRECOMMENDS:append = " mwifiexconf"

IMX_DEFAULT_BSP = “nxp”
IMX_DEFAULT_BSP:upstream = “mainline”

require conf/machine/include/imx-base.inc

override imx-base.inc which sets this to cortexa53-crypto

DEFAULTTUNE:mx8mm-generic-bsp = “armv8a-crypto”
require conf/machine/include/arm/armv8a/tune-cortexa53.inc

Don’t include kernels in standard images

RRECOMMENDS:${KERNEL_PACKAGE_NAME}-base = “”

KERNEL_DTB_PREFIX = “freescale/”
KERNEL_DEVICETREE = "
${KERNEL_DTB_PREFIX}imx8mm-verdin-wifi-ivy.dtb
"
KERNEL_IMAGETYPE:mx8-generic-bsp = “Image.gz”

UBOOT_CONFIG ??= “sd”
UBOOT_CONFIG[sd] = “verdin-imx8mm_defconfig,sdcard”
SPL_BINARY = “spl/u-boot-spl.bin”

UBOOT_DTB_LOADADDRESS:mx8mm-generic-bsp = “0x50200000”
UBOOT_DTBO_LOADADDRESS:mx8mm-generic-bsp = “0x50240000”
UBOOT_ENTRYPOINT:mx8mm-generic-bsp = “0x48200000”
UBOOT_RD_LOADADDRESS = “0x52300000”

Set u-boot DTB

UBOOT_DTB_NAME = “imx8mm-verdin-wifi-ivy.dtb”

Set DDR FIRMWARE

DDR_FIRMWARE_NAME = "
lpddr4_pmu_train_1d_imem.bin
lpddr4_pmu_train_1d_dmem.bin
lpddr4_pmu_train_2d_imem.bin
lpddr4_pmu_train_2d_dmem.bin
"

ATF_PLATFORM = “imx8mm”
SOC_ATF_BOOT_UART_BASE:verdin-imx8mm = “0x30860000”

BOOT_SPACE = “65536”

Set imx-mkimage boot target

IMXBOOT_TARGETS = “flash_evk_emmc_fastboot”
IMX_BOOT_SOC_TARGET = “iMX8MM”

IMAGE_BOOT_FILES:append = " boot.scr-${MACHINE};boot.scr"
WKS_FILE_DEPENDS:append = " u-boot-default-script"
PREFERRED_PROVIDER_u-boot-default-script = “u-boot-distro-boot”

LOADADDR = “”
UBOOT_SUFFIX = “bin”
UBOOT_MAKE_TARGET = “”
IMX_BOOT_SEEK = “33”

SERIAL_CONSOLES = “115200;ttymxc0”

MACHINE_FEATURES += “3g bluetooth alsa ext2 pci screen touchscreen tpm2 usbgadget usbhost vfat wifi”

PREFERRED_PROVIDER_virtual/kernel = “linux-toradex”
PREFERRED_PROVIDER_virtual/kernel:preempt-rt = “linux-toradex”
PREFERRED_PROVIDER_virtual/kernel:use-mainline-bsp = “linux-toradex-upstream”
PREFERRED_VERSION_linux-toradex-upstream = “6.6%”
PREFERRED_PROVIDER_virtual/kernel:use-mainline-bsp:preempt-rt = “linux-toradex-upstream-rt”
PREFERRED_VERSION_linux-toradex-upstream-rt = “6.6%”
PREFERRED_PROVIDER_virtual/dtb:use-mainline-bsp = “device-tree-overlays-mainline”
PREFERRED_VERSION_linux-imx-headers = “6.6”

IMX_DEFAULT_BOOTLOADER = “u-boot-toradex”

variables to control imx-boot with u-boot

ATF_LOAD_ADDR = “0x920000”
IMX_EXTRA_FIRMWARE = “firmware-imx-8m”
TEE_LOAD_ADDR = “0xbe000000”
UBOOT_MAKE_TARGET:use-mainline-bsp = “all”

handle machine firmware

MACHINE_FIRMWARE:append = " linux-firmware-ath10k linux-firmware-imx-sdma-imx7d"
MACHINE_FIRMWARE:append = " linux-firmware-sd8997"
MACHINE_FIRMWARE:append = " firmware-imx-vpu-imx8"

BOARD_TYPE = “verdin”

IMAGE_CLASSES:append = " image_type_tezi"
IMAGE_FSTYPES += “teziimg”

UBOOT_BINARY_TEZI_EMMC = “imx-boot”
OFFSET_BOOTROM_PAYLOAD = “2”

TEZI_EXTERNAL_KERNEL_DEVICETREE_BOOT = “verdin-imx8mm_dsi-to-hdmi_overlay.dtbo verdin-imx8mm_spidev_overlay.dtbo”

TORADEX_PRODUCT_IDS = “0055 0057 0059 0060 0068 0086 0087 0090 0216”
TORADEX_PRODUCT_IDS[0055] = “imx8mm-verdin-wifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0057] = “imx8mm-verdin-nonwifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0059] = “imx8mm-verdin-nonwifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0060] = “imx8mm-verdin-wifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0068] = “imx8mm-verdin-wifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0086] = “imx8mm-verdin-nonwifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0087] = “imx8mm-verdin-nonwifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0090] = “imx8mm-verdin-wifi-v1.1-dev.dtb”
TORADEX_PRODUCT_IDS[0216] = “imx8mm-verdin-wifi-v1.1-dev.dtb”

From my understanding, TORADEX_PRODUCT_IDS is used by Toradex Easy Installer and U-Boot to select the right DTB for the detected hardware. I think the issue for me is my device is still using imx8mm-verdin-wifi-dev device tree , and for that reason my RS485 in the device tree is not working , temporary fix is configure rs485 from user space , I did it in c++ like this


bool ModbusRtuMaster::configureRs485(const QString &portName)

{

int fd = ::open(portName.toStdString().c_str(), O_RDWR);

if (fd < 0) {

perror("open");

return false;

}

struct serial_rs485 rs485conf {};

if (ioctl(fd, TIOCGRS485, &rs485conf) < 0) {

perror("TIOCGRS485");

::close(fd);

return false;

}

rs485conf.flags |= SER_RS485_ENABLED;

rs485conf.flags |= SER_RS485_RTS_ON_SEND;

rs485conf.flags &= ~SER_RS485_RTS_AFTER_SEND;

rs485conf.delay_rts_after_send = 1;

if (ioctl(fd, TIOCSRS485, &rs485conf) < 0) {

perror("TIOCSRS485");

::close(fd);

return false;

}

::close(fd);

return true;

}

but I’m, still dealing with selecting the proper device tree

Hi @nidhishende ,
Please let me know the UART pins that you are using(eg SODIMM x).
Also, before using it in the application, test it from the command line as mentioned here.

Let me know the results.