0% found this document useful (0 votes)
12 views

PDoA Tag Source Code Guide

The DWM1003 PDoA Tag Source Code Guide provides comprehensive instructions for the source code of Decawave's PDoA evaluation kit Tag Application, which operates on the ARM Cortex M4F MCU. It details the architecture, core tasks, and operational flow of the application, including how to build and run the code. The document also includes information on the tag's functionality, including ranging operations and communication with external applications.

Uploaded by

jeong ok
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

PDoA Tag Source Code Guide

The DWM1003 PDoA Tag Source Code Guide provides comprehensive instructions for the source code of Decawave's PDoA evaluation kit Tag Application, which operates on the ARM Cortex M4F MCU. It details the architecture, core tasks, and operational flow of the application, including how to build and run the code. The document also includes information on the tag's functionality, including ranging operations and communication with external applications.

Uploaded by

jeong ok
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

DWM1003 PDoA Tag Source Code Guide

Version 1.1

This document is subject to change without notice.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1


DWM1003 PDoA Tag Source Code Guide

TABLE OF CONTENTS
1 INTRODUCTION ................................................................................................................................. 4
1.1 BASIC OPERATION ...................................................................................................................................... 4
1.2 THIS DOCUMENT ....................................................................................................................................... 4
2 DESCRIPTION OF THE TAG ARM PLATFORM ....................................................................................... 5
2.1 TAG ARCHITECTURE .................................................................................................................................... 5
2.1.1 Top-level application layer ............................................................................................................. 5
2.1.2 Core tasks....................................................................................................................................... 5
2.1.3 Drivers ............................................................................................................................................ 6
2.1.4 FreeRTOS ........................................................................................................................................ 6
2.2 TAG SOURCE CODE - FOLDER STRUCTURE ....................................................................................................... 7
3 OPERATION OF THE MAIN CODE ........................................................................................................ 8
3.1 STARTUP, INITIAL HAL CONFIGURATION AND STARTING OF THE KERNEL .............................................................. 8
3.2 CORE TASKS .............................................................................................................................................. 8
3.2.1 Default task .................................................................................................................................... 9
3.2.2 Control task .................................................................................................................................... 9
3.2.3 Command mode of Control task .................................................................................................... 9
3.2.4 “Flush” task .................................................................................................................................. 13
3.3 RTOS EXTENSIONS USED IN THE APPLICATIONS ............................................................................................. 14
4 TOP-LEVEL APPLICATIONS................................................................................................................ 15
4.1 TAG TOP-LEVEL APPLICATION ..................................................................................................................... 15
4.1.1 The Discovery phase .................................................................................................................... 17
4.1.2 The Ranging phase....................................................................................................................... 18
4.1.3 IMU task....................................................................................................................................... 19
4.1.4 The superframe, the wakeup timers and the slot correction ....................................................... 20
4.2 TCFM AND TCWM TOP-LEVEL APPLICATIONS.............................................................................................. 22
4.3 LOW POWER MODE.................................................................................................................................. 22
5 OPERATIONAL FLOW OF EXECUTION................................................................................................ 23
5.1 INTRODUCTION ....................................................................................................................................... 23
5.2 THE MAIN APPLICATION ENTRY ................................................................................................................... 23
5.3 STARTING OF THE EXECUTION OF THE STARTDEAFULTTASK ............................................................................. 23
5.4 THE TAG_HELPER() FUNCTION ................................................................................................................... 23
5.4.1 Discovery phase ........................................................................................................................... 24
5.4.2 Ranging phase ............................................................................................................................. 24
6 BUILDING AND RUNNING THE CODE ................................................................................................ 27
6.1 BUILDING THE CODE ................................................................................................................................. 27
6.2 INSTALLING OF THE SEGGER IDE................................................................................................................. 27
6.3 LOADING OF THE PROJECT TO THE IDE......................................................................................................... 27
6.4 CONNECTING, BUILDING AND RUNNING OF THE APPLICATION ......................................................................... 27
7 APPENDIX A .................................................................................................................................... 28
7.1 PDOA TWR APPLICATION’S TAG/PDOA NODE TWO-WAY RANGING ALGORITHM ............................................... 28
7.2 UWB CONFIGURATION AND TWR TIMING PROFILE USED IN THE PDOA SYSTEM ................................................ 29
7.3 FRAME TIME ADJUSTMENTS....................................................................................................................... 30
7.4 UWB MESSAGES, USED IN THE PDOA TWR ................................................................................................ 30
7.4.1 Tag blink message ....................................................................................................................... 30

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 2


DWM1003 PDoA Tag Source Code Guide

7.4.2 Ranging Config message.............................................................................................................. 30


7.4.3 Ranging messages ....................................................................................................................... 31
7.5 SLOT TIME CORRECTION METHOD............................................................................................................... 33
7.6 THE APPLICATION ARCHITECTURE IN THE FLOWCHART .................................................................................... 34
7.7 LIST OF SOURCE CODE FILES ....................................................................................................................... 37
8 BIBLIOGRAPHY ................................................................................................................................ 40
9 DOCUMENT HISTORY ...................................................................................................................... 41
10 FURTHER INFORMATION .............................................................................................................. 42

TABLE OF FIGURES
FIGURE 1: ARCHITECTURE OF THE TAG APPLICATION ...................................................................................................... 5
FIGURE 2: TAG SOURCE CODE FOLDER STRUCTURE ......................................................................................................... 7
FIGURE 3: INITIAL START-UP WORKFLOW ..................................................................................................................... 8
FIGURE 4 CONTROL TASK (IN COMMAND MODE) SENDS EVENT TO THE DEFAULT TASK ....................................................... 9
FIGURE 5 OUTPUT DATA USING SHARED REPORT BUFFER .............................................................................................. 13
FIGURE 6 TAG TOP-LEVEL APPLICATION ...................................................................................................................... 16
FIGURE 7 TAG’S DISCOVERY PHASE: BLINK THREAD ..................................................................................................... 17
FIGURE 8 TAG’S DISCOVERY PHASE: RX THREAD .......................................................................................................... 17
FIGURE 9 TAG’S RANGING PHASE: POLL THREAD ......................................................................................................... 18
FIGURE 10 TAG’S RANGING PHASE: RX THREAD .......................................................................................................... 18
FIGURE 11 IMU TASK ............................................................................................................................................. 19
FIGURE 12: SUPERFRAME STRUCTURE AND RANGING EXCHANGE TIME PROFILE ................................................................ 20
FIGURE 13: RANGE CALCULATION IN PDOA TWR ....................................................................................................... 28
FIGURE 14: PDOA TWR TIMING PROFILE .................................................................................................................. 29
FIGURE 15 ENCODING OF TAG'S 12-BYTES BLINK MESSAGE ........................................................................................... 30
FIGURE 16 FRAME FORMAT OF RANGING CONFIG MESSAGE ......................................................................................... 31
FIGURE 17 FRAME FORMAT USED FOR RANGING ......................................................................................................... 32
FIGURE 18 NODE-TAG SLOT TIME CORRECTION METHOD ............................................................................................. 34
FIGURE 19 APPLICATION FLOWCHART PART 1 ............................................................................................................. 35
FIGURE 20 APPLICATION FLOWCHART PART 2 ............................................................................................................. 36

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 3


DWM1003 PDoA Tag Source Code Guide

1 INTRODUCTION
This document, “DWM1003 PDoA Tag Source Code Guide” is a guide to the application source code of
Decawave’s phase difference of arrival (PDoA) evaluation kit Tag Application, running on the ARM Cortex M4F
MCU on the PDoA tag hardware platform. The Node project is supplied as Segger Embedded studio project
with Nordic SDK15.

The application source code employs a real-time operating system (FreeRTOS), however it is possible to use
another RTOS or potentially remove the operating system and implement the tag application using a ‘Round
Robin’ scheduling with interrupts technique (main super loop).

1.1 Basic operation

The basic operation of the system is as follows: The tag performs double-sided two-way ranging with the PDoA
node, which calculates the range and phase difference of the arriving signals and reports the calculated X and
Y position to an external application (e.g. PC application). The PC application then plots the position of the tag
based on the reported X-Y coordinates.

On start-up, the Tag sends a Blink message and listens for the Ranging Config response message from the
PDoA node. On the reception of the Blink, the PDoA node responds with the Ranging Config message, which
provides information describing how to perform ranging with the PDoA node. This includes the Pan ID, the short
address of the PDoA node, a short address assignment to the tag, and timing parameters for ranging phase.
Upon receiving the Ranging Config message, the tag starts ranging.

The PDoA node has two antennae and two DW1000 ICs (one for each antenna). Each ranging exchange starts
with the tag sending a Poll message, while the PDoA node listens with only one DW1000 IC active. When the
PDoA node receives the Poll message, it replies with a Response message, and the tag completes the ranging
exchange by sending a Final message. The PDoA node turns on both DW1000 ICs to receive the Final
message. This enables it to determine the phase difference (PDoA) between their arrival times at each antenna.
The PDoA node then calculates the X and Y positions of the tag which it reports via USB/UART for displaying
by the PC GUI application.

1.2 This document

This document relates to the PDoA tag project "dwm1003", of the Beta PDoA Kit source code package, tag’s
application version ”4.2.0” and DW1000 device driver version “04.01.01”, running on PDoA tag hardware
“dwm1003”. In the source code itself, the application version is specified in the “version.h” file, and the DW1000
driver version information can be found in the file “deca_version.h”.

• Section 2 provides a detailed description of the architecture, structure, and workflow of the application.
• Section 3 provides a description of the operation of the core tasks.
• Section 4 describes the operation of the top-level applications.
• Section 5 is a walkthrough of the execution flow of the software, to give an understanding of the basic
operational steps of transmission and reception. Understanding this may ease the work of integrating
or porting the ranging function to other platforms.
• Section 6 gives a brief overview on how-to build, run and debug the code.
• Section 7 Appendix A details the ranging method and the ranging messages, and provides a flowchart
of the interaction between the major software blocks, and gives a list of the project files.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 4


