Dear Toradex support,
we are using the Colibri i.MX7 SoM (eMMC, 1GB DRAM) in our product and have recently upgraded our OS to Yocto Kirkstone.
This means we are now using the kirkstone-6.x.y branch of the meta-toradex-bsp-common Git repository. More precisely we use the linux-toradex-mainline recipe to build our kernel.
We have a .bbappend with some patches that we apply to the kernel, but more on that later.
So first of all, Kirkstone is working pretty well. No larger problems so far. I also was pleasantly surprised that we amount of patches applied to the mainline kernel is pretty small. So I guess, a big thanks for upstreaming!
Now for the problem itself. On the board, where the Colibri SoM is operating on, we have a RS485 transceiver (some Renesas thing, ISL8xxx series). The transceiver is connected to UART6. We talk ModBus RTU over this bus, the SoM is the ModBus master.
Here’s how stuff is connected:
- SODIMM 152 (with 22K PD) → ISL8xxx DE
- SODIMM 103 → ISL8xxx DI (driver input)
- SODIMM 101 → ISL8xxx RO (receiver output)
We used to use this pinctrl configuration in the DT:
pinctrl_uart6_p5x: uart6-grp {
fsl,pins = <
MX7D_PAD_ECSPI1_MOSI__UART6_DCE_TX 0x79 /* SODIMM 103 */
MX7D_PAD_ECSPI1_SCLK__UART6_DCE_RX 0x79 /* SODIMM 101 */
MX7D_PAD_EPDC_DATA11__UART6_DTE_RTS 0x79 /* SODIMM 152 */
>;
};
Together with this UART configuration:
&uart6 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart6_p5x>;
assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
linux,rs485-enabled-at-boot-time;
uart-has-rtscts;
};
This was the configuration that was working with the old 5.4 downstream kernel: toradex_5.4-2.3.x-imx
This configuration stopped working with the 6.1 upstream kernel. Stopped working, as in, regular ModBus read register calls (that previously worked), so longer work (either due to timeouts, or corrupted data). I tracked the problem down to the following commit by Marek Vasut: Link
As a first step I configured the RTS pin as GPIO and used to rts-gpios property. This restores functionality, but I wasn’t really satisfied with this approach. Why has this worked all the time, was the question that went through my head.
So this commit, which attempts to fix the RS485 DE active high scenario, seems to break the configuration we use on our hardware. Further analysis reveals that it’s the loopback mode that the commit uses to fix things.
I’ve put my changes on the FD GitLab:
So I’ve introduced a new DT property that disables the use of loopback mode. Once I disable loopback things work again. Of course the scenario that Marek was trying to fix is then broken again, but this scenario doesn’t matter for us (we can live with the transceiver blocking the bus if nobody has opened the corresponding tty).
For reference here’s the DTSI we are using:
What I don’t understand is how loopback mode could’ve broken anything to begin with. Hence me posting here to maybe get some insight from Toradex.
With best wishes,
Tobias
P.S.: As I’ve said above, we have applied some other patches to the kernel, see the FD GitLab. But the other patches have no influence on the UART (just a bunch of DRM stuff).