Enable UART instead of 'Verdin CAN_1' on Verdin AM62

Hello Toradex Community

I’m trying to disable the ‘Verdin CAN_1’ (aka main_mcan0) peripheral which uses the SODIMMs 20 and 22. My goal is to use the SODIMM 20 as UART5_RXD and SODIMM 22 as UART5_TDX instead.

im working with the following setup:

  • Verdin AM62 1GB WB IT (V1.1A)
  • Verdin Development Board (V1.1F)
  • TorizonCore Version: 6.5.0+build.8
  • Host-System Win 10 (WSL2)

I’m relatively new to the Device-Tree game and used the the following tutorials/threads as a start:

I’ve started to write a dt-overlay to implement the desired modification:

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <k3-pinctrl.h>

/ {
    compatible = "toradex,verdin-am62"; // Set hardware compatibility
};

/* disable Verdin CAN_1 */
&main_mcan0 {
    status = "disabled";
};

/* configure pins for uart*/
&main_pmx0 {
    pinctrl_mcan0_uart5: main-mcan0-pins-uart5 {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x01d8, PIN_INPUT_PULLUP, 1) /* (C15) UART5_RXD */ /* SODIMM 20 */
            AM62X_IOPAD(0x01dc, PIN_OUTPUT,       1) /* (E15) UART5_TXD */ /* SODIMM 22 */
        >;
    };
};

I hope until here the dt-overlay is correct. But now the struggle begins.
Any other already configured peripheral adds the pinctrl to a node, like ‘Verdin UART_1’ does here (k3-am62-verdin.dtsi):

/* Verdin UART_1 */
&main_uart1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart1>;
	status = "disabled"; //will be enabled later in k3-am62-verdin-dev.dtsi
};

Also in k3-am62a-main.dtsi the clock for this peripheral is configured?!?

main_uart1: serial@2810000 {
    compatible = "ti,am64-uart", "ti,am654-uart";
    reg = <0x00 0x02810000 0x00 0x100>;
    interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
    power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
    clocks = <&k3_clks 152 0>;
    clock-names = "fclk";
    status = "disabled";
};

I dont know how i should do the above for my UART5. Because the node &main_uart5 is already in use for ‘On-module Bluetooth’ (see k3-am62-verdin-wifi.dtsi). I tried to used the seemingly unused node &main_uart6 in the dt-overlay like:

&main_uart6 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_mcan0_uart5>;
    status = "okay";
};

After that the whole TorizonCore build with the added dt-overlay finished successfully, but i cant see any new UART in the Linux. The only thing I saw was the marked line below:

torizon@verdin-am62-15207085:~$ dmesg | grep -i serial
[    0.000000] Kernel command line: root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/86ed0c547c7bbab93bbf612e6e049042edcbfeaf0e61960a33850d8172ac28b2/0
[    0.028120] Serial: AMBA PL011 UART driver
[    0.978712] Serial: 8250/16550 driver, 6 ports, IRQ sharing enabled
[    1.010025] usbcore: registered new interface driver usbserial_generic
[    1.010047] usbserial: USB Serial support registered for generic
[    1.220492] 4a00000.serial: ttyS3 at MMIO 0x4a00000 (irq = 291, base_baud = 3000000) is a 8250
[    1.222122] 2b300000.serial: ttyS1 at MMIO 0x2b300000 (irq = 292, base_baud = 3000000) is a 8250
[    1.223553] 2800000.serial: ttyS2 at MMIO 0x2800000 (irq = 293, base_baud = 3000000) is a 8250
[    1.232810] 2810000.serial: ttyS0 at MMIO 0x2810000 (irq = 294, base_baud = 3000000) is a 8250
[    1.234101] omap8250 2850000.serial: PM domain pd:156 will not be powered off
[    1.234523] 2850000.serial: ttyS4 at MMIO 0x2850000 (irq = 295, base_baud = 3000000) is a 8250
[    1.234695] serial serial0: tty port ttyS4 registered
[    1.235554] omap8250 2860000.serial: failed to get alias <---------------------------------------
[    6.238108] systemd[1]: Unnecessary job was removed for /sys/devices/platform/bus@f0000/2800000.serial/tty/ttyS2.
[    6.306810] systemd[1]: Created slice Slice /system/serial-getty.

So i added a new alias, like it was done for the already configured UARTs and my dt-overlay ended up like this:

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <k3-pinctrl.h>

/ {
    compatible = "toradex,verdin-am62"; // Set hardware compatibility
    aliases {
        serial5 = &main_uart6;
    };
};

/* disable Verdin CAN_1 */
&main_mcan0 {
    status = "disabled";
};

