Bugged uart communication in custom carrier

I have a problem with serial communication on a custom carrier. I’m trying to
use uart2 with module iMX7D and I get a lot of timeouts in communication.
Same carrier driven by an iMX6DL module has not this issue.

Hardware designers used this scheme for pin design:

 Signal	        Pin	iMX7D Function	iMX7D Pin SoC
 GPIO_SODIMM_28	28	gpio1.IO[9]	GPIO1_IO09
 GPIO_SODIMM_29	29	gpio1.IO[7]	GPIO1_IO07
 GPIO_SODIMM_30	30	gpio1.IO[10]	GPIO1_IO10
 GPIO_SODIMM_32	32	gpio6.IO[21]	SAI2_RXD
 I2C_1_SCL    	196	i2c4.SCL	ENET1_TD2
 I2C_1_SDA    	194	i2c4.SDA	ENET1_TD3
 SD_1_CD_B     	43	gpio1.IO[0]	GPIO1_IO00
 SD_1_CLK     	47	usdhc1.CLK	SD1_CLK
 SD_1_CMD     	190	usdhc1.CMD	SD1_CMD
 SD_1_DATA0    	192	usdhc1.DATA0	SD1_DATA0
 SD_1_DATA1    	49	usdhc1.DATA1	SD1_DATA1
 SD_1_DATA2    	51	usdhc1.DATA2	SD1_DATA2
 SD_1_DATA3    	53	usdhc1.DATA3	SD1_DATA3
 UART_A_RTS    	27	uart1.RTS_B	SAI2_TXC
 UART_A_RX    	33	uart1.TX	UART1_TXD
 UART_A_TX    	35	uart1.RX	UART1_RXD
 UART_B_RTS   	34	uart2.RTS_B	SAI2_TXD
 UART_B_RX    	36	uart2.TX	UART2_TXD
 UART_B_TX    	38	uart2.RX	UART2_RXD
 UART_C_RX    	19	uart3.TX	UART3_TXD
 UART_C_TX    	21	uart3.RX	UART3_RXD
 UART_D_RX    	75	uart5.TX	I2C4_SDA
 UART_D_TX    	96	uart5.RX	I2C4_SCL
 USB_C_DM     	145	USB_OTG1_DN	USB_OTG1_DN
 USB_C_DP     	143	USB_OTG1_DP	USB_OTG1_DP
 USB_H_DM     	141	USB_OTG2_DN	USB_OTG2_DN
 USB_H_DP     	139	USB_OTG2_DP	USB_OTG2_DP
 USB_H_OC     	131	usb.OTG2_OC	UART3_RTS
 USB_H_PWR_EN  	129	usb.OTG2_PWR	UART3_CTS

I created this device tree override:

/dts-v1/;
#include "imx7d-colibri.dtsi"
#include "imx7-colibri-eval-v3.dtsi"


/ {
        model = "Toradex Colibri iMX7D on xyz board";
        version = "014";
        compatible = "toradex,colibri_imx7d-eval", "toradex,colibri_imx7d", \
                     "fsl,imx7d";
};

&usbotg2 {
        vbus-supply = <&reg_usb_otg2_vbus>;
        status = "okay";
};

&iomuxc {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog_1 &pinctrl_hog_3 &pinctrl_hog_4 &pinctrl_hog_5 &pinctrl_gpioreset &pinctrl_gpioled>;

        imx7d-colibri {
                pinctrl_uart2: uart2grp {
                        fsl,pins = <
                                MX7D_PAD_UART2_TX_DATA__UART2_DTE_RX 0x79
                                MX7D_PAD_UART2_RX_DATA__UART2_DTE_TX 0x79
                                MX7D_PAD_SAI2_TX_DATA__UART2_DCE_RTS 0x79
                        >;
                };

                pinctrl_uart5: uart5grp {
                        fsl,pins = <
                                MX7D_PAD_I2C4_SDA__UART5_DTE_RX 0x79
                                MX7D_PAD_I2C4_SCL__UART5_DTE_TX 0x79
                        >;
                };

                pinctrl_gpioreset: gpioreset {
                        fsl,pins = <
                                MX7D_PAD_SAI2_RX_DATA__GPIO6_IO21 0x80 /* SoC PAD 32 */
                        >;
                };

                pinctrl_gpioled: gpioled {
                        fsl,pins = <
                                MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x80 /* SoC 28 - Blue */
                                MX7D_PAD_GPIO1_IO07__GPIO1_IO7 0x80 /* SoC 29 - Green*/
                                MX7D_PAD_GPIO1_IO10_GPR__GPIO1_I10 0x80 /* SoC 30 - Red*/
                        >;
                };

        };
};

