set fan curve functionality
This commit is contained in:
@@ -10,6 +10,12 @@
|
||||
#define AIO_COLOR_WHITE { 255, 255, 255 }
|
||||
#define AIO_COLOR_OFF { 0, 0, 0 }
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
// roughly converts fan speed to duty
|
||||
#define SPD2DTY(spd) MAX(0, MIN(spd * 100 / max_fan_speed, 100))
|
||||
|
||||
enum aio_pump_mode_t : uint8_t {
|
||||
QUIET,
|
||||
BALANCED,
|
||||
@@ -29,7 +35,12 @@ struct rgb_t {
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct aio_t{
|
||||
struct curve_point_t {
|
||||
uint8_t temp;
|
||||
uint8_t duty;
|
||||
};
|
||||
|
||||
struct aio_t {
|
||||
libusb_device_handle* handle;
|
||||
enum aio_pump_mode_t pump_mode;
|
||||
float water_temp;
|
||||
|
||||
39
src/aio.c
39
src/aio.c
@@ -8,6 +8,9 @@
|
||||
static const uint16_t usb_timeout = 250;
|
||||
static const uint8_t buf_size = 32; // needs 32 bc of overflow issue on these aios?
|
||||
|
||||
static const uint16_t max_fan_speed = 1200;
|
||||
static const uint8_t max_curve_points = 7;
|
||||
|
||||
// posts cmd to the aio, puts n bytes of response inside resp buffer
|
||||
#define POST_AND_GET_RESP(cmd, n) uint8_t req = cmd; uint8_t resp[buf_size]; aio_post(dev, &req, 1, resp, n)
|
||||
|
||||
@@ -99,6 +102,33 @@ static void aio_set_color(libusb_device_handle* dev, const enum aio_color_mode_t
|
||||
aio_post(dev, req, 2, resp, buf_size);
|
||||
}
|
||||
|
||||
static void aio_set_fan_curve(libusb_device_handle* dev, const struct curve_point_t *curve, const uint8_t count) {
|
||||
if (count < 1 || count > max_curve_points) {
|
||||
applog(LOG_ERR, "aio: curve must have 1-%d points", max_curve_points);
|
||||
return;
|
||||
}
|
||||
|
||||
struct curve_point_t padded[max_curve_points];
|
||||
for (int i = 0; i < max_curve_points; i++)
|
||||
padded[i] = (i < count) ? curve[i] : curve[count - 1];
|
||||
|
||||
uint8_t req[16], resp[32];
|
||||
req[0] = 0x40;
|
||||
|
||||
// setup request
|
||||
for (int i = 0; i < max_curve_points; i++)
|
||||
req[2 + i] = padded[i].temp;
|
||||
for (int i = 0; i < max_curve_points; i++)
|
||||
req[9 + i] = padded[i].duty;
|
||||
|
||||
// set curve for both fans
|
||||
for (int i = 0; i < 2; i++) {
|
||||
req[1] = i;
|
||||
aio_post(dev, req, sizeof(req), resp, sizeof(resp));
|
||||
}
|
||||
applog(LOG_INF, "set up AIO fan curve");
|
||||
}
|
||||
|
||||
void aio_detect(struct aio_t *aio, const float t_quiet, const float t_balanced) {
|
||||
libusb_init(NULL);
|
||||
aio->handle = libusb_open_device_with_vid_pid(NULL, AIO_USB_VID, AIO_USB_PID);
|
||||
@@ -110,6 +140,13 @@ void aio_detect(struct aio_t *aio, const float t_quiet, const float t_balanced)
|
||||
aio->t_q = t_quiet;
|
||||
aio->t_b = t_balanced;
|
||||
|
||||
const struct curve_point_t fan_curve[] = {
|
||||
{ 35, SPD2DTY(480) },
|
||||
{ 39, SPD2DTY(750) },
|
||||
{ 45, SPD2DTY(1000) },
|
||||
{ 48, SPD2DTY(max_fan_speed) }
|
||||
};
|
||||
|
||||
/* detaches other software that might take the device? */
|
||||
if (libusb_kernel_driver_active(aio->handle, 0))
|
||||
libusb_detach_kernel_driver(aio->handle, 0);
|
||||
@@ -117,6 +154,8 @@ void aio_detect(struct aio_t *aio, const float t_quiet, const float t_balanced)
|
||||
aio_usb_claim(aio->handle);
|
||||
applog(LOG_INF, "found Corsair AIO device at %04x:%04x, fw ver: %s, B mode at %.1fC, Q mode at %.1fC", AIO_USB_VID, AIO_USB_PID, aio_get_firmware_version(aio->handle, (char[16]){0}), aio->t_b, aio->t_q);
|
||||
aio_set_pump_mode(aio->handle, QUIET); // needed for init ig?
|
||||
aio_set_color(aio->handle, AIO_COLOR_FIXED, 0, NULL, 0); // so it doenst complain the func is unused
|
||||
aio_set_fan_curve(aio->handle, fan_curve, sizeof(fan_curve) / sizeof(fan_curve[0]));
|
||||
aio_usb_release(aio->handle);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user