/* configure pins for uart*/
&main_pmx0 {
    pinctrl_mcan0_uart5: main-mcan0-pins-uart5 {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x01d8, PIN_INPUT_PULLUP, 1) /* (C15) UART5_RXD */ /* SODIMM 20 */
            AM62X_IOPAD(0x01dc, PIN_OUTPUT,       1) /* (E15) UART5_TXD */ /* SODIMM 22 */
        >;
    };
};

&main_uart6 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_mcan0_uart5>;
    status = "okay";
};

But then I got the following error in the torizoncore build:

=> Adding device-tree overlay 'device-trees/overlays/custom-overlay.dts'
device-trees/overlays/custom-overlay.dts:9.13-11.7: ERROR (path_references): /aliases: Reference to non-existent node or label "main_uart6"

So where I went wrong?

  • Is the usage of the node &main_uart6 the wrong approach?
  • Why does the adding of a additional alias failed?

And one last question: Where does the symlinks “verdin-uart1” etc. in the Torizon linux come from?

torizon@verdin-am62-15207085:~$ ls -lah /dev/verdin-uart*
lrwxrwxrwx 1 root root 5 Apr 28 17:42 /dev/verdin-uart1 -> ttyS0
lrwxrwxrwx 1 root root 5 Apr 28 17:42 /dev/verdin-uart2 -> ttyS1
lrwxrwxrwx 1 root root 5 Apr 28 17:42 /dev/verdin-uart3 -> ttyS2
lrwxrwxrwx 1 root root 5 Apr 28 17:42 /dev/verdin-uart4 -> ttyS3

Sorry for the long post, but I tried to cover everything I did to give you the entire overview.

Thank in advance

Uwe

So I thought a little more about it. Maybe (as I already said) the Bluethooth is ‘blocking’ the UART5 peripheral and my approach to use &main_uart6 instead isn’t allowed? So I tried to disable the Bluetooth in my dt-overlay and use &main_uart5.

Here is the modified dt-overlay:

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <k3-pinctrl.h>

/ {
    compatible = "toradex,verdin-am62"; // Set hardware compatibility
};

/* disable Verdin CAN_1 */
&main_mcan0 {
    status = "disabled";
};

&main_uart5 {
    pinctrl-0 = <&pinctrl_mcan0_uart5>;
    /delete-property/ uart-has-rtscts;
    status = "okay";

    /delete-property/ bluetooth;
};
    
&main_pmx0 {
    /* Scemtec UART_5, used for Thyone-I wireless chip */
    pinctrl_mcan0_uart5: main-mcan0-pins-uart5 {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x01d8, PIN_INPUT_PULLUP, 1) /* (C15) UART5_RXD */ /* SODIMM 20 */
            AM62X_IOPAD(0x01dc, PIN_OUTPUT,       1) /* (E15) UART5_TXD */ /* SODIMM 22 */
        >;
    };
};

After rebuilding/compiling the Bluetooth is not longer accessible in the CLI.

