Skip to content

UART

Test external UART

By default, Variscite enabled in the device tree the following UARTs.

configuration 6UL Custom Board Concerto Board Symphony Board
UART UART3 UART5 UART7
device /dev/ttymxc2 /dev/ttymxc4 /dev/ttymxc6
RX pin J9.5 J26.4 J18.9
TX pin J9.7 J26.2 J18.7

To test you can use minicom to connect.
Set the serial to the right device.
You can use a loopback or connect to anther computer.

Example: configure UART4, ttymxc3 (using DART-6UL)

In the kernel source code, edit the following device tree file:
arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi

Look for:

/* ttymxc2 UART */
&uart3 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart3>;
    fsl,uart-has-rtscts;
    status = "okay";
};

Duplicate it and change the name and the pinctrl. For Example:

&uart4 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart4>;
    fsl,uart-has-rtscts;
    status = "okay";
};

Duplicate the corresponding pinctrl. Copy :

    pinctrl_uart3: uart3grp {
        fsl,pins = <
            MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX   0x1b0b1
            MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX   0x1b0b1
            MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS    0x1b0b1
            MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS    0x1b0b1
        >;
    };

Into:

    pinctrl_uart4: uart4grp {
        fsl,pins = <
                        MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX   0x1b0b1
                        MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX   0x1b0b1
            MX6UL_PAD_ENET1_RX_DATA1__UART4_DCE_CTS 0x1b0b1
            MX6UL_PAD_ENET1_RX_DATA0__UART4_DCE_RTS 0x1b0b1
        >;
    };

Note: The pins here were set arbitrarily. You should set them based on your hardware design, and make sure they are not conflicting with other devices in the device tree.

Continue following the "Build Linux from source code" guide to build only the device trees and to copy them to your SD card.

Use UART3 for console (instead of UART1)

In the following example we use UART3 for console.
Other UART ports can be used, similarly.

Note:
See the notes on pages 6 & 7 on the dart-6ul customboard schematics file:
https://variscite.com/wp-content/uploads/2017/12/VAR-6ULCustomboard-Schematics.pdf

- "Pull down resistor and delay circuitry is added on DEBUG_UART_RTS_B to allow reboot
   from SD Card using POR signal, since DEBUG_UART_RTS_B is used as SD1_CD_B by Boot ROM.

   In case DEBUG_UART_RTS_B signal is not required, the delay mechanism is redundant and can be depopulated.
   DEBUG_UART_RTS_B however should be always pulled down to ground using a 10K resistor to simulate SD Card detect."

- "Watchdog circuitry is required for proper SW reboot!"

Changes needed in U-Boot

Subject: [PATCH] imx6ul_var_dart: Use UART3 for console (instead of UART1)

---
 arch/arm/dts/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi | 2 +-
 board/variscite/imx6ul_var_dart/spl.c                    | 8 ++++----
 include/configs/imx6ul_var_dart.h                        | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/dts/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi b/arch/arm/dts/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi
index 96514058280..63d16903000 100644
--- a/arch/arm/dts/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi
+++ b/arch/arm/dts/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi
@@ -16,7 +16,7 @@
    };

    chosen {
-       stdout-path = &uart1;
+       stdout-path = &uart3;
    };

    keys {
diff --git a/board/variscite/imx6ul_var_dart/spl.c b/board/variscite/imx6ul_var_dart/spl.c
index 67df403e59a..b3a01b92f0b 100644
--- a/board/variscite/imx6ul_var_dart/spl.c
+++ b/board/variscite/imx6ul_var_dart/spl.c
@@ -34,14 +34,14 @@ enum {
    PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |       \
    PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)

-static const iomux_v3_cfg_t uart1_pads[] = {
-   MX6_PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
-   MX6_PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
+static const iomux_v3_cfg_t uart3_pads[] = {
+   MX6_PAD_UART3_TX_DATA__UART3_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
+   MX6_PAD_UART3_RX_DATA__UART3_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
 };

 static void setup_iomux_uart(void)
 {
-   imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
+   imx_iomux_v3_setup_multiple_pads(uart3_pads, ARRAY_SIZE(uart3_pads));
 }

 static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
diff --git a/include/configs/imx6ul_var_dart.h b/include/configs/imx6ul_var_dart.h
index 2c8def77a7b..a4527344955 100644
--- a/include/configs/imx6ul_var_dart.h
+++ b/include/configs/imx6ul_var_dart.h
@@ -29,7 +29,7 @@
 #define MMC_ROOTFS_PART            2

 /* Console configs */
-#define CFG_MXC_UART_BASE      UART1_BASE
+#define CFG_MXC_UART_BASE      UART3_BASE

 /* MMC Configs */

@@ -119,7 +119,7 @@
    "bootenv=uEnv.txt\0" \
    "script=boot.scr\0" \
    "image=zImage\0" \
-   "console=ttymxc0\0" \
+   "console=ttymxc2\0" \
    "carrier=undefined\0" \
    "fdt_file=undefined\0" \
    "fdt_addr=0x83000000\0" \
-- 
2.47.0

You can follow the "Build U-Boot from source code" guide to get the U-Boot source code and build it.

Changes needed in the Kernel

Subject: [PATCH] imx6ul-var-dart: Use UART3 for console (instead of UART1)

---
 .../dts/nxp/imx/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi
index 90831d33396b..c15af7ffda66 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-var-dart-6ulcustomboard.dtsi
@@ -16,7 +16,7 @@ backlight {
    };

    chosen {
-       stdout-path = &uart1;
+       stdout-path = &uart3;
    };

    keys {
-- 
2.47.0

You can follow the "Build the Linux kernel from source code" guide to get the Kernel source code and build it.

Configuring RS485 Half-Duplex

Each UART can be configured for RS485 Half-Duplex mode by using a GPIO pin to drive the receive and transmit enable inputs. This can be configured in the device tree by making the following changes to the uart node and replacing X, Y & Z with the proper values:

&uartX {                                                          /* Add RS485 properties to uartX */
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uartX>, <&pinctrl_uartX_rs485>;     /* Add RS485 GPIO pinctrl */
    rts-gpios = <&gpioY Z GPIO_ACTIVE_LOW>;                   /* Add rts-gpios property */
    linux,rs485-enabled-at-boot-time;                         /* Enable RS485 at boot time to skip using TIOCSRS485 ioctl */
    status = "okay";
};

Next, configure the RS485 GPIO pin by adding pinctrl_uartX_rs485 to iomuxc. Replace X, GPIO_PIN_FUNCTION, and GPIO_PIN_SETTINGS with the proper values:

&iomuxc {
    pinctrl_uartX_rs485: uartXrs485 {
        fsl,pins = <
            GPIO_PIN_FUNCTION  GPIO_PIN_SETTINGS
        >;
    };
};

Note: For more information about configuring pins, please see i.MX Device Tree Pinmux Settings Guide

After making these changes, RS485 mode will be enabled by default and can be verified from the console by running the commands below. Replace N with the proper value, which is typically X-1 relative to the device tree node uartX:

# stty -F /dev/ttymxcN -echo -onlcr 115200
# echo hello > /dev/ttymxcN

The below logic analyzer capture shows the RS485 RX/TX enable line toggling when writing to the UART:

Rs485.png

Please refer to the Linux device tree bindings for more RS485 configuration options.