&pwm2 {
        // Possible conflicts with blue led:
        // use pad GPIO1_IO09 as PWM2_OUT
        status = "disabled";
};

&uart1 {
        rs485-rts-delay = <0 0>;
        linux,rs485-enabled-at-boot-time;
        fsl,dte-mode;
        fsl,uart-has-rtscts;
};

&uart2 {
        rs485-rts-delay = <0 0>;
        linux,rs485-enabled-at-boot-time;
        fsl,dte-mode;
        fsl,uart-has-rtscts;
};

&uart5 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart5>;
        fsl,dte-mode;
        status = "okay";
};

My doubts are around pin “SAI2_TX_DATA” (in pin designer this pin is referred
as “SAI2_TXD”): referring to pin design this pin must be connected to signal
UART_B_RTS. So, looking to header file imx7d-pinfunc.h I guessed that the
right configuration was: MX7D_PAD_SAI2_TX_DATA__UART2_DCE_RTS. These are all
the possible values related to that pin:

 MX7D_PAD_SAI2_RX_DATA__SAI2_RX_DATA0 
 MX7D_PAD_SAI2_RX_DATA__ECSPI3_SCLK   
 MX7D_PAD_SAI2_RX_DATA__UART4_DCE_CTS 
 MX7D_PAD_SAI2_RX_DATA__UART4_DTE_RTS 
 MX7D_PAD_SAI2_RX_DATA__UART2_DCE_CTS 
 MX7D_PAD_SAI2_RX_DATA__UART2_DTE_RTS 
 MX7D_PAD_SAI2_RX_DATA__FLEXTIMER2_CH6
 MX7D_PAD_SAI2_RX_DATA__GPIO6_IO21    
 MX7D_PAD_SAI2_RX_DATA__KPP_COL7      

I also tried using MX7D_PAD_SAI2_TX_DATA__UART2_DTE_CTS configuration, but I
still get same communication issues.

Is my configuration right or I should use a different pin/signal?

Useful links:

hi albeus,

what is your communication speed for uart2? Are the erros happening randomly or all the time?

You should mux SAI2_TX_DATA to DTE CTS mode (use MX7D_PAD_SAI2_TX_DATA__UART2_DTE_CTS), even though you use it as RTS signal. The i.MX IP is really confusing in that area, but in DTE mode the CTS signal is an output, what really RTS should be… See also chapters 15.3.7.1 Generalities and 15.3.4.3.3 CTS_B - Clear To Send of the i.MX 7 Reference Manual.

It is not clear to me what could cause the issues. I would recommend to try out our latest V2.7 release (which is a stable release). Also make sure to compare with the same BSP version for on i.MX 6.

Thank you stefan.tx for your interesting informations! We are trying to follow
your hints, but up to now we still have the issue. As we would succeed we will
inform you about the solution.

