My Corsair AX760i PSU has some extra pins that hooked up to my fan controller to show power statistics in the link desktop software.

Corsair LINK software Power Supply Window
So juicy, I want it all

To add some pizzazz to my DIY arduino fan controller, I want to hook up to my Corsair 760AXi PSU and show these power usage stats.

The four pins on the PSU can either be connected to the Corsair fan controller, which in turn connects via an internal USB header, or using a dongle that does the same thing and comes with the PSU.

Corsair LINK dongle

The AXi models are unique in this way, with later models (HXi/RMi) connecting straight to USB.

So what protocol is this weirdo cable using? Corsair’s website actually sells the cable individually, listing it as “AXI I2C 800mm PMBus Cable”. Which is a clue and a half, and led me to learn all about PMBus (Power Management Bus), based off SMBus, itself an I2C protocol. It does exactly what corsair’s software shows, and is an open standard.

I also found one chap on Corsair’s forums that has attempted to communicate with the PSU directly.

Usually boards have 5 pins, but there is always a NC (no connection pin) so maybe it is minus the NC pin….. however I just tried to connect it to my buspirate (i2c/uart/etc) host, have tried even setting it to 400khz in I2C mode and have had no luck handshaking with it, I want to believe its possible that it might be a UART, since several other models claim to have a “serial” port.

But it seems they had no luck

Suffice to say, I am not your average “bling bling lil wayne gangster wannabe overclockin my **** yo” computer user and I suspect I can cause a great deal of trouble. […] I can’t seem to figure out the correct way to connect it to my motherboard, since I can’t figure out what pins are data, clock, and 3.3V (they’re all +3.3v except the clock and the ground… so obviously I’ve tried different combinations, with no luck. I’m really starting to lose my patience.

  • paigeadele, Corsair forums

Perhaps due to their lack of street smarts, the rambling post made me feel there’s a chance I could succeed where paigeadele failed.

Most people attempting to talk to these PSUs are linux users left in the cold by Corsair on the software side, but happy to use the USB dongle. Ripping it open, or just looking at the driver details reveals it to be a Silicon Labs CP210x. Basically a USB/UART adapter.

So it seems this I2C PMBus business was a ruse? I guess I trust my eyeballs over Corsair’s online store authors. I tapped into the data lines, and figured out it seemed to be running at 115200 baud. Unfortunately instead of nice text, it appeared to be incomprehensible binary data being transferred.

How do I figure out what on earth this nonsense is? Well, instead of doing that I found a program cpsumon on github that could already talk to these AXi PSUs. It promised answers in it’s cpsumon.c file. Written by ka87, who when asked “How did you reverse engineer this?”, he answered

I used usb sniffer program to figure out the communication

  • ka87, god among men

I read through the code, and I was none the wiser. The author of OpenCorsairLink, another open source linux program to interact with Corsair’s products, was asked to integrate cpsumon. A year later, he gave up:

…nothing is known about the protocol for the PSUs, now I know there’s software, but there’s no description of the protocol used (who ever wrote cpusmon didn’t comment or document whats going on). So until I have time or the money to buy an AXi powersupply and reverse engineer the two different physical interfaces this will never get implemented.

  • audiohacked, a mere mortal

So instead of fully understanding the protocol, I figured the queries sent to the PSU are the same every time, and decided to just blindly send the same queries and interpret the replies later.

set main page:
PC: "\x54\x5a\x56\x56\x55\x65\x55\x59\x55\x55\x55\x55\x55\x00"
PSU: \xa8
PC: "\x54\x5a\x56\x5a\x55\x69\x55\x56\x55\x6a\x55\x56\x55\x55\x55\x00"
PSU: \xa8
PC: "\x54\x95\x55\x6a\x55\x56\x55\x00"
PSU: a8 55 55

// get unk1 value
PC: "\x54\x5a\x56\x5a\x55\x69\x55\x56\x55\x6a\x55\x59\x55\x6a\x96\x00"
PSU: \xa8
PC: "\x54\x95\x55\x6a\x55\x59\x55\x00"
PSU:  5 bytes

//get current
PC: "\x54\x5a\x56\x5a\x55\x69\x55\x56\x55\x6a\x55\x59\x55\x96\x95\x00"
PSU: \xa8
PC: "\x54\x95\x55\x6a\x55\x59\x55\x00"
PSU: 5 bytes

//get voltage
PC: "\x54\x5a\x56\x5a\x55\x69\x55\x56\x55\x6a\x55\x59\x55\x95\x95\x00"
PSU: \xa8
PC: "\x54\x95\x55\x6a\x55\x59\x55\x00"
PSU: five bytes

// get input power
PC: "\x54\x5a\x56\x5a\x55\x69\x55\x56\x55\x6a\x55\x59\x55\xa9\xa9\x00"
PSU: \xa8
PC: "\x54\x95\x55\x6a\x55\x59\x55\x00"
PSU: five bytes

After making sure you’re on the right ‘page’, requesting each value seems to be a two step affair, with a confirmation of 0xa8 after the first command. I double checked this was correct with my own python script using /dev/ttyUSB to communicate with the USB dongle. Indeed I got all the responses back just like cpsumon did.

Making sure to use a level shifter in between (the PSU uses 3.3V not 5V), I sent the above from an arduino directly to the PSU. I didn’t receive ANY response. At all. I double checked the RX TX direction, the baud rate, the bit length and parity settings. I was speaking to a brick wall.

To double check how the dongle managed it, I spied on the UART data lines while running my script slowly. It was then I noticed that first command with an a8 response is not even sent to the PSU! That is all the dongle speaking! Here’s what is actually being sent to the PSU in hex, each line is a run of the commands.

051FC0733CFC08D1F0113FC06FC0E03D600F807FF3C07D8107C1F8
051FC05378FF08D3F0E35FF0DC0E027FE05180FFFFF07D810211FC
051FE01F30FE08D3F0E3F0FE037C0E027FE0D80FFFF80FF302373FF
071FD0530F006F3F0E31FF0DC0E067FF037808FE81C0DF1F0831F8
051FD0130FE0D3F015FF0FC0E027FF0D8087FF3C07D107C1BFE
0F1FC0B37CFE0D7F01BDFE0DC0189D600D1808FFFFF07D810E3330

There’s a pattern but they are also all different and even different lengths. Remember, these are the commands from above being sent to the PSU, they are exactly the same each time. All of the x55s and structure is gone.

Clearly I underestimated how much extra translation this dongle was doing. Am I looking at I2C traffic interpreted at UART? Does the command depend on the phase of Mars’ moons? I’m truly back where I started, staring at random binary data.

Sadly this is where the story ends. After changing some hardware in my PC, this PSU fried and doesn’t turn on any more. I can’t pretend it was unrelated to me fiddling with it for a month, but I also didn’t have any of my stuff plugged in when it died so who knows. Corsair don’t make this model any more so it’s communication protocol shall forever remain a mystery to me.

Bonus Round

While looking for people/software that have already figured out the AXi link protocol, I came across Ray Hinchliffe’s SIV – System Information Viewer. I mean just look at that homepage.

Screenshot of SIV's website homepage

This puppy works from Windows NT 3.51 all the way to the most recent releases of Win10. For over 15 years Ray has been adding support for every piece of hardware under the sun.

SIV's avatar
He Is a Man of Focus Commitment and Sheer Fucking Will Meme

If ka87 was a god among men, Ray is a fucking titan. There’s even a forum, where someone posted just to thank Ray for supporting the AXi PSUs. On his flippin’ XP machine. In 2019.

Avatar
> I never thought I’d get any software to manage the Corsair Link part via that USBXpress interface from within XP x64 natively, but with SIV, it works wonderfully. […] I’m really happy to have discovered this today, so I wanted to express my thanks to you, Mr. Hinchliffe, for implementing support for Corsair Link devices, even for deprecated operating systems!

I had no idea this world of wizards and cowboys running obscure hardware on ancient software existed, but I am now both horrified and aroused.