LWB+ integration on i.MX8M Plus EVK (lrd-11.x)

This tutorial shows how to integrate the LWB+ on the imx8mp-evk. The LWB+ uses SDIO for the Wi-Fi interface and UART for the Bluetooth interface. It is assumed the user is familiar with Linux and embedded systems. Included in this tutorial are the physical setup, Yocto setup and build, and verifying the Wi-Fi and Bluetooth are functional.

Note: This guide is for Laird Connectivity code lrd-11.x and higher. For Laird Connnectivity code lrd-10.x or for kernel 5.15 or lower please see: https://lairdcp.github.io/guides/LWBp-tutorials/1.0/imx8mp-lwbplus.html

Requirements

Required items:

Physical setup

i.MX 8M Plus (imx8mp)

This tutorial uses the microSD slot on the imx8mp as the Wi-Fi interface. This requires the software to be loaded on to the emmc which can be done with the uuu utility with the Serial Download boot mode or using u-boot with the ums tool.

The imx8mp bb expansion header is used to connect the power, Bluetooth UART, and REG_ON pins for Wi-Fi and Bluetooth.

Schematic of the expansion header: exp

The UART3 lines are used for the bluetooth UART. The ECSPI2 MOSI and SCLK are used for the REG_ON pins to control resets.

LWB+

Jumper Position Use
J4 2-3 VCCIO 3.3v
J5   Ext Voltage from imx8
J6 1-2 VDD 3.3v
J7 2-3 VBATT EXT

LWB+

Note on LWB+ and SD adapter

Cut and place to shape two layers of stickers on the LWB+ and the adapter board that goes into the imx8mp and micro SD to SD adapter to ensure the devices are not loose. Example used here is a UPS tracking receipt that is a label. The label is thin thus requiring 2-4 layers on each. This connection can be very sensitive and delicate, so ensure it’s supported properly and not bending the micro sd tab which is the vulnerable point of the connection.

Physical Connections

LWB+ LWB+ Notes   imx8mp imx8mp Notes
J3.6 BT CTS -> J21.7 uart3.cts
J3.8 BT TXD -> J21.10 uart3.rxd
J3.10 BT RXD -> J21.8 uart3.txd
J3.14 BT RTS -> J21.11 uart3.rts
J3.16 GND -> J21.9 GND
J3.11 WL_REG_ON   J21.23 GPIO5.io10
J3.13 BT_REG_ON   J21.19 GPIO5.io11
J5.3.3 3.3v input <- J21.1 3.3v supply
J5.GND GND <- J21.6 GND

imx8+LWB+

Yocto setup and build

Get yocto-mickeldore

repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-mickledore -m imx-6.1.22-2.0.0.xml
repo sync

DISTRO=fsl-imx-wayland MACHINE=imx8mpevk source imx-setup-release.sh -b build-imx8mpevk

Get meta-summit-radio

cd ../sources
git clone https://github.com/LairdCP/meta-summit-radio

Update image in ~/projects/yocto-mickledore/sources/meta-summit-radio/meta-summit-radio/recipes-packages/images

Copy sample-image-lwb5plus.bb to lwbp-lrd11.bb make the IMAGE_INSTALL section like below:

IMAGE_INSTALL += "\
	iproute2 \
	rng-tools \
	ca-certificates \
	tzdata \
	alsa-utils \
	htop \
	ethtool \
	iperf3 \
	tcpdump \
	iw \
	kernel-module-lwb-backports-summit \
	lwbplus-firmware \
	summit-supplicant-lwb \
	summit-supplicant-libs-lwb \
    summit-networkmanager-lwb \
	summit-networkmanage-lwb-nmcli \
    libgpiod \
	libgpiod-tools \
	hostapd \
    "

~/projects/yocto-mickledore/build-imx8mpevk/conf/bblayers.conf

Edit your bblayers.conf file and add the following to the bottom.

BBLAYERS += "${BSPDIR}/sources/meta-summit-radio/meta-summit-radio"

~/projects/yocto-mickledore/build-imx8mpevk/conf/local.conf

Edit your local.conf file and add the following to the bottom.

PREFERRED_PROVIDER_wpa-supplicant = "summit-supplicant-lwb"
PREFERRED_PROVIDER_wpa-supplicant-cli = "summit-supplicant-lwb"
PREFERRED_PROVIDER_wpa-supplicant-passphrase = "summit-supplicant-lwb"
   
BBMASK += " \
    meta-summit-radio/meta-summit-radio/recipes-packages/openssl \
    meta-summit-radio/meta-summit-radio/recipes-packages/.*/.*openssl10.* \
    "
   
PREFERRED_RPROVIDER_wireless-regdb-static = "wireless-regdb"
LWB_REGDOMAIN = "US"

Note: You do not need to use LWB_REGDOMAIN to specify the regulatory domain. You could choose to implement it using a device tree setting or configure the module parameter some other way. However, the regulatory domain must be configured for the LWB+ in some manner.

kernel menuconfig

Run the following command to launch the kernel menuconfig.

bitbake -c menuconfig virtual/kernel

Make the following modifications:

In the menuconfig use / to search for each of the below configuration parameters in caps.

WLAN
- deselect Device Drivers -> Network device support -> Wireless LAN

CONFIG_BT
- deselect Networking support -> Bluetooth subsystem support

CFG80211
- set to module (M) Networking support -> Wireless -> cfg80211 - wireless configuration API

CONFIG_FW_LOADER_USER_HELPER_FALLBACK
- deselect Device Drivers -> Generic Driver Options -> Firmware Loader 
    -> Firmware loading Facility ->Force the firmware sysfs fallback mechanism when possible

CONFIG_IMX_SDMA
- set to module (M) Device Drivers -> DMA Engine support -> i.MX SDMA support

Save your changes and exit menuconfig.

Disable nxp drivers

Edit the file ~/projects/yocto-mickledore/sources/meta-imx/meta-bsp/conf/layer.conf Comment out the whole section (4 lines): # NXP Wi-Fi firmware & extra Wlan SDK

# NXP WiFi firmware & extra Wlan SDK
#MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'nxp8987', 'linux-firmware-nxp89xx', '', d)}"
#MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'nxp8997', 'linux-firmware-nxp89xx', '', d)}"
#MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'iw612', 'linux-firmware-nxp89xx', '', d)}"
#MACHINE_EXTRA_RRECOMMENDS:remove = "kernel-module-nxp89xx"
#MACHINE_EXTRA_RRECOMMENDS:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'nxp8987', 'nxp-wlan-sdk kernel-module-nxp89xx', '', d)}"
#MACHINE_EXTRA_RRECOMMENDS:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'nxp8997', 'nxp-wlan-sdk kernel-module-nxp89xx', '', d)}"
#MACHINE_EXTRA_RRECOMMENDS:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'iw612', 'iw612-sdk kernel-module-iw612', '', d)}"

Modify devicetree

Below is a diff of the changes made in the devicetree as a patch.

For reference:

Location of the devicetree is: ~/projects/yocto-honister/build-imx8mpevk/tmp/work-shared/imx8mpevk/kernel-source/arch/arm64/boot/dts/freescale/imx8mp-evk.dts

cd ~/projects/yocto-honister/build-imx8mpevk/tmp/work-shared/imx8mpevk/kernel-source/arch/arm64/boot/dts/freescale/


--- imx8mp-evk.dts	2022-06-01 12:11:11.540506538 -0400
+++ imx8mp-evk.dts.lwbplus	2022-06-01 12:05:27.722792689 -0400
@@ -34,6 +34,26 @@
 		      <0x1 0x00000000 0 0xc0000000>;
 	};
 
+	wifi_pwrseq: wifi-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		regulator-name = "wifi-pwrseq";
+		pinctrl-names = "default";
+		reset-gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
+		post-power-on-delay-ms = <150>;		
+	};
+
+	reg_bt: regulator-bt {
+		compatible = "regulator-fixed";
+		regulator-name = "bt";
+		gpio = <&gpio5 11 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <100>;
+		enable-active-high;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
 	reg_can1_stby: regulator-can1-stby {
 		compatible = "regulator-fixed";
 		regulator-name = "can1-stby";
@@ -272,7 +292,8 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>;
 	cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
-	status = "okay";
+	//status = "okay";
+	status = "disabled"; /* added */
 
 	spidev1: spi@0 {
 		reg = <0>;
@@ -888,8 +909,10 @@
 	pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
 	pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
 	pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+	max-frequency = <100000000>;
 	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
 	vmmc-supply = <&reg_usdhc2_vmmc>;
+	mmc-pwrseq = <&wifi_pwrseq>;
 	bus-width = <4>;
 	status = "okay";
 };
@@ -919,6 +942,8 @@
 
 	pinctrl_hog: hoggrp {
 		fsl,pins = <
+            MX8MP_IOMUXC_ECSPI2_MOSI__GPIO5_IO11        0x00000146
+            MX8MP_IOMUXC_ECSPI2_SCLK__GPIO5_IO10        0x00000146
 			MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL	0x400001c3
 			MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA	0x400001c3
 			MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD		0x40000019

bitbake

bitbake lwbp-lrd11

yocto_build

Flashing with u-boot and ums

  1. Ensure the usb-c cable from PORT1 is connected to the PC.
  2. Enter u-boot and enter the following command:

     ums 0 mmc 2
    
  3. The emmc is now shown on the host PC and can be flash using dd in Linux or balenaetcher.

     bzip2 -dkf tal-lwbp-su-lrd10-imx8mpevk.wic.bz2 
     sudo dd if=tal-lwbp-su-lrd10-imx8mpevk.wic of=/dev/sdb bs=1M status=progress
     sync
    
  4. Reboot the device with the LWB+ attached.

Test module

Wi-Fi

iw dev


root@imx8mpevk:~# iw dev
phy#0
        Unnamed/non-netdev interface
                wdev 0x2
                addr c2:ee:40:b0:03:9c
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 5
                wdev 0x1
                addr c0:ee:40:b0:03:9c
                ssid dogfish
                type managed
                channel 1 (2412 MHz), width: 20 MHz, center1: 2412 MHz
                txpower 31.00 dBm

Wi-Fi iperf3 tests

iperf3 -c 10.0.0.2


root@imx8mpevk:~# iperf3 -c 10.0.0.2
Connecting to host 10.0.0.2, port 5201
[  5] local 10.0.0.37 port 38532 connected to 10.0.0.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  5.44 MBytes  45.6 Mbits/sec    0    226 KBytes
[  5]   1.00-2.00   sec  4.47 MBytes  37.5 Mbits/sec    0    266 KBytes
[  5]   2.00-3.00   sec  5.10 MBytes  42.7 Mbits/sec    0    266 KBytes
[  5]   3.00-4.00   sec  4.66 MBytes  39.1 Mbits/sec    0    266 KBytes
[  5]   4.00-5.00   sec  5.03 MBytes  42.2 Mbits/sec    0    277 KBytes
[  5]   5.00-6.00   sec  4.54 MBytes  38.1 Mbits/sec    0    277 KBytes
[  5]   6.00-7.00   sec  4.91 MBytes  41.2 Mbits/sec    0    277 KBytes
[  5]   7.00-8.00   sec  4.78 MBytes  40.1 Mbits/sec    0    277 KBytes
[  5]   8.00-9.00   sec  4.47 MBytes  37.5 Mbits/sec    0    277 KBytes
[  5]   9.00-10.00  sec  4.54 MBytes  38.1 Mbits/sec    0    277 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  47.9 MBytes  40.2 Mbits/sec    0             sender
[  5]   0.00-10.00  sec  47.4 MBytes  39.8 Mbits/sec                  receiver

iperf Done.



iperf3 -c 10.0.0.2 -R


root@imx8mpevk:~# iperf3 -c 10.0.0.2 -R
Connecting to host 10.0.0.2, port 5201
Reverse mode, remote host 10.0.0.2 is sending
[  5] local 10.0.0.37 port 38536 connected to 10.0.0.2 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  6.14 MBytes  51.5 Mbits/sec
[  5]   1.00-2.00   sec  6.39 MBytes  53.6 Mbits/sec
[  5]   2.00-3.00   sec  6.43 MBytes  53.9 Mbits/sec
[  5]   3.00-4.00   sec  6.42 MBytes  53.9 Mbits/sec
[  5]   4.00-5.00   sec  6.40 MBytes  53.7 Mbits/sec
[  5]   5.00-6.00   sec  6.36 MBytes  53.4 Mbits/sec
[  5]   6.00-7.00   sec  6.29 MBytes  52.8 Mbits/sec
[  5]   7.00-8.00   sec  6.26 MBytes  52.5 Mbits/sec
[  5]   8.00-9.00   sec  6.41 MBytes  53.8 Mbits/sec
[  5]   9.00-10.00  sec  6.55 MBytes  55.0 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  66.5 MBytes  55.8 Mbits/sec    0             sender
[  5]   0.00-10.00  sec  63.7 MBytes  53.4 Mbits/sec                  receiver

iperf Done.

Bluetooth

btattach -B /dev/ttymxc2 -P bcm -S 3000000 &


root@imx8mpevk:~# btattach -B /dev/ttymxc2 -P bcm -S 3000000 &
[1] 488
Attaching Primary controller to /dev/ttymxc2
[ 2929.323498] Bluetooth: HCI UART driver ver 2.3
[ 2929.327993] Bluetooth: HCI UART protocol H4 registered
[ 2929.333521] Bluetooth: HCI UART protocol Broadcom registered
root@imx8mpevk:~# Switched line discipline from 0 to 15
Device index 0 attached
[ 2929.456927] Bluetooth: hci0: BCM: chip id 147
[ 2929.464112] Bluetooth: hci0: BCM: features 0x0e
[ 2929.492213] Bluetooth: hci0: CYW4343A2
[ 2929.495986] Bluetooth: hci0: BCM4343A2 (001.003.016) build 0000
[ 2929.503453] Bluetooth: hci0: BCM4343A2 'brcm/BCM4343A2.hcd' Patch
[ 2930.414080] Bluetooth: hci0: CYW43439 UART 26 MHz wlbga_BU Laird
[ 2930.420123] Bluetooth: hci0: BCM4343A2 (001.003.016) build 0000
[ 2930.587952] NET: Registered PF_ALG protocol family
[ 2930.606343] Bluetooth: RFCOMM TTY layer initialized
[ 2930.611282] Bluetooth: RFCOMM socket layer initialized
[ 2930.616521] Bluetooth: RFCOMM ver 1.11

root@imx8mpevk:~# bluetoothctl
Agent registered
[..CHG..] Controller C0:EE:40:B0:49:87 Pairable: yes
[bluetooth]# power on
[..CHG..] Controller C0:EE:40:B0:49:87 Class: 0x00200000
Changing power on succeeded
[..CHG..] Controller C0:EE:40:B0:49:87 Powered: yes
[bluetooth]# scan on
Discovery started
[..CHG..] Controller C0:EE:40:B0:49:87 Discovering: yes
[..NEW..] Device D7:DD:31:1F:D7:CF D7-DD-31-1F-D7-CF
[..NEW..] Device 7A:65:4F:4B:65:EF 7A-65-4F-4B-65-EF
[..NEW..] Device E7:A3:99:CE:06:A2 BL654 BME280 Sensor

Bluetooth troubleshooting

Use lower speed if having issues with btattach, due to the length of jumper wires a higher speed connection might not work or be reliable.

btattach -B /dev/ttymxc2 -P bcm -S 115200 &