Initial commit for KrakenX fan controller

Commits squashed and amended for code style by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
Scott Wilde
2021-05-09 13:50:38 -05:00
committed by Adam Honse
parent b5105ed096
commit 7266e4131a
6 changed files with 272 additions and 4 deletions

View File

@@ -0,0 +1,71 @@
/*-----------------------------------------*\
| FanController_NZXTKraken.cpp |
| |
| Generic Fan Interface for NZXT Kraken |
| |
| swilde 5/2021 |
\*-----------------------------------------*/
#include "FanController_NZXTKraken.h"
FanController_NZXTKraken::FanController_NZXTKraken(NZXTKrakenController* kraken_ptr)
{
kraken = kraken_ptr;
name = "NZXT Kraken X2";
description = "NZXT Kraken X42/X52/X62/X72";
version = kraken->GetFirmwareVersion();
location = kraken->GetLocation();
serial = kraken->GetSerialString();
kraken->UpdateStatus();
fan new_fan;
/*---------------------------------------------------------*\
| Add fan |
| X52 has a max fan RPM of 200, the X42 and X62 max is 1800 |
\*---------------------------------------------------------*/
new_fan.name = "NZXT Kraken Fan";
new_fan.speed_min = 25;
new_fan.speed_max = 100;
new_fan.speed_cmd = 100 * kraken->fan_speed / 2000;
new_fan.prev_speed_cmd = 0;
new_fan.rpm_rdg = kraken->fan_speed;
fans.push_back(new_fan);
/*---------------------------------------------------------*\
| Add pump |
\*---------------------------------------------------------*/
new_fan.name = "NZXT Kraken Pump";
new_fan.speed_min = 50;
new_fan.speed_max = 100;
new_fan.speed_cmd = 100 * kraken->pump_speed / 2800;
new_fan.prev_speed_cmd = 0;
new_fan.rpm_rdg = kraken->pump_speed;
fans.push_back(new_fan);
UpdateControl();
}
void FanController_NZXTKraken::UpdateControl()
{
if(fans[0].speed_cmd != fans[0].prev_speed_cmd)
{
kraken->SetSpeed(NZXT_KRAKEN_CHANNEL_FAN, fans[0].speed_cmd);
fans[0].prev_speed_cmd = fans[0].speed_cmd;
}
if(fans[1].speed_cmd != fans[1].prev_speed_cmd)
{
kraken->SetSpeed(NZXT_KRAKEN_CHANNEL_PUMP, fans[1].speed_cmd);
fans[1].prev_speed_cmd = fans[1].speed_cmd;
}
}
void FanController_NZXTKraken::UpdateReading()
{
kraken->UpdateStatus();
fans[0].rpm_rdg = kraken->fan_speed;
fans[1].rpm_rdg = kraken->pump_speed;
}

View File

@@ -0,0 +1,23 @@
/*-----------------------------------------*\
| FanController_NZXTKraken.h |
| |
| Generic Fan Interface for NZXT Kraken |
| |
| swilde 5/2021 |
\*-----------------------------------------*/
#pragma once
#include "FanController.h"
#include "NZXTKrakenController.h"
class FanController_NZXTKraken : public FanController
{
public:
FanController_NZXTKraken(NZXTKrakenController* kraken_ptr);
void UpdateControl();
void UpdateReading();
private:
NZXTKrakenController* kraken;
};

View File

@@ -41,6 +41,9 @@ NZXTKrakenController::NZXTKrakenController(hid_device* dev_handle, const char* p
| Get the firmware version |
\*-----------------------------------------------------*/
UpdateStatus();
int major_firmware_version = std::stoi(firmware_version.substr(0, firmware_version.find(".")));
supports_cooling_profiles = major_firmware_version >= 3;
}
NZXTKrakenController::~NZXTKrakenController()
@@ -196,3 +199,135 @@ void NZXTKrakenController::SendEffect
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
}
void NZXTKrakenController::SetSpeed(unsigned char channel, unsigned int speed_cmd)
{
unsigned char duty;
/*-----------------------------------------------------*\
| Verify channel |
\*-----------------------------------------------------*/
if(channel == NZXT_KRAKEN_CHANNEL_FAN)
{
duty = std::max((unsigned char) 25, std::min((unsigned char) 100, (unsigned char) speed_cmd));
}
else if(channel == NZXT_KRAKEN_CHANNEL_PUMP)
{
duty = std::max((unsigned char) 50, std::min((unsigned char) 100, (unsigned char) speed_cmd));
}
else
{
return;
}
/*-----------------------------------------------------*\
| Write speed |
\*-----------------------------------------------------*/
if(supports_cooling_profiles)
{
SetFixedSpeedProfile(channel, duty);
}
else
{
SetInstantaneousSpeed(channel, duty);
}
}
void NZXTKrakenController::SetFixedSpeedProfile(unsigned char channel, unsigned char duty)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set to fan write |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x02;
usb_buf[0x01] = 0x4d;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Generate steps |
\*-----------------------------------------------------*/
unsigned char temps[36];
for(int i = 0; i < 30; i++)
{
temps[i] = 20 + i;
}
for(int i = 0; i <= 5; i++)
{
temps[30 + i] = 50 + 2*i;
}
/*-----------------------------------------------------*\
| Write temp speed pairs |
\*-----------------------------------------------------*/
unsigned char curr_duty = duty;
for(int i = 0; i < 36; i++)
{
if(temps[i] == 60)
{
curr_duty = 100;
}
/*-----------------------------------------------------*\
| Set channel and index |
\*-----------------------------------------------------*/
usb_buf[0x02] = channel + i;
/*-----------------------------------------------------*\
| Set temp |
\*-----------------------------------------------------*/
usb_buf[0x03] = temps[i];
/*-----------------------------------------------------*\
| Set duty |
\*-----------------------------------------------------*/
usb_buf[0x04] = curr_duty;
/*-----------------------------------------------------*\
| Write speed |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
}
}
void NZXTKrakenController::SetInstantaneousSpeed(unsigned char channel, unsigned char duty)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set to fan write |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x02;
usb_buf[0x01] = 0x4d;
/*-----------------------------------------------------*\
| Set channel |
\*-----------------------------------------------------*/
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Set temp (0 for instantaneous speed) |
\*-----------------------------------------------------*/
usb_buf[0x03] = 0;
/*-----------------------------------------------------*\
| Set duty |
\*-----------------------------------------------------*/
usb_buf[0x04] = duty;
/*-----------------------------------------------------*\
| Write speed |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
}

View File

@@ -48,6 +48,12 @@ enum
NZXT_KRAKEN_SPEED_FASTEST = 0x04, /* Fastest speed */
};
enum
{
NZXT_KRAKEN_CHANNEL_FAN = 0x80, /* Fan channel */
NZXT_KRAKEN_CHANNEL_PUMP = 0xc0, /* Pump channel */
};
class NZXTKrakenController
{
public:
@@ -58,6 +64,12 @@ public:
std::string GetLocation();
std::string GetSerialString();
void SetSpeed
(
unsigned char channel,
unsigned int speed_cmd
);
void UpdateEffect
(
NZXTKrakenChannel_t channel,
@@ -68,9 +80,12 @@ public:
std::vector<RGBColor> colors
);
private:
void UpdateStatus();
unsigned int fan_speed;
unsigned int pump_speed;
private:
void SendEffect
(
unsigned char channel,
@@ -83,12 +98,23 @@ private:
int size = 0
);
void SetFixedSpeedProfile
(
unsigned char channel,
unsigned char duty
);
void SetInstantaneousSpeed
(
unsigned char channel,
unsigned char duty
);
hid_device* dev;
// -- status
std::string firmware_version;
double liquid_temperature;
std::string location;
unsigned int fan_speed;
unsigned int pump_speed;
bool supports_cooling_profiles;
};

View File

@@ -13,6 +13,7 @@
#include <hidapi.h>
#include "Detector.h"
#include "NZXTKrakenController.h"
#include "FanController_NZXTKraken.h"
#include "RGBController.h"
#include "RGBController_NZXTKraken.h"
@@ -37,6 +38,17 @@ void DetectNZXTKrakenControllers(hid_device_info* info, const std::string& name)
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
if(info->product_id == NZXT_KRAKEN_X2_PID)
{
/*---------------------------------------------*\
| Kraken M22 doesn't have liquid temp sensor or |
| ability to report or set fan or pump speeds |
\*---------------------------------------------*/
FanController_NZXTKraken* fan_controller = new FanController_NZXTKraken(controller);
fan_controller->name = name;
ResourceManager::get()->RegisterFanController(fan_controller);
}
}
} /* DetectNZXTKrakenControllers() */

View File

@@ -22,6 +22,7 @@ typedef struct
\*--------------------------------------------------------------*/
std::string name; /* Fan name */
unsigned int speed_cmd; /* Speed command */
unsigned int prev_speed_cmd; /* Last speed command */
unsigned int speed_min; /* Minimum speed command */
unsigned int speed_max; /* Maximum speed command */
unsigned int rpm_rdg; /* RPM reading */
@@ -48,4 +49,4 @@ public:
\*---------------------------------------------------------*/
virtual void UpdateControl() = 0;
virtual void UpdateReading() = 0;
};
};