Advanced detailed overview - ZuwaiiVR/Watchman_V2_detailed GitHub Wiki

Specifications


NRF52840 on Tundra Firmware

  • Data Transfer 1mbit
  • Radio Bandwidth 1Mhz
  • Using Nordic Proprietary Radio Protocol.
  • Channels 0-80 (2400-2480mhz)
  • Transmit Power +4dbm ~ -4dbm (varies on activity)
  • USB Current draw 5v 0.012A +/- (active) (PCA10059 dongle)
  • USB Full Speed
  • USB HID 64bytes / 500 pps
  • USB PID VID 28de 2102
  • Datasheet https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.8.pdf

Serial Number meaning

The numbers you see often for example 86CB101CCF-1YX are based on Device Address from the FICR register 0x10000000 0x0A4/0x0A8 (Factory information configuration) These numbers are unique per chip and burned inside the chip and cannot be changed. However these numbers are not exactly the same numbers (FICR vs steamvr). Afaik, these were replicated to match the older Watchman dongles with NRF24 inside. We break out the serial numbers into parts how it is generated..

[86] [CB 10] [1C CF]-[1][YX]

So first we have our device Address from the FICR register follows as a unsigned 32 bit int.

uint32_t DEVICEADDR[0] = 0xcb101e05;

uint32_t DEVICEADDR[1] = 0x81c29cb6;

to create [86] we have this formula.

uVar1 = (DEVICEADDR[0] >> 0x10 | (DEVICEADDR[1] & 0xffff | 0xc000) << 0x10) & 0x00CFFFFF;

creates 0x000000000086CB10

The second [CB 10] is basically a copy of DEVICEADDR[0], so we can do it like this

uVar2 = uVar1 * 0x10000;

creates : 00000086CB100000

the third [1C CF] part was tricky to figure out but it seems it is a lookup table inside the binary file. The lookup table can be found on address 0x000E24D4 and it look like this.. image

uVar3 = (uint) * (ushort *)(DAT_000e24d4 + ((DEVICEADDR[0] & 0xffff) * 0x230 >> 0x10) * 2);

creates : 0000000000001CC

So if you add them all up you get

00000086CB101CCF

from

UVar1 : 000000000086CB10

UVar2 : 00000086CB100000

UVar3 : 0000000000001CCF

Next the [1] defines whether the dongle is configured as First or Last position in the (Super Dongle) configuration by physical pins shorting to ground, this also change some Synchronization pin which I will talk about later.

The [YX] I haven't look for it yet however this part changes if you configure the dongle as a Valve Radio or Valve Radio + MIC These are the labels you probably seen if you own a Valve Index Headset, the serial number ends with [LYM] and second [RYB]. There are other labels such as [LYX] or [DYX] also available. The labels xYX (x represents number) are not available inside the Valve Index radio firmware.

On my guess, the labels might represent...

LYM - Left Main dongle + i2S Microphone (Yes this dongle is also used for Mic input on Valve Index lol) + Sync Output.

DYX - Accessory Extra tracker? + Sync Output.

LYX - Left Main dongle without Mic + Sync Output

RYB - Right + Sync Input

1-7YX - Tundra Custom implantation

besides Tundra's implantation, I never seen the LYX or DYX labels before.

Pins and Ports


Reversing the firmware

Block Diagram


step Dongle To Tracker connection simplified
1 Dongle Watchman V2, Firmware read's DeviceID from NRF unique FICR register
2 Firmware generates 5byte ID, Adds another ID based on GPIO states (-1YX .. -7YX)
3 Firmware send new generated unique ID through USB and NRF Radio for frequencies and pairing
4 Tracker side
5 After pairing Tracker will receive Dongle Address
6 On power up, Tracker read's Dongle address (it can be multiple)
7 Tracker generates frequencies from dongle's Device ID.
8 Tracker Transmit a package to see if dongle response
9 if Dongle response, Dongle sends a small packet back to tracker
10 tracker send out tracking data in sequence (through ch1 - ch7)
step Pairing
1 On Dongle, To enter pairing mode, use SteamVR or Lighthouse_console command "pair"
2 Dongle's receiving address will change to a fixed address to listen on.
3 Tracker side: Going into pairing mode will send a package on all available legal channels
3a Sweeps through 2-80ch, or 2402Mhz - 2480Mhz
4 once dongle receives, it replies back, and both are paired, changes address to dongle's

Registers configuration on tracker/dongle

Register Pairing mode Dongle
pcnf 00030006 01040020
base f24a2a9a 0080603c
prefix c040006a 0000a020
txrxaddr 00000000 00000003
Register Pairing mode Tracker
pcnf 00030006 01040020
base f24a2a9a 43434343
prefix 23c3436a 13e363a3
txrxaddr 00000000 00000001
Register Listening Dongle (normal use)
pcnf 00030006 01040020
base f24a2a9a 0080603c (Dongle Address)
prefix c040006a 0000a020
txrxaddr 00000000 00000003

Memory registers


Device Function Address
Tracker Channel/Frequency Array 0x20000095
Tracker Partial Serial Number for RADIO 0x20000091
Dongle Channel/Frequency Array 0x2001b042
Dongle Partial Serial Number for RADIO 0x2001b03E

Frequencies


Each dongle uses a unique set and pattern of channels, this quote is from Valve them self. ( https://steamcommunity.com/app/358720/discussions/0/1495615865215597066/ ) This is true and I can confirm that through capturing the 2.4ghz band with SDR, or by reading out the memory when dongle is operating through SWD. image The channels, or frequencies are based on the Serial Number that has been created through DEVICEID that is unique from the NRF52840. once that has been done, the firmware gives this serial number to a generator that generates the pre-assigned 7 channels. image Here's a picture where I copied the values from the dongles through SWD and read the memory array where these frequencies are stored. The pattern look's interesting, though you notice red dots to the bottom, those channels will overlap the more dongles you use. Overlapping wont say it's gonna be bad, they can overlap as they don't sent 7 channels all at once, rather they switch very fast.

After analyzing how they send it, it's just from 0-6.. I have changed the 7 frequencies on the tracker side, to send out 2407 to 2414mhz to see how this is working. each packet they send out is different but from the same stream they send out. there's no such as "First channel does IMU, Second does..." Nope.

image

So like these serial numbers..

Dongle SN C1 C2 C3 C4 C5 C6 C7
000000063C-4YX 31 3e 18 0d 08 45 27
000100063C-4YX 29 22 13 38 4c 05 3d
000200063C-4YX 2b 0e 21 43 48 34 02

When the dongle has one of these serial numbers, for example "000100063C" it will send out first 0x29, then 0x22... and so on. The Pros are, we don't have to worry to configure the channels and sort of unlimited use of any dongles however...

The Cons... your dongle does not change frequencies, so if you always experience fly aways, or disconnects, you're better off to buy a new dongle to change frequencies (This can be a problem with SW3/SW/4SW5/SW7 tundra), also if some other dongle uses similar frequencies. you're out of luck and this issue will always happen. however, my firmware modification allows you to change this serial number to a custom one so you can avoid certain channels etc.

So far I tried to re-create the frequency generator through reversing the firmware, however I didn't get that working proper yet.

So what happens if one of the packets get lost due the heavy traffic with wifi?

This is by reading the reversed code and testing by occupying a channel when tracker and dongle are paired. Using Lighthouse_console, the usbcheck command will reveal how much packages are received. Nearly around 500 when connection is perfect.

image

When a few packages are missing, lighthouse_driver.dll or steamvr would just try to interpolate as there is also a timestamp sended with it. But if too much is lost, which cause your fly away's, this is mainly, it's too busy on the 2.4ghz band. The dongle tries to catch up as quick as possible. Also another downside is the NRF radio itself is not a very good radio, for example, on the SDR graph, it's pretty sharp to see where the channels are... This is however not the same thing for the NRF Radio.

On a stock NRF Radio when running a custom code to run RSSI (Received Signal Strength Indicator) the NRF52 will receive the channels beside it too! Example, listening to Channel 5, you will hear noise on Channel 4 and 6 at half strength, and channel 3 and 7 half strength of 4 6 etc... I tried to change the 7 channels into one channel and put all 4 trackers very close to each other, result was very bad actually lol.

image

The first tracker was fine-ish, however the second and 3rd were disconnecting, the 4th was still sending but doesn't appear in SteamVR. But tracking is fine, when only 1 tracker is active. So channel switching is a must to avoid crosstalking(?).

image This is a image where you can see the SDR is receiving very clearly. The device on the right is a RSSI debugger using a NRF52840 to look also onto the 2.4ghz band, but a different approach to plot a graph, each pixel represents a frequency (1mhz), you can clearly see the NRF52 doesnt fill up 1 channel but multiple. This is how the NRF520840 see's in the Radio 2.4ghz band.

About decreasing the 7 channel array is possible, I tried changing it to 1 channel in the trackers and dongle's firmware, however this didnt go well. This is mainly because of I explained above, however I changed it into 2 Channels, so it sends 2 channels, this worked better somehow but not perfect. I haven't test 3 or 4 Channels, maybe this might be a sweet spot since it wont spread out all over the entire band. As Wifi takes 20mhz or 40Mhz, it would be nice to avoid those as much as possible. (If you can't control your wifi environment ...) Decreasing or increasing doesn't affect performance or any packet drops, it will always still 500 packets per seconds on lighthouse_console.

However, to decrease the channels, I had to modify the tracker's firmware too, so to make this effective for testing I would need to modify all firmware's on the trackers and Index Controller.. The firmware's on them should be similar across devices.

Transmit Power


When monitoring the TX Power register on the dongle, I get various results, it's either set to 0xFC (-4dbm) or as high but not max (+4dbm, not +8dbm). It's controlled in a matter probably when it needs to increase when sending data I assume, or how close the tracker is away from you but so far I havent focusing reversing this yet. When doing the same thing on the Tracker, the Tracker is fixed at +4dbm, so no change in there. On HTC Vive Dongles 4dbm is max.

Microphone


Yes this dongle supports also a Microphone. The dongle needs to be configured as LYM.

I haven't tested it physically. On Valve Index the Microphone becomes active when you start SteamVR. If you have a dongle which expose many pins, you might even try to connect one. This is the configuration of the I2S port, and configure pins should not be connected and Valve Radio + Microphone should be preset in windows (with label xxxxxxxxxx-LYM).

Description Pins on NRF52840
MCK none
SCK Pin 0.08
LRCK Pin 1.08
SDIN Pin 0.01
SDOUT none
i2s Register Description
0x504 MODE 0x01 SLAVE
0x524 Format 0x00 Original I2S format.
0x528 0x01 Channels 1 (Left)
0x51c 16Bit