SteamVR Tracking HDK

SteamVR Tracking HDK

denw Jan 17, 2021 @ 6:31am
Programming the watchman dongle firmware to alternative nRF24LU1+ USB devices
Hello all,
Recently I have come into a handful of Logitech Unifying dongles with the same chipset and the correct 32kb variant, and the firmwares can be overwritten. I'm hoping these can be repurposed to be watchman dongles. I read that others with similar Nordic development kit boards, as well as Crazyradio PA devices have had success flashing the watchman_dongle_combined.bin to their devices.

The one caveat with the Logitech dongles are that their bootloaders are not fully unlocked, and cannot be written to via the USB DFU tool. Everything from 0x0000 to 0x6800 is writeable, which is roughly 26.6kb of space; More than enough to write the watchman dongle payload.

However, I have been running into issues with the dongle not wanting to negotiate with the host upon flashing, and essentially ending up with a bricked device. I am able to short P0.4 and P0.5 on the nrf24LU1 chip itself to force it to go back to the Logitech bootloader afterwards to recover it.

Are there other things I have to look out for when flashing this firmware?
Furthermore, is it even possible to run the watchman dongle payload without the Steam branded bootloader?

Hoping that someone can shine some light on this, and point me in the right direction.
Thanks for everyones time in advance.
Last edited by denw; Jan 17, 2021 @ 6:32am
< >
Showing 16-21 of 21 comments
zra123 Apr 24, 2023 @ 2:46pm 
Originally posted by wa:
I think you will be convinced that this won't work if you dump the firmware after flashing the watchman_combined.ihex onto your dongle. The logitech bootloader sections will have disappeared, which simply isn't possible on a real dongle due to the write protection that cannot be undone without SPI flashing the infopages.
I bought a logitech receiver, as you said the receiver has security enabled, 0x20=0x3a, 0x21=0x00, 0x23=0x00 in the infopage. 0x20=0x3a(58) Unprotected 0-57 (0x0000-0x73FF) pages and 58-63 (0x7400-0x7FFF) protected pages. And also 0x21=0x00 FPCR.DAEN=1, which means that data pages 62-63 (0x7C00-0x7FFF) can be erased and overwritten. 0x23=00 SPI read-back disable of MainBlock. It does not affect anything, all operations will be done by the MCU.
As a result, all our limitation is the inability to write to pages 58-61 (0x7400-0x7C00).

The first problem is at 0x7400 in the watchman dongle pairing database, I disassembled the firmware and found two matches at 0x74. the first is at 0x258d and if you look at the code below, you can see that this is the part responsible for writing (according to the datasheet, you need to write to the FСR register 0xAA and then 0x55 to start writing). https://imgur.com/JGdvMBu
The second match is at 0x2739, I didn't quite figure it out, but it looks like it's a read. https://imgur.com/1qlpEho
By replacing 0x74 with 0x66 in two places we will shift the database to address 0x6600

The second problem is with the bootloader, the watchman dongle has it written at address 0x7800 where we can't write, searching for 0x7800 gives address 0x201. here we have ljmp at 0x7800. https://imgur.com/jYlPsF8 when lighthouse_watchman_update.exe puts the dongle in bootloader mode, it erases page 0, thereby running the code from address 0x200 sending us to 0x7800, changing the address accordingly, we can move the downloader link. I tried to move the bootloader, from the watchman dongle, to the address above, but I didn't have the skill to do it.
Therefore, we use the logitech bootloader, respectively, change 0x7800 to 0x7400.

Third problem, in logitech firmware the last 16 bytes have an odd sum (0x7FF0 | F1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF) as discussed above, according to point 17.5.2 of the datasheet, if FPCR.DAEN=1 and the last 16 bytes have an odd sum then FSR.STP=1. The controller boot starts from the protected area (0x7400) of the logitech bootloader. That is why during firmware, the device turns into a brick, and when P0.4 and P0.5 are closed, it returns to bootloader mode. There are two options for solving the problem, make friends with the bootloader firmware or change the sum of the last 16 bytes to even. It would be great to do 1 option, it will save you from the actions described below.
I was able to implement option 2. It looks like the logitech bootloader has limitations and can only write the firmware up to 0x67FF, the CRC sum is also calculated during the firmware and writes to the end of the firmware. Therefore, we will use a third-party bootloader, for example nrf24lu1p-512-bootloader, dump the last 63 page (0x7E00-0x7FFF), replace the bytes at addresses (0x7FF0-0x7FFF) with 0xFF and flash the page back to keep the logitech bootloader working. Thus, our launch will start from the address (0x0000).

As a result, by changing 0x74 to 0x66 at addresses 0x258d and 0x2739, we transfer the pairing database. Also, 0x78 to 0x74 at 0x201 bootloader starts correctly. Flash a third party bootloader nrf24lu1p-512-bootloader, change 0x7E00 to 0xFF and flash the modified firmware.

I also ordered a new receiver from aliexpress and I couldn’t flash it, because its bootloader has version BOT01.04_B0016 and the old receiver BOT01.02_B0015, also the firmware version is RQR12.09_B0030. In the new bootloader, logitech has implemented additional protection or sum check (firmware files *.shex), also in infopage 0x20=0x36, 0x21=0x00, 0x23=0x00 and the bootloader is located at 0x6c00. So the above is relevant for older receivers.
Last edited by zra123; Apr 24, 2023 @ 2:49pm
bendotcom  [developer] Apr 27, 2023 @ 6:37pm 
Nice analysis.

The reason for the even/odd bootloader thing is that flash bits erase to FF and that can only be done in bulk, but you can write any bit to 0 any time. So the idea is for the application to be able to enter the bootloader by changing a bit to 0, and then the bootloader can reactivate the application by changing another bit to 0. It's a scheme that's very safe relative to being interrupted during a firmware update (or transition in/out).

I'm not sure it's worth making the bootloader work again. There haven't been updates to that firmware (although the combined image itself is probably out of date) so if you just flash the current wireless receiver app it would probably never try to update. You could NOP out the code that sends it to bootloader just to be sure.
zra123 May 6, 2023 @ 3:35pm 
Originally posted by bendotcom:
The reason for the even/odd bootloader thing is that flash bits erase to FF and that can only be done in bulk, but you can write any bit to 0 any time. So the idea is for the application to be able to enter the bootloader by changing a bit to 0, and then the bootloader can reactivate the application by changing another bit to 0. It's a scheme that's very safe relative to being interrupted during a firmware update (or transition in/out).
You are right but not completely, it erases to FF, but you can write FF-> FE-> FD-> FC .... you can lower the value by 1, and not immediately to 00.
Originally posted by bendotcom:
I'm not sure it's worth making the bootloader work again. There haven't been updates to that firmware (although the combined image itself is probably out of date) so if you just flash the current wireless receiver app it would probably never try to update. You could NOP out the code that sends it to bootloader just to be sure.
My idea is to be able to return the dongle to the logitech unifying receiver. even if there is an update, it will go into the logitech bootloader and not turn into a brick.
Last edited by zra123; May 6, 2023 @ 3:35pm
zra123 May 6, 2023 @ 3:50pm 
I present instructions on how to turn the Logitech Receiver Unifying into a Watchman Dongle
Only one model out of more than twenty dongles is suitable for flashing, namely
C-U0007[i.imgur.com]

But only the C-U0007 unifying version with an orange star! With the ability to connect up to 6 devices (mouse, keyboard), the NRF24LU1P-F32Q32 chip is installed in it, the older version in the line, and the other two NRF24LU1P-O17Q32 and nRF24LU1P-F16Q32, which are installed in the logitech nano receiver, are not suitable for us due to the small size of the internal memory. Firmware from Watchman Dongle will not fit.
And so there is a restriction on the bootloader up to version BOT01.04_B0016, it has protection and it is impossible to write an unsigned firmware. Therefore, only versions BOT01.01_B0001-BOT01.02_B0015 work
Indirectly, you can determine which bootloader is written in the dongle according to the firmware version using the program Logitech Unifying Software[support.logi.com]
Firmwares[i.imgur.com] starting from version RQR12.01_B0019 and up to RQR12.08_B0030 and RQR12.10_B0032 have a bootloader below BOT01.04_B0016 and they suit us.
Also in appearance, you need a dongle[i.imgur.com] in the old case with a recess for gripping, the new case already has a bootloader BOT01.04_B0016

You found the right device, what's next?
And then we need Linux, it is possible under VM


Instructions for Windows.

1. Download 2 files nRF24LU1P_BootLoader.exe and nRF24LU1P_Flash.exe
https://github.com/zra123/nrf24lu1p-512-bootloader/releases/tag/Release

2. Run nRF24LU1P_BootLoader.exe > Continue > Update > Close

3. Download and run Zadig[zadig.akeo.ie]
Run Zadig > Options > List ALL Devices > Select USB Input Devices, USB ID 1915 0101 > Select Driver libusb-win32 > Push button Replace Driver > Wait finish and close

4. Run nRF24LU1P_Flash.exe > Starting to write watchman_dongle_mod.hex > Disable protection! > Yes > Done
Done, you have a Watchman Dongle!


Instructions for Linux.
1. Download and install the necessary applications
sudo apt-get update sudo apt-get install git python3 python3-pip sudo pip install pyusb intelhex
2. Download two repositories
3. Go to the folder with the tool for working with the Logitech receiver
cd nrf-research-firmware/prog/usb-flasher
4. We make a backup of the native firmware and find out the version of the firmware and bootloader
sudo python3 logitech-usb-backup.py firmware.bin infopage.bin
5. Flashing a temporary bootloader
sudo python3 logitech-usb-flash.py bootloader.bin bootloader.hex
6. Go to the folder to work with the temporary loader
cd ../../../nrf24lu1p-512-bootloader/scripts/
7. We flash the modified firmware, with the shifted address of the synchronization database and the changed jump address to the bootloader.
sudo python3 flash.py write watchman_dongle_mod.hex
8. We confirm that the STP memory protection is disabled so that the microcontroller starts from address zero, and not from the address of the protected area. 17.5.2 datasheet item
Done, you have a Watchman Dongle!


Return to Logitech Receiver Unifying

On Windows

1. Open the console and go to the folder with SteamVR.
cd %ProgramFiles(x86)%\Steam\steamapps\common\SteamVR\tools\lighthouse\bin\win32
2. You need to downgrade the firmware, thereby launch the Logitech bootloader and close the console after.
lighthouse_watchman_update.exe -e ..\..\firmware\vr_controller\archive\htc_pre_vrc_dongle_1450758230_2015_12_22.bin
3. Download and run Logitech Firmware Update Tool[support.logi.com]
Last edited by zra123; May 7, 2024 @ 11:09am
denw May 18, 2023 @ 2:50pm 
Bravo, zra123! You achieved what I couldn't do, which was the decompilation portion.

Thank you for proving that this was in fact possible, and I can finally cross this one off the list of "what ifs" :)
zra123 May 25, 2023 @ 12:27am 
thx
Last edited by zra123; Aug 8, 2023 @ 11:59pm
< >
Showing 16-21 of 21 comments
Per page: 1530 50