The Steam Controller D0ggle Adventure

There's this gaming classics bucket list I've been making way through throughout the years. These are the games I would've been too young to play, or didn't have any means to. A major motivating factor is understanding the excitement and the innovations these games introduced at their release. Final Fantasy 7 was an excellent example of this: watching the old advertisements gave this sense of grandiose experience. The scale of its development reached into the hundreds of employees. Of the other historical games I played up until that time, it was clear this was a "Hollywood release" of video games. The game itself was fine, but man, the teen angst does not really hold up. I was fortunate to even experience the true-to-story fan translation via the XStation hardware mod I installed on my Playstation One.

The latest in gaming classics for me is Diablo II. Back when I was 7 or 8, I have vague recollections of my teenage baby sitter turning on their beige computer tower, the CRT reflecting the oscillations coming off the dim kitchen fan-light, and starting Diablo II among the assortment of other desktop icons living on the green-blue background of Windows 98. Seeing that blazing title screen left a great impression years later. (He also inspired me to play Parasite Eve, which I had to recover my save after corrupting from plugging in 2 wireless controllers, pulling too much current. You'll probably enjoy the read if you're reading this article already: https://ecc-comp.blogspot.com/2024/02/a-journey-recovering-my-genuine.html)

One evening, getting ready to play through Act 2, I pulled out my beloved Steam Controller from a backpack which was brought to my brother-in-law's, set it aside, and searched for the dongle. I was momentarily stunned by what I found: the PCB of the dongle was entirely exposed; no case to be found. Always hoping for the best, I figure maybe it was only the case that broke off, since it's more or less press-fit. Nope. Plugging it into the Steam Deck, the Steam Controller did not want to pair. Shit. We continued the evening with a Nintendo Switch Pro controller, which while good quality, is not the same experience.

(Post-project state. It visually looked much better initially.)

What followed spanned weeks of random tests, experiments, waiting on parts, and a ton of failures!

I tried my best to be chronologically ordered in this article, but the truth is, I try anything and everything at various times in various combinations.

Act I: Fiddling Around Hopelessly

The first experiments around diagnosing the issue were centered around fiddling with the dongle. Speculation leaned toward a typical trace-break around the USB port, so I put pressure in various ways on its neck. `dmesg` would report a USB device sometimes and `lsusb` would successfully report it's a Valve Steam Controller.

A little later, after finding out more details on the chip inside I would further diagnose various points with my multi-meter and do a shallow reversing of the traces, trying to figure out where there were non-normal points of operation.

(It's neat to note Valve exposed the ISP/SPI programmer pins via test pads here.)

Great, all I would need to do is re-melt some cracked solder right? Wrong. I would come to learn the traces in these dongles run through the boards themselves (indicating multi-layer PCB), and thus are extremely prone to hairline fractures and other stress-related breakage. Something to keep in mind when designing my own crap in the future...

Very clearly fucked, the search for a replacement began. Knowing the Steam Controller has been discountinued since 2019, no doubt the price of a new dongle was going to be ridiculous.

The price of a new-used dongle was $46 CAD alone. That price reflects in the listings of controllers with and without the dongle too.

Most people would've bought the stand-alone dongle or even cheaper, flashed the controller with Valve's Bluetooth Low Energy (BLE) support. Heck even I would normally prefer BLE over a proprietary dongle.

Unfortunately I have an apparent mental condition where I believe I should be able to self-support the best version of a product. As per Valve's own words on their support page: they say that people should not use the Bluetooth mode if they want the best experience!

"Otherwise we suggesting sticking with the original protocol. It provides the fastest connection, with low latency" (actual typo)

Yeah that sounds exactly like what I want for gaming...!

Act II: Flashing in Futility & My Wade Into SPI

How does the Steam Controller dongle operate? What chips does the dongle use? These are easy to answer by looking at the chip's printed text, NRF F 24LU1P. The datasheet practically presents itself from Nordic Semiconductor's website. I won't post a screenshot of it here (you may have noticed all my images are all very low-res; this is intentional so readers aren't busting my local bandwidth, but I have made great efforts to hand-edit them so you can still see what's in them, even the text!), but it's highly available.

This chip was the basis for dozens of world-renowned products, such as Logitech's Unifying Dongles, and even Guitar Hero wireless guitars. Today the remaining users seem to be quadcopter enthusiasts of "Bitcraze". It's almost a shame that Nordic did not continue to support this line of chips for consumers in a backward compatible way in their newer chips. Fortunately electronic logistics companies still have leftover stock. Lately I've been using Digikey more and more over Mouser, and this time was no exception: Mouser has these under "restricted access", for some reason, while Digikey has ~300 immediately available.

No way though I was going to order these, exfiltrate Valve's dongle firmware, create a programmer, do SMD soldering, etc, etc, etc. No way. No... way...

Instead let's try to order NRF24LU1P dev boards off Aliexpress, or flash known unlocked dongles from other products, all with complete failure!

These are $6 CAD NRF24LU1P-based dongles off Aliexpress. Absolutely perfect for my problem! No! In both a review on the product page, and on an open source project I'll get to shortly, these people say these dongles are all essentially bricked. The only way to program them is with an SPI programmer. Surely someone has detailed a workflow then to flash these somewhere. I ordered 2 and waited about a week, along with some other basic electronics supplies I was running out of.

A week goes by. Boards come in. The https://github.com/FMMT666/NRF24LU1prog project is exactly one of those I spoke of. The person wrote a simple Arduino-based project to speak the commands clearly detailed in the NRF24 datasheet. Reading through the source code, everything matched up to the spec. But one problem: it only supports a Teensy and a Sparkfun board. I've only got Aliexpress RP2040 boards. Naturally I added supported for my board. I never use the Arduino ecosystem, but every time I pass by, things always seems smooth to port something to a new board. After about 30 minutes of remapping pins, and updating SPI code to use modern Arduino functions, we were off to the races.

For makers out there, I extremely recommend these USB boards. I've used about 3 now for various projects. They are so reusable and flexible.

The pictures show how I directly wired up the SPI pins of the Ali NRF24 board to the RP2040 via friction fitting the pins like a boss. Yes it all works. Simple is best. It was time to interact with the board via the RP2040 over `minicom`, aka UART!

Aaand the people were right, this board is a toasted little noodle! Who in the fuck is buying these? No matter what commands we transfer to the NRF24, it reports everything is locked. You cannot read, you cannot write. It's essentially a dud. The chip's "InfoPage" itself is read-blocked.

That's not even the real blocker though. The real blocker is these are the 16kb flash memory sized variants! For our dongle we need the 32kb variant. Augh!

More research is required.

Leading us to the second significant project in this journey: The Bastille NRF Research Firmware. (https://github.com/BastilleResearch/nrf-research-firmware) My hopes rose.

This group appears to be at least somewhat credible, and their notes in the project align with all the other information I had come across, in addition to the source code once again matching up with what the datasheet spec details. And oh, what's this? Logitech Unifying Dongles can be flashed?! Oh but it's a particular model, the C-U0007, because other models use Texas Instruments chips and not Nordic. I wonder how much these are?

It's much better than a new Steam Controller dongle, but there is zero guarantee any of these are the correct model... Maybe I have one laying around from the various Logitech devices over the years?

Bingo! Of the 3 I had around, this one was good.

Alas another incompatibility at the source level though: `nrf-research-firmware` is so old that it uses Python 2 to drive everything. After updating the scripts to use Python 3, I had to also write additional USB code so Linux would stop acquiring some sort of lock on the Logitech dongle. After everything was tested for the billionth time I was starting to realize I think even with the correct Logitech dongle model, the god damn bootloader on these is locked, and after more research it was exactly that. So not only do you need the correct hardware model, you need the correct firmware as well, making buying these as replacement dongles unfeasible or rather "unreasonable". Fuck, fuck, fuck!

Act III: Time to Unlock My Next Ability; SMD Soldering Go!

A brilliant, simple idea came to me. Why don't I just do a chip swap? The NRF24 datasheet details that chips coming from the factory are pre-loaded with USB bootloader firmware. That would completely remove my need for any custom weird-ass SPI programmer-over-RP2040 setup too. And I would gain the confidence to do other SMD rework projects. AND I would gain the workflow to create new Steam Controller dongles for years to come. Talk about major win if I could pull it off. I sent off an order to Digikey for a single $10 NRF24LU1P F32. It arrived after the weekend.

I want to show my workstation to other makers who feel they need some sort of workshop or whatever to pull off these kind of projects. You don't! This is my desk in the basement that while looks like a fricking mess, is temporary. Once I'm done a project like this I put it all away in a box and just tuck it away underneath. Note there are no specialty tools. These are all cheap products.

After watching some videos on proper SMD rework (the one from Louis Rossman is pretty good! Hi Louis.), I got to business.

Here I use kapton tape to isolate the heat to just the chip area and prevent other components from moving. The heat is set to 380C, and low air flow. The chip itself becomes so hot you can continue to move it around on the board for several seconds. To remove it though, I let weight of the PCB pop the chip off.

Surprise! I didn't capture the process for the brand new NRF24 chip I bought. It was only after I completed the whole project, I realized hey, I could swap the OG one off the Steam dongle! (And decided this was article-worthy.)

The result was effectively the same. Now I have a brand new Steam dongle, and a "new" refurbished one that uses the OG chip. Let's pretend though we're still dealing with my first swap with the brand new chip. With all that said and done, I have to say I'm extremely surprised by just how easy working with SMD parts was with the right technique. Anyone who's afraid, well, hopefully some of this new found confidence radiates your way!

It's time to pair!

Act IV: Taking D0ggle for a Walk

Ok ok hold on, we can't pair just-just yet. We may have done the swap, but we need to confirm if the Nordic datasheet was lying or not about there being factory-installed USB firmware!

Finally, some god damn success! WOOHOO!

Earlier on when I fiddled with trying to revive the original dongle by re-soldering the USB joints, I also tried to exfiltrate the firmware without any success. I attributed it to Valve likely also setting the "no read" bits of the chip too, since it's so easy to protect their IP. Where could I turn to now to find the firmware? Surely some cracked hardware hacker had done it to one of the coolest controllers on the planet. Turns out not even; Valve put it out in the open when they offered their Bluetooth support. The zip extract of their ad-hoc post-market solution holds it:

Cute right? They internally called it d0g, or "the d0ggle".

Fantastic so we have the ingredients to flash now (wait, we do? what about the flashing software?): the hardware is unlocked, the Steam Controller dongle firmware, and `nrf-research-firmware` to do the flashing! All it involved was a little extra changes with USB vendor IDs in the Python scripts.

At first I thought the process failed because of a failed verification check but the failure was from not changing that part of the script. The reality was...

It frickin' WORKED! Now we can actually pair.

Valve dropped pairing from Steam quite some time ago apparently. Today there is a button that saying "Pair a controller" in the settings but it does absolutely nothing. While I had thoughts about installing an older Steam version, people online were saying it's probably not a good idea as it could mess up your library.

I had the other idea of using an old Steam Link that would have an old Steam version on it, but I couldn't find the proprietary power cable to it. Ooof.

Once again, given the popularity of the controller, surely someone must have reversed some of the proprietary protocol. Enter: OpenSteamController.

Someone or a small group decided to completely trace the controller in KiCAD. Absolute insanity. Then after remaining dormant for years someone revived the project to also reverse the dongle traces and called it OpenSteamController-Continued. Within one of these branches someone briefly detailed an incomplete breakdown of the protocol, but it was too incomplete to be useful.

The protocol uses "USB feature reporting". It's an extremely simple protocol with requests of the format [type byte][length byte][payload bytes], and it simply respond with some bytes. In Linux, you can communicate directly with devices this way via the /dev/hidraw* synthetic files! Which is really cool because now you can essentially write a USB driver in any language you want. Instead of needing to do that, I got lucky and found another soul on GitHub who had written their own C-based library for the controller that sent the correct bytes but I had to construct the correct sequence of commands myself still. (https://github.com/kolrabi/steamcontroller) At first, I thought it'd be as simple as sending an EnablePairing command followed by CommitPairing command, but no. The dongle reports 4 different HID devices, and it's our job to find the right one, followed by listening for a request from the controller itself, and then CommitPairing.

Instead of writing anything precise I opted for a small program that sent those commands in a reasonably ordered time and mashed pair on the controller and mashed run on the program. And it worked. Another success baby.

The joy that consistently lit Steam logo brought me was unreasonable. I had successfully created a brand new Steam Controller dongle. I will never again be without one!

Post-mortem

Phew, what a rollercoaster. It's times like these I really appreciate Valve's design philosophy. All of this was possible only because they went with simple, widely available components, and actually weren't trying to hide their firmware. Obviously they didn't make it super easy either, since they could've released the dongle protocol, explain how to flash a new dongle, list what the bill of materials is, etc. Half the value is in the rights to sell the design but the other half is the logistics too behind it all. When a product is discontinued at least consumers can gain the right to support themselves having that information.

With the Steam Controller 2 around the corner, I hope this article can make its way across the screen of a Valve employee and brings it up at the next weekly, encouraging them to release information so that stupid, consumable hardware like dongles aren't a factor in longevity. We love your hardware Valve. Let the people who love it help you long term support it out of passion for great, interesting products.

See you later alligators,

-- Lee