Issue with RTS/CTS Flow Control on IW612 Bluetooth (MAYA-W27x) with Verdin iMX8MP

Software summary

Bootloader: U-Boot
Kernel version: 6.6.74-7.2.0-devel-ge87d31337232 #1 SMP PREEMPT Wed Feb 26 11:01:24 UTC 2025
Kernel command line: root=PARTUUID=da1de54a-02 ro rootwait console=tty1 console=ttymxc2,115200
Distro name: NAME=“TDX Wayland with XWayland”
Distro version: VERSION_ID=7.2.0-devel-20250312062116-build.0
Distro variant: -
Hostname: verdin-imx8mp-15460290

Hardware info

HW model: Toradex Verdin iMX8M Plus on Verdin Development Board
Toradex version: 0063 V1.1B
Serial number: 15460290
Processor arch: aarch64

Hi there,

I am working on integrating the IW612-based Bluetooth module (MAYA-W27x: NXP IW612) with the Verdin i.MX8MP platform. While the Bluetooth functionality works correctly when RTS/CTS flow control is not used, I encounter issues when enabling RTS/CTS.

Specifically, when I connect the RTS and CTS pins between the host and the module, Bluetooth initialization fails with opcode timeouts and TX errors. Based on these symptoms, I suspect that the RTS/CTS handshake is not completing successfully.

root@verdin-imx8mp-15460290:~# modprobe btnxpuart                                                   
[   42.127549] wlan: SCAN COMPLETED: scanned AP count=17
root@verdin-imx8mp-15460290:~# [   42.439851] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[   42.445247] Bluetooth: BNEP socket layer initialized
[   43.266730] Bluetooth: hci0: FW already running.
[   45.315028] Bluetooth: hci0: Opcode 0x0c03 failed: -110
[   47.330733] Bluetooth: hci0: Setting baudrate failed (-110)
root@verdin-imx8mp-15460290:~# 
root@verdin-imx8mp-15460290:~# [   49.346732] Bluetooth: hci0: Setting wake-up method failed (-110)
[   51.362750] Bluetooth: hci0: Setting Power Save mode failed (-110)

Interestingly, if I ground the CTS pin on the Bluetooth module and leave the RTS pin unconnected, the module initializes correctly and basic functionality appears to work. However, when I attempt to scan for nearby Bluetooth devices, the following errors occur:

root@verdin-imx8mp-15460290:~# hciconfig 
hci0:   Type: Primary  Bus: UART
        BD Address: 20:BA:36:56:BB:E0  ACL MTU: 1021:7  SCO MTU: 120:6
        UP RUNNING PSCAN 
        RX bytes:902 acl:0 sco:0 events:65 errors:0
        TX bytes:1610 acl:0 sco:0 commands:64 errors:0
root@verdin-imx8mp-15460290:~# bluetoothctl 
hci0 new_settings: powered bondable ssp br/edr le secure-conn cis-central cis-p
Agent registered
[CHG] Controller 20:BA:36:56:BB:E0 Pairable: yes
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# pairable on
Changing pairable on succeeded
[bluetooth]# scan on
SetDiscoveryFilter success
hci0 type 7 discovering on
Discovery started
[CHG] Controller 20:BA:36:56:BB:E0 Discovering: yes
[bluetooth]# [  139.054737] Bluetooth: hci0: Frame reassembly failed (-84)
[NEW] Device 44:A1:70:C1:74:43 44-A1-70-C1-74-43
[bluetooth]# [  139.836671] Bluetooth: hci0: Frame reassembly failed (-84)
[  139.842218] Bluetooth: hci0: Frame reassembly failed (-84)
[CHG] Device 4F:03:41:6A:A2:92 RSSI: 0xffffffaa (-86)
[bluetooth]# [  139.985060] Bluetooth: hci0: Frame reassembly failed (-84)
[NEW] Device 36:D2:3A:FC:99:05 36-D2-3A-FC-99-05
[bluetooth]# [  140.125421] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.167024] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.177003] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.187464] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.197413] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.202975] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.665359] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.729600] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.742113] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.747642] Bluetooth: hci0: Frame reassembly failed (-84)
[NEW] Device 2C:A7:EF:C5:1D:CE 2C-A7-EF-C5-1D-CE
[bluetooth]# [  140.776055] Bluetooth: hci0: Frame reassembly failed (-84)
[  140.833336] Bluetooth: hci0: Frame reassembly failed (-84)

Here’s my dts node;

&uart1 {
         pinctrl-names = "default";
         pinctrl-0 = <&pinctrl_uart1>;
        status = "okay"; 
        assigned-clocks = <&clk IMX8MP_CLK_UART1>;
        assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
        uart-has-rtscts;
       bluetooth {
              compatible = "nxp,88w8987-bt";
             fw-init-baudrate = <115200>;
             status = "okay";
       };
};

 &iomuxc {
 pinctrl_uart1: uart1grp {
         fsl,pins =
                 <MX8MP_IOMUXC_SAI2_RXD0__UART1_DCE_RTS          0x1c4>, /* SODIMM 135 */
                 <MX8MP_IOMUXC_SAI2_TXFS__UART1_DCE_CTS          0x1c4>, /* SODIMM 133 */
                 <MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX           0x1c4>, /* SODIMM 129 */
                 <MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX           0x1c4>; /* SODIMM 131 */
 };
};

My hardware connection are as follows:

HOST SIDE MODULE SIDE
VERDIN_UART1_TX MODULE_UART_RX
VERDIN_UART1_RX MODULE_UART_TX
VERDIN_UART1_CTS MODULE_UART_RTS
VERDIN_UART1_RTS MODULE_UART_CTS

I have also tried reversing the RTS and CTS connections, but there was no change in behaviour.

Questions:

  1. What could be causing this failure when RTS/CTS is enabled?
  2. What configuration or hardware checks would you recommend to ensure proper RTS/CTS operation?

Thanks,
Pratham.

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello Pratham,

Thank you for the detailed description and the information about your software, hardware, device tree, and wiring. Let’s address your questions step by step for integrating the IW612-based Bluetooth module and handling the RTS/CTS flow control on the Verdin i.MX8M Plus platform.

1. Root Cause for Failure When RTS/CTS Is Enabled

Based on your wiring and device tree, and as per Toradex documentation, the Verdin i.MX8M Plus UART controllers can operate in either DTE (Data Terminal Equipment) or DCE (Data Communication Equipment) mode. The signal direction and function of RTS and CTS lines change depending on the selected mode.

Typical Issue Causes:

  • Incorrect Mode Setting: For proper operation with Bluetooth modules like the IW612 (MAYA-W27x), you typically need the UART in DCE mode, since the Bluetooth module usually acts as a DTE.
  • Pin Direction Swap: In DCE mode, the assignment for RTS/CTS is swapped on the SoC:
    • DCE Mode: TX and CTS are outputs, RX and RTS are inputs.
    • You must ensure that your physical connections and software mode (DTE/DCE) match.
  • Pin Muxing Issues: Pinmux and device tree settings can prevent correct operation if not configured for flow control.
  • Driver/Handshake Initialization: The driver and module must be in sync at boot (e.g., baudrate, mode, and flow control).

2. Configuration and Hardware Recommendations for RTS/CTS

A. Double-Check UART Mode (DTE/DCE)

  • By default, the Verdin iMX8M Plus UARTs may be in DTE mode. For many modules, including IW612, you must use DCE mode and swap RTS/CTS.

  • Physical connection in DCE mode should be (assuming host as DCE and module as DTE):

    HOST UART1 (DCE) MODULE (DTE)
    VERDIN_UART1_TX (output) MODULE_UART_RX
    VERDIN_UART1_RX (input) MODULE_UART_TX
    VERDIN_UART1_CTS (output) MODULE_UART_RTS
    VERDIN_UART1_RTS (input) MODULE_UART_CTS

    This matches the connection table you shared, so verify your SoC is actually running in DCE mode.

  • Configure SoC UART as DCE:

    • This is done by a pinmux configuration in the device tree (sometimes with a property like fsl,uart-has-rtscts; alone is NOT sufficient).
    • You may need to set fsl,dce-mode; or equivalent, or adjust the pinctrl to DCE.

B. Device Tree Example

Check the Toradex docs and your SoC datasheet for exact DCE mode configuration. A typical node might look like:

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
    status = "okay";
    assigned-clocks = <&clk IMX8MP_CLK_UART1>;
    assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
    uart-has-rtscts;
    /* Add property if needed for DCE mode:
    fsl,dce-mode;
    */
    bluetooth {
        compatible = "nxp,88w8987-bt";
        fw-init-baudrate = <115200>;
        status = "okay";
    };
};
  • Double-check your SoC or BSP supports a DCE property, as not all have this explicitly. Sometimes, you adjust this in the PinCtrl group (by mapping the pins to the correct function for DCE, not DTE).

C. Lower Initial Baud Rate

  • Start with a conservative baud rate (e.g., 115200) for initial bring-up to avoid timing issues.

D. Additional Checks

  • Ensure no external pull-ups/pull-downs are interfering with the flow control lines.
  • Verify both hardware ends are not asserting or hard-wiring RTS/CTS incorrectly.
  • Run a loopback test with RTS/CTS enabled (short CTS to RTS on one end) to isolate if the error is SoC-side or module-side.

E. Software/Driver

  • Confirm the btnxpuart and hciattach parameters match your setup, especially device, baudrate, and flow control method.
  • Monitor dmesg for relevant UART or pinmux warnings at boot.

Key Documentation Links

Summary

  1. Ensure your UART1 is configured in DCE mode, and verify via pinmux or device tree.
  2. Confirm your wiring aligns with DCE mode requirements.
  3. Try a lower baud rate, and check with basic UART loopback tests if needed.
  4. Review and, if required, adjust your device tree for explicit DCE mode if your SoC/BSP needs it.
  5. Monitor the kernel UART logs for clues about pin direction or handshake failures.

If you need guidance for a specific device tree DCE mode setting or interpreting your pinmux, let me know!

Best regards,
Toradex AI Assistant.

Hello @prathammalaviya !

Please review items 1 and 2A from the Toradex AI Assistant’s response, as they are especially relevant to the RTS/CTS behavior you’re encountering.

As a reminder, according to the iMX8M Plus Datasheet, section 5.10, the SoC signal UARTx_CTS_B is routed to the connector pin UARTx_RTS (SODIMM 135), and vice versa.
This means that Verdin’s RTS pin is actually driven by the SoC’s CTS signal, and wiring must reflect this inversion to ensure correct flow control behavior.

Additionally, verify whether your Bluetooth module actively drives RTS and CTS. CTS must not be left floating or weakly pulled; doing so can prevent the SoC from transmitting. If the module does not actively drive the CTS line, consider adding a pull-up resistor to ensure a valid idle state on the signal.