NOTE: This set of projects require Zephyr Version 3.6
This also implies that zephyr-sdk-0.16.5 be installed or updated.
This project contains examples on how to use the Ultra Wideband (UWB) and Bluetooth hardware based DWM1001 module together with Zephyr RTOS. It's an adaptation of Decawave's examples distributed along with their driver.
This project is a clone of the Decawave's Zephyr project, in response to the original code not being buildable with the latest versions of Zephyr.
This project assumes some familiarity with Zephyr. Zephyr is not too difficult to install and learn, but there are good tutorials available which explain how to establish a working version of Zephyr on your development system.
The major changes from the original Decawave project are:
Change to using a custom board profile. This allows the nrf52_dwm1001 board to be defined within this project, thereby eliminating the need for adding the board defintion in the base Zephyr sources.
Change hardware-related reference to Device Tree Symbolics (DTS). Some DTS symbols were already being used, but there were a few cases which needed to be converted.
The Bluetooth example has been completely replaced with a new example. The original BLE support used what appeared to be a BLE-SIG defined UUID, named dps
, a 16-bit UUID, which is no longer available in Zephyr.
This example uses a custom 128-bit UUID for both the DWM1001 service and characteristics. This serves as a better starting-point example, as most developers will interested in custom BLE services/charactersistics.
The original code had comment lines which extended well past 80 columns. This is very inconvienent for development within VMs on laptops where screen real-estate limited. So the code was reformatted to 80-column max lines. It's just easier to read and understand: that is the point of examples, right?!
NOTE: Interoperability with DWM3000 Example Projects
This project now supports interoperability with the newer DecaWave UWB module, DWM3000 series.
See the DWM3000 archive for details on that project.
Linux, Mac or Windows
This project was developed on Ubuntu 22.04 (LTS), but there is no reason these changes should work with the other OSes.
You will need at least one DWM1001-dev
board and a micro-USB
cable.
Many of the examples will require two boards or more, such as the micro-location examples.
NOTE: Because the DWM1001 board incorporates a Segger JLink debugger (on-board), it is highly recommended to install the Segger JLink package on your development system: it's free, and provides support for gdb, pyocd, and Ozone (Segger's debugger).
Because this board incorporates JLink support, Segger's RTT console support is used for logging. This eliminates the need to configure and run a seperated UART-based console when developing.
A major feature of this project is the defining of the DWM1001 board as part of this project. The original project from which this project was cloned, required the use of a special version of the Zephyr project which had the DWM1001 board definitions inserted into the base Zephyr project. Later versions of Zephyr now have a method for defining custom boards within a project, eliminating the need to modify (and maintain) Zephyr itself.
Under this project's root directory, there is a the following file tree structure:
boards/
└── arm
└── nrf52_dwm1001
├── board.cmake
├── doc
├── Kconfig
├── Kconfig.board
├── Kconfig.defconfig
├── nrf52_dwm1001_defconfig
├── nrf52_dwm1001.dts
└── nrf52_dwm1001.yaml
In each example sub-project, the CMakeList.txt file has been updated with the following statement. This statement merges the custom board definition into the Zephyr board configuration process.
set(BOARD_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../..")
There's quite a lot to install if you haven't already. First we're going to build the firmware, after which we can flash it on the board.
Follow the instructions from Zephyr here.
NOTE: The toolchain is now provided in the latest version of Zephyr, so you will not need to install or build them yourself. This provides build-consistency across Zephyr projects.
This project was developed using only cmake
, not west
or ninja
, but you should be able to use them if you prefer.
There are two ways to flash one of the example project's firmware onto a DWM1001 board.
nrfjprog
utility via running make: make flash
In order to flash the boards with nrfjprog
you will need to install nrfjprog
. This tool is also available on all 3 main OS's. You can find it here. After installing, make sure that your system PATH contains the path to where it is installed.
After installing nrfjprog
, quickest way is probably using make flash
.
But note, this does not allow you to see the console messages.
If you are developing a new project or modifying an existig project, the you will probably be using an debugger with some form of graphical interface.
Now change your active directory:
cd zephyr
Now source the script zephyr-env.sh (linux & macOS) or run zephyr-env.cmd to make sure all the environment variables are set correctly.
The github repository is the one that contains the specific DWM1001 example code. Download or clone this repository to your local computer:
git clone https://github.com/foldedtoad/dwm1001.git
NOTE: The original code can be found here
Start building the real examples from the project.
NOTE: The procedure is identical for all examples.
We will proceed with building the first simple example: ./examples/ex_01a_simple_tx/
.
cd examples/ex_01a_simple_tx
Configure the build system with cmake
as follows:
cmake -B build -DBOARD=nrf52_dwm1001 .
NOTE: You will need to re-do the above step whenever new "C"-type files are added to your project. The Zephyr cmake support is good at detecting changes in existing files, but doesn't detect newly added files; thus the need to run the above again.
NOTE: Sometimes you might get error messages from the above configuration procedure. If so, delete the whole build directory and try again; often there are residual files in an existing build directory which appear to collide with the new configuration definitions.
OPTIONAL: If you are developing on a Linux or OSX system, then you may use the script configure.sh
, which does the same operation.
And we actually build or firmware with make
:
cd build
make
Now let's flash the binary file that we just built onto the board. Make sure you have nrfjprog properly installed and that it is in the system PATH.
make flash
If you are developing on a Linux or OSX system and have installled the JLink package, then you can use the rtt.sh
script (in the root directory) to start console instance. Something like the rtt.sh
script may be possible on Windows, but it has not be tried. Be sure to follow the directions displayed when rtt.sh
starts: h
, r
, g
in the JLinkExe shell.
If you have RTT message support and started, then you should see the following
***** Booting Zephyr OS build zehpher-V2.0.0-882-g89a984e64424 *****
main_thread
SIMPLE TX 13
device_id: deca0130
The following examples are provided (checkbox checked if all functionality of the example is fully functional):