Reading ranging data from DecaWave EVK1000

DecaWave EVK1000 and TREK1000

EVK1000 and TREK1000 are Two-way Ranging Evaluation Kit for DecaWave’s UWB DW1000 chip. You can see and evaluate a ranging result on a screen of each of them. However, to see a positioning result, you need to connect one of them with a PC and use DecaWave’s dedicated software only on Windows. Here’s how to read data from EVK1000 without the dedicated software

Preparing a Driver

This kit has a COM (serial) port. But this port is wrapped with USB interface and operates with a virtual COM port driver

  • On Windows, a driver for this (STM32 Virtual ComPort in FS Mode v1.4.0) can be downloaded at here. After downloading and extracting the file, run <OS>/dpinst_<arch>.exe where <OS> and <arch> are your OS and architecture, respectively. A related thread can be found here
  • On Linux and macOS, when a board is connected, a driver will be automatically loaded

For more detail, please refer FTDI Chip

Reading and Parsing Ranging Data

Configure anchors and a tag by flipping switches as instruction says, and connect an anchor or a tag with a PC. Since it uses a virtual COM port, serial communication parameters are automatically configured and you don’t need to worry about it

When connection is successful, you can see outputs on a serial port terminal as the following:

1
2
3
4
5
6
7
8
9
10
11
mr 01 000004d1 00000000 00000000 00000000 001e 20 403c403c t7:0
mc 01 0000058c 00000000 00000000 00000000 001f 21 00003fe5 t7:0
mr 01 000004ba 00000000 00000000 00000000 001f 21 403c403c t7:0
mc 01 0000059a 00000000 00000000 00000000 0020 22 000040fd t7:0
mr 01 000004c8 00000000 00000000 00000000 0020 22 403c403c t7:0
mc 01 00000579 00000000 00000000 00000000 0021 23 00004215 t7:0
mr 01 000004a7 00000000 00000000 00000000 0021 23 403c403c t7:0
mc 01 0000059a 00000000 00000000 00000000 0022 24 0000432d t7:0
mr 01 000004c8 00000000 00000000 00000000 0022 24 403c403c t7:0
mc 01 00000574 00000000 00000000 00000000 0023 25 00004445 t7:0
...

Here, important columns are from the 3rd to 6th, 7th, 8th columns

  • The 3rd to 6th columns represent a range measurement from each anchor 0 to 3 in hexadecimal
    • For example, 000004d1 represents 0x4d1 or 1233, which is 1.233 m.
  • The 7th column represents a sequence number
  • The 8th column represents a ranging sequence number

Modifying regulations in Intel Wi-Fi card EEPROM

Regulations in EEPROM

Wi-Fi regulation defines various restirctions such as transmission power, initial radiation, and dynamic frequency switching for Wi-Fi to operate in a certain country. Most OSs including Linux contain regulations in their kernels, and we can bypass them by modifying a regulation file or a kernel.

However, certain Wi-Fi cards such as Intel’s have their own regulations in their EEPROM, which takes precedence to kernel’s regulations. Here’s how to modify regulations in Intel Wi-Fi card’s EEPROM. In this article, Intel Ultimate N WiFi Link 5300 is used

Preparing a Tool

iwleeprom is a software to read and write content in an EEPROM. Clone, build and install it:

1
2
3
4
$ git clone [https://github.com/0x90/iwleeprom](https://github.com/0x90/iwleeprom)
$ cd iwleeprom
$ make
$ [sudo] make install

Interpreting a Regulation Flag

First, let’s have a look at what EEPROM contains. To read regulations in EEPROM, type iwleeprom -s:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ iwleeprom -s
Supported devices detected:
[1] 0000:03:00.0 [RW] Ultimate N WiFi Link 5300 (8086:4236, 8086:1011)
Select device [1-1] (or 0 to quit): 1
Using device 0000:03:00.0 [RW] Ultimate N WiFi Link 5300
No file names given or patch option selected!
No EEPROM actions will be performed, just write-enable test
Regulatory data from card EEPROM...
Regulatory base: 0156
Channel 1: 0e6f
Channel 2: 0f6f
...
Channel 64: 0f31
...
Channel 1 (HT40): 0a6f
Channel 2 (HT40): 0f6f
...
Channel 157 (HT40): 0f61

What those 0e6f, 0f31 and other things mean? Those are flags defining regulations. So, which bit stands for what? When you are looking into Linux kernel source code, specifically, iwlwifi driver, you can see flag definition as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* enum iwl_eeprom_channel_flags - channel flags in EEPROM
* @EEPROM_CHANNEL_VALID: channel is usable for this SKU/geo
* @EEPROM_CHANNEL_IBSS: usable as an IBSS channel
* @EEPROM_CHANNEL_ACTIVE: active scanning allowed
* @EEPROM_CHANNEL_RADAR: radar detection required
* @EEPROM_CHANNEL_WIDE: 20 MHz channel okay (?)
* @EEPROM_CHANNEL_DFS: dynamic freq selection candidate
*/
enum iwl_eeprom_channel_flags {
EEPROM_CHANNEL_VALID = BIT(0),
EEPROM_CHANNEL_IBSS = BIT(1),
EEPROM_CHANNEL_ACTIVE = BIT(3),
EEPROM_CHANNEL_RADAR = BIT(4),
EEPROM_CHANNEL_WIDE = BIT(5),
EEPROM_CHANNEL_DFS = BIT(7),
};

For example, channel 1 has flags 0e6f, which is 1110 0110 1111 in binary. Its interpretation is:

1
2
3
4
5
6
7
8
1110 0110 1111
.............1 This channel is valid
............1. Not valid for IBSS
...........1.. (Unknown)
..........1... Active scanning is allowed
........0..... RADAR detection is not required
.......1...... Supports wide band
......1....... Candidate for dynamic frequency selection

Reading EEPROM

To read and dump EEPROM, type iwleeprom -o <outfile>:

1
2
3
4
5
6
7
8
9
10
11
12
$ iwleeprom -b -o eeprom_dump
Supported devices detected:
[1] 0000:03:00.0 [RW] Ultimate N WiFi Link 5300 (8086:4236, 8086:1011)
Select device [1-1] (or 0 to quit): 1
Using device 0000:03:00.0 [RW] Ultimate N WiFi Link 5300
Saving dump with byte order: BIG ENDIAN
0000 [................................................................]
0080 [................................................................]
...
0780 [................................................................]

EEPROM has been dumped to eeprom_dump

We can view the dumped EEPROM with xxd command or hex mode (:%!xxd) in vim, and can find channel flags. They are written in the same order of channels, but their offsets are not in linear relationships. You can manually locate an offset of each channel:

1
2
3
4
5
6
7
8
9
10
11
12
$ vim eeprom_dump
:%!xxd
00000000: 5a40 0050 7000 0410 0030 0000 0280 8086 4236 8086 1011 0d01 [email protected].......
...
00000150: ---- ---- ---- ---- ---- ---- ---- --0e 6f0f 6f0f 6f0f 6f0f :.........oM.W...o.o.o.o.
00000168: 6f0f 6f0f 6f0f 6f0f 6f0f 6f0f 6f0f 610f 6100 0000 0000 0000 :o.o.o.o.o.o.o.a.a.......
00000180: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 :........................
00000198: 0000 000f e100 000f e100 000f e100 000f e10f 310f 310f 310f :..................1.1.1.
000001b0: 3100 000f 310f 310f 310f 310f 310f 310f 310f 310f 310f 310f :1...1.1.1.1.1.1.1.1.1.1.
000001c8: 3100 0000 000f a10f a10f a10f a10f a100 000d 0a6f 0f6f 0f6f :1..................o.o.o
000001e0: 0f6f 0f6f 0f6f 0c6f 0000 0ce1 0fe1 0f31 0d31 0e31 0f31 0f31 :.o.o.o.o.......1.1.1.1.1
000001f8: 0f31 0f31 0f61 0f61 :.1.1.a.a

Modifying Regulations

It is easy. Open the dumped EEPROM in vim and set to hex mode (:%!xxd). And change the content as you want. To save changes, reert hex mode (:%!xxd -r) and save it (:w)

Writing New Regulations in EEPROM

After finishing modification, rewrite EEPROM with iwleeprom -m -c -i <infile>:

1
2
3
4
5
6
7
8
9
10
11
12
$ iwleeprom -m -c -i eeprom_dump
Supported devices detected:
[1] 0000:03:00.0 [RW] Ultimate N WiFi Link 5300 (8086:4236, 8086:1011)
Select device [1-1] (or 0 to quit): 1
Using device 0000:03:00.0 [RW] Ultimate N WiFi Link 5300
Dump file byte order: BIG ENDIAN
0000 [================================================================]
0080 [================================================================]
...
0780 [================================================================]

EEPROM has been written from eeprom_dump

Finally, you can check modification is applied via iw phy command