This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM6411: How to enable UART2 HW flow control ?

Part Number: AM6411

Tool/software:

Hi, 

We are struggling to enable the HW flow control on UART2. We have applied the patch below to the dts file and set the CRTSCTS flag in the termios call in our Linux UART application. The UART TX and RX work as expected but the HW flow control is still disabled. 

Is there anything wrong in the patch below ?

diff --git a/arch/arm64/boot/dts/ti/k3-am64x-wiser.dts b/arch/arm64/boot/dts/ti/k3-am64x-wiser.dts

index 86bf47a96a64..09f7e6aaea4b 100644

--- a/arch/arm64/boot/dts/ti/k3-am64x-wiser.dts

+++ b/arch/arm64/boot/dts/ti/k3-am64x-wiser.dts

@@ -265,6 +265,7 @@ &main_uart2 {

pinctrl-names = "default";

pinctrl-0 = <&zigbee_pins_default>;

current-speed = <115200>;

+  uart-has-rtscts;

};

 

@@ -176,6 +174,8 @@ zigbee_pins_default: zigbee-default-pins {

pinctrl-single,pins = <

AM64X_IOPAD(0x0238, PIN_INPUT, 3) /* (B16) UART0_CTSn.UART2_RXD */

AM64X_IOPAD(0x023c, PIN_OUTPUT, 3) /* (A16) UART0_RTSn.UART2_TXD */

+      AM64X_IOPAD(0x0294, PIN_OUTPUT_PULLUP, 1) /* (J19) GPIO1_76.UART2_RTSn */

+      AM64X_IOPAD(0x028C, PIN_INPUT_PULLUP, 1) /* (L20) GPIO1_75.UART2_CTSn */

  • Hi Geoffrey,

    +      AM64X_IOPAD(0x0294, PIN_OUTPUT_PULLUP, 1) /* (J19) GPIO1_76.UART2_RTSn */

    +      AM64X_IOPAD(0x028C, PIN_INPUT_PULLUP, 1) /* (L20) GPIO1_75.UART2_CTSn */

    First please check if the pinmux is set correctly. Ensure these two pins are not used on other modules. On AM64x GPEVM and SKEVM, these two pins are used for the SD card.

    Check if the padconfig registers for these two pins are indeed set correctly.

    If pinmux has no issue, please explain how did you observed the hw flow control is disabled.

  • Hi Bin Liu,

    Based on the diff pasted on the initial post, we believe that the pins have been successfully repurposed from their previous usage (CMD/CLK).  And cannot see them referenced anywhere else.

    Regarding testing; the issue we see is that the CTS/RTS is always TTL low, signalling continuous transmission, even in the case the RX buffer is overflowing, or the RX buffer isn't being read from.  Repeating the exact same test with the same tools on different uart hardware causes the CTS/RTS to go TTL high until the buffer is read from.  If we disconnect the RTS from CTS, and apply TTL low to the CTS, the transmission stops - implying CTS is working as it should.  However, the RTS isn't being driven as it should be based on rx buffer state / whatever should be requesting to pause transmission.

  • Hi Shahbaz,

    Please read the corresponding padconfig registers to ensure the pinmux is correct. The register address is listed in the AM64x Datasheet, you can use devmem2 tool to read the address.

    Which SDK version do you use? I'd like to check its kernel uart driver code.

  • We finally managed to get this working now.

    A bit of history; we had these J19 and L20 pins configured for 4 bit SDIO previously (Mode 0).  Then now trying to repurpose them to be used for UART2 CTS/RTS (Mode 1).

    This is the change we made:

           mmc1_pins_default: mmc1-default-pins {
                   pinctrl-single,pins = <
    -                      AM64X_IOPAD(0x0294, PIN_INPUT, 0) /* (J19) MMC1_CMD */
    -                      AM64X_IOPAD(0x028c, PIN_INPUT, 0) /* (L20) MMC1_CLK */
                           AM64X_IOPAD(0x0288, PIN_INPUT, 0) /* (K21) MMC1_DAT0 */
                           AM64X_IOPAD(0x0284, PIN_INPUT, 0) /* (L21) MMC1_DAT1 */
                           AM64X_IOPAD(0x0280, PIN_INPUT, 0) /* (K19) MMC1_DAT2 */
    @@ -176,6 +174,8 @@ zigbee_pins_default: zigbee-default-pins {
                   pinctrl-single,pins = <
                           AM64X_IOPAD(0x0238, PIN_INPUT, 3) /* (B16) UART0_CTSn.UART2_RXD */
                           AM64X_IOPAD(0x023c, PIN_OUTPUT, 3) /* (A16) UART0_RTSn.UART2_TXD */
    +                      AM64X_IOPAD(0x028c, PIN_INPUT, 1) /* (L20) MMC1_CLK.UART2_CTSn */
    +                      AM64X_IOPAD(0x0294, PIN_OUTPUT_PULLUP, 1) /* (J19) MMC1_CMD.UART2_RTSn */
                   >;
           };

    The expectation was that this would be all that's required to now have working CTS/RTS Flow Control on UART2.

    However, with this change only, we were experiencing some weird behaviour on the RTS pin, resulting in the flow control protocol not working.

    How we managed to fix it was to remove the SDIO definition from the source code entirely:

    -&sdhci1 {
    -    status = "okay";
    -    vmmc-supply = <&wifi_3v3_wb>;
    -    bus-width = <4>;
    -    non-removable;
    -    disable-wp;
    -    cap-power-off-card;
    -    keep-power-in-suspend;
    -    ti,driver-strength-ohm = <50>;
    -      pinctrl-0 = <&mmc1_pins_default>;
    -    pinctrl-names = "default";
    -    mmc-pwrseq = <&wfx_pwrseq>;
    -
    -    /* 25Mhz support */
    -    sd-uhs-sdr12;
    -    /* 50Mhz support */
    -    sd-uhs-sdr25;
    -    /* Support hardware reset */
    -    cap-mmc-hw-reset;
    -
    -    /* Force to 26Mhz (max freq. supported by the wf200) */
    -    max-frequency = <26000000>;
    -
    -    #address-cells = <1>;
    -    #size-cells = <0>;
    -
    -    wifi1: wifi@1 {
    -        compatible = "silabs,wf200";
    -        status = "okay";
    -        reg = <1>;
    -    };
    - };
    

    That should not have been required at all.

    I am not sure whether it was the sdhci1{} definition itself, or the pinctrl-0 = <&mmc1_pins_default>; definition inside this structure, but the result was that flow control didn't work until we removed this block.  i.e. the existence of this block is was interfering with pinmux / mode change of those 2 pins.

    The build was done using yocto scarthgap on 6.6 BSP, but had the same issue on other yocto versions with previous BSP iterations too, so I believe it exists everywhere.

    Can you please investigate the issue on your end and report back?

  • Hi Shahbaz,

    Yes, to change the MMC pins to different pinmux mode, the corresponding MMC module has to be disabled (powered off). For your use case, you could remove the entire sdhci1 node as you showed above, or the better solution is to add the following to the board devicetree file.

    &sdhci1 {
        status = "disabled";
    }

    I am out of office for the last few days. I will update this thread later this week to explain in details why this is required.

  • Hi Shahbaz,

    I couldn't find any documentation stating the MMC module has to be disabled for its pins to be in GPIO mode, but this is related to the MMCSD_SS_PHY_CTRL_1 register.

    For MMC pins to be used in gpio mode, the register bit31 has to be set to '1'. But it will be set to '0' in MMC driver init. That is why the MMC module has to be disable for its pins to be in gpio mode.