Skip to content

Handling Timestamps

Daniel King edited this page Nov 6, 2016 · 1 revision

Ultra-wideband radios, as defined by IEEE 802.15.4-2011, operate at a peak chipping frequency of 499.2 MHz. This frequency is used to derive counters in the DW1000 that are used for its timestamping features. The DW1000 is capable of timestamping events based on a ~64 GHz clock (i.e. 499.2 MHz * 128), which provides a precision of 15.65 picoseconds and allows the DW1000 to achieve its 10 cm ranging precision.

Although the transmit and receive timestamps operate at the highest precision (15.65 ps), other features of the DW1000 (such as delayed transmit/receive) are based on the DW1000's System Time Counter which operates at 124.8 MHz, i.e. (499.2 MHz * 128) / 512. The precision of the System Time Counter is therefore approximately 8 nanoseconds.

The timestamps are represented in the DW1000 register set as 40 bit unsigned integers, which provides a range of up to approximately 17.21 seconds, i.e. (2^40 - 1) / (499.2 MHz * 128). The System Time Counter therefore wraps-around every 17.21 seconds.

The DW1000.System_Time Package

The DW1000.System_Time package provided by this driver defines several fixed-point types to represent these different granularities of time:

  • The type Fine_System_Time is a fixed-point type representing the time in seconds with a delta of 15.65 picoseconds (0.000_000_000_015_65 seconds), and a range of 0.0 to approximately 17.21 seconds. This type is used mainly for the transmit and receive timestamps.
  • The type Coarse_System_Time is a fixed-point type representing the time in seconds with a delta of approximately 8 nanoseconds (0.000_000_008), and a range of 0.0 to approximately 17.21 seconds.
  • The type Antenna_Delay_Time is a subtype of Fine_System_Time, used to represent the antenna delay. The antenna delay has a precision of 15.65 ps (same as Fine_System_Time), but has a reduced range of up to 525.128 microseconds (0.000_525_128 seconds).
  • The type Frame_Wait_Timeout_Time is a fixed-point type representing the time in seconds with a delta of 8 nanoseconds (same as Coarse_System_Time), but with a limited range of up to ~67.22 milliseconds. This type is used for the frame wait timeout functionality.

Converting to/from Bits Representations

The DW1000 register set represents the time using 40 bit unsigned integers (where the least significant bit (LSB) is 15.65 picoseconds), or 16 bit unsigned integers in the case of antenna delay values. The DW1000.System_Time package provides functions to convert from its fixed-point types to their unsigned integer representations. These functions are as follows:

  • The To_Bits_40 function is overloaded to convert from either Fine_System_Time or Coarse_System_Time to their corresponding Bits_40 representation used by the DW1000 register set.
  • The To_Bits_16 function is overloaded to convert from either Antenna_Delay_Time or Frame_Wait_Timeout_Time to their corresponding Bits_16 representation used by the DW1000 register set.

There are also functions to convert the other way that are named after the type to which they convert. For example, To_Fine_System_Time converts to Fine_System_Time from either the Bits_40 representation, or from another fixed-point time type, such as Coarse_System_Time.

Calculating The Time Elapsed Between Two Timestamps

Since the System Time Counter wraps around every 17.21 seconds, it is necessary to take into account this wrap-around when calculating the time elapsed between two timestamps. For example, given two timestamps A and B, where A occurs before B. If they are 1 second apart then it is possible that A = 17.0 and B = 0.79, since the counter wraps around at 17.21 seconds.

The DW1000.System_Time package provides the Calculate_Span function to calculate the time elapsed between two timestamps, taking wrap-around into account. The return type of Calculate_Span is System_Time_Span, which has the same range and precision as the Fine_System_Time type (i.e. 15.65 picoseconds).

Below is an example of calculating the time elapsed between two timestamps:

declare
   A       : Fine_System_Time := 17.0;
   B       : Fine_System_Time := 0.79;
   Elapsed : System_Time_Span;
begin
   Elapsed := Compute_Span (A, B);
   --  Elapsed is approximately equal to 0.997 (almost 1 second).
end;

The Calculate_Span function is overloaded to accept combinations of Fine_System_Time and Coarse_System_Time.