But the UART is still not accessible. The output of dmesg | grep -i serial let me assume that the UART5 has to be on ttyS4 because of the addressmain_uart5: serial@2850000 {

torizon@verdin-am62-15207085:~$ dmesg | grep -i serial
[    0.000000] Kernel command line: root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/7a6dd317c89ee12a09203641ddd7cb15a1d1a9a66d69c4255b3af028c7db5649/0
[    0.028269] Serial: AMBA PL011 UART driver
[    0.978029] Serial: 8250/16550 driver, 6 ports, IRQ sharing enabled
[    1.009043] usbcore: registered new interface driver usbserial_generic
[    1.009064] usbserial: USB Serial support registered for generic
[    1.221485] 4a00000.serial: ttyS3 at MMIO 0x4a00000 (irq = 291, base_baud = 3000000) is a 8250
[    1.223072] 2b300000.serial: ttyS1 at MMIO 0x2b300000 (irq = 292, base_baud = 3000000) is a 8250
[    1.224466] 2800000.serial: ttyS2 at MMIO 0x2800000 (irq = 293, base_baud = 3000000) is a 8250
[    1.233668] 2810000.serial: ttyS0 at MMIO 0x2810000 (irq = 294, base_baud = 3000000) is a 8250
[    1.234762] omap8250 2850000.serial: PM domain pd:156 will not be powered off
[    1.235229] 2850000.serial: ttyS4 at MMIO 0x2850000 (irq = 295, base_baud = 3000000) is a 8250
[    1.235388] serial serial0: tty port ttyS4 registered
[    6.514010] systemd[1]: Unnecessary job was removed for /sys/devices/platform/bus@f0000/2800000.serial/tty/ttyS2.
[    6.586481] systemd[1]: Created slice Slice /system/serial-getty.

but there is no ttyS4:

torizon@verdin-am62-15207085:~$ ls -lah /dev/ttyS*
crw-rw---- 1 root    dialout 4, 64 Apr 28 17:42 /dev/ttyS0
crw-rw---- 1 root    dialout 4, 65 Apr 28 17:42 /dev/ttyS1
crw------- 1 torizon tty     4, 66 Apr 28 17:49 /dev/ttyS2
crw-rw---- 1 root    dialout 4, 67 Apr 28 17:42 /dev/ttyS3
crw-rw---- 1 root    dialout 4, 69 Apr 28 17:42 /dev/ttyS5

So clearly I’m missing something. Can someone give my a little guidance?

Best regards

Uwe

hi @buw3,

we just had similar post here: How to configure custom UART? - #15 by SmartStuff.

@SmartStuff made it to work and could also maybe give some tips :slight_smile: Let us know if this helps you.

Hallo @andi.tx ,

you were right with the similar post. Sorry I have missed that. I read the whole thread and managed to get the additional alias right. The difference to How to configure custom UART? is that I want to disable the ‘Verdin CAN_1’ (aka &main_mcan0) instead of ‘Verdin SPI_1’ (aka &main_spi1) and than configure a new UART. Here is my dt-overlay:

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <k3-pinctrl.h>

/ {
    compatible = "toradex,verdin-am62"; // Set hardware compatibility
};

/* add a new alias so the serial device will show up in '/dev' and delete alias can0*/
&{/} {
    aliases {
        /delete-property/ can0;
        serial5 = "/bus@f0000/serial@2860000";
    };
};

/* disable Verdin CAN_1 */
&main_mcan0 {
    status = "disabled";
};

/* configure pins for uart*/
&main_pmx0 {
    pinctrl_uartx: main-uartx-pins-default {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x01d8, PIN_INPUT_PULLUP, 6) /* (C15) PR0_UART0_RXD */ /* SODIMM 20 */
            AM62X_IOPAD(0x01dc, PIN_OUTPUT,       6) /* (E15) PR0_UART0_TXD */ /* SODIMM 22 */
        >;
    };
};

&main_uart6 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uartx>;
    status = "okay";
};

The deletion of the can0 alias doesn’t seem to work, because it is still listed if I type ls -l /proc/device-tree/aliases/

With mesg | grep -i serial i can see that there is an additional UART in /dev/ttyS5:

torizon@verdin-am62-15207085:~$ dmesg | grep -i serial
[    0.000000] Kernel command line: root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/819abd8275813c9fe50da7865bb4a1afc247d28123b05d7d55c60ab0fbcfdf3b/0
[    0.028067] Serial: AMBA PL011 UART driver
[    0.976584] Serial: 8250/16550 driver, 6 ports, IRQ sharing enabled
[    1.007444] usbcore: registered new interface driver usbserial_generic
[    1.007467] usbserial: USB Serial support registered for generic
[    1.210839] 4a00000.serial: ttyS3 at MMIO 0x4a00000 (irq = 291, base_baud = 3000000) is a 8250
[    1.212369] 2b300000.serial: ttyS1 at MMIO 0x2b300000 (irq = 292, base_baud = 3000000) is a 8250
[    1.213788] 2800000.serial: ttyS2 at MMIO 0x2800000 (irq = 293, base_baud = 3000000) is a 8250
[    1.222936] 2810000.serial: ttyS0 at MMIO 0x2810000 (irq = 294, base_baud = 3000000) is a 8250
[    1.224093] omap8250 2850000.serial: PM domain pd:156 will not be powered off
[    1.224486] 2850000.serial: ttyS4 at MMIO 0x2850000 (irq = 295, base_baud = 3000000) is a 8250
[    1.224653] serial serial0: tty port ttyS4 registered
[    1.225962] 2860000.serial: ttyS5 at MMIO 0x2860000 (irq = 296, base_baud = 3000000) is a 8250
[    7.251402] systemd[1]: Unnecessary job was removed for /sys/devices/platform/bus@f0000/2800000.serial/tty/ttyS2.
[    7.349531] systemd[1]: Created slice Slice /system/serial-getty.

I can also configurate it like:

torizon@verdin-am62-15207085:~$ stty < /dev/ttyS5
speed 9600 baud; line = 0;
-brkint -imaxbel
torizon@verdin-am62-15207085:~$ stty -F /dev/ttyS5 115200
torizon@verdin-am62-15207085:~$ stty < /dev/ttyS5
speed 115200 baud; line = 0;
-brkint -imaxbel