In the meanwhile other doubts arose:

  1. Is it right to keep following settings for uart1 or we should
    customize accordingly that port?

    pinctrl_uart1: uart1grp {
    fsl,pins = <
    MX7D_PAD_UART1_TX_DATA__UART1_DTE_RX 0x79
    MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX 0x79
    MX7D_PAD_SAI2_TX_BCLK__UART1_DTE_CTS 0x79
    MX7D_PAD_SAI2_TX_SYNC__UART1_DTE_RTS 0x79
    >;
    };

    pinctrl_uart1_ctrl1: uart1-ctrlgrp1 { /* Additional DTR, DCD /
    fsl,pins = <
    MX7D_PAD_SD2_DATA1__GPIO5_IO15 0x14 /
    DCD /
    MX7D_PAD_SD2_DATA0__GPIO5_IO14 0x14 /
    DTR */
    >;
    };

    pinctrl_uart1_ctrl2: uart1-ctrlgrp2 { /* Additional DSR, RI /
    fsl,pins = <
    MX7D_PAD_GPIO1_IO07__GPIO1_IO7 0x14 /
    DSR /
    MX7D_PAD_GPIO1_IO06__GPIO1_IO6 0x14 /
    RI */
    >;
    };

    &uart1 {
    pinctrl-names = “default”;
    pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1 &pinctrl_uart1_ctrl2>;
    assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
    assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
    fsl,uart-has-rtscts;
    fsl,dte-mode;
    rs485-rts-delay = <0 0>;
    linux,rs485-enabled-at-boot-time;
    };

  2. Using those configurations is linux kernel autonomous in handling “Request
    to Send” signals, or should we use explicit controls at application layer?

  1. The settings look good, they should be fine to use UART1 for RS485.
  2. The RS485 mode is supported in hardware, so the hardware will toggle the RTS signal accordingly.

Some updates about last trials:

1 - We debugged serial communications signals using an oscilloscope. It shows that
RTS signal is relased with a random delay.

IMAGE_A: iMX6 image working correctly:

[upload|TCBm8jfdqbWwN/TA9TkV5DoqyEE=]

IMAGE_B: An error using the iMX7d image:

[upload|oe68dSm4Ze9oH+IMz1S7E6Kmpa8=]

Red signal is RTS. As you can see in IMAGE_A, it’s relased imediately after the packet trasmission ends. To the opposite IMAGE_B shows a delay in red signal release that cause the loss of next packet.

2 - We also tested a new image using kernel tag
“Colibri-iMX7_LXDE-Image_2.8b1.64-20171229” as starting point. The device tree
was adapted to this code (just some minor changes). This image give worst
results than the first: we see all uart ports, but RTS signal doesn’t work at
all.

Regarding 2: We recently noticed that RS-485 mode is not working in the 2.8 series (Linux 4.9), see issue 35051.

There are fixes for it on our -next Linux branch toradex_4.9-1.0.x-imx-next. You will have to recompile and replace the kernel and device tree.

During development of that fix I did not notice such long delays, so I would expect that with the 2.8 series and the fixes this should not happen.

I tryed using the last 2.7 image (tag: Colibri-iMX6ULL_LXDE-Image_2.7b5-20171201).

This time all uart seems to work fine (RTS is perfectly syncronized) except for
̶u̶a̶r̶t̶0̶ uart1 that returns weird signal errors and noisy communication.

We did some debug, it shows that the actual baud rate is different from the
one setted by application (there is a mismatch in UBIR registry). So we forced the registers to have the right baudrate, but it’s not enough to have a clean communication.

So it seems that this kernel is bugged as well. Do you agree?

I’m trying to further downgrade the kernel in order to find a working version.

I highly recommend using newer kernel rather than older. Especially Colibri iMX6ULL support has only been started with the 2.7 image series, so there is no real downgrade possibility.

I am not sure what you exactly mean by uart0. The i.MX 6ULL starts to enumerate UARTs with 1 (UART1/2/3…). The Linux tty device starts with 0 though, so I assume you mean UART1?

Note that this is the default serial console of our Linux BSP. Did you take steps to disable the serial console?

See also Linux (UART).

OK, I agree, I don’t like downgrading as well, I’m only searching for the newest working kernel. However I will try my best to go deep into this issue and to use recent and well supported kernels.

Yes, it was a typo: I meant uart1. The getty service should have been disabled, however I will check better this kind of interferences.

Thank you for the support stefan!

Hello
Thanks for the feedback. Once you have more Information about the Issue, you can come back to us.