Giter Club home page Giter Club logo

Comments (13)

david-sawatzke avatar david-sawatzke commented on July 20, 2024 4

No idea if this is accurate, but when switching to the BLE firmware, steam outputs this, after updating the nxp firmware before that:

Starting SWD flash work itemFWU: Starting SWD radio update
Fetching Config Sets 1
CClientJobFetchPersonalizationFileID
FWU: Sending start command
FWU: Erasing by pages
FWU: start addr erased 0, end addr erased 126996

They seem to be using the nxp chip as an swd programmer, which seems pretty brick resistant.
This is also supported by the connections reverse engineering, which states that the swdio/swclk pins of the nrf are connected to the lpc11u37f.
For dev purposes, simply flashing a cmsis-dap firmware onto the lpc11u37 should probably work well enough, and there seem to already exist ports, for example http://wiki.tinker-pot.com/doku.php?id=en:cmsis-dap_adapter

from opensteamcontroller.

greggersaurus avatar greggersaurus commented on July 20, 2024 3

I have considered what it will require. I'll list my thoughts below for now:

  • Currently no work has been done to interface with the nRF51822 Bluetooth chip.
  • Interfacing with the nRF51822 seems to be done with the UART on the LPC11U37F
  • We should be able to leverage DFU to reprogram the nRF51822. However, this presents a risk of bricking the nRF51822 (meaning the controller will only work in wired mode). So we need to proceed cautiously when looking into this.

from opensteamcontroller.

2bndy5 avatar 2bndy5 commented on July 20, 2024 1

I've been reading through the nRF5 SDK docs; I found this little section on the nRF51's debugging interface in the nRF51 reference manual. It's not everything we need to know, but its a start. Also the same document has details on the nRF51822 UART, but that is pretty straight forward. We just need to upload a program that dumps outgoing data (from UART RX/ LPC11's TX) into either the nRF51's TX FIFO (RF comms) or BLE advertise() call, and also handle pairing/bonding operations (RF & BLE).

Valve is probably using a generic SoftDevice + customized GATT profile for utilizing the nRF51 as a BLE co-processor (many DIY-ers use the UART service in a GATT profile -- not whatever Valve did). I have a hunch that Valve might be using the EasyDMA mode to utilize the nRF51 as an RF co-processor. Although that's assuming the included wireless dongle is also using an nRF51xxx or nRF52xxx, which is probably not the case. An older nRF24 could send/receive RF signals to/from the nRF51 using the nordic proprietary Enhanced ShockBurst protocol (Logitech is using an nRF24 for their unifying receiver dongle -- with added encryption & their own HID++ protocol). The nRF5 SDK also boasts Zigabee/ANT/Thread/Mesh support, but that's for later down the road.

It should be said that Bluetooth is different from BLE, and the nRF51822 doesn't support full-fledged Bluetooth. So maybe adjust the title of this issue...

EDIT: I can confirm that the dongle is using an nRF24LU1P

from opensteamcontroller.

roblabla avatar roblabla commented on July 20, 2024 1

So I started reverse engineering the protocol a bit, the findings presented below are based on my reverse engineering efforts on version 57bf5c10 (which doesn't have bluetooth support).

The USART protocol has a first "framing" layer where a packet starts with byte \0x02 and ends with byte \0x03. Byte \0x1f is used as an escaping character, such that within the packet, every time a 2, 3 or 1f is encountered, it is prefixed by a 1f and xor'd with 0x20.

Code for doing the escaping (sorry, it's Rust, but I hope the idea is conveyed):

fn usart_send_escaped_str(mut data: &[u8]) {
    while let Some(pos) = data.iter().position(|&v| v == 0x02 || v == 0x03 || v == 0x1f) {
        if pos != 0 {
            usart_send_raw_str(&data[..pos]);
        }
        usart_send_raw_str(&[0x1f, data[pos] ^ 0x20]);
        data = &data[pos + 1..];
    }

    if !data.is_empty() {
        usart_send_raw_str(data);
    }
}

Once the framing layer is removed, we get a datagram-oriented protocol. The first byte of the datagram is usually a packet ID. This table is what I more-or-less understood happening. Note that this is all just an informed guess based on my RE efforts, and 1000% untested :D. I'll keep it updated when I find new stuff.

Here are the packet IDs nRF->LPC:

Hex Packet ID Char Packet ID Packet Name Description
0x50 'P' ControllerHIDTransaction Initiated by the nRF side: calls the Controller SetReport handler, and then sends the resulting "answer" report back (see packet 0x50 LPC->nRF side)
0x52 'R'
0x53 'S' IsReady? No data. Seems to signal when the nRF chip is started and ready to go?
0x57 'W'
0x58 'X' NrfVersion Has 4 bytes arguments corresponding to the nRF version.
0x59 'Y' FirmwareUploadResult 1 byte argument, some kind of success code?
0x5a 'Z'
0x5b '['
0x66 'f'
0x69 'i'
0x6a 'j'

Packet IDs LPC->nRF:

Hex Packet ID Char Packet ID Packet Name Description
0x51 'Q' Sends lots of data, including the Keyboard Report and Mouse Report.
0x53 'S'
0x54 'T' Always followed by one byte.
0x56 'V' Sends 0x19 additional bytes. Always followed by a 'Q' packet.
0x58 'X' QueryNrfVersion Asks the NRF chip to send its version.
0x59 'Y' StartFirmwareUpload No args, signals the start of a firmware upload. If it works like the LPC bootloader, it will erase the flash.
0x5a 'Z' FirmwareUpload Sends at most 0x40 bytes of firmware data to flash on the nRF. The nRF will start flashing from 0x10_000.
0x5b '[' EndFirmwareUpload Sends a 0x10 byte checksum to verify the uploaded firmware.
0x5c '\' RESET Always accompanied by "RESET". Resets the nRF chip.
0x5d ']' Sent when receiving a HID Controller SetReport packet 0x9a. Data from that packet is forwarded.
0x63 'c' GetDeviceID Sends a DeviceID request.
0x64 'd' doze ALways followed by "doze".
0x69 'i' Has 0x20 bytes of arguments. Sent when receiving a HID Controller SetReport packet 0xbb.
0x6a 'j' Has 2 bytes.

from opensteamcontroller.

greggersaurus avatar greggersaurus commented on July 20, 2024

Awesome. Thanks for that additional info @david-sawatzke. The CMSIS-DAP firmware seems really promising!

Also, I'm aware I'm being a bit paranoid about bricking the nRF51822. Part of it is the "better safe than sorry" approach. Especially when it could ruin someone's hardware, which is no longer being produced :(. Also, I was fortunate enough to be on a podcast to talk about this project and got to talk to Jeff Keyzer (one of the designers for the SC) and he mentioned bricking the radio chip at least once (https://embedded.fm/episodes/304). So that adds a little to the concern ¯_(ツ)_/¯

from opensteamcontroller.

LemmaEOF avatar LemmaEOF commented on July 20, 2024

I’m pretty sure you can reflash the nRF51822 over wired connection, since that’s what you do to enable BLE mode.

from opensteamcontroller.

greggersaurus avatar greggersaurus commented on July 20, 2024

@Boundarybreaker if you have any details on how the wired connection is reflashing the nRF51822 via Steam and how that might be leveraged or reproduced please let me know. Otherwise thanks for the tip regarding another path to dig into!

from opensteamcontroller.

LemmaEOF avatar LemmaEOF commented on July 20, 2024

I don't have any details, sadly. I just know that I didn't have the bluetooth dongle for one of my steam controllers, but was able to update it to BLE over wired connection.

from opensteamcontroller.

roblabla avatar roblabla commented on July 20, 2024

Here's some new info. It turns out there is an nRF firmware hidden within the vcf_wired_controller_d0g_57bf5c10.bin file. When the Steam Controller firmware runs, it pings the nRF firmware for its version, and if it's different from what it expects, it will upload a default firmware that's stored at offset 0x1C010 and of size 0x3CFC.

That's a relatively small firmware, all things considered. Small enough that it seems doable to pick it apart relatively quickly to find its workings. I already identified the function that parses the protocol (and found some new LPC->nRF packets in the process) just by going through every function looking for a big if/else forest 😆. So I'll be focusing my effort on this cute little firmware, see what's to be found in there.

from opensteamcontroller.

2bndy5 avatar 2bndy5 commented on July 20, 2024

@roblabla I must say I'm impressed with your progress!

I recently ran across a multiple protocol support in the nRF5 SDK that theoretically allows both BLE and ESB protocols concurrently using Nordic's Timeslots API. Although this API isn't fully utilized in any existing opensource firmware that I"m aware of (looking into the Arduino support for the nRF52840 and CircuitPython firmware for various nRF chips) outside of scheduling events for BLE protocol usage via the Nordic softdevice (s130 seems to be the preferred softdevice version in the aforementioned firmwares).

As far as reverse engineering purposes, the Timeslots API may not need special implementation as the Steam controller uses either ESB or BLE, but not at the same time.

from opensteamcontroller.

Argon2000 avatar Argon2000 commented on July 20, 2024

Any progress/update on this feature? I just tested my SC with my Switch using cable, and it works great!
The not so great thing though is that the cable is like 1.5m long 😆. This would be awesome if you got working.
Thanks for the great work so far guys!

from opensteamcontroller.

JerionZer0 avatar JerionZer0 commented on July 20, 2024

Hi, any progress on this? It’s a wonderful enhancement idea that I’d love to see working.

from opensteamcontroller.

X007AceX avatar X007AceX commented on July 20, 2024

Fantastic work! I have a SC that has been collecting dust until I stumbled on this project. Looking forward to bluetooth support!

from opensteamcontroller.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.