DWM1003 PDoA Tag Source Code Guide

2 DESCRIPTION OF THE TAG ARM PLATFORM


The tag platform is based on NORDIC Semiconductor ARM Cortex M4F MCU. The sections below discuss
the architecture, structure and workflow of the software, residing in the microcontroller, that the developer can
understand the philosophy and be able to add functionality or port the project to another platform, if necessary
(i.e. to Cortex M0/M0+, M3, or other architecture).

2.1 Tag architecture

An overview of the architecture of the tag is given by Figure 1. The figure shows, that the platform can be
structured as layers (or levels) of code, namely: “Top-level applications”, “Core tasks”, “FreeRTOS”, “Drivers”
and “HAL” which interact with corresponding physical interfaces. The detailed scheme of interactions between
software blocks is given in the Appendix A, section 7.6.

TAG TCFM

Idle
RX Poll
Top-level TCWM
IMU BLINK
applications
Default

FreeRTOS
Flush Control
Core tasks

DW1000 SPI/USB/UART
Device Driver Drivers

Target HAL
Physical interfaces

DW1000 UWB USB UART IMU BLE


radio I/O I/O I/O I/O UART I/O

Figure 1: Architecture of the tag application

2.1.1 Top-level application layer

This is the top level of the software defining the operation of the tag unit. It has four separate applications /
modes of operation. The main mode, named “TAG” is the normal tag functionality as introduced in section 1.1
above, while the three other operational modes are for testing purposes. These are: TCFM – Test Continuous
Frame transmission Mode; TCWM – Test Continuous Wave transmission Mode; and, USB2SPI test mode,
allowing external test software direct access to the DW1000 SPI.

The top-level applications cannot run concurrently since they use the same resources: e.g. TAG application
configures the DW1000 to do two-way ranging, while TCWM application initializes DW1000 to run a Continuous
Wave mode test.

2.1.2 Core tasks

The core tasks are always running once the RTOS kernel has been started. These core tasks are described in
section 3.2. The core tasks are:

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 5


DWM1003 PDoA Tag Source Code Guide

• The Default core task is responsible for starting one of the top-level applications. It receives events
from the Control task to switch to a particular mode of operation and starts corresponding top-level
application. This is described in detail in section: 3.2.1
• The Control core task is responsible for reception and execution of commands from external IO
interfaces USB and UART. The Control task can also pass data from those I/O interfaces to the top-
application layer. This is described in detail in section: 3.2.2
• The Flush core task is responsible for transmitting of any output data to the external I/O interfaces
USB and UART. This is described in detail in section 3.2.4.

2.1.3 Drivers

The drivers are responsible for translating of higher-layer requests and the specific sequences to control
particular peripherals.

To control the DW1000 UWB radio transceiver the DW1000 API and the device driver is incorporated as a
library. Other physical interfaces have corresponding drivers, namely UART, I2C, etc.

2.1.4 FreeRTOS

The PDoA tag platform runs under the FreeRTOS operating system control. This a CMSIS compatible RTOS,
thus the tag software is portable to other CMSIS-RTOS if needed. The CMSIS-RTOS is a common API for Real-
Time operating systems. It provides a standardized programming interface that is portable to many RTOS and
enables therefore software templates, middleware, libraries, and other components that can work across
supported the RTOS systems.

The tag software has two layers of operation: RTOS tasks, which run concurrently, and bare-metal functions,
which run under operation of the RTOS based application. Potentially it is possible to remove RTOS tasks, and
implement their functionality using Round Robin technique (super loop), however this may lead to a complex
times management and complexity in the code (spaghetti-code).

Some of the bare-metal functions, such as SPI driver are running above the RTOS priority, which means that
they cannot be interrupted by the RTOS or use RTOS mechanisms for communications. This is done to increase
the performance of running applications.

FreeRTOS uses the so-called tickless idle mode (configUSE_TICKLESS_IDLE==2) and a special platform-
specific vPortSuppressTicksAndSleep function which actually puts all the system to the lowest power
consuming mode. In order to achieve minimum sleep current, the UART module is switched off automatically
after 30 sec of inactivity. To wake up UART user needs to send any symbol to the UART port (this and only this
symbol will be discarded).

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 6


DWM1003 PDoA Tag Source Code Guide

2.2 Tag source code - Folder structure

The initial folder structure is shown on the


figure below. Folder Description
name

Output files The target build directory.


Device This folder contains the HAL drivers and
nRF_Drivers runtime support for nRF52832
nRF_Libraries
nRF_Log
nRF_Segger_RTT

10_dof_driver This folder contains 10 degrees of


freedom IMU driver

deca_driver This folder contains DW1000 driver

freeRTOS This folder contains the FreeRTOS


source code..

Src Tag’s main project folder, where:


• “bare” – collection of bare-metal
functions and “processes”, which
holds the actual functionality to make
a non-RTOS based application;
• “port” – folder with platform-
dependent files
• “task” – collection of core and user-
application tasks, needed to
implement the actual functionality,
using RTOS;
• “utils” – collection of support utilities.

Figure 2: Tag source code folder structure

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 7


DWM1003 PDoA Tag Source Code Guide

3 OPERATION OF THE MAIN CODE


Please read this chapter with project’s code opened in your preferred editor, e.g. Eclipse or similar. Initially open
main.c file from Src folder, where the main() - entry point to the application is located.

3.1 Startup, initial HAL configuration and starting of the kernel

At entry point of the main() the RTOS is not configured and is not running. The code in main() file provides the
initial hardware configuration using Nordic HAL libraries, initialises the core tasks and starts the RTOS kernel.

At the startup, the main() loads the saved configuration from the FConfig, which is the Non Volatile Memory
(NVM) of the MCU (in used ARM it’s organized as a part of FLASH CODE memory), into the RAM segment,
called bssConfig. On the run-time the application uses the configuration parameters from bssConfig only.

The bssConfig parameters may be updated by the Control task and saved to the Fconfig section of NVM.

NOTE: the application has two configuration sections in the NVM memory, called defaultConfig and FConfig,
and one section in the RAM memory, called bssConfig. The defaultConfig NVM segment stores the default data
configuration and this cannot be changed, but can be used to restore the initial configuration. The FConfig NVM
segment stores the current configuration, which can be updated by the Control task. The bssConfig RAM
segment holds the actual run-time working parameters copied from FConfig during the startup.

All globally accessible variables are defined in the global “app” structure.
app_t app; /**< All global variables are in the "app" structure */
load_bssConfig();/**< load the RAM Configuration parameters from NVM block */
app.pConfig = get_pbssConfig();/* app.pConfig is pointed to the RAM (bssConfig)*/
After loading of the configuration parameters, the main() code initialises the core tasks and enables the Real-
Time kernel (scheduler), see Figure 3. After starting of the RTOS kernel, the core tasks will begin to run “in
parallel”, each executing its dedicated role.
Power on, read config

Default Task Control Task Flush Task


Select top-level (USB UART - RX) (USB UART -TX)
application to Process Sends data from
run commands REPORT buffer
received over over UART/USB
USB/UART

Start RTOS kernel (scheduler)

Figure 3: Initial start-up workflow

3.2 Core tasks

There are few logically different core functions, which are running “in parallel” as core tasks all the time. All
core tasks have lower priority than top-level application tasks, thus core tasks can be interrupted by the RTOS
kernel when more important thread needs to process the data (i.e. RxTask, BlinkTask, PollTask, see 4.1).
The following are the core tasks.
• The Default task, which is coded in the DefaultTask(), is responsible for starting individual top-level
application tasks which operate in a mutually exclusive way with the DW1000 because they cannot share
this unique resource for their operation, i.e. only one of these top-level tasks is enabled to run at any one
time. This is described in more detail in section 3.2.1.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 8


DWM1003 PDoA Tag Source Code Guide

• The Control task, which is coded in the CtrlTask(), is responsible for reading of the input from USB and
UART, translating it to the appropriate command and executing of that command, see 3.2.2.
• The Flush task, coded in the FlushTask() is attempting to output all data to USB and UART from the
common circular report buffer Report.buf, which used as a common data storage for all output information
coming from any running processes, see 3.2.4.

There is one more special core task, called the Idle() task, which is created automatically when the RTOS
scheduler is started. It is created at the lowest possible priority to ensure it does not use any CPU time if there
are higher priority tasks in the ready state. The power-saving mode of the MCU is implemented as a part of
this task.

3.2.1 Default task

The Default task is waiting for a global event xStartTaskEvent, which instructs it to enable a particular top-level
application task, depending on the requested operation mode. This event can be received from Control task or
as a part of parsing of initial configuration, see 3.2.2 below.

On reception of non-empty xStartTaskEvent, the Default task stops all running top-level tasks and their
corresponded processes, and then starts the requested top-level application from its initial condition.

For more details about events and tasks interconnection mechanisms see section 3.3.

3.2.2 Control task

The Control task awaits an input on UART interfaces. The task has two modes of operation, Command mode
and Data mode.

The Control task in Command operational mode, see Table 1, Table 2 and Table 3 arises and executes a
command, and can set an event to xStartTaskEvent, which will be received by Default task, see Figure 4. More
details of Command mode of operation of Control task is given in the paragraph 3.2.3.

TagTask
Command parser EVENT
TcfmTask
Data parser
TcfmTask

Figure 4 Control task (in command mode) sends EVENT to the Default task

3.2.3 Command mode of Control task

The command mode of Control task includes parsing and execution of a number of different input command
sets. In this section a more advanced description of this mode will be given.

On reception of a valid command by the Control task, the command is processed and corresponded reply is
been sent for output. The Flush task is then actually sending of the output to the USB/UART.