I connected a UART-USB-dongle via the Level-Shifter on the Verdin-Eval-Board with SODIMM 20/22, but still I can’t read/write to /dev/ttyS5. I tripple checked that my UART-USB-dongle setup is working.


I guess the problem here is:

&main_uart6 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uartx>;
    status = "okay";
};

because I’m trying to assign the Pin configuration PR0_UART0 (aka pinctrl_uartx) to the node &main_uart6, which is not valid. Am I right? But which node do I use instead?
And why is the deletion of the can0 alias not working?

Best Regards

Uwe

Hi Uwe,
no problem at all. The other post was just very recent and I happen to also learn quite a bit so I could help you. Btw, welcome to the Device Tree game, hope you “enjoyed” it so far! Well, back to the matter. I believe that you triple-checked your UART-USB-dongle, so let’s triple check your DT Overlay :slight_smile:

Before we continue, I would ask you to consider if you really need Device Tree Overlay because it has its limitation: delete node/properties won’t work (read here or here). It is best if you rethink and only do “addition” with overlay. I recommend having the modification in your own .dts device tree base file, e.g. my-verdin-am62-dev.dts.

But let’s see what we can do with overlay and check your DT overlay step-by-step:

  1. “aliases” node: as mentioned above, you can’t delete can0 alias in overlay. I suggest you delete the CAN node that in your custom .dts and enable in the overlay if you need it. Since you want to use UART5, it has been aliased in k3-am62-verdin.dtsi as serial4. What you did just now, was adding alias for UART6. So, we don’t need aliases in the overlay but we must deal with the connection with the Bluetooth module later.

  2. Disabling &main_mcan0 node is good.

  3. &main_pmx0 pinmux node. You are defining pinctrl_uart6 which you never use. &main_uart6 is connected to a realuart6 in the SoC and this is not what you want. Yes, the issue is with using PR0_UART0 instead of the UART5. You should use number 1 as in AM62X_IOPAD(0x01d8, PIN_INPUT_PULLUP, 1). Most likely you already know where it comes from, but just for completeness’ sake I put the excerpt from the datasheet below. You can also read here Pinmuxing AM6X Based Modules | Toradex Developer Center

  4. &main_uart5 node: if k3-am625-verdin-wifi-dev.dtb is enabled on your board (run sudo tdx-info -dt to check). I suggest that you change to k3-am625-verdin-nonwifi-dev.dts. This base .dts didn’t define any bluetooth connection. I think why you don’t see bluetooth connection anymore is not because of /delete-property/ but because you gave the pin for your pinctrl_mcan0_uart5 which didn’t include the CTS&RTS pins but &main_uart5 node was defined still with /delete-property/ uart-has-rtscts; (again delete-property doesn’t work).

Try the following overlay and use k3-am625-verdin-nonwifi-dev.dts as your base device tree:

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <k3-pinctrl.h>

/ {
    compatible = "toradex,verdin-am62"; // Set hardware compatibility
};

/* no need for aliases. delete can0 alias in your .dts and UART5 has been aliased to serial4 in k3-am62-verdin.dtsi */

/* disable Verdin CAN_1 */
&main_mcan0 {
    status = "disabled";
};

/* configure pins for UART5*/
&main_pmx0 {
    /* Scemtec UART_5, used for Thyone-I wireless chip - node naming is not crucial */
    pinctrl_uart5: main-uart5-pins-thyone-i {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x01d8, PIN_INPUT_PULLUP, 1) /* (C15) UART5_RXD */ /* SODIMM 20 */
            AM62X_IOPAD(0x01dc, PIN_OUTPUT,       1) /* (E15) UART5_TXD */ /* SODIMM 22 */
        >;
    };
};

&main_uart5 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart5>;
	status = "okay";
};

Let me know if this works. At least, you should have a better idea of what to do.

Hallo @andi.tx

thank you for the detailed reply.

I tried the overlay you suggested with the k3-am625-verdin-nonwifi-dev.dts as the base device tree. It worked!

I also tried to use the k3-am625-verdin-wifi-dev.dts as the base device tree and manipulated the sources for UART5 and removed the bluetooth stuff (without any overlay). This also worked!

Thank you very much for helping to clear the fog a little :slight_smile:

Two last questions:

  1. Is there any chance to use PR0_UART0 so the bluetooth will still work?
  2. If PR0_UART0 can’t be used. One approach to still use the wifi (which is required in out project) would be?
    • use k3-am625-verdin-nonwifi-dev.dts as the base device tree
    • write an overlay to use UART5 (as we already did)
    • write another overlay which enables just the wifi stuff (without bluetooth)

Kind Regards,
Uwe

Hallo @buw3,

great, thank you for the feedback!

My comments:

  1. If I can rephrase your goal, that you need additional UART that doesn’t interrupt with bluetooth, then I think it is achievable. Have you checked our pinout designer tool? If not, have a look and watch the webinar. Once you have all the pins set correctly according to the interfaces you need, then you start modifying the device tree. Not the other way around.
  2. This approach seems viable too. The modification would look like k3-am62-verdin-wifi.dtsi while leaving out the bluetooth node and assigning the pinctrl-0 property correctly. Again, if you do it on overlay or not, you know my opinion. I know you can make it work both ways since you just did it :+1:

Hope this is clear now. Let me know if you have further questions.

Hallo @andi.tx,

thanks for the continuous help =) I appreciate it!

Normally I would agree 100%, but we used the pinout designer tool first and then designed our hardware (as you suggested). The thing is that the pinout designer doesn’t show a conflict between UART5 and Bluetooth :man_shrugging: But its not big of a deal, because currently Bluetooth is not required in our project. But it would have been nice if the option is available without redesigning the hardware.

Anyway, we will do the second approach (overlay for UART5 and WIFI - without Bluetooth). I will post the final result here to sum everything up of the thread.

Kind Regards,
Uwe

For everyone who is interested in the final solution. Here it is…

We are using the Verdin AM62 1GB WB IT (V1.1A) so there is Wifi and Bluetooth on it. We didn’t realise that the Bluetooth is using the SODIMM_20 and SODIMM_22 which we planned to use for an additional UART. In our project Bluetooth it not mandatory so we disable it to use UART5 instead.

As a base device tree we use: k3-am625-verdin-nonwifi-dev.dts

To enable UART5 we use this overlay:

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <k3-pinctrl.h>

/ {
    /* Set hardware compatibility */
    compatible = "toradex,verdin-am62-nonwifi-dev",
             "toradex,verdin-am62-nonwifi",
             "toradex,verdin-am62",
             "ti,am625";
};

/* disable Verdin CAN_1 */
&main_mcan0 {
    status = "disabled";
};

/* configure pins for uart5*/
&main_pmx0 {
    pinctrl_uart5: main-uart5-pins-default {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x01d8, PIN_INPUT_PULLUP, 1) /* (C15) UART5_RXD */ /* SODIMM 20 */
            AM62X_IOPAD(0x01dc, PIN_OUTPUT,       1) /* (E15) UART5_TXD */ /* SODIMM 22 */
        >;
    };
};

&main_uart5 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart5>;
    status = "okay";
};

To enable Wifi (without enabling Bluetooth) we use this overlay:

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <dt-bindings/gpio/gpio.h>

/ {
    /* Set hardware compatibility */
    compatible = "toradex,verdin-am62-nonwifi-dev",
             "toradex,verdin-am62-nonwifi",
             "toradex,verdin-am62",
             "ti,am625";
};

&{/} {
    wifi_pwrseq: wifi-pwrseq {
        compatible = "mmc-pwrseq-simple";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_wifi_en>;
        reset-gpios = <&main_gpio0 22 GPIO_ACTIVE_LOW>;
    };
};

/* On-module Wi-Fi */
&sdhci2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sdhci2>;
    bus-width = <4>;
    cap-power-off-card;
    keep-power-in-suspend;
    mmc-pwrseq = <&wifi_pwrseq>;
    non-removable;
    ti,fails-without-test-cd;
    ti,driver-strength-ohm = <50>;
    vmmc-supply = <&reg_3v3>;
    status = "okay";
};

I hope this may help someone in the future.

Best Regards

Uwe

1 Like

Thank you @buw3 for sharing and contributing with the community! Good to know that you can confirm our “theory”. Hope somebody can profit from this :slight_smile:

To comment a bit on this:

Normally I would agree 100%, but we used the pinout designer tool first and then designed our hardware (as you suggested). The thing is that the pinout designer doesn’t show a conflict between UART5 and Bluetooth :man_shrugging: But its not big of a deal, because currently Bluetooth is not required in our project. But it would have been nice if the option is available without redesigning the hardware.

Yes, unfortunately we don’t indicate that the UART is used by the wireless module. I will check internally if we can improve this. Could you not use UART6 or other unused one without the need to modify the UART5?

Hi @andi.tx

We will consider this in our next hardware design. Thanks for the suggestion =)

Kind Regards,
Uwe