Overview
This document provides step-by-step procedures to build and test coex examples, and also instructions for running the included sample applications.
Hardware requirements
Micro USB cable
evkcmimxrt1060 board
Personal Computer
One of the following modules:
Embedded Artists 2LL M.2 Module (EAR00500) - direct M2 connection
Embedded Artists 2EL M.2 Module(Rev-A1) - direct M2 connection
Board settings
Before building the example application define Wi-Fi module in the _boards/evkcmimxrt1060/coex_examples/coex_wifi_edgefast/prj.conf
.
If you want to use Embedded Artists 2LL M.2 Module(EAR00500), please set CONFIG_MCUX_COMPONENT_component.wifi_bt_module.board_murata_2ll_m2 to y.
CONFIG_MCUX_COMPONENT_component.wifi_bt_module.IW61X=y
CONFIG_MCUX_COMPONENT_component.wifi_bt_module.board_murata_2ll_m2=y
If you want to use Embedded Artists 2EL M.2 Module(Rev-A1), please set CONFIG_MCUX_COMPONENT_component.wifi_bt_module.board_murata_2el_m2 to y.
CONFIG_MCUX_COMPONENT_component.wifi_bt_module.IW61X=y
CONFIG_MCUX_COMPONENT_component.wifi_bt_module.board_murata_2el_m2=y
Jumper settings for RT1060-EVKC (enables external 5V supply):
remove J40 5-6 connect J40 1-2 connect J45 with external power(controlled by SW6)
Murata Solution Board settings
Embedded Artists 2LL module datasheet: https://www.embeddedartists.com/wp-content/uploads/2024/12/2LL_M2_Datasheet.pdf Embedded Artists 2EL module datasheet: https://www.embeddedartists.com/doc/ds/2EL_M2_Datasheet.pdf
The hardware should be reworked according to the hardware rework guide for evkcmimxrt1060 and Murata 1XK/1ZM/2EL/2LL M.2 Adapter in document Hardware Rework Guide for EdgeFast BT PAL.
NOTE:
To ensure that the LITTLEFS flash region has been cleaned, all flash sectors need to be erased before downloading example code.
After downloaded binary into qspiflash and boot from qspiflash directly, please reset the board by pressing SW7 or power off and on the board to run the application.
Nighthwak and Firecrest BT UART Rework (LPUART3)
Mount R93, R96
Remove R193
Connect J109, J76 2-3
WiFi and BLE use LPUART.
Build and flash
Prerequisites:
CMake (version >=3.24)
Ninja (version >=1.12)
ARM GCC Toolchain (only support ARM GCC)
Python3 (version >=3.6)
NOTE: Make sure that the paths of all these tools are set into the path system variable.
2. Building
Modify examples/coex_examples/coex_wifi_edgefast/app_config.cmake
to generate different coexistence images.
coexistence images |
CONFIG_WIFI |
CONFIG_BLE |
Simulation Case |
---|---|---|---|
WiFi + BLE |
1 |
1 |
Matter over WiFi |
Macors releated to Wi-Fi supplicant,
Wi-Fi supplicant |
CONFIG_WPA_SUPPLICANT |
---|---|
embedded supplicant |
0 |
wpa supplicant |
1(default) |
NOTE: 2EL_M2 only supports embedded supplicant and WPA supplicant.
Building coex examples with CMake
flexspi_nor_debug:
$ cd <sdk root>
$ west build -b evkcmimxrt1060 examples/coex_examples/coex_wifi_edgefast --toolchain armgcc --config flexspi_nor_debug -d coex_wifi_edgefast
flexspi_nor_release:
$ cd <sdk root>
$ west build -b evkcmimxrt1060 examples/coex_examples/coex_wifi_edgefast --toolchain armgcc --config flexspi_nor_release -d coex_wifi_edgefast
NOTE:
-d coex_wifi_edgefast
-> Specify the generated project path. Can name it as needed.Find coex_wifi_edgefast.elf/coex_wifi_edgefast.bin in coex_wifi_edgefast folder.
Only support armgcc to build coex application.
4. Flash Binaries
Flash the image with the following command,
# CMD to write CPU3 coex app image to flash in J-link window:
J-Link> loadbin C:\xxx\coex_wifi_edgefast.bin, 0x60000000
Run
Prepare the Demo
Connect a micro USB cable between the PC host and the MCU-Link USB port (J7) on the board.
Open a serial terminal with the following settings:
115200 baud rate
8 data bits
No parity
One stop bit
No flow control
Download the program to the target board.
Launch the debugger in your IDE to begin running the example.
Running the example
The log below shows the output of the coex examples (based on edgefast-shell) in the terminal window:
SHELL build: Coex APP
========================================
========================================
Initialize Nighthwak-2LL (IW610) M2 Module
========================================
Feb 24 2025
Copyright 2020 NXP
========================================
WiFi shell initialization
========================================
BLE shell initialization
@bt> ========================================
@Coex>
WiFi Test
NOTE: All wifi commands require adding
wifi.
prefix.
Get the Wi-Fi driver and firmware version:
@Coex> wifi.wlan-version
WLAN Driver Version : v1.3.r48.p32
@Coex> WLAN Firmware Version : iw610w-V0, SDIO, FP99, 18.99.5.p51, PVE_FIX 1
Command wlan-version
Get MAC Address:
@Coex> wifi.wlan-mac
MAC address
@Coex> STA MAC Address: 00:50:43:02:98:23
uAP MAC Address: 00:50:43:02:99:23
Command wlan-mac
Scan the network:
@Coex> wifi.wlan-scan
Scan scheduled...
@Coex> Command wlan-scan
2 networks found:
1C:6A:7A:87:FF:BF "NXP" Infra
mode: 802.11AC
channel: 161
rssi: -74 dBm
security: WPA2 Enterprise
WMM: YES
802.11K: YES
802.11V: YES
802.11W: NA
WPS: NO
1C:6A:7A:87:FF:BE "NXPOPEN" Infra
mode: 802.11AC
channel: 161
rssi: -75 dBm
security: WPA2
WMM: YES
802.11K: YES
802.11V: YES
802.11W: NA
WPS: NO
BLE Test
NOTE: Please use the command “help” to view the specific commands supported by the example.
BLE scan devices (the BLE host must initialized before):
@Coex> bt.init
@Coex> Bluetooth initialized
Settings Loaded
@Coex> bt.scan on
Bluetooth active scan enabled
@Coex> [DEVICE]: 44:6D:F5:85:DC:5F (random), AD evt type 0, RSSI -64 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 44:6D:F5:85:DC:5F (random), AD evt type 4, RSSI -63 C:0 S:1 D:0 SR:1 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 6D:B3:D3:8E:ED:A2 (random), AD evt type 0, RSSI -77 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 6D:B3:D3:8E:ED:A2 (random), AD evt type 4, RSSI -76 C:0 S:1 D:0 SR:1 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 3F:FB:95:F7:F9:14 (random), AD evt type 3, RSSI -75 C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 49:A3:4E:86:63:0C (random), AD evt type 0, RSSI -76 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 49:A3:4E:86:63:0C (random), AD evt type 4, RSSI -75 C:0 S:1 D:0 SR:1 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 5C:28:50:F9:DD:57 (random), AD evt type 0, RSSI -82 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 4A:7D:B4:12:7B:7A (random), AD evt type 0, RSSI -82 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 4A:7D:B4:12:7B:7A (random), AD evt type 4, RSSI -82 C:0 S:1 D:0 SR:1 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 5A:54:C8:99:13:4A (random), AD evt type 0, RSSI -76 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 3B:95:00:4D:F3:EB (random), AD evt type 3, RSSI -82 C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 47:9D:D0:CB:5F:0D (random), AD evt type 0, RSSI -86 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
@Coex> bt.scan off
Scan successfully stopped
@Coex>
BLE advertise (the BLE host must initialized before):
@Coex> bt.init
@Coex> Bluetooth initialized
@Coex> bt.advertise on
Advertising started
@Coex> bt.advertise off
Advertising stopped
BLE connect (the BLE host must initialized before):
@Coex> bt.init
@Coex> Bluetooth initialized
@Coex> bt.connect C0:95:63:23:55:87 random
Connection pending
Connected: 7D:FD:FD:4D:FD:90 (random)
BLE pairing and bonding:
GATT peripheral role side,
1. Initialize the Host, press "bt.init",
2. Advertising, press "bt.advertise on",
3. After the connection is established, perform the pairing sequence,
it could be started from peripheral side by pressing "bt.security <level>", such as "bt.security 2".
4. If the bondable is unsupported by peripheral role, press "bt.bondable off". Then start step 3.
GATT central role side,
1. Initialize the Host, press "bt.init",
2. Scaning advertising packets, press "bt.scan on",
3. A few seconds later, stop the scanning, press "bt.scan off"
4. Select the target board and create a new connection. If the taregt is not listed, repeat steps 2 and 3.
Then press "bt.connect <address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"
5. After the connection is established, perform the pairing sequence,
it could be started from central side by pressing "bt.security <level>", such as "bt.security 2".
6. If the bondable is unsupported by central role, press "bt.bondable off". Then start step 5.
BLE 1M/2M/Coded PHY update:
GATT peripheral role side,
1. Initialize the Host, press "bt.init",
2. Advertising, press "bt.advertise on",
3. After the connection is established.
4. Send phy update command, press "bt.phy-update <tx_phy> [rx_phy] [s2] [s8]", tx_phy/rx_phy could be 1(1M) or 2(2M) or 4(Coded).
such as "bt.phy-update 2 2".
5. The message "LE PHY updated: TX PHY LE 2M, RX PHY LE 2M" would be printed if the phy is updated. note, if peer do not support phy update, then this message will not be printed.
GATT central role side,
1. Initialize the Host, press "bt.init",
2. start scan, press "bt.scan on", Bluetooth device around your current bluetooth will be list, for example,
[DEVICE]: 72:78:C1:B5:0F:DA (random), AD evt type 4, RSSI -32 BLE Peripheral C:0 S:1 D:0 SR:1 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: C4:0D:02:55:5E:AD (random), AD evt type 0, RSSI -83 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
[DEVICE]: 66:8F:26:27:1F:52 (random), AD evt type 0, RSSI -82 C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
3. stop scan, press "bt.scan off",
4. connect target device, press "bt.connect <address: XX:XX:XX:XX:XX:XX> <type: (public|random)>", such as bt.connect 72:78:C1:B5:0F:DA random
5. Send phy update command, press "bt.phy-update <tx_phy> [rx_phy] [s2] [s8]", tx_phy/rx_phy could be 1(1M) or 2(2M) or 4(Coded).
such as "bt.phy-update 2 2".
6. The message "LE PHY updated: TX PHY LE 2M, RX PHY LE 2M" would be printed if the phy is updated. note, if peer do not support phy update, then this message will not be printed.
BLE Data Packet Length Extension update:
GATT peripheral role side,
1. Initialize the Host, press "bt.init".
2. Advertising, press "bt.advertise on".
3. After the connection is established.
4. Check current LE RX/TX maximum data length and time, press "bt.info", as blow, default RX/TX maximum data length is 27 and default RX/TX maxumum time is 328.
Type: LE, Role: slave, Id: 0
59:8F:3C:20:93:86 (random)
Remote address: 59:8F:3C:20:93:86 (random) (resolvable)
Local address: 80:D2:1D:E8:30:EC (public) (identity)
Remote on-air address: 59:8F:3C:20:93:86 (random) (resolvable)
Local on-air address: 7C:59:48:2E:A4:51 (random) (resolvable)
Interval: 0x0024 (45 ms)
Latency: 0x0000 (0 ms)
Supervision timeout: 0x0190 (4000 ms)
LE PHY: TX PHY LE 1M, RX PHY LE 1M
LE data len: TX (len: 27 time: 328) RX (len: 27 time: 328)
5. When LE data len is updated by the peer device, below information will be printed.
LE data len updated: TX (len: 27 time: 328) RX (len: 50 time: 512)
6. Update maximum tx data length, press "bt.data-len-update <tx_max_len> [tx_max_time]", such as bt.data-len-update 65, below information will be printed.
Calculated tx time: 632
59:8F:3C:20:93:86 (random)
data len update initiated.
LE data len updated: TX (len: 65 time: 632) RX (len: 50 time: 512)
GATT central role side,
1. Initialize the Host, press "bt.init".
2. Start scan, press "bt.scan on", Bluetooth device around your current bluetooth will be list, for example,
[DEVICE]: 7C:59:48:2E:A4:51 (random), AD evt type 4, RSSI -44 BLE Peripheral C:0 S:1 D:0 SR:1 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 ms), SID: 0xff
3. Stop scan, press "bt.scan off",
4. Connect target device, press "bt.connect <address: XX:XX:XX:XX:XX:XX> <type: (public|random)>", such as bt.connect 7C:59:48:2E:A4:51 random
5. Check current LE RX/TX maximum data length and time, press "bt.info", as blow, default RX/TX maximum data length is 27 and default RX/TX maxumum time is 328.
Type: LE, Role: master, Id: 0
7C:59:48:2E:A4:51 (random)
Remote address: 7C:59:48:2E:A4:51 (random) (resolvable)
Local address: C0:95:DA:00:BC:82 (public) (identity)
Remote on-air address: 7C:59:48:2E:A4:51 (random) (resolvable)
Local on-air address: 59:8F:3C:20:93:86 (random) (resolvable)
Interval: 0x0024 (45 ms)
Latency: 0x0000 (0 ms)
Supervision timeout: 0x0190 (4000 ms)
LE PHY: TX PHY LE 1M, RX PHY LE 1M
LE data len: TX (len: 27 time: 328) RX (len: 27 time: 328)
6. Update maximum tx data length, press "bt.data-len-update <tx_max_len> [tx_max_time]", such as bt.data-len-update 50, below information will be printed.
Calculated tx time: 512
7C:59:48:2E:A4:51 (random)
data len update initiated.
LE data len updated: TX (len: 50 time: 512) RX (len: 27 time: 328)
7. When LE data len is updated by the peer device, below information will be printed.
LE data len updated: TX (len: 50 time: 512) RX (len: 65 time: 632)
BLE GATT data signing:
GATT peripheral role side,
1. Initialize the Host, press "bt.init",
2. Advertising, press "bt.advertise on",
3. After the connection is established, perform the pairing sequence,
it could be started from peripheral side by pressing "bt.security <level>", such as "bt.security 2",
4. After the authentication is successfully, disconnect the connection,
it could be started from peripheral side by pressing "bt.disconnect",
5. Waiting for new connection. After the connection is established (LL enceyption should be disabled),
add new serivce "gatt.register".
GATT central role side,
1. Initialize the Host, press "bt.init",
2. Scaning advertising packets, press "bt.scan on",
3. A few seconds later, stop the scanning, press "bt.scan off"
4. Select the target board and create a new connection. If the taregt is not listed, repeat steps 2 and 3.
Then press "bt.connect <address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"
5. After the connection is established, perform the pairing sequence,
it could be started from central side by pressing "bt.security <level>", such as "bt.security 2",
6. After the authentication is successfully, disconnect the connection,
it could be started from central side by pressing "bt.disconnect",
7. Repeat the steps 2 and 3. After the connection is established (LL enceyption should be disabled),
perform the GATT data signing sequence, press "gatt.signed-write <handle> <data> [length] [repeat]",
such as "gatt.signed-write 22 AA 1"
BLE GATT Service Changed Indication:
GATT peripheral role side,
1. Initialize the Host, press "bt.init",
2. Advertising, press "bt.advertise on",
3. After the connection is established. and waiting for the service changed indication is subsribed,
4. Add new serivce, press "gatt.register",
5. Remove the added serivce, press "gatt.unregister".
GATT central role side,
1. Initialize the Host, press "bt.init",
2. Scaning advertising packets, press "bt.scan on",
3. A few seconds later, stop the scanning, press "bt.scan off"
4. Select the target board and create a new connection. If the taregt is not listed, repeat steps 2 and 3.
Then press "bt.connect <address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"
5. After the connection is established, subscribe the GATT service changed indicator. press "bt.subscribe <CCC handle> <value handle> [ind]",
such as "gatt.subscribe f e ind".
Running a2dp:
The commands are as follow:
+---"a2dp": a2dp Bluetooth A2DP shell commands
+---"register_sink_ep": register_sink_ep <select codec.
1:SBC
2:MPEG-1,2
3:MPEG-2,4
4:vendor
5:sbc with delay report and content protection services
6:sbc with all other services(don't support data transfer yet)>
+---"register_source_ep": register_source_ep <select codec.
1:SBC
2:MPEG-1,2
3:MPEG-2,4
4:vendor
5:sbc with delay report and content protection services
6:sbc with all other services(don't support data transfer yet)>
+---"connect": connect [none]
+---"disconnect": disconnect [none]
+---"configure": configure [none]
+---"discover_peer_eps": discover_peer_eps [none]
+---"get_registered_eps": get_registered_eps [none]
+---"set_default_ep": set_default_ep <select endpoint>
+---"configure_ep": configure_ep "configure the default selected ep"
+---"deconfigure": deconfigure "de-configure the default selected ep"
+---"start": start "start the default selected ep"
+---"stop": stop "stop the default selected ep"
+---"send_media": send_media <second> "send media data to the default selected ep"
Test flow:
Create ACL connection between two devices (A and B).
In device B, input “a2dp.register_sink_ep x” to initialize sink endpoint.
In device A, input “a2dp.register_source_ep x” to initialize source endpoint.
In device A, input “a2dp.connect” to create a2dp connection with the default ACL connection.
In device A, input “a2dp.configure” to configure the a2dp connection.
In device A, input “a2dp.start” to start the a2dp media.
In device A, input “a2dp.send_media x” to send media data for x seconds.
For other commands:
“a2dp.disconnect” is used to disconnect the a2dp.
“a2dp.discover_peer_eps” is used to discover peer device’s endpoints.
“a2dp.get_registered_eps” is used to get the local registered endpoints.
“a2dp.set_default_ep” is used to set the default selected endpoint.
“a2dp.deconfigure” de-configure the endpoint, then it can be configured again.
“a2dp.stop” stops media.
“a2dp.send_delay_report” send delay report.
br discovery:
@Coex> br.discovery on
Discovery started
@Coex> BR/EDR discovery complete
[DEVICE]: BC:7E:8B:E6:53:E1, RSSI -73 [TV] Samsung BET Series (55)
[DEVICE]: 04:21:44:03:57:9F, RSSI -24 SRS-XB12
[DEVICE]: 48:74:12:3F:9E:04, RSSI -81 OnePlus Nord CE 2
[DEVICE]: C0:95:DA:00:D1:3D, RSSI -75 edgefast_hfp
To connect:
Coex> br.connect 04:21:44:03:57:9F
Connection pending
@Coex> BR Connected: 04:21:44:03:57:9F
To initialize source endpoint:
@Coex> a2dp.register_source_ep 1
SBC source endpoint is registered
To create a2dp connection with the default ACL connection:
@Coex> a2dp.connect
@Coex> Security changed: 04:21:44:03:57:9F level 2
a2dp connected
To configure the a2dp connection:
@Coex> a2dp.configure
@Coex> configure success
the default ep is set as the configured ep
To start the a2dp media:
@Coex> a2dp.start
@Coex> a2dp start playing
To send media data for 20 seconds:
@Coex> a2dp.send_media 20
@Coex>