Jump to content
Corsair Community

Developers: The Corsair Link USB protocol!


CFSworks

Recommended Posts

Hi Guys,

 

Fantastic work on the protocol specification. I got myself a Corsair Link Bridge based on this thread in the hope that it might have somehow worked with the Bridge.

 

Sadly, even with modified IDs, although I can get a handle to the device in the CorsairLink init, I can't get the ID or anything further.

 

Has any work been done towards the Analog bridge? I bought this to go in my headless server so I can log some PSU stats, I don't run Windows anywhere so I don't even know what information the PSU can give since I've never been able to run the software.

 

I have the output of lsusb if it's of any use;

 

$ sudo lsusb -D /dev/bus/usb/001/002
Device: ID 1b1c:0c06 Corsair 
Device Descriptor:
 bLength                18
 bDescriptorType         1
 bcdUSB               2.00
 bDeviceClass            0 (Defined at Interface level)
 bDeviceSubClass         0 
 bDeviceProtocol         0 
 bMaxPacketSize0         8
 idVendor           0x1b1c Corsair
 idProduct          0x0c06 
 bcdDevice            0.03
 iManufacturer           1 Corsair Memory, Inc.
 iProduct                2 RM-Series C-Link Adapter
 iSerial                 0 
 bNumConfigurations      1
 Configuration Descriptor:
   bLength                 9
   bDescriptorType         2
   wTotalLength           34
   bNumInterfaces          1
   bConfigurationValue     1
   iConfiguration          0 
   bmAttributes         0x80
     (Bus Powered)
   MaxPower              100mA
   Interface Descriptor:
     bLength                 9
     bDescriptorType         4
     bInterfaceNumber        0
     bAlternateSetting       0
     bNumEndpoints           1
     bInterfaceClass         3 Human Interface Device
     bInterfaceSubClass      0 No Subclass
     bInterfaceProtocol      0 None
     iInterface              0 
       HID Device Descriptor:
         bLength                 9
         bDescriptorType        33
         bcdHID               1.11
         bCountryCode            0 Not supported
         bNumDescriptors         1
         bDescriptorType        34 Report
         wDescriptorLength      27
         Report Descriptor: (length is 27)
           Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
                           (null)
           Item(Local ): Usage, data= [ 0x01 ] 1
                           (null)
           Item(Main  ): Collection, data= [ 0x01 ] 1
                           Application
           Item(Global): Report Size, data= [ 0x08 ] 8
           Item(Global): Logical Minimum, data= [ 0x00 ] 0
           Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
           Item(Global): Report Count, data= [ 0x08 ] 8
           Item(Local ): Usage, data= [ 0x01 ] 1
                           (null)
           Item(Main  ): Input, data= [ 0x02 ] 2
                           Data Variable Absolute No_Wrap Linear
                           Preferred_State No_Null_Position Non_Volatile Bitfield
           Item(Global): Report Count, data= [ 0x08 ] 8
           Item(Local ): Usage, data= [ 0x02 ] 2
                           (null)
           Item(Main  ): Output, data= [ 0x02 ] 2
                           Data Variable Absolute No_Wrap Linear
                           Preferred_State No_Null_Position Non_Volatile Bitfield
           Item(Main  ): End Collection, data=none
     Endpoint Descriptor:
       bLength                 7
       bDescriptorType         5
       bEndpointAddress     0x81  EP 1 IN
       bmAttributes            3
         Transfer Type            Interrupt
         Synch Type               None
         Usage Type               Data
       wMaxPacketSize     0x0008  1x 8 bytes
       bInterval              10
Device Status:     0x0000
 (Bus Powered)

 

 

If I run the modified OpenCorsairLink with the new IDs in place of either the CLINK or the H80I devices I get the following:

 

$ sudo ./OpenCorsairLink 
Open Corsair Link (Cooling Node):
Error: Unable to write() No data available
Device ID: 00 mismatch. Not Corsair Cooling Node
Cannot initialize link.

 

I get the same thing using the other method and my ID.

 

Anyone able to point me in the right direction? I have zero experience with HID devices but am happy to write up the rest of the code required to communicate with the device if someone can help get me communicating with it.

Link to comment
Share on other sites

  • Replies 185
  • Created
  • Last Reply

Top Posters In This Topic

 

Thanks,

 

That'll do nicely when I'm finally able to get the data out.

 

I'm trying to use python currently to prototype this, but I really don't know what I need to write to the device in order to get an input report from it.

 

Anyone able to offer help with that?

Link to comment
Share on other sites

  • 3 weeks later...

I'm going all-in.

 

Found a kernel module someone wrote in 2008 for the Gigabyte Odin GT, which had similar proprietary-protocol-USB-HID based monitoring/control. Using it as a basis for corsair-link.ko. Have some kernel developer friends coaching me.

Link to comment
Share on other sites

0x15 RW 2 bytes Report external temperature to fan controller - used for controlling fans via external sensors

 

This needs to be written when using curve mode 7 (manual) to set the external temperature. An example would be setting the Disk temperature to control fans that cool the Disk Drive.

 

0x18 RW 2 bytes Fan under speed threshold

 

I have not used this. I expect if the fan drops below this value the status (0x03) will be set of 0xFF.

Link to comment
Share on other sites

Does

 

03 01 09 01 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 

Look like a correct HID report to send to an H100i to get the FW version?

 

I'm no longer causing kernel oopses all the bloody time, but my report_in is all 0's. I'm not sure if the problem is in my kernel send/reply code, or the actual HID report I'm sending.

 

3 significant bytes, command id 1, retrieve 2-byte value opcode, register 0x01 (firmware version)

Link to comment
Share on other sites

I suspect the attached SIV startup log may help you know what to send. Note that on Windows there is a one byte header (the RID) which I don't think is there on Linux.

 

SIV-Startup-More.txt is an annotated log with rather more CL hardware connected. This is the sort of setup I advise you to design for as CL 3 only reports some of these devices. 2 x CLCC are missing and all the devices attached via them and one of the RM-Series C-Link Adapters.

 

I don't think this thread mentioned the 0x4F command. This should be sent first to find out which bridge channels are being used and what type of device they are. There are 8 bytes in the reply, one for each C-Link channel. The channel index must be in the high nibble of the command.

 

GID     @ 07:58:38 seq 01 -> 00 02 01 4F 00 00 00 00 00 00 00 00 00 00 00 00
GID                seq 01 <- 00 01 0F 05 FF 05 05 01 FF FF FF 00 00 00 00 00

#define CLC_SET_BYTE    0x06    // 06 AA BB          - Write BB into one-byte register AA
#define CLC_GET_BYTE    0x07    // 07 AA             - Read from one-byte register AA
#define CLC_SET_WORD    0x08    // 08 AA BB CC       - Write BB CC into two-byte register AA
#define CLC_GET_WORD    0x09    // 09 AA             - Read from two-byte register AA
#define CLC_SET_MANY    0x0A    // 0A AA 03 00 11 22 - Write 3-byte sequence (00 11 22) into 3-byte register AA
#define CLC_GET_MANY    0x0B    // 0B AA 03          - Read from 3-byte register AA
#define CLC_GET_CHAN    0x4F    // 4F                - Report Channels - 8 byte reply

#define CCT_PSUS        0x01    // PSU type Channel
#define CCT_FLOW        0x03    // AirFlow  Channel
#define CCT_LINK        0x05    //    Link  Channel

SIV-Startup-Log.txt

SIV-Startup-More.txt

Edited by red-ray
Added SIV startup log and channel info
Link to comment
Share on other sites

I suspect the attached SIV startup log may help you know what to send. Note that on Windows there is a one byte header (the RID) which I don't think is there on Linux.

 

I don't think this thread mentions the 0x4F command. This should be sent first to find out which bridge channels are being used and what type of device they are. There are 8 bytes on the reply, one for each C-Link channel. The channel index must be in the high nibble of the command.

 

GID     @ 07:58:38 seq 01 -> 00 02 01 4F 00 00 00 00 00 00 00 00 00 00 00 00
GID                seq 01 <- 00 01 0F 05 FF 05 05 01 FF FF FF 00 00 00 00 00

#define CLC_SET_BYTE    0x06    // 06 AA BB          - Write BB into one-byte register AA
#define CLC_GET_BYTE    0x07    // 07 AA             - Read from one-byte register AA
#define CLC_SET_WORD    0x08    // 08 AA BB CC       - Write BB CC into two-byte register AA
#define CLC_GET_WORD    0x09    // 09 AA             - Read from two-byte register AA
#define CLC_SET_MANY    0x0A    // 0A AA 03 00 11 22 - Write 3-byte sequence (00 11 22) into 3-byte register AA
#define CLC_GET_MANY    0x0B    // 0B AA 03          - Read from 3-byte register AA
#define CLC_GET_CHAN    0x4F    // 4F                - Report Channels - 8 byte reply

#define CCT_PSUS        0x01    // PSU type Channel
#define CCT_FLOW        0x03    // AirFlow  Channel
#define CCT_LINK        0x05    //    Link  Channel

 

Brilliant, thank you. That looks exactly like what I've been missing.

Link to comment
Share on other sites

  • 4 weeks later...
I have some code in SIV that manages to read the temperature, fan and pump speeds from a H100iGTX, but it also seems to set the fans to 100%. The SIV message trace is as below.

 

The USB trace I sent you earlier was useless? I can do another, but I simply don't know how to get a usable trace with a software capturer.

Link to comment
Share on other sites

That was a while ago, I can't find it and can't even remember which cooler you have. Was it the raw trace file or a hex printout of the data in the packets? I just need the hex printout. Now I have managed to get SIV showing signs of life I suspect I will try harder.

I have the H100iGTX and sent you a USBPcap trace (Wireshark compatible). The problem was that it captured everything on the root hub in question, including mouse and keyboard events, so some filterint was needed.

 

There's not a lot of possibilities for capturing USB via software on Windows as far as I can see, if you like me to try something else just name it.

 

Looking at http://forums.aida64.com/topic/892-the-ability-to-read-asetek-usb-cpu-cooler-data/ I suspect AIDA64 may report your cooler. Does it and if so do the fans get switched to 100%?

AIDA64 is payware only offering "trials" which is probably full of nagware and other nasties. I'd rather not install that.

Link to comment
Share on other sites

  • 3 weeks later...
  • 5 months later...

The USB PIDs for the H80iV2 + H100iV2 + H115i are as below and I expect as the firmware is unchanged no other information will be needed to support them. I have not as yet tested with any of these new coolers though.

 

There is also the CoolIT H110i which I suspect will just work as was the case for the H110iGT.

 

if( ( tcsnieql( dip, TEXT(    "\\VID_1B1C&PID_0C02" ), 18 ) ) ||  // Corsair H80iGT   Hydro Series 7289 USB Device
   ( tcsnieql( dip, TEXT(    "\\VID_1B1C&PID_0C03" ), 18 ) ) ||  // Corsair H100iGTX Hydro Series 7289 USB Device
   ( tcsnieql( dip, TEXT(    "\\VID_1B1C&PID_0C07" ), 18 ) ) ||  // Corsair H110iGTX Hydro Series 7289 USB Device
   ( tcsnieql( dip, TEXT(    "\\VID_1B1C&PID_0C08" ), 18 ) ) ||  // Corsair H80iV2   Hydro Series 7289 USB Device
   ( tcsnieql( dip, TEXT(    "\\VID_1B1C&PID_0C09" ), 18 ) ) ||  // Corsair H100iV2  Hydro Series 7289 USB Device
   ( tcsnieql( dip, TEXT(    "\\VID_1B1C&PID_0C0A" ), 18 ) ) )   // Corsair H115i    Hydro Series 7289 USB Device

Edited by red-ray
new layout
Link to comment
Share on other sites

  • 3 months later...

Anyone know how to talk to the 1B1C:1C0D device that appears when you connect the USB C-Link cable from a RM1000i ? (not to be confused with non-i RM1000 which does not have USB)

 

I modified CL++ to use the new PID but it doesn't seem to use a similar protocol. Any advice is greatly appreciated, thanks.

Link to comment
Share on other sites

Anyone know how to talk to the 1B1C:1C0D device.

 

I use a function that converts a packet that would be sent to a HXi/RMi PSU via a CLCC to be directly sent via USB, but I don't wish to post the source.

 

If you e-mail me you may convince me to send you the source. Given that seven days later you have not even checked for a reply to your initial post this is not likely.

Edited by red-ray
seven days later then no e-mail.
Link to comment
Share on other sites

  • 2 weeks later...

Hi @red-ray,

 

There is more then just that PID you need to support and you should add your PC specs to your profile. I use a function that converts a packet that would be sent to a HXi/RMi PSU via a CLCC to be directly sent via USB, but I don't wish to post the source.

 

Thanks for your reply. I'm not running my PSU in a PC, I actually bought several hundred of these PSUs for a hobby project involving lots of GPUs. I was hoping to write a simple utility in Linux that I could add to my monitoring system to periodically check the Watts In / Watts Out for power consumption statistics.

 

If you e-mail me you may convince me to send you the source. Given that seven days later you have not even checked for a reply to your initial post this is not likely.

 

Sorry for the late response. Since the last post to this thread was 4 months ago, I actually didn't expect much of a reply at all. I just thought back to check this thread today and I was very happy to see your reply.

 

I came across the CL++ project on Github, but it seems to not support this PSU at all... If you can give me any advice that would be a big help, and when I get it working then I will submit a patch for merging into CL++ in the form of a pull-request. There really isn't enough OSS support for these PSUs, and I would like to contribute to the community effort.

 

Thanks!

 

Best Regards,

J. Maurice

 

of5r9l5h.jpg

Edited by jmaurice
fix image
Link to comment
Share on other sites

  • 5 months later...

I was able to read data from RM-Series C-Link Adapter (device 1b1c:0c06) in Ubuntu 16.04 using libusb 1.0 with this control transfer and an 8 byte buffer:

libusb_control_transfer(dev_handle, 0xa1, 1, 0x100, 0, buf, len, TIMEOUT)

 

The attached program reads data, and decodes it using the code from http://forum.corsair.com/forums/showthread.php?p=755521

I had to subtract 1 from the indexes, because it seems not to have the first byte.

 

It should support also multiple RM-Series C-Link Adapters connected to same machine, but I haven't tried if that works.

c_link.zip

Link to comment
Share on other sites

  • 1 month later...

Registered to say *THANK YOU* for the great info in this thread!

 

And to ask: Can anyone post or link to info on Commander Mini (product ID = 0c04) registers? I'm most interested in PWM fan control registers but any info at all would be great.

 

I'm using Ubuntu 16.04 Linux and have been poking at the device using Python and hidapi-cffi:

https://github.com/jbaiter/hidapi-cffi

packaged as python3-hidapi in Debian & Ubuntu. (If installing using package manager, you need to install undeclared dependency python3-cffi package as well.)

 

I've been able to send and receive data (status LED briefly changes from green to amber), but the registers don't seem to match up with those for the other devices in this thread so far. Any help greatly appreciated!

Link to comment
Share on other sites

  • 2 weeks later...

Thanks red-ray for PM confirming that Commander Mini uses same registers as H80i/H100i, as posted in this thread by Thatualle1970 on 2013-09-09. I now have a Python program / library that can measure temperatures, control fans, and set custom fan curves for fans attached to the Commander Mini. I'm using it in Linux. Suppose it could be used in Windows too, if *Global\CorsairLinkReadWriteGuardMutex* could be added. (I've made no attempt to do so.) Of course best bet for Windows is

red-ray's excellent SIV (no surprise to anyone reading this & other forum threads). It & red-ray's various posts here were a big help as I wrote my script. As was code in this thread from volmok & dwmccauley. Thanks guys!

 

If there's interest I'll post my code. It's fairly rough and only good for Commander Mini at this point. But not hard to extend / refine to fit your purpose.

 

A question: is register 0x18, fan under speed threshold, of any use at all? It seems there's only a single value (not 1 per fan). And I don't see any effect from setting it...?

Link to comment
Share on other sites

  • 1 month later...
Last I noticed about the AX1500i was the screenshot of USB analyzer earlier. Anybody have any (partial) protocol for it yet? Happy to work on code myself, but don't want to send it the wrong signal and fry it :( Edited by petteyg359
Link to comment
Share on other sites


×
×
  • Create New...