LWB+ integration on imx6ullevk (lrd-11.x) LWB+ integration on imx6ull EVK (lrd-11.x) This tutorial shows how to integrate the Sterling-LWB+ on the NXP i.mx6ull EVK. The Sterling-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 is the physical setup including hardware modifications needed, the Yocto setup and build, and verifying the Wi-Fi and Bluetooth are functional. Note: This guide is for Ezurio backports version lrd-11.x and higher. For Ezurio code lrd-10.x or lower please see: https://lairdcp.github.io/guides/LWBp-tutorials/1.0/imx6ullevk-lwbplus.html Requirements Required items: imx6ullevk Sterling-LWB+ devkit - 453-00085-K1 3.3V power supply breadboard jumper wires arduino headers or breadboard pins Soldering iron Oscilloscope (Optional) Physical Setup Hardware setup imx6ullevk modifications Populate R1732 R1732 needs installed to enable UART2 CTS line. R1732 shorted together. Arduino headers For ease of use, we recommend you install Arduino headers to support breadboard jumper wires. Breadboard pins can also be used if Arduino headers are not available. It is easier to populate R1732 before installing Arduino headers due to the tight space. Compute Module breakout - NVCC_SD / SD VDD_IO The SDIO VDD I/O signal voltage needs to be broken out on the compute module and ran to VDD_IO of the LWB+. TP709 (NVCC_SD) broken out to breadboard pin with wire wrap. Breadboard jumper connections Below are the connections between the Sterling-LWB+ for UART and regulators for Wi-Fi and Bluetooth. Signal Signal Direction Target Board LWB+ Tx Host to LWB J1703-P2 J3-P10 Rx LWB to Host J1703-P1 J3-P8 RTS Host to LWB J1703-P4 J3-P6 CTS LWB to Host J1703-P3 J3-P14 GND J1704-P7 J3-16 BT_REG_ON Host to LWB J1704-P9 J3-13 WL_REG_ON Host to LWB J1704-P10 J3-11 VDDIO IMX to LWB NVCC_SD CM J4-2 The i.mx6ull EVK and Sterling-LWB+ fully connected together. Sterling-LWB+ setup Jumper J7 needs set to pins 2-3 (EXT) Jumper J4 needs removed and pin 2 ran to the Compute Module J5 needs connected to a 3.3V source Note on Sterling-LWB+ and SD adapter Cut and place to shape two layers of stickers on the Sterling-LWB+ and the adapter board that goes into the i.mx6ull EVK and the SD to SD card slot 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. Yocto setup and build Create project folders mkdir -p ~/projects/yocto-mickledore cd ~/projects/yocto-mickledore Download Yocto Mickledore release 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 Note: At the time of writing, version 6.1.22-2.0.0 is the latest Mickledore release. Please check https://github.com/nxp-imx/imx-manifest for the latest available version. Setup build config Create a build directory and set the DISTRO and MACHINE type. DISTRO=fsl-imx-fb MACHINE=imx6ullevk source imx-setup-release.sh -b build-imx6ullevk Resourcing environment If the terminal is closed the environment will need to be resourced. cd ~/projects/yocto-mickledore . setup-environment build-imx6ullevk Welcome to Freescale Community BSP The Yocto Project has extensive documentation about OE including a reference manual which can be found at: http://yoctoproject.org/documentation For more information about OpenEmbedded see their website: http://www.openembedded.org/ You can now run 'bitbake <target>' Common targets are: core-image-minimal meta-toolchain meta-toolchain-sdk adt-installer meta-ide-support Your configuration files at build-imx6ullevk/ have not been touched. #### Edit the file ~/projects/yocto-mickledore/build-imx6ullevk/conf/local.conf and add the following to the end of the file: MACHINE_FEATURES:remove = "nxp8987 nxp8997 iw612" MACHINE_FIRMWARE:remove = "linux-firmware-ath10k" PREFERRED_PROVIDER_wpa-supplicant = "summit-supplicant-lwb" PREFERRED_PROVIDER_wpa-supplicant-cli = "summit-supplicant-lwb" PREFERRED_PROVIDER_wpa-supplicant-passphrase = "summit-supplicant-lwb" 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. Edit bblayers.conf Edit your bblayer.conf file and add the following to the bottom. BBLAYERS += "${BSPDIR}/sources/meta-summit-radio/meta-summit-radio" Download Yocto meta-layer (meta-summit-radio) cd ~/project_directory/sources #clone the meta layer for yocto git clone [ -b <branch> ] https://github.com/LairdCP/meta-summit-radio Note: At the time this document was written version 11.39.0.x was the latest release of Ezurio Backports, so the command would have been git clone -b lrd-11.39.0.x https://github.com/LairdCP/meta-summit-radio. There may be a new version available. Please check https://github.com/LairdCP/meta-summit-radio for the latest image and update the branch info as needed. Copy sample image recipe Copy a sample image recipe and rename the recipe to something memorable. Here I’ve used my name, the product name, the product interface (sdio/uart or su), and the meta-summit-radio current release for the image recipe name. When Yocto builds the image it will add the platform name(imx6ullevk) to the filename. In the end the filename will be: bob-lwbp-su-lrd11-imx6ullevk-20220603211329.rootfs.wic.zst, providing information on who built it, what Wi-Fi module it’s for, the interface used, which driver release, platform, and date created. cd ~/project_directory/sources/meta-summit-radio/meta-summit-radio/recipes-packages/images #copy the bitbake recipe example cp sample-image-lwb5plus.bb bob-lwbp-imx6ull-lrd11.bb Edit sample image recipe Edit the recipe that you just created in the last step and confirm that the IMAGE_INSTALL section looks like the below: IMAGE_INSTALL += "\ iproute2 \ rng-tools \ ca-certificates \ tzdata \ alsa-utils \ htop \ ethtool \ iperf3 \ tcpdump \ iw \ bluez5 \ bluez5-noinst-tools \ bluez5-obex \ openobex \ obexftp \ packagegroup-core-buildessential \ gattlib \ packagegroup-tools-bluetooth \ kernel-module-lwb-backports-summit \ lwbplus-firmware \ summit-supplicant-lwb \ summit-networkmanager-lwb \ summit-networkmanager-lwb-nmcli \ libgpiod \ libgpiod-tools \ hostapd \ " Configure the kernel cd ~/projects/yocto-mickledore/build-imx6ullevk bitbake -c menuconfig virtual/kernel Backports will replace the wireless and Bluetooth stack. The CONFIG_FW_LOADER_USER_HELPER_FALLBACK needs removed to allow for faster loading of the firmware at boot. Make the following modifications: In the menuconfig use / to search for each of the below configuration parameters in all caps. WLAN - deselect Device Drivers -> Network device support -> Wireless LAN 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 Device Drivers -> DMA Engine support -> i.MX SDMA support CONFIG_BT - deselect Networking support -> Bluetooth subsystem support CFG80211 - set to module (M) Networking support -> Wireless -> cfg80211 - wireless configuration API Save your changes and exit menuconfig. Modify devicetree The devicetree needs modified to enable the outputs for the WL_REG and BT_REG. Below is a diff that shows the difference between the imx6ul-14x14-evk.dtsi and the modified imx6ul-14x14-evk.dtsi.lwbplus. A bluetooth regulator is created, wifi mmc-pwrseq is created and tied to the usdhc1, and regulator outputs are setup on gpio1 30 and 31. For reference: Original dtsi Modified dtsi for LWB+ cd ~/projects/yocto-mickledore/build-imx6ullevk/tmp/work-shared/imx6ullevk/kernel-source/arch/arm/boot/dts --- imx6ul-14x14-evk.dtsi 2022-06-06 09:57:31.208840447 -0400 +++ imx6ul-14x14-evk.dtsi.lwbplus 2022-06-06 09:57:31.208840447 -0400 @@ -78,6 +78,25 @@ gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>; }; + reg_bt: regulator-bt { + compatible = "regulator-fixed"; + regulator-name = "bt"; + gpio = <&gpio1 31 GPIO_ACTIVE_HIGH>; + startup-delay-us = <100>; + enable-active-high; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + regulator-name = "wifi-pwrseq"; + pinctrl-names = "default"; + reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <250>; + }; + sound-wm8960 { compatible = "fsl,imx-audio-wm8960"; model = "wm8960-audio"; @@ -155,6 +174,7 @@ wlf,gpio-cfg = <1 3>; clocks = <&clks IMX6UL_CLK_SAI2>; clock-names = "mclk"; + status = "disabled"; }; ov5640: ov5640@3c { @@ -424,6 +444,7 @@ keep-power-in-suspend; wakeup-source; vmmc-supply = <®_sd1_vmmc>; + mmc-pwrseq = <&wifi_pwrseq>; status = "okay"; }; @@ -518,9 +539,11 @@ pinctrl_i2c2: i2c2grp { fsl,pins = < - MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 + MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x00003031 + MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x00003031 + /* MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0 - >; + */ >; }; pinctrl_lcdif_dat: lcdifdatgrp { Find sample image Search for the image name and ensure bitbake can see it. bitbake -s | grep bob- $ bitbake -s | grep bob- bob-lwbp-imx6ull-lrd11 :1.0-r0 Build image Depending on the CPU, hard drive, and internet connection this can take a while to run. We recommend running the build overnight if a slower PC is used. bitbake bob-lwbp-imx6ull-lrd11 flashing image to micro sd card The SD flashing program used is Balena Etcher a cross platform flashing tool to put the wic.bz2 image onto a micro SD card. https://www.balena.io/etcher/ Use BalenaEtcher to flash the image file ending in wic.bz2. The file location will be in ~/projects/yocto-hardknott/build-imx6ullevk/tmp/deploy/images/imx6ullevk/. $ cd ~/projects/yocto-mickledore/build-imx6ullevk/tmp/deploy/images/imx6ullevk/ $ ls -alh *wic.bz2 -rw-r--r-- 2 travis travis 102M Jun 3 14:02 tal-lwbp-su-lrd10-imx6ullevk-20220603180047.rootfs.wic.bz2 lrwxrwxrwx 2 travis travis 58 Jun 3 14:03 tal-lwbp-su-lrd10-imx6ullevk.wic.bz2 -> tal-lwbp-su-lrd10-imx6ullevk-20220603180047.rootfs.wic.bz2 Bring up and verification Install micro SD card Install the micro on the Compute Module. Connect to console Use a terminal program to connect to the serial console over the USB cable. Example terminal programs: PuTTY TeraTerm Minicom Check dmesg During or after boot, check dmesg for driver and firmware loading. Shown below: mmc-pwrseq is set backports loaded firmware downloaded regulatory domain set to “US” dmesg | egrep 'brcm|backport|mmc' root@imx6ullevk:~# dmesg | egrep 'brcm|backport|mmc' [ 0.000000] Kernel command line: console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw [ 2.001389] sdhci-esdhc-imx 2190000.mmc: Got CD GPIO [ 2.014565] sdhci-esdhc-imx 2190000.mmc: allocated mmc-pwrseq [ 2.046189] mmc1: SDHCI controller on 2194000.mmc [2194000.mmc] using ADMA [ 2.105702] mmc1: host does not support reading read-only switch, assuming write-enable [ 2.117507] mmc1: new high speed SDHC card at address aaaa [ 2.127493] mmcblk1: mmc1:aaaa SD32G 29.7 GiB [ 2.156353] mmcblk1: p1 p2 [ 2.340476] mmc0: SDHCI controller on 2190000.mmc [2190000.mmc] using ADMA [ 2.530806] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none. [ 2.589314] mmc0: new high speed SDIO card at address 0001 [ 5.839291] EXT4-fs (mmcblk1p2): re-mounted. Opts: (null). Quota mode: none. [ 11.619149] brcmutil: loading out-of-tree module taints kernel. [ 11.625521] brcmutil: loading out-of-tree module taints kernel. [ 11.699262] Loading modules backported from Summit Linux version LRD-REL-10.4.0.10-0-gf2716e8912e5 [ 11.833986] Backport generated by backports.git v10.4.0.10 [ 12.320038] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43439-sdio for chip BCM43439/5 [ 12.415309] brcmfmac mmc0:0001:1: Direct firmware load for brcm/brcmfmac43439-sdio.fsl,imx6ull-14x14-evk.bin failed with error -2 [ 12.542549] brcmfmac: brcmf_fw_request_firmware: no board-specific nvram available (ret=-2), device will use brcm/brcmfmac43439-sdio.t [ 12.816273] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43439-sdio for chip BCM43439/5 [ 12.908703] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43439/5 wl0: Oct 6 2021 04:40:45 version 7.95.48 (9e85f5c CY) FWID 01-e3ef7 [ 13.086190] brcmfmac: brcmf_cfg80211_attach: Using regulatory domain US root@imx6ullevk:~# Testing Wi-Fi Check iw to see that phy is up and running. iw dev root@imx6ullevk:~# iw dev phy#0 Unnamed/non-netdev interface wdev 0x2 addr c2:ee:40:b0:49:86 type P2P-device txpower 31.00 dBm Interface wlan0 ifindex 7 wdev 0x1 addr c0:ee:40:b0:49:86 type managed channel 1 (2412 MHz), width: 20 MHz, center1: 2412 MHz txpower 31.00 dBm root@imx6ullevk:~# Add network connection in NetworkManager nmcli con add con-name "test" ifname wlan0 type wifi ssid "test" wifi-sec.key-mgmt wpa-psk wifi-sec.psk "password1" Connect to “test” network listed in NetworkManager nmcli c u "test" Connection information using: iw wlan0 station dump root@imx8mpevk:~# iw wlan0 station dump root@imx6ullevk:~# iw wlan0 station dump Station 94:83:c4:01:6f:d8 (on wlan0) inactive time: 0 ms rx bytes: 2651 rx packets: 16 tx bytes: 5338 tx packets: 36 tx failed: 0 signal: -45 dBm tx bitrate: 65.0 MBit/s rx bitrate: 58.5 MBit/s authorized: yes authenticated: yes associated: yes WMM/WME: yes TDLS peer: no DTIM period: 2 beacon interval:100 short preamble: yes short slot time:yes connected time: 21 seconds current time: 956491579 ms Ping test ping 8.8.8.8 root@imx6ullevk:~# ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 64 bytes from 8.8.8.8: seq=0 ttl=55 time=32.981 ms 64 bytes from 8.8.8.8: seq=1 ttl=55 time=29.779 ms 64 bytes from 8.8.8.8: seq=2 ttl=55 time=33.251 ms 64 bytes from 8.8.8.8: seq=3 ttl=55 time=33.208 ms ^C --- 8.8.8.8 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 29.779/32.304/33.251 ms root@imx6ullevk:~# iperf3 results For this test to work, you must set up an iperf3 server on the connected network. Start an iperf3 server with the commands ‘iperf3 -s’. iperf3 -c 10.0.0.2 iperf3 -c 10.0.0.2 -R root@imx6ullevk:~# iperf3 -c 10.0.0.2 Connecting to host 10.0.0.2, port 5201 [ 5] local 10.0.0.37 port 59068 connected to 10.0.0.2 port 5201 [ ID] Interval Transfer Bitrate Retr Cwnd [ 5] 0.00-1.00 sec 4.94 MBytes 41.4 Mbits/sec 0 201 KBytes [ 5] 1.00-2.00 sec 4.47 MBytes 37.5 Mbits/sec 0 201 KBytes [ 5] 2.00-3.00 sec 4.54 MBytes 38.1 Mbits/sec 0 228 KBytes [ 5] 3.00-4.00 sec 4.47 MBytes 37.5 Mbits/sec 0 240 KBytes [ 5] 4.00-5.00 sec 4.47 MBytes 37.5 Mbits/sec 0 240 KBytes [ 5] 5.00-6.00 sec 4.41 MBytes 37.0 Mbits/sec 0 240 KBytes [ 5] 6.00-7.00 sec 4.35 MBytes 36.5 Mbits/sec 0 240 KBytes [ 5] 7.00-8.00 sec 4.35 MBytes 36.5 Mbits/sec 0 240 KBytes [ 5] 8.00-9.00 sec 4.35 MBytes 36.5 Mbits/sec 0 240 KBytes [ 5] 9.00-10.00 sec 4.35 MBytes 36.5 Mbits/sec 0 240 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-10.00 sec 44.7 MBytes 37.5 Mbits/sec 0 sender [ 5] 0.00-10.00 sec 44.1 MBytes 37.0 Mbits/sec receiver iperf Done. root@imx6ullevk:~# 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 59072 connected to 10.0.0.2 port 5201 [ ID] Interval Transfer Bitrate [ 5] 0.00-1.00 sec 4.93 MBytes 41.4 Mbits/sec [ 5] 1.00-2.00 sec 4.84 MBytes 40.6 Mbits/sec [ 5] 2.00-3.00 sec 4.93 MBytes 41.4 Mbits/sec [ 5] 3.00-4.00 sec 4.72 MBytes 39.6 Mbits/sec [ 5] 4.00-5.00 sec 5.01 MBytes 42.0 Mbits/sec [ 5] 5.00-6.00 sec 5.20 MBytes 43.6 Mbits/sec [ 5] 6.00-7.00 sec 5.03 MBytes 42.2 Mbits/sec [ 5] 7.00-8.00 sec 4.78 MBytes 40.1 Mbits/sec [ 5] 8.00-9.00 sec 5.04 MBytes 42.3 Mbits/sec [ 5] 9.00-10.00 sec 4.95 MBytes 41.5 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-10.00 sec 51.7 MBytes 43.3 Mbits/sec 0 sender [ 5] 0.00-10.00 sec 49.4 MBytes 41.5 Mbits/sec receiver iperf Done. Testing Bluetooth Bluetooth attach to bluez btattach -B /dev/ttymxc1 -P bcm -S 3000000 & root@imx6ullevk:~# btattach -B /dev/ttymxc1 -P bcm -S 3000000 & [1] 202 Attaching Primary controller to /dev/ttymxc1 root@imx6ullevk:~# [ 26.651179] Bluetooth: HCI UART driver ver 2.3 [ 26.655659] Bluetooth: HCI UART protocol H4 registered [ 26.698247] Bluetooth: HCI UART protocol Broadcom registered Switched line discipline from 0 to 15 Device index 0 attached [ 26.852244] Bluetooth: hci0: BCM: chip id 147 [ 26.859832] Bluetooth: hci0: BCM: features 0x0e [ 26.887365] Bluetooth: hci0: CYW4343A2 [ 26.891259] Bluetooth: hci0: BCM4343A2 (001.003.016) build 0000 [ 26.906070] Bluetooth: hci0: BCM4343A2 'brcm/BCM4343A2.hcd' Patch [ 27.823484] Bluetooth: hci0: CYW43439 UART 26 MHz wlbga_BU Laird [ 27.829719] Bluetooth: hci0: BCM4343A2 (001.003.016) build 0000 [ 27.998565] NET: Registered protocol family 38 [ 28.088258] Bluetooth: RFCOMM TTY layer initialized [ 28.093194] Bluetooth: RFCOMM socket layer initialized [ 28.100936] Bluetooth: RFCOMM ver 1.11 Bluetooth scan bluetoothctl root@imx6ullevk:~# bluetoothctl Agent registered [CHG] Controller C0:EE:40:B0:03:9D Pairable: yes [bluetooth]# power on [CHG] Controller C0:EE:40:B0:03:9D Class: 0x00200000 Changing power on succeeded [CHG] Controller C0:EE:40:B0:03:9D Powered: yes [bluetooth]# scan on Discovery started [CHG] Controller C0:EE:40:B0:03:9D Discovering: yes [NEW] Device E7:A3:99:CE:06:A2 BL654 BME280 Sensor [bluetooth]#