There are three types of commands, which can be parsed in the tag: anytime commands, state changing
commands and run-time parameters access commands, which all can be named as “generic commands” set.

Generic commands set has the general format of <Command>[<SPACE><Val>]<CR>

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 9


DWM1003 PDoA Tag Source Code Guide

Where <Command> is the command string from the Table 1, Table 2 and Table 3 below, [<SPACE><Val>]
is optional and <CR> is representing the carriage return (can be any of <CR>, <LF>, <CRLF>, <LFCR>).

3.2.3.1 Anytime commands

The anytime commands listed in Table 1 can be executed anytime except of the USPI mode of operation, i.e.
when binary data parser is running (see 3.2.2). The only exception is a STOP command, which can be
executed in all modes.

Table 1 Anytime commands

Command Definition of functionality

STAT Reports the status. Gives a dump of software version info, all configuration
values and the current operation mode (TAG, TCFM, TCWM or STOP).

HELP or ? Outputs a list of all known commands.

STOP Stops running any of top-level applications and places the tag to the STOP
mode, where only core tasks are running.

SAVE Stores the bssConfig configuration to the FConfig.

Tag’s top-level Outputs a JSON formatted string if requested or if PCREP parameter set to “1”.
application output

3.2.3.2 Commands to change mode of operation

The commands to change mode of operation can be executed only after the STOP command (otherwise the
command parser will output the string “error incompatible mode”). They are used to send an appropriate event
request to the Default task to start a particular top-level application.

On reception of a command to change the mode the Control task sets an event for to the xStartTaskEvent which
is then received by the Default task, as described on the Figure 4 above. For a complete list of commands to
change the mode of operation see Table 2 below.

Table 2 Commands to change mode of operation

Command Definition of functionality

TAG Enable the TAG mode of operation.

TCWM Enable the TEST of Continuous Wave transmission Mode.

TCFM Enable the TEST of Continuous Frame transmission Mode.

3.2.3.3 Commands to change run-time parameters

The commands to change run-time parameters, listed in Table 3, can be executed only when a top-level
application is not running, i.e. the STOP command is needed to place the PDoA node into its STOP mode
before accessing these parameters. All parameters are a part of the bssConfig, and all changes will be

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 10


DWM1003 PDoA Tag Source Code Guide

applied at the start of a top-level application. The SAVE command can be used to save changed parameters
to the FConfig that they also will be used after the reboot of the device.

Table 3 Commands to change run-time parameters

Command Definition of functionality

F_NUM <val> Tag top-level application Ranging phase configuration:. Range Fails number
after which tag top-level application will return back to Discovery phase.

RCDEL <val> Tag top-level application Discovery phase configuration. The <val> is the delay
in microseconds (µs) between tag’s completion of sending a Blink and start of
tag’s reception of Ranging Config response from the node. Both nodes and tag
have this configuration parameter and it should be the same for all the devices
in the system. Default is 1000 µs.

UART <val> “0” (default) - Disables the UART. The tag will not output data to UART.
“1” Enables the UART. This enables Tag I/O to/from UART, which is also
means the tag software will not be power-save efficient during operation, as tag
will need to keep running MCU to output data to the UART.

RCTO <val> Tag top-level application Discovery phase configuration. The <val> is a time in
microseconds (µs), of how long the tag will stay in reception of the Ranging
Configuration state. This parameter directly affect tag’s current consumption.
Default is 300 µs.

AUTO <val> Used to start default Tag top-level application automatically after Reset/Power
on. Default is “1”, but may be configured to “0” to stay in Idle mode of
operation.

PCREP <val> “1” (default) enables the tag’s output of its location position, which tag receive
back from the node to the USB/UART. This also enables tag to output its
“Stationary” JSON object to the output.
“0” disables the output from IMU and Tag tasks.

BLINK <val> Blink period in ms, val = [500,..10000].

ANTTX <val> Sets the TX antenna delay value to specified val (INT16) decimal value, in
device time units of 1/499.2e+6/128 (approx. 15.65 ps). Applied to the TX
antenna delay configuration.

ANTRX <val> Sets the RX antenna delay value to specified val (INT16) decimal value, in
device time units of 1/499.2e+6/128 (approx. 15.65 ps). Applied to the RX
antenna delay configuration.

RESTORE Restore tag’s configuration to default. This command copies the defaultConfig
section to the bssConfig. SAVE command shall be used thereafter if user wants
to save the FConfig section.

3.2.3.4 The Tag top-level application output

The Tag top-level application may output to the PC using JSON formatted output. The JSON object is
encapsulated in TLV format (Type-Length-Value) to ease the implementation of parser on the PC side. The
reader may find a description of JSON format in the RFC 4627, [https://tools.ietf.org/html/rfc4627].
<TYPE><LENGTH><VALUE>, where <TYPE> is “JS”, <LENGTH> is 4-byte hexadecimal length of <VALUE>

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 11


DWM1003 PDoA Tag Source Code Guide

field, which is a JSON object, see Table 4 below.

Table 4 Tag top-level application JSON outputs

Action JSON Type Format of JSON object with TLV wrapper


object
Reply to the Info Info JSxxxx{"Info": <info_object>}
“DECA$” object The device reports the information about it.
Example:

JS0087{"Info":{
"Device":"PDoA Tag",
"Version":"4.0.0",
"Build":"May 30 2018 12:20:37",
"Driver":"DW1000 Device Driver Version 04.00.07"}}

When the ST Tag’s JSxxxx{"ST": <stationary_obj>}


IMU task is Station
running, it ary Where <stationary_obj> is:
may report Object {"a16":<string>,"V":<int>,"X":<int>,"Y":<int>,"Z":<int>}
the “ST”
object "a16" - is tag’s short address, hex
anytime "V" - is a service data wrt to the node, bitfields, dec:
node is bit 0 indicates 1 if node is stationary and 0 if tag is moving.
moving "X" - is the node’s accelerometer X axis data, in milli-G, dec
"Y" - is the node’s accelerometer Y axis data, in milli-G, dec
"Z" - is the node’s accelerometer Z axis data, in milli-G, dec
Example:
JS0033{"ST": {"a16":"06A5","V":0,"X":-2,"Y":193,"Z":954}}
When the tag TAR Tag’s JSxxxx{"TAR": <twr_obj>}
is ranging to Twr
the node, it Object Where <tar_obj> is:
receives the {"a16":<string>,"n16":<string>,"R":<int>,"T":<int>,"D":<int>,"P":<int>
information ,“A”:<int>,"O":<int>}
from the
node about "a16" - is tag’s short address, hex;
its last "n16" - is node’s short address, tag is ranging to, hex;
located "R" - is the range number, dec;
position. This "Xcm" - is the last calculated X position from Node point of view
can be sent onto the tag, centimeters, (float as int), dec
anytime if "Ycm" - is the last calculated Y position from Node point of view
PCREP onto the tag, centimeters, (float as int), dec
parameter is "O" - is a clock offset of the tag to the ranging node in hundreds of
set to “1”. ppm (float as int), dec

Example:
JS0043{"TAR":
{"a16":"06A5","n16":"0001","R":54,"Xcm":-34,"Ycm":72,"O":268}}

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 12


DWM1003 PDoA Tag Source Code Guide

3.2.4 “Flush” task

Any functions, including ISR functions, or RTOS tasks can produce and request to send data to the terminal
output (UART). In the data sending function port_tx_msg(), the data is copied to the intermediate Report Buffer,
which is then flushed by the “Flush” task. This is illustrated on the Figure 5 below.

The Flush task is coded as FlushTask() in the task_flush.c source code file.

The Report buffer is a circular buffer, which is statically allocated in the usb_uart_tx.c as txHandle.Report. The
port_tx_msg() function is copying data to the txHandle.Report.buf and then sets the app.flushTask.Signal to the
Flush task to start immediate transmitting of data via UART.

The Flush task is emptying the Report buffer onto the UART. The Report buffer is a statically allocated area of
REPORT_BUFSIZE. The size of Report buffer is sufficient that any task/function can send a chunk of data for
background output without delaying its throughput, even during an ISR, see Figure 5 below.

From any functions to debug, FlushTask is emptying the


including ISR level functions Report buffer independently

REPORT
BUFFER

Process USB2SPI
protocol commands
Discovery phase
Port_tx_msg SPI to DW1000
Waiting a node in the range and
Ranging Configuration message

Start a TWR timer for slots


Start ImuTask
Ranging phase
Performs TWR as per the supplied
configuration from
Run Test Continuous
Ranging Configuration message
Frame mode
SPI to DW1000
SPI to DW1000

Command parser
Read IMU Sensor & Run Test Continuous
sets/clear Data parser
Wave mode
Stationary flag
SPI to DW1000
SPI to IMU TWR timer for slots

Figure 5 Output data using shared Report buffer

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 13


DWM1003 PDoA Tag Source Code Guide

3.3 RTOS extensions used in the applications

For performance optimization, RTOS queues or mailboxes are not used within the tag application. In order to
transfer data in-between tasks or from an ISR to a task, a circular buffer alternative is used.

For locking and signalling, the following mechanisms are used: mutexes, events and signals. Mutexes are used
to protect task execution from being killed in the Default task while they still in the running state.

The EventGroup mechanism, is used to send relatively slow events between tasks. This method is used to
instruct the Default task to start a particular top-level application.

As a fast and simple alternative to EventGroup, the fast task notification mechanism can also be used. In the
CMSIS-RTOS this defined as signals. The signal is delivering a simple message to the specific task. This
mechanism is faster that EventGroup and in the application is used to organize interconnection from ISR level
functions to a RTOS-based tasks. For more information please refer to the FreeRTOS documentation
[www.freertos.org].

For the purposes of unification, all tasks (top-level applications and sub-levels), which are capable of receiving
signals are defined as task_signal_t structures in the global app structure. Below is a code example:

/* Application tasks handles & corresponded signals structure */


typedef struct
{
osThreadId Handle; /* Task’s handler */
osMutexId MutexId; /* Task’s mutex */
int32_t Signal; /* Task’s signal */
}task_signal_t;

In the code, task handlers and signals are defined within the app structure as follows:

//defaultTask is always running and is not accepting signal

task_signal_t ctrlTask; /* usb/uart RX: Control task */


task_signal_t flushTask; /* usb/uart TX: Flush task */

/* tasks for TAG top-level application */


task_signal_t imuTask; /* IMU task */
task_signal_t rxTask; /* RX task of Tag top-level application */
task_signal_t blinkTask; /* Blink task of Tag top-level application */
task_signal_t blinkTmr; /* Blink timer of Tag top-level application */
task_signal_t pollTask; /* Poll task of Tag top-level application */

/* tasks for special top-level applications */


task_signal_t usb2spiTask; /* USB2SPI top-level application */
task_signal_t tcfmTask; /* TCFM top-level application */
task_signal_t tcwmTask; /* TCWM top-level application */

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 14


DWM1003 PDoA Tag Source Code Guide

4 TOP-LEVEL APPLICATIONS
There are four top-level applications, listed in the Table 5, which can run in the dedicated mode on the tag
platform. Each top-level application consists of a task (or a number of tasks) and a set of non-RTOS based
functions to implement the application’s functionality.

Table 5 Top-level applications and corresponded commands

Top-level application Corresponded command Description

Tag, see 4.1 TAG PDoA two-way ranging tag application

TCFM, see 4.2 TCFM Test Continuous Frame transmission Mode: used
for testing

TCWM, see 4.2 TCWM Test Continuous Wave transmission Mode: used
for testing

4.1 Tag top-level application

Once tag top-level application is started, it will setup and execute the two-way-ranging Tag application which
consists of Discovery and Ranging phases.

The system may include more than one tag ranging to the same PDoA node. To prevent interference between
tags, a Time-Division Multiple Access method (TDMA) is employed to separate the tags ranging exchanges into
individual “slots” within a repeating "superframe" structure specified by the PDoA node, see 4.1.4.

Initially the tag will send blink messages to advertise itself and be discovered by the PDoA node. This is called
the Discovery phase. After sending the blink, the tag awaits the response from the PDoA node and upon
successful reception it configures itself as instructed by the PDoA node. The tag application supports ranging
to a single PDoA node only.

For each ranging exchange, the tag sends a Poll message (addressed to the PDoA node address, specified in
the Ranging Config message), and awaits a Response message from the PDoA node, and upon its successful
reception, sends a Final message to complete the ranging exchange. After completing the ranging exchange
(or if it fails to complete because of error or timeout), the tag will put the DW1000 into DEEPSLEEP until a
configured WakeUp timer period elapses. Once WakeUp timer elapsed, the tag will wake the DW1000 up and
repeat the full process to complete another ranging exchange.

Figure 6 shows a high-level view of the Tag application flow.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 15


DWM1003 PDoA Tag Source Code Guide

Tag top-level application

Setup Discovery phase

Send Poll Send Final

Send Blink
Response from
the node
received? YES

Ranginig Config NO
message NO
received?
Inc faultyRangesCnt

YES
Stop Discovery phase.
Setup Ranging phase.
NO faultyRangesCnt >
faultyRanges?

YES
Send EventGroup event to restart
the whole TAG user application

Figure 6 Tag top-level application

There is a set of RTOS tasks (threads) to implement the Tag’s functionality above. On reception of the
Ev_Tag_Task event, the Default core task executes the tag_helper() function, which configures all the HW to
operate for the Tag top-level application, i.e. initially wakes up of the DW1000, then configures it for running
with configured UWB parameters and starts following sub-tasks: BlinkTask, PollTask, RxTask and ImuTask.
Finally.

The operation of the tag and its sub-tasks are described in detail in the sub-sections 4.1.1, 4.1.2 and 4.1.3
below.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 16


DWM1003 PDoA Tag Source Code Guide

4.1.1 The Discovery phase

Once the BlinkTask has started, the tag starts sending periodic blink messages and awaits a response in the
RxTask, see Figure 8 below. This is called the Discovery phase, and continues indefinitely, until a Ranging
Config message is received from the node.

APP level

DW1000 IRQ:
rx_callback()
IRQ level
Expire
[SIGNAL]
[SIGNAL]
APP level

WakeUp DW1000
Get data from circ_buf
Send blink

twr_initiator_algorithm_rx()
initiator_send_blink()

Compatible
Figure 7 Tag’s Discovery phase: Blink Thread Range
NO
Configuration
message?

YES

Stop Low-Resolution Blink Timer


Setup high-resoluution RTC timer

end

Figure 8 Tag’s Discovery phase: Rx Thread

The Blink message is an IEEE specified 12-byte message with long addressing mode, see 7.4.1. The Ranging
Config message uses long-short addressing mode (see 7.4.2) and contains configuration options: the version
of Ranging Config, Tag’s and Node’s short addresses, PDoA system PanID, timings for range exchange, etc.

On reception of the Range Config response, the RxTask stops the low resolution Blink Timer and sets a higher
precision RTC wakeup timer to expire and Signal to the PollTask to attempt a first ranging. The Discovery phase
has finished at this point and tag application goes to the Ranging phase.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 17


DWM1003 PDoA Tag Source Code Guide

4.1.2 The Ranging phase

The RTC wakeup timer, first time configured at the end of Discovery phase, expires when the tag is due to send
the Poll message. The Wakeup timer is reloaded with the periodic value, corresponded to the super frame
duration value from Ranging Config message. It will also be corrected by the PDoA node in every response
message. The PollTask receives the signal from Wakeup timer and sends the Poll to the PDoA node, initiating
a Ranging sequence, see Figure 9. On reception of UWB packet, the dwt_isr() rx_callback() sends the SIGNAL
to the rxTask, which is then responsible for the setup of the Final reply message to the node, see Figure 10.

DW1000 IRQ:
RTC Wakeup Timer
rx_callback()
IRQ level [SIGNAL]
IRQ level
[SIGNAL] APP level
APP level

Get data from circ_buf


Wakeup DW1000

Send Poll twr_initiator_algorithm_rx()

initiator_send_poll() Response from NO


the node?

YES
Inc faultyRangesCnt
Figure 9 Tag’s Ranging phase: Poll Thread Send Final message
Correct RTC Wakeup Timer

End

Figure 10 Tag’s Ranging phase: Rx Thread

The IMU sensor is controlled by the ImuTask. The IMU functionality (on/off) is specified in the Ranging Config
message. If the ImuTask sets that the tag is “stationary”, the ranging rate is reduced to the slow location rate as
provided in the Range Config message, see 4.1.3. Otherwise Wake up timer sends SIGNALs to the PollTask
as configured in the fast location rate parameter.

Outside of the ranging exchange, the DW1000 is placed into its DEEPSLEEP Mode, and the MCU can be in a
low-power mode if other tasks are not running, this is under control of the Idle task.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 18


DWM1003 PDoA Tag Source Code Guide

4.1.3 IMU task

The IMU task, see Figure 11, is started by tag_helper() and it uses the separate MCU’s SPI peripheral to read
the IMU sensor’s state periodically and determine whether the tag is moving or stationary. This task is not
conflicting to any of top-level applications and can be run with any of them if needed.
The flag is used in the tag’s Poll task to change the location rate, i.e. when stationary the tag uses a slow ranging
frequency, specified by the pollMultSlow configuration parameter, and when it is not stationary (active/moving)
the tag uses the fast ranging frequency, specified by the pollMultFast configuration parameter, of the Ranging
Configuration message, see 7.4.2.

If the PCREP configuration parameter is set to “1”, the tag is also reporting to the output the “ST” JSON object,
see Table 4. The accelerometer readings are normalized to 1000 milli-g per every of 3 axis. If PDoA tag is not
moving, it sends last report, indicated node is stationary and after that it does not sends reports to the output
unless the IMU task will detect movement again.

IMU task APP level

Start IMU task


Imu_enabled = 0.

Wait IMU_READ_DELAY_MS

IMU task is NO
ON?

YES Imu_enabl
NO
ed ?
NO
Imu_enabl
ed ? YES

YES Stop_imu()

Stationary = run_imu()

Imu_enabled = start_imu()

Figure 11 IMU task

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 19


DWM1003 PDoA Tag Source Code Guide

4.1.4 The superframe, the wakeup timers and the slot correction

In order to implement non-overlapping ranging exchanges for multiple tags, the PDoA node uses Time-Division
Multiple Access method (TDMA), to assign to every tag its own dedicated slot (of T_Slot duration) within the
PDoA node’s superframe period, see Figure 12.
Node’s Superframe (n) Superframe (n+1)

Tag0’s Superframe

Slot 0 Slot 1 Slot 2 Slot 3 Slot 4 Slot 5 ... Slot N Slot 0 Slot 1

T_Slot T_Slot

TWR T0 to Guard TWR T1 to Guard


the Node Time the Node Time

rx delay

TX TX
Poll Final
R R
Node TX
Resp-
onse

Poll2Final

Figure 12: Superframe structure and ranging exchange time profile

On the picture above, the R represents the RMARKER, which is the event nominated by the IEEE 802.15.4
UWB PHY standard for message time-stamping. The time the first symbol of the PHR launches from the
antenna (defined as the RMARKER) is the event nominated as the transmit time-stamp, see [3].

The Poll2Final configuration value defined the rough time between transmissions of RMARKERS for Poll and
Final messages from the tag. Rx_delay is the time between tag’s end transmission of the Poll and its start of
reception of a Response from a Node, see P2FDEL and RCDEL parameters in Table 3 above.

Note, the slot number zero is reserved and may be used for future enhancement of the system, for example
Node can beacon in this slot and Tag can listen for the beacon and be instructed to transmit only on allowed
time.

The PDoA node and the tag hardware RTCs have a small drift with respect to each other, so to maintain the
tag ranging in its assigned slot, the PDoA node specifies the superframe period in the Ranging Config message
which the tag saves in its framePeriod_ms variable. Every time the tag receives a ranging Response message
from the PDoA node, it includes a correction factor, the slotCorr_us, which indicates the difference between the
start of Tag’s dedicated slot and the actual reception time of the poll from the PDoA node’s point of view. Using
this information, the tag can adjust its wakeup timer for the next period to send its poll in the assigned slot, see
section 7.5 for more details.

On the expiry, the Wakeup Timer will reload the framePeriod_ms. Then the Wakeup timer counts the number
of expiration times and compares this to the pollMultFast (if the tag is moving) or pollMultSlow (if the tag is
stationary). On reaching the number of expiration times, pollMultFast or pollMultSlow, the Wakeup timer sends
the SIGNAL to the PollTask, to initiate a new range exchange.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 20


DWM1003 PDoA Tag Source Code Guide

As mentioned above, the Tag does not know the Node’s superframe and range timings configuration until it
receives the Ranging Config message. Thus, the configuration of the superframe and slots timings is completely
up to the node’s side and determines the tag’s fastest possible ranging rate.

For example, for configuration with 20 slots, each of 5 ms, the superframe is 100 ms long. This means, that the
fastest possible Ranging exchange for the tag, (when pollMultFast = 1), is 10 Hz.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 21


DWM1003 PDoA Tag Source Code Guide

4.2 TCFM and TCWM top-level applications

These tasks configure the DW1000 to run in the particular operational test mode (Test Continuous Wave or
Test Continuous Frame) and awaiting to be stopped from Control task. Both of them are an interface to the
corresponding bare-metal production test functions, located in files tcfm.c and tcwm.c respectively.

4.3 Low power mode

Tag enters low power mode when not actively ranging. Currently this is done for DW1000 after completion of
an dwt_isr() by executing of dwt_entersleep() driver function. The STOP command, also will put DW1000 to the
low power mode.

For the MCU the low power is implemented in the Idle() thread, which is executing every time FreeRTOS finished
executing of all other higher-priority tasks. For illustration purposes, the Idle() puts the MCU core to a low power
by executing of a “WFI” instruction only.

Future versions of software may improve this by switching the MCU’s operational frequency to a slower one,
based on expected sleep time and powering off unnecessary peripheral modules and/or use additional power-
save features of the target MCU. Additional features of FreeRTOS, such as tickles idle also can be used to
improve low power consumption feature.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 22


DWM1003 PDoA Tag Source Code Guide

5 OPERATIONAL FLOW OF EXECUTION


5.1 Introduction

This section is intended to be a guide to the flow of execution of the software as it runs, reading this and following
it at the same time by looking at the code should give the reader a good understanding of the basic way the
software operates as control flows through the layers. This understanding should be an aid to integrating/porting
the ranging function to other platforms.

To use this effectively, the reader is encouraged to browse the source code (e.g. in the Eclipse IDE) at the same
time as reading this description, and find each referred item in the source code and follow the flow as described
here.

5.2 The main application entry

The application is initialised and run from the main(). Firstly it initialises the hardware including various MCU
peripherals using CubeMX’s generated MX_xxx_Init() functions. Then the application copies the NVM
configuration to the bssConfig and initialises the core tasks: DefaultTask, FlushTask and CtrlTask. Finally
main is executing osKernelStart(). The DefaultTask, FlushTask and CtrlTask are now running. The FlushTask
and CtrlTask are waiting for the corresponding signals, and only the DefaultTask is initially executing when the
kernel has started.

5.3 Starting of the execution of the StartDefaultTask

When it starts, the StartDefaultTask() flashes LEDs three times and then sets the Ev_Tag_Task event to the
app.xStartTaskEvent and enters a continuous while() loop, in which it periodically checks the
app.xStartTaskEvent and calls the usb_vbus_driver() if there are no events set.

As app.xStartTaskEvent already has the event, the Ev_Tag_Task will cause the StartDefaultTask to terminate
any possible running top-level applications and create a new TagTaskHelper() task. After that the while loop of
StartDefaultTask will keep calling the usb_vbus_driver() every USB_DRV_UPDATE_MS period.

5.4 The tag_helper() function

Once the tag_helper() has been called, it wakes up and initializes the DW1000 chip, sets the Tag’s top-level
application tasks (see 4.1) (namely BlinkTask, PollTask, RxTask), executes the tag_process_init() and starts
the app.blinkTmr timer (with callback BlinkTimer_cb) to expire every BLINK_PERIOD_MS milliseconds and
enables the DW1000 IRQ.

The DW1000’s IRQ call-back dwt_isr() is a part of HAL_GPIO_EXTI_Callback(). It will be called when the
DW1000 will set the IRQ line to 1. The top-level application specific call-backs are set during initialization in the
tag_process_init().

As mentioned in the 3.3, all tasks which are capable of receiving a SIGNAL are defined as task_signal_t
structures in the global structure app. Tag’s tasks will run as explained in section 4.1 Tag top-level . The Tag
Discovery phase is described in the section 5.4.1 below.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 23


DWM1003 PDoA Tag Source Code Guide

5.4.1 Discovery phase

The BlinkTimer_cb callback of the Blink timer, which is set in tag_helper(), expires every BLINK_PERIOD_MS
and sends the SIGNAL to the TwrBlinkTask. The SIGNAL will be delivered by the kernel to the handler
app.blinkTask.Handle, which is a pointer to the BlinkTask. This is coded as a CMSIS function call
osSignalSet(app.blinkTask.Handle, app.blinkTask.Signal);

The BlinkTask is waiting for the SIGNAL using osSignalWait(app.blinkTask.Signal, osWaitForever), and on
reception of it, wakes up the DW1000, using port_wakeup_dw1000_fast() and disables future sleeping of the
DW1000 by setting the app.DwCanSleep flag to “0”;

Once the wake up of DW1000 has completed, the blink message is sent with initiator_send_blink() function.

The initiator_send_blink() configures the DW1000 to send an immediate blink, configures the delayed reception
and timeout in order to receive the Ranging Config response. While the DW1000 is sending the blink, the
TwrBlinkTask returns to its “suspended” state, awaiting for the next Signal from the blink timer to send another
blink.

After transmission of the blink, the DW1000 will produce the IRQ, which will force MCU to execute the dwt_isr(),
which then will call the tx callback twr_tx_tag_cb().The DW1000 will be in the “wait for Rx” state, counting off
the time to its enabling of its receiver.

The twr_tx_tag_cb() saves the blinkRtcTimeStamp – MCU RTC timestamp in to the TwrInfo structure.

After DW1000 enables its receiver, it may either receive a good frame or receive a timeout or an error.

On reception of a valid or error frame or on timeout, the DW1000 will assert its IRQ line, which interrupts the
MCU causing it to execute the dwt_isr(). The dwt_isr() will calls the callback twr_rx_cb() on reception of a valid
frame or twr_rx_timeout_cb() or twr_rx_error_cb() otherwise. Reception of RxTimeout and RxError aborts the
current discovery phase iteration.

The twr_rx_cb() saves the received Rx frame and the Timestamp to the circular buffer rxPcktBuf as structure
rx_pckt_t, and signals the app.rxTask, which causes the TagRxTask to process the received Rx packet.

The RxTask() extracts the prxPckt from the rxPcktBuf and passes it to the twr_initiator_algorithm_rx() for
processing. The TagRxTask has the highest possible RTOS IRQ priority, so that the Signal from the ISR passes
to the task as fast as possible and the time-critical TagRxTask cannot be interrupted by any other tasks.

The twr_initiator_algorithm_rx() receives the RxPckt and checks whether the packet has a valid format for a
Ranging Config message, and if so sets all necessary parameters for the Ranging phase in the
initiator_received_range_init(), stops the app.blinkTmr timer and starts the RTC WakeUp Timer.

Alternatively, i.e. if the Ranging Config message has unexpected format (or is not received, or has RX errors),
the tag will keep transmitting blink messages, awaiting a correct Ranging Confign response from an PDoA node.

When the discovery phase is successful the tag application stops the Blink timer and sets up the Wakeup RTC
timer for ranging, and switches to the Ranging phase.

5.4.2 Ranging phase

The Ranging phase operation is similar to the Discovery phase. Instead of Blinking timer there is the WakeUp
timer, instead of BlinkTask() it has PollTask(). The difference is that after the Response message, tag will
transmit the Final message to the node.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 24


DWM1003 PDoA Tag Source Code Guide

On expiry of the RTC Wakeup timer, HAL_RTCEx_WakeUpTimerEventCallback(), SIGNAL is sent to the


TagPollTask().

The SIGNAL will be delivered by the kernel to the handler app.pollTask.Handle, which is a pointer to the
BlinkTask. This is coded as a CMSIS function call osSignalSet(app.pollTask.Handle,app.pollTask.Signal);

The PollTask is waiting for the SIGNAL using osSignalWait(app.pollTask.Signal, osWaitForever), and on
reception of it, wakes up the DW1000, using port_wakeup_dw1000_fast() and disables future sleeping of the
DW1000 by setting the app.DwCanSleep flag to “0”;

Once the wake up of DW1000 has completed, and the counter of faulty ranges faultyRangesCnt is less than
F_NUM parameter, the poll message is sent with initiator_send_poll() function. Alternatively, if faulty counter
reaches the maximum number of sequential faulty range attempts, the pollTask is simply re-starts the whole tag
top-level application by setting the xEventGroupSetBits(app.xStartTaskEvent, Ev_Tag_Task);

The initiator_send_poll() configures the DW1000 to send an immediate Poll message, and configures the
delayed reception (using timing configuration from Ranging Config message, see delayRx_us ) and reception
timeout (which is doubled of awaiting Response message length time, see env.responseRxTo_sy) in order to
receive the Response message from the node. While the DW1000 is sending the poll, the TagPollTask returns
to its “suspended” state, awaiting for the next SIGNAL from the RTC Wakeup timer to send another poll.

After transmission of the Poll message, the DW1000 will produce the IRQ, which will force MCU to execute the
dwt_isr(), which then will call the tx callback twr_tx_tag_cb().The DW1000 will be in the “wait for Rx” state,
counting off the time to its enabling of its receiver.

The twr_tx_tag_cb() saves the pollRtcTimeStamp – MCU RTC timestamp and pollTx_ts – DW1000 timestamp
into the TwrInfo structure.

After DW1000 enables its receiver, it may either receive a good frame or receive a timeout or an error. On any
of those events the DW1000 will assert its IRQ line, which interrupts the MCU causing it to execute the dwt_isr().
The dwt_isr() calls the callback twr_rx_cb() on reception of a valid frame or twr_rx_timeout_cb() or
twr_rx_error_cb() otherwise. Reception of an rx_timeout and an rx_error aborts the current ranging phase
iteration and increments the faultyRangesCnt, which will be analysed in the PollTask next time Wakeup timer
will expire.

The twr_rx_cb() saves the received Rx frame and the Rx timestamp to the circular buffer rxPcktBuf as structure
rx_pckt_t, and signals the app.rxTask, which causes the TagRxTask to process the received Rx packet.

The TagRxTask extracts the prxPckt from the rxPcktBuf and passes it to the twr_initiator_algorithm_rx() for
processing.

The TagRxTask has the highest possible RTOS IRQ priority, so that the Signal from the ISR passes to the task
by the RTOS kernel as fast as possible and the time-critical TagRxTask cannot be interrupted by any other
tasks.

The twr_initiator_algorithm_rx() receives the RxPckt and checks whether the packet has a valid format for both
known messages: Ranging Config or Response message, and if so it either updates the parameters in the tag’s
configuration by calling the initiator_received_range_init() function, or checks whether the response has been
received from the node which tag has polled, and if so, passes the received packet to the
initiator_received_response() function.

The initiator_received_response() function setup the DW1000 to send delayed Final message to the node using
precise calculation, based on PollTx2FinalTxDelay parameter received in the Ranging Config.

After setting up of the DW1000 for delayed transmit (for the Final) in the initiator_received_response(), the

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 25


DWM1003 PDoA Tag Source Code Guide

twr_initiator_algorithm_rx() calculates and sets the rough RTC Wakeup timer for next wakeup with correction of
slotCorr_us received in the Response message from the node. This is done in the
twr_configure_rtc_wakeup_ns().

At this point bare-metal twr_initiator_algorithm_rx() returns back to the TagRxTask. If reception of the Response
and sending of the Final was without errors, and the configuration parameter reportLevel (PCREP in Table 3)
is enabled, then the tag will output the last location information received in the Response: X, Y coordinates with
respect to the node and clock offset value. After that the TagRxTask is suspended, awaiting for a next SIGNAL
from twr_rx_cb().

During this time, or a bit after, the DW1000 will set the IRQ line, indicating successful finishing of transmission
of Final message, and call bare dwt_isr() function, which then will execute a twr_tx_tag_cb() call back. The
callback will setup the app.DwCanSleep flag to “1” and on exit from dwt_isr(), the DW1000 will be put to the
deep sleep mode. The same will happen if Error or RX Timeout were received during the RX interrupt.

In between of all actions described above the MCU can be in the Sleep mode, if task’s queue is completed and
FreeRTOS kernel can execute a system Idle task.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 26


DWM1003 PDoA Tag Source Code Guide

6 BUILDING AND RUNNING THE CODE


6.1 Building the code

This project is created using the Segger Embedded Studio IDE. The Segger IDE includes a full
license to develop, debug and run applications targeting nRF52832 ARM MCU, which is the MCU
used onto the Decawave’s DWM1001 hardware platform.

6.2 Installing of the Segger IDE

Download and install the Segger Embedded Studio IDE from the following web site:
https://www.segger.com/products/development-tools/embedded-studio/

6.3 Loading of the project to the IDE

Unpack the source code to the, for example, “dw_pdoa_tag” folder. In the Segger IDE, choose File-
>Open Solution and select the project dw_pdoa_tag.emProject, located in the
examples\dw_pdoa_tag\ folder.

6.4 Connecting, Building and Running of the application

Connect the board to the PC. You may require to install J-Link drivers, which could be found on the
Segger web site:
https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack
Install J-Link Software and Documentation pack, which includes drivers and J-Flash Lite tool
needed for reprogramming new FW binary into tag.
To check if the target board is working select Target->Connect J-Link from the menu. To start the
TDOA Tag application select Build->Build and Run from menu.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 27


DWM1003 PDoA Tag Source Code Guide

7 APPENDIX A
7.1 PDoA TWR application’s tag/PDoA node two-way ranging algorithm

The tag periodically initiates a range measurement, while the PDoA node listens and responds to the tag and
calculates the range. The ranging method uses a set of three messages to complete two-round trip
measurements from which the range is calculated. As messages are sent and received, the message send and
receive times are retrieved from the DW1000. These transmit and receive timestamps are used to work out a
round trip delay and calculate the range.

In the ranging scheme shown in Figure 13 below, the tag sends a Poll message which is received by the PDoA
node. The PDoA node replies with a response packets Resp, after which the tag sends the Final message.

Since the PDoA node also calculates the phase difference on the reception of the Final message, this means
that the tag can be located relative to the node after just a single ranging exchange. The range and measured
phase difference used on the node’s side to work out tag’s X-Y position relative to the node.

Tround1 Treply2
Tag time
Poll Resp Final
TX RX TX

RMARKER
Tprop Tprop Tprop

Node
Poll Resp Final
RX TX RX
Treply1 Tround2

The Final message communicates the tag’s Tround and Treply times
to the node, which calculates the range to the tag as follows:

Tround1 × Tround2 ̶ Treply1 × Treply2


Tprop =
Tround1 + Tround2 + Treply1 + Treply2

Figure 13: Range calculation in PDoA TWR

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 28


DWM1003 PDoA Tag Source Code Guide

7.2 UWB configuration and TWR timing profile used in the PDoA system

The PDoA node and tags hardware and software are designed to operate on one UWB configuration. This
includes antenna designs, data rate and message timings, used in the TWR exchange. This specified in the
Table 6 below.

Table 6 UWB mode of operation of PDoA system

UWB Channel Data Preamble PRF Preamble SFD PHR PAC Smart Tx
Config Rate Length Code mode power

Value 5 6.81 128 64 9 Non- Standard 8 Disabled


Mbit/s MHz Standard

In the PDoA TWR timing profile, see Figure 14, there are two timing parameters, pollTxToFinalTx_us and
delayRx_us. The pollTxToFinalTx_us parameter, specifies the rough time between RMARKER of Poll
and RMARKER of the Final Tx messages for the tag, see 7.1. And the delayRx_us parameter specifies the
rough time, the Tag shall activate its receiver after transmission of the Poll in order to receive the Response
from the PDoA node.
TWR timing profile
time µs

Tag’s State pollTxToFinalTx_us

SLEEP IDLE FRAME TX IDLE RX ON IDLE FRAME TX DEEP SLEEP

Poll dRx_us Final

Preamble Data

delayRx_us

Node’s State

Chip A RX ON FRAME RX IDLE FRAME TX IDLE RX ON – FRAME RX IDLE RX ON

Response
2450

Chip B IDLE RX ON – FRAME RX IDLE

Figure 14: PDoA TWR timing profile

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 29


DWM1003 PDoA Tag Source Code Guide

7.3 Frame time adjustments

Successful ranging relies on the system being able to accurately determine the TX and RX times of the
messages as they leave one antenna and arrive at the other antenna. This is needed for antenna-to-antenna
time-of-flight measurements and the resulting antenna-to-antenna distance estimation.

The significant event making the TX and RX times is specified in IEEE 802.15.4 [3] as the “Ranging Marker
(RMARKER): The RMARKER is defined to be the time when the beginning of the first symbol of the PHR of
the RFRAME is at the local antenna. The time stamps should reflect the time instant at which the RMARKER
leaves or arrives at the antenna. However, it is the digital hardware that marks the generation or reception of
the RMARKER, so adjustments are needed to add the TX antenna delay to the TX timestamp, and, subtract
the RX antenna delay from the RX time stamp. This is done automatically by DW1000, as long as the TX and
RX antenna delays are configured.

The tag’s and PDoA node uses configurable antenna delay values (which are initially defined in the
default_config.h file). The values have been experimentally set by adjusting them until the average reported
distance is the measured distance. This can be re-programmed in the NVM by using a corresponding control
command interface, see 3.2.2. This can be done temporarily during the GUI calibration stage, when the
values will be adjusted in the GUI PC application.

7.4 UWB messages, used in the PDoA TWR

There are following messages addressing modes employed in the PDoA system: the Blink message uses
long (64-bits) addressing mode, the Ranging Config message uses short-long (16 to 64-bits) addressing
mode, and the Poll, the Response, and the Final messages are uses short-short (16 to 16-bit) addressing
mode.
The general message formats, used in the Discovery phase and the Ranging phase follow the IEEE 802.15.4
standard encoding for a data frame, for more description see below.
Note:
The messages follow IEEE message encoding conventions, but these are not standardised RTLS messages.
The reader is referred to the ISO/IEC 24730-62 international standard for details of standardised message
formats for use in RTLS systems based on IEEE 802.15.4 UWB. This may be changed in future software
revisions.

7.4.1 Tag blink message

Initially a tag transmits Blink messages using the shortest IEEE blink message format. This is an optimized
blink message which also can be used for TDOA (Time Difference of Arrival) location methods. The encoding
of the blink message is as per Figure 15 below.
1 octet 1 octet 8 octets 2 octets
Tag’s
Frame Seq
64-bit FCS
Ctrl Number
Address

0xC5 - -

Figure 15 Encoding of Tag's 12-bytes blink message

7.4.2 Ranging Config message

During initial blinking the tag has only long 64-bit address. To maintain shortest timings, the PDoA node
assign to the tag a temporary short address using Ranging Config response. Thus, for Ranging Config
message to be delivered to the tag, the short-long addressing mode is used. This is shown on the Figure 16
below.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 30


DWM1003 PDoA Tag Source Code Guide

Frame buffer indices: 0, 1 2 3, 4 5 to 12 13 to 20 21 and up

2 octet 1 octet 2 octets 8 octets 8 octets Variable # octets 2 octets


Frame Sequence Destination Source Ranging Config
PAN ID FCS
Control (FC) Number Address Address Data
0x41 0xCC 0xCA 0xDE

Frame Control (FC)


Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Bit7 Bit 8 Bit 9 10 11 12 13 14 15
1 0 0 0 0 0 1 0 0 0 DestAd drMode 0 0 SrcAdd rMo de

Data Frame SEC PEND ACK 1 1 1 1


64-bit

Figure 16 Frame format of Ranging Config message

The PAN ID of the PDoA system and the PDoA node’s 16-bit addresses are in the MAC header, and the rest
is in the Ranging Config Data field: tag’s new 16-bit address and its configuration parameters. The description
of Ranging Config Data part of a range_init_msg_t structure is given in the Table 7.

Table 7: Fields within the Ranging Config message

Parameter Size, Value Description


octets
fCode 1 0x20 Function code: This octet 0x20 identifies this as node’s Ranging
Config message
tagAddr 2 Tag's short address to be used in the Ranging phase
reserved 4 Reserved for compatibility with Decawave’s TREK-1000 project
version 1 0x02 Version of Ranging Config message.
Version 0x02 : PDoA TWR to one node.
sframePeriod_ms 2 Super Frame period, ms
slotCorr_us 4 Slot correction from reception of Blink to the dedicated slot, µs
pollTxToFinalTx_us 2 The rough delay to be used by the tag, when it ranging to the node:
from the RMARKER of the Poll to the RMARKER of the Final, µs
delayRx_us 2 The tag shall start reception of Response with this delay after the
end of transmission of the Poll, µs
pollMultFast 2 The multiplier factor for Fast ranging (when tag is moving), in
number of superframes, e.g. 1 means “range every 1 superframe”
pollMultSlow 2 The multiplier factor for Slow ranging (when tag is stationary), in
number of superframes, e.g. 10 means “range every 10th
superframe”
mode 2 Bit fields for tag mode of operation:
bit 0: The Tag should use its IMU to detect its stationary mode.
bit 1-15: reserved for future application enhancement.

7.4.3 Ranging messages

During the Two Way Ranging, the tag and node use short (16-bit) addressing modes. The format of the
ranging frames, which are Poll, Response and Final is shown in Figure 17 below.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 31


DWM1003 PDoA Tag Source Code Guide

Frame buffer indices: 0, 1 2 3, 4 5 to 6 7 to 8 9 and up

2 octet 1 octet 2 octets 2 octets 2 octets Variable # octets 2 octets


Frame Sequence Destination Source Two Way
PAN ID FCS
Control (FC) Number Address Address Ranging Data
0x41 0x88 PanID

Frame Control (FC)


Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Bit7 Bit 8 Bit 9 10 11 12 13 14 15
1 0 0 0 0 0 1 0 0 0 DestAd drMode 0 0 SrcAdd rMo de

Data Frame SEC PEND ACK 0 1 0 1

Figure 17 Frame format used for Ranging

The content of the Two Way Ranging Data portion of the frame, defined by a first octet, identifies the type of
the Ranging message: Poll, Response or Final, as per Table 8 below.

Table 8 List of Function Codes in the PDoA TWR exchange

Function Code Description


Twr_Fcode_Tag_Poll 0x84 Initiator (Tag) Poll message
Twr_Fcode_PDOA_Resp 0x72 Responder (PDoA node) extended Response
Twr_Fcode_Tag_Accel_Final 0x89 Initiator (Tag) Final message back to responder (PDoA node)

7.4.3.1 The Poll message

The Poll message structure defined in the code as a structure of type poll_msg_t. This sent by the tag to
initiate a Ranging sequence. Table 9 describes the individual fields within the Poll message.

Table 9: Fields within the ranging Poll message

Parameter Size, Description


octets
fCode 1 Function code: This octet 0x84 identifies this as a tag Poll message
rNum 1 Range number: This is a range sequence number, on each range this
number is incremented (by modulo 256).

7.4.3.2 Response message

The Response message structure is defined in the code as a structure of type resp_msg_t. This sent by the
node as a Response to a Poll from the tag. Table 10 describes the individual fields within the Response
message.

Table 10: Fields within the ranging Response message

Parameter Size, Description


octets
fCode 1 Function code: This octet 0x71 identifies this as the Response message
slotCorr_us 4 Tag’s correction in microseconds, Least Significant Byte First.
This four octets is a correction factor that adjusts the Tag’s next wakeup

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 32


DWM1003 PDoA Tag Source Code Guide

Parameter Size, Description


octets
duration so that the Tag’s ranging activity can be assigned and aligned
into its dedicated slot.
rNum 1 Range number: This is a range sequence number, corresponding to the
range number as sent in the Poll.
x_cm 2 Last measurement of the X coordinate reported back to the tag from the
node. If no previous measurements, the 0xDEAD reported (-8531 dec).
y_cm 2 Last measurement of the Y coordinate reported back to the tag from the
node. If no previous measurements, the 0xDEAD reported (-8531 dec).
offset_ppmh 2 The Tag’s crystal offset value with respect to the Nodes’ master TCXO,
reported back to the tag from the node. If no previous measurements,
the 0xDEAD reported (-8531 dec). This can be used in the automatic
crystal trimming process with respect to the node on the tag’s side.

7.4.3.3 Final message

The Final message is a structure of type final_msg_t and it sent by the tag after receiving the PDoA node’s
Response message. Table 11 lists and describes the individual fields within the Final message.

Table 11: Fields within the ranging Final message

Octet #’s Size, Description


octets
fCode 1 Function code: This octet identifies the message as the tag Final
message
rNum 1 Range number: This is a range sequence number, corresponding to
the range number as sent in the Poll.
pollTx_ts 5 Tag Poll TX time: This 5 octet field is the TX timestamp for the tag’s
poll message, i.e. the precise time the Poll frame was transmitted.
responseRx_ts 5 Tag Response RX time: This 5 octet field is the RX timestamp for the
response from the PDoA node, i.e. the time the tag received the
Response frame from the PDoA node.
finalTx_ts 5 Final TX time: This 5 octet field is the TX timestamp of the final
message, i.e. the time the Final frame will be transmitted, (this is pre-
calculated by the tag).
flag 1 User flag, where bit 0 indicates whether the Tag is moving or not.
acc_x 2 IMU data, accelerometer raw value for X-axis
acc_y 2 IMU data, accelerometer raw value for Y-axis
acc_z 2 IMU data, accelerometer raw value for Z-axis

7.5 Slot Time correction method

The PDoA node and tag both use RTC timers to implement the slotted TDMA access method. The PDoA
node’s RTC timer is used to trigger the start of node’s superframe, which absolute timestamp in MCU RTC
time units is saved in the gRtcNode timestamp variable (in the Node’s application it is
gRtcSFrameZeroCnt).
The tag’s RTC timer is intended to keep the tag transmitting in its assigned TDMA slot. Every time the tag is
starting a Poll frame, the timer is configured to expire every wakeUpPeriodCorrected_ns, which holds the
value, of the duration of the tag’s superframe – note this is in the tag’s time and not in the PDoA node’s time
domain (the value is close to the PDoA node’s superframe period, but may vary). If the tag is not intended to

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 33


DWM1003 PDoA Tag Source Code Guide

range on the next expiration of the timer (i.e. when the tag is configured to range less frequently than every
superframe), the timer will keep expiring every wakeUpPeriodCorrected_ns until tag decides it is time for
the next ranging exchange.
On the reception of the Response message from the PDoA node, the tag receives the slotCorr_us, which
specifies the time where the PDoA node has expected the reception of the tag’s Poll with respect to the start
of the node’s superframe (gRtcNode), see Figure 18. Upon reception of the Response, the
nextWakeUpPeriod_ns is calculated as follows:
nextWakeUpPeriod_ns = 1e6* sframePeriod_ms;
nextWakeUpPeriod_ns -= WKUP_RESOLUTION_NS * (rtcNow - gRtcSFrameZeroCnt );
nextWakeUpPeriod_ns -= 1e3* slotCorr_us;
The method above includes the correction of the time needed for the tag to wake up and initiate transmit the
Poll message, so that for the next transmission the RTC should wake up the MCU at the correct time for the
pollTask to execute and transmit the Poll message.
TAG
Set the standard nextWakeUpPeriod_ns gRtcTag
Wakeup time to the
gRtcTag ~SF Period Expected PollRxRtcNode_us

pollTxRtcTag pollTxRtcTag
TX
pollTxFinalTx_us

respRxRtcTag
RX
ReplyDelay_us

NODE: chip A

gRtcNode gRtcNode
Expected
pollRxRtcNode

TX
Next poll
Assigned slot to shall be
earlier this Tag s Poll
the Tag s Poll:
time. within the
slot missed or not
slotCorr_us assigned slot
very accurate
Actual
pollRxRtcNode
RX

Figure 18 Node-Tag Slot Time correction method

7.6 The application architecture in the flowchart

The flowcharts of Figure 19 and Figure 20 shows the interaction of the software blocks with each other and
shows where the main functionality of the tag can be found in the sources.
With the reference to the figures, the main blocks are as follow:
1. Initialization of the hardware and peripherals. This is generated by CubeMX HAL software, by
providing the initialization of the target MCU and simplifying the physical interface driver development.
2. RTOS based functionality. This includes the FreeRTOS kernel, and all files with prefix “task_”. This
separates the functionality of the applications, and aids in the management of MCU time more
effectively and makes the code design cleaner at the expense of a small increase in latency. This
adds an “application” layer, sitting on the top of bare-metal implementations.
3. Bare-metal implementation of actual functionality: callbacks, tx_start, usb_uart_rx, usb_uart_tx, etc.

The source files are organized to match the architecture of the application, see 2.2, 7.7

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 34


RTC WKUP TIMER IRQ - RTOS level prio;
TAG INIT thread (tag_helper)
- Once configured, is always running;
Start - Setup run-time environment of DW1000 - 30.5175us resolution;
for TAG mode (CH/PRF/FrameFiltering/ Scope:

© Decawave 2018 Confidential


callbacks) - Sets gRtcSFrameZeroCnt: start of
- Setup RANGE-INIT ms-resolution timer; internal SuperFrame;
- Setup Blinking thread; - Counting Slow/Fast range options;
INITIALIZE HW - Setup Tag Rx thread; - Signal to the Poll thread to transmit;
- Self-destroy. - Wake up MCU every SuperFrame;
Signal
nRF HAL
initiator_send_poll()
tx_start()
Polling Thread (TagPollTask) - Setup Tag Poll Msg;
Read Default - Setup Delayed Rx, Delayed Rx timeout;
No
Configuration - Wait Poll Signal; - Transmit Poll immediate;
data
(NVM) - Wake up DW1000;
- Execute fn: initiator_send_poll().
- If FaultyRange Counter is over the limit, initiator_send_blink() initiator_received_response()
SETUP Core tasks then setup Event to Switch Helper to
restart the Tag app. - Setup Tag Final Msg;
- Setup Tag Std Blink Msg;
DWM1003 PDoA Tag Source Code Guide

- Default thread. - Setup Delayed Rx, Delayed Rx timeout; - Calculate Final Tx Time;
- Control thread. - Transmit Blink immediate; - Transmit Final delayed;
- Flush thread. (DW1000 will go to sleep on RX_Timeout/RX_err c
No
data
Blinking Thread (BlinkTask)

EVENT: restart TAG


START SCHEDULER - Wait for Blink signal; initiator_wake_and_send_poll()
- Wake up DW1000;
- Execute fn: initiator_send_blink(); - On reception of Range-Init Msg executes
initiator_received_range_init(): Configure RTC WKUP TIMER.
Default Thread STOP . Setup Range Phase parameters;
(Task Switch Helper) Signal . Stop Range-Init timer (SW timer). - Configures the RTC WKUP Timer
. Configure RTC WKUP TIMER. to the correct slot for the next

AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1
Poll

Figure 19 Application flowchart part 1


RANGE-INIT TIMER (BlinkTimer_cb) - On reception of Response Msg
-Initial LED blinking; . Configure/Adjust RTC timer for exact Slot for next Poll;
-Setup Event to start Tag task; ~1ms resolution SW timer. . Execute fn: initiator_received_response(); Setup Range Phase parameters
-Slow run forever: - Count Blink period; rxPckt
User Aplication Task Switch - Signal to the Blinking thread to transmit - Configure air run-time parameters:
data
helper: If Event to start a user . Tag Short Address,
application task, then kill all . SuperFrame period,
twr_rx_cb() . TWR exchange delays,
running task and start Event s
Tag Rx Thread (TagRxTask) . Slow and Fast range rates.
one. - Save rxPacket, TimeStamp, RTC Rx
- Wait the Rx Signal. Time to the fast circular buf;
- Extract rxPckt from circular buf; Signal -Signal to the Rx Thread.
- Execute fn: twr_initiator_algorithm_rx();
main.c
Note: this should be the high priority task. Src/bare/tag.c

EVENTs to start User application task Call RX callback from DWT_ISR()


Src/task/Task_tag.c

Page 35
DWM1003 PDoA Tag Source Code Guide

Figure 20 Application flowchart part 2

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 36


DWM1003 PDoA Tag Source Code Guide

7.7 List of source code files

Table 12 gives a list of files (excluding nRF SDK files) that make up the source code of the Tag ARM
application.

Table 12 List of core files and directories in the Tag ARM application

Filename Brief description


decadriver
deca_device.c DW1000 device library API functions – source code
deca_device_api.h DW1000 device library API interface header
deca_params_init.c Device library configuration parameters tables
deca_param_types.h Device library configuration parameters interface header
deca_regs.h DW1000 Register Definitions
deca_types.h Device library types definition
deca_version.h DW1000 device library version
10_dof_driver 10 degrees of freedom IMU drivers
10_dof_driver\lis2mdl 3DoF magnetometer/compass
lis2mdl.c
lis2mdl.h
10_dof_driver\lps22hb Barometer
lps22hb.c
lps22hb.h
lps22hb_reg.h
10_dof_driver\lsm6dsl 3DoF accelerometer + 3DoF gyro
lsm6dsl.c
lsm6dsl.h
examples\bsp
boards.h
pca10040.h Definitions for the board – pins, LEDs, etc.
examples\dw_pdoa_tag
dw_pdoa_tag.emProject Project file
dw_pdoa_tag.emSession
flash_placement.xml Linker config file (stack, heap, code, data, etc.)
examples\dw_pdoa_tag\Src
freertos.c application-interface to the FreeRTOS
Entry point to the application.
main.c
Has the Default task in the StartDefaultTask()
dw_pdoa_tag_common.c
examples\dw_pdoa_tag\Src\bare
cmd.c Command parser
cmd_fn.c Command parser’s functions for execution
config.c Interface to NVM and .bss configurations
tag.c Collection of bare-metal functions to implement Tag application.
tcfm.c Collection of bare-metal functions to implement TCFM application.
tcwm.c Collection of bare-metal functions to implement TCWM application.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 37


DWM1003 PDoA Tag Source Code Guide

Filename Brief description


usb_uart_rx.c Bare-metal receive from USB/UART
usb_uart_tx.c Bare-metal transmit via to USB/UART
usb2spi.c
examples\dw_pdoa_tag\Src\Inc
circ_buf.h Macros for circular buffer
cmd.h Header for cmd.c
cmd_fn.h -
config.h -
deca_sleep.h -
default_config.h Default configuration header. All default parameters are here.
error.h Error codes
msg_time.h -
tag.h Header for tag.c
task_ctrl.h Header for task_ctrl.c
task_flush.h -
task_imu.h -
task_tag.h -
task_tcfm.h -
task_tcwm.h -
task_usb2spi.h -
tcfm.h -
tcwm.h -
translate.h -
usb2spi.h -
usb_uart_rx.h -
usb_uart_tx.h -
util.h -
uwb_frames.h Defines the common frames structures used in Tag and Node
version.h Version of the application
examples\dw_pdoa_tag\Src\port
deca_uart.c Platform-specific UART functions
deca_usb.c Platform-specific USB functions
dw1000_rbct.c DW1000 range correction tables
port_platform.c Other platform-specific functions
port_platform.h -
examples\dw_pdoa_tag\Src\task
task_ctrl.c Core task: Command Control and Data task
task_flush.c Core task: Flush Report Buffer
task_imu.c Service task for IMU sensor, sets stationary flag
task_tag.c Collection of top-level application tasks for Tag
task_tcfm.c top-level application task: TCFM
task_tcwm.c top-level application task: TCFM

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 38


DWM1003 PDoA Tag Source Code Guide

Filename Brief description


task_usb2spi.c top-level application task: USB2SPI
examples\dw_pdoa_tag\Src\utils
msg_time.c Calculates frames durations
translate.c Translates some parameters to human-readable format and back
util.c Collection of helpful utilities
examples\dw_pdoa_tag\Output Build files for the project
examples\dw_pdoa_tag\config
sdk_config.h Configuration of peripherals used by SDK and application
components nRF SDK source files
external nRF SDK source files
integration nRF SDK source files
modules nRF SDK source files

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 39


DWM1003 PDoA Tag Source Code Guide

8 BIBLIOGRAPHY
Ref Author Title
[1] Decawave DW1000 Data Sheet
[2] Decawave DW1000 User Manual
IEEE 802.15.4‐2011 or “IEEE Std 802.15.4™‐2011” (Revision of
IEEE Std 802.15.4-2006).
IEEE Standard for Local and metropolitan area networks— Part 15.4: Low-Rate
[3] IEEE
Wireless Personal Area Networks (LR-WPANs). IEEE Computer Society
Sponsored by the LAN/MAN Standards Committee.
Available from http://standards.ieee.org/

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 40


DWM1003 PDoA Tag Source Code Guide

9 DOCUMENT HISTORY
Table 13: Document History

Revision Date Description


1.1 27th of August 2019 Minor fixes to meet FW v4.2.0
1.0 19th of October 2018 First release

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 41


DWM1003 PDoA Tag Source Code Guide

10 FURTHER INFORMATION
Decawave develops semiconductors solutions, software, modules, reference designs - that enable real-time, ultra-
accurate, ultra-reliable local area micro-location services. Decawave’s technology enables an entirely new class of easy
to implement, highly secure, intelligent location functionality and services for IoT and smart consumer products and
applications.
For further information on this or any other Decawave product, please refer to our website www.decawave.com.

© Decawave 2018 Confidential AP-DWM1003-PDoA-Tag-Source-Code-Guide-1.1 Page 42

You might also like