Creating Bluetooth dongle using Zephyr
- 6 minutes read - 1169 wordsOverview
The Zephyr RTOS includes support for Bluetooth controller and the lower-layer HCI interface. This allows building a Bluetooth dongle using the Nordic nRF52 dongle and the connecting to any machines as a standard Bluetooth HCI dongle.
Zephyr requirements
The quickest path to setup a Zehyr environment is to follow the Getting Started Guide.
When it comes to Linux, I am defaulting to Fedora Linux and my installation of a Fedora 38 has all required development components already installed. The guide requires minimal versions of CMake, Python and Devicetree compiler and all of them are already met.
$ cmake --version
cmake version 3.27.6
$ python3 --version
Python 3.11.5
$ dtc --version
Version: DTC 1.7.0
Installing Zephyr
To get started we create a directory where all Zephyr work will happen.
Following the guide that is zephyrproject
directory in your home.
$ mkdir ~/zephyrproject
The guide suggest using Python virtual environments and that seems reasonable to avoid any weird interactions with other projects utilizing Python.
With Fedora 38 there is no need to install anything special since the feature is already installed and available. So it is just required to setup the environment.
$ python -m venv ~/zephyrproject/.venv
Now the new environment needs to be activated.
$ source ~/zephyrproject/.venv/bin/activate
Every time you start a new shell, the environment needs to be activated
again. You see an activated environment with a prefixed (.venv)
prompt.
Next step is to install the Zephyr specific management tool west
.
(.venv) $ pip install west
And then get the Zephyr source code.
(.venv) $ west init ~/zephyrproject
(.venv) $ cd ~/zephyrproject
(.venv) $ west update
And export Zephyr CMake package required for building Zephyr applications.
(.venv) $ west zephyr-export
And install all additional Python dependencies.
(.venv) $ pip install -r ~/zephyrproject/zephyr/scripts/requirements.txt
Due to some outdated Python YAML support a manual upgrade is needed.
(.venv) $ pip install --upgrade PyYaml
And now deactivate the environment before installing the SDK.
(.venv) $ deactivate
Installing Zephyr SDK
The Zephyr SDK contains 18 different tool chains and unless you are planning to build for multiple targets this is a bit of excessive overhead that is installed. Since the target is a nRF52 dongle with an ARM chip, lets focus on just the ARM toolchain and host tools.
The latest release is the Zehyr SDK 0.16.3 and provides a minimal install.
$ cd ~
$ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.3/zephyr-sdk-0.16.3_linux-x86_64_minimal.tar.xz
Upack the archive.
$ tar xvf zephyr-sdk-0.16.3_linux-x86_64_minimal.tar.xz
After unpacking the directory $HOME/zephyr-sdk-0.16.3
will be created and
it is required to run that its setup.sh
script to install the toolchain,
the host tools and the cmake integration.
$ cd zephyr-sdk-0.16.3
$ ./setup.sh -t arm-zephyr-eabi
$ ./setup.sh -h
$ ./setup.sh -c
Installing nrfutil tool
For flashing and programming the nRF52 dongle, the nRF Util from Nordic is required. For some reason it has become this magic everything and the kitchen sink utility that requires a manual installation.
The Nordic DevZone has tons of details about the tool.
Nordic wants you to follow their download popup from the tools website, but the following link should work as well.
$ cd ~
$ wget wget https://developer.nordicsemi.com/.pc-tools/nrfutil/x64-linux/nrfutil
The download is the nrfutil
executable and not any kind of package and
thus it needs to be make executable and then best moved into $HOME/bin
to have it in the search path.
$ chmod 755 nrfutil
$ mkdir -p ~/bin
$ mv nrfutil ~/bin
The tool has packages that need to be installed first. A list of available packages can be looked up.
$ nrfutil search
Command Installed Latest Status
ble-sniffer 0.9.1 Not installed
completion 1.3.0 Not installed
device 1.4.5 Not installed
nrf5sdk-tools 1.0.1 Not installed
toolchain-manager 0.14.0 Not installed
trace 2.1.0 Not installed
Found 6 installable command(s)
The package nrf5sdk-tools
is required to be installed.
$ nrfutil install nrf5sdk-tools
$ nrfutil list
Command Version Description
nrf5sdk-tools 1.0.1 nRF5 SDK tools that were available in nRF Util 6
dfu
keys
pkg
settings
zigbee
Found 1 installed command(s)
Building the controller firmware
First activate the environment.
$ source ~/zephyrproject/.venv/bin/activate
Now change to the Zephyr directory and build the firmware.
(.venv) $ cd ~/zephyrproject/zephyr
(.venv) $ west build -p always -b nrf52840dongle_nrf52840 samples/bluetooth/hci_usb
Using west flash
doesn’t work at the moment and thus manual steps are
required to flash the new firmware into the controller.
Flashing firmware into the controller
The nRF52840 Dongle board page describes all the details about the dongle and how to flash it.
For flashing it is required to press RESET button
on the board and then
call nrfutil
to flash the firmware.
First the new firmware needs to be packaged.
(.venv) $ nrfutil pkg generate --hw-version 52 --sd-req=0x00 --application build/zephyr/zephyr.hex --application-version 1 hci_usb.zip
And then flash the firmware using /dev/ttyACM0
.
(.venv) $ nrfutil dfu usb-serial -pkg hci_usb.zip -p /dev/ttyACM0
After successful flashing the device will re-enumerate as new Bluetooth HCI
USB device and be picked up by btusb
Linux driver.
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 2fe3:000b NordicSemiconductor USB-DEV
$ cat /sys/kernel/debug/usb/devices
T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=02 Dev#= 2 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=2fe3 ProdID=000b Rev= 3.05
S: Manufacturer=ZEPHYR
S: Product=USB-DEV
S: SerialNumber=xxxxxxxxxxxxxxxx
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms
E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
$ dmesg -t
usb 1-7: new full-speed USB device number 2 using xhci_hcd
usb 1-7: New USB device found, idVendor=2fe3, idProduct=000b, bcdDevice= 3.05
usb 1-7: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-7: Product: USB-DEV
usb 1-7: Manufacturer: ZEPHYR
usb 1-7: SerialNumber: xxxxxxxxxxxxxxxx
Supported features
The controller will be identified as Bluetooth 5.4 compliant controller with certain features enabled.
< HCI Command: Read Local Version Information (0x04|0x0001) plen 0
> HCI Event: Command Complete (0x0e) plen 12
Read Local Version Information (0x04|0x0001) ncmd 1
Status: Success (0x00)
HCI version: Bluetooth 5.4 (0x0d) - Revision 0 (0x0000)
LMP version: Bluetooth 5.4 (0x0d) - Subversion 65535 (0xffff)
Manufacturer: The Linux Foundation (1521)
< HCI Command: Read Local Supported Features (0x04|0x0003) plen 0
> HCI Event: Command Complete (0x0e) plen 12
Read Local Supported Features (0x04|0x0003) ncmd 1
Status: Success (0x00)
Features: 0x00 0x00 0x00 0x00 0x60 0x00 0x00 0x00
BR/EDR Not Supported
LE Supported (Controller)
< HCI Command: LE Read Local Supported Features (0x08|0x0003) plen 0
> HCI Event: Command Complete (0x0e) plen 12
LE Read Local Supported Features (0x08|0x0003) ncmd 1
Status: Success (0x00)
Features: 0xff 0x49 0x01 0x00 0x00 0x00 0x00 0x00
LE Encryption
Connection Parameter Request Procedure
Extended Reject Indication
Peripheral-initiated Features Exchange
LE Ping
LE Data Packet Length Extension
LL Privacy
Extended Scanner Filter Policies
LE 2M PHY
LE Coded PHY
Channel Selection Algorithm #2
Minimum Number of Used Channels Procedure
The exposed controller is LE-only since Zephyr doesn’t support any BR/EDR features. However Zephyr does support for LE features that are enabled by default.
Enabling other features is a post for another day.