Copy Corsair Lighting Node code to Zalman Z Sync code as the two use the same protocol

This commit is contained in:
Adam Honse 2021-01-31 17:06:03 -06:00
parent 578157f44d
commit 51142d6ab6
4 changed files with 861 additions and 91 deletions

View file

@ -9,52 +9,221 @@
#include "RGBController_ZalmanZSync.h"
RGBController_ZalmanZSync::RGBController_ZalmanZSync(ZalmanZSyncController* controller_ptr)
{
controller = controller_ptr;
type = DEVICE_TYPE_LEDSTRIP;
name = "Zalman Z Sync Device";
description = "Zalman Z Sync Device";
location = controller->GetDeviceLocation();
serial = controller->GetSerialString();
controller = controller_ptr;
name = "Zalman Z Sync Device";
vendor = "Zalman";
description = "Zalman Z Sync Device";
type = DEVICE_TYPE_LEDSTRIP;
version = controller->GetFirmwareString();
location = controller->GetLocationString();
serial = controller->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode RainbowWave;
RainbowWave.name = "Rainbow Wave";
RainbowWave.value = ZALMAN_Z_SYNC_MODE_RAINBOW_WAVE;
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
RainbowWave.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
RainbowWave.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
RainbowWave.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
RainbowWave.direction = MODE_DIRECTION_RIGHT;
RainbowWave.color_mode = MODE_COLORS_NONE;
modes.push_back(RainbowWave);
mode ColorShift;
ColorShift.name = "Color Shift";
ColorShift.value = ZALMAN_Z_SYNC_MODE_COLOR_SHIFT;
ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
ColorShift.colors_min = 2;
ColorShift.colors_max = 2;
ColorShift.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
ColorShift.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
ColorShift.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorShift.colors.resize(2);
modes.push_back(ColorShift);
mode ColorPulse;
ColorPulse.name = "Color Pulse";
ColorPulse.value = ZALMAN_Z_SYNC_MODE_COLOR_PULSE;
ColorPulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
ColorPulse.colors_min = 2;
ColorPulse.colors_max = 2;
ColorPulse.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
ColorPulse.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
ColorPulse.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
ColorPulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorPulse.colors.resize(2);
modes.push_back(ColorPulse);
mode ColorWave;
ColorWave.name = "Color Wave";
ColorWave.value = ZALMAN_Z_SYNC_MODE_COLOR_WAVE;
ColorWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
ColorWave.colors_min = 2;
ColorWave.colors_max = 2;
ColorWave.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
ColorWave.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
ColorWave.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
ColorWave.direction = MODE_DIRECTION_RIGHT;
ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorWave.colors.resize(2);
modes.push_back(ColorWave);
mode Static;
Static.name = "Static";
Static.value = ZALMAN_Z_SYNC_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors.resize(1);
modes.push_back(Static);
mode Temperature;
Temperature.name = "Temperature";
Temperature.value = ZALMAN_Z_SYNC_MODE_TEMPERATURE;
Temperature.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Temperature.colors_min = 3;
Temperature.colors_max = 3;
Temperature.color_mode = MODE_COLORS_MODE_SPECIFIC;
Temperature.colors.resize(3);
modes.push_back(Temperature);
mode Visor;
Visor.name = "Visor";
Visor.value = ZALMAN_Z_SYNC_MODE_VISOR;
Visor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Visor.colors_min = 2;
Visor.colors_max = 2;
Visor.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
Visor.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
Visor.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
Visor.color_mode = MODE_COLORS_MODE_SPECIFIC;
Visor.colors.resize(2);
modes.push_back(Visor);
mode Marquee;
Marquee.name = "Marquee";
Marquee.value = ZALMAN_Z_SYNC_MODE_MARQUEE;
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Marquee.colors_min = 1;
Marquee.colors_max = 1;
Marquee.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
Marquee.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
Marquee.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
Marquee.direction = MODE_DIRECTION_RIGHT;
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
Marquee.colors.resize(1);
modes.push_back(Marquee);
mode Blink;
Blink.name = "Blink";
Blink.value = ZALMAN_Z_SYNC_MODE_BLINK;
Blink.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Blink.colors_min = 2;
Blink.colors_max = 2;
Blink.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
Blink.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
Blink.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
Blink.color_mode = MODE_COLORS_MODE_SPECIFIC;
Blink.colors.resize(2);
modes.push_back(Blink);
mode Sequential;
Sequential.name = "Sequential";
Sequential.value = ZALMAN_Z_SYNC_MODE_SEQUENTIAL;
Sequential.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Sequential.colors_min = 1;
Sequential.colors_max = 1;
Sequential.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
Sequential.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
Sequential.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
Sequential.direction = MODE_DIRECTION_RIGHT;
Sequential.color_mode = MODE_COLORS_MODE_SPECIFIC;
Sequential.colors.resize(1);
modes.push_back(Sequential);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = ZALMAN_Z_SYNC_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = ZALMAN_Z_SYNC_SPEED_SLOW;
Rainbow.speed_max = ZALMAN_Z_SYNC_SPEED_FAST;
Rainbow.speed = ZALMAN_Z_SYNC_SPEED_MEDIUM;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
SetupZones();
}
RGBController_ZalmanZSync::~RGBController_ZalmanZSync()
{
}
void RGBController_ZalmanZSync::SetupZones()
{
for(unsigned int zone_idx = 0; zone_idx < 8; zone_idx++)
/*-------------------------------------------------*\
| Only set LED count on the first run |
\*-------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
zone new_zone;
first_run = true;
}
new_zone.name = "Channel " + std::to_string(zone_idx + 1);
new_zone.type = ZONE_TYPE_LINEAR;
new_zone.leds_min = 24;
new_zone.leds_max = 24;
new_zone.leds_count = 24;
new_zone.matrix_map = NULL;
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
zones.resize(ZALMAN_Z_SYNC_NUM_CHANNELS);
zones.push_back(new_zone);
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
for (unsigned int channel_idx = 0; channel_idx < ZALMAN_Z_SYNC_NUM_CHANNELS; channel_idx++)
{
char ch_idx_string[2];
sprintf(ch_idx_string, "%d", channel_idx + 1);
for(unsigned int led_idx = 0; led_idx < 24; led_idx++)
zones[channel_idx].name = "Channel ";
zones[channel_idx].name.append(ch_idx_string);
zones[channel_idx].type = ZONE_TYPE_LINEAR;
/*-------------------------------------------------*\
| I did some experimenting and determined that the |
| maximum number of LEDs the Corsair Commander Pro |
| can support is 200. |
\*-------------------------------------------------*/
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = 204;
if(first_run)
{
led new_led;
zones[channel_idx].leds_count = 0;
}
new_led.name = "LED " + std::to_string(led_idx + 1);
zones[channel_idx].matrix_map = NULL;
for (unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
char led_idx_string[4];
sprintf(led_idx_string, "%d", led_ch_idx + 1);
led new_led;
new_led.name = "LED ";
new_led.name.append(led_idx_string);
leds.push_back(new_led);
leds_channel.push_back(channel_idx);
}
}
@ -63,33 +232,89 @@ void RGBController_ZalmanZSync::SetupZones()
void RGBController_ZalmanZSync::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_ZalmanZSync::DeviceUpdateLEDs()
{
for(unsigned int zone_idx = 0; zone_idx < 8; zone_idx++)
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
controller->SetLEDs(zone_idx, zones[zone_idx].colors);
controller->SetChannelLEDs(zone_idx, zones[zone_idx].colors, zones[zone_idx].leds_count);
}
}
void RGBController_ZalmanZSync::UpdateZoneLEDs(int zone)
{
controller->SetLEDs(zone, zones[zone].colors);
controller->SetChannelLEDs(zone, zones[zone].colors, zones[zone].leds_count);
}
void RGBController_ZalmanZSync::UpdateSingleLED(int led)
{
DeviceUpdateLEDs();
unsigned int channel = leds_channel[led];
controller->SetChannelLEDs(channel, zones[channel].colors, zones[channel].leds_count);
}
void RGBController_ZalmanZSync::SetCustomMode()
{
active_mode = 0;
}
void RGBController_ZalmanZSync::DeviceUpdateMode()
{
if(modes[active_mode].value == 0xFFFF)
{
DeviceUpdateLEDs();
}
else
{
for(int channel = 0; channel < ZALMAN_Z_SYNC_NUM_CHANNELS; channel++)
{
unsigned int direction = 0;
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
}
if(modes[active_mode].direction == MODE_DIRECTION_RIGHT)
{
direction = 1;
}
unsigned char mode_colors[9];
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
for(std::size_t i = 0; i < modes[active_mode].colors.size(); i++)
{
mode_colors[(3 * i) + 0] = RGBGetRValue(modes[active_mode].colors[i]);
mode_colors[(3 * i) + 1] = RGBGetGValue(modes[active_mode].colors[i]);
mode_colors[(3 * i) + 2] = RGBGetBValue(modes[active_mode].colors[i]);
}
}
controller->SetChannelEffect(channel,
zones[channel].leds_count,
modes[active_mode].value,
modes[active_mode].speed,
direction,
random,
mode_colors[0],
mode_colors[1],
mode_colors[2],
mode_colors[3],
mode_colors[4],
mode_colors[5],
mode_colors[6],
mode_colors[7],
mode_colors[8]);
}
}
}

View file

@ -15,12 +15,11 @@ class RGBController_ZalmanZSync : public RGBController
{
public:
RGBController_ZalmanZSync(ZalmanZSyncController* controller_ptr);
~RGBController_ZalmanZSync();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
@ -29,5 +28,7 @@ public:
void DeviceUpdateMode();
private:
ZalmanZSyncController* controller;
};
ZalmanZSyncController* controller;
std::vector<unsigned int> leds_channel;
std::vector<unsigned int> zones_channel;
};

View file

@ -1,80 +1,470 @@
/*-----------------------------------------*\
| ZalmanZSyncController.cpp |
| |
| Definitions and types for Zalman Z Sync |
| lighting controller |
| |
| The Zalman Z Sync device uses the same |
| protocol as the Corsair Lighting Node |
| devices except supports 8 channels. |
| |
| This code copied from the |
| CorsairLightingNodeController files |
| |
| Adam Honse (CalcProgrammer1) 1/30/2021 |
\*-----------------------------------------*/
#include "ZalmanZSyncController.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
using namespace std::chrono_literals;
ZalmanZSyncController::ZalmanZSyncController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
SendFirmwareRequest();
/*-----------------------------------------------------*\
| The Corsair Lighting Node Pro requires a packet within|
| 20 seconds of sending the lighting change in order |
| to not revert back into rainbow mode. Start a thread |
| to continuously send a keepalive packet every 5s |
\*-----------------------------------------------------*/
keepalive_thread_run = 1;
keepalive_thread = new std::thread(&ZalmanZSyncController::KeepaliveThread, this);
}
ZalmanZSyncController::~ZalmanZSyncController()
{
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
}
std::string ZalmanZSyncController::GetDeviceLocation()
void ZalmanZSyncController::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(5))
{
SendCommit();
}
std::this_thread::sleep_for(1s);
}
}
std::string ZalmanZSyncController::GetFirmwareString()
{
return(firmware_version);
}
std::string ZalmanZSyncController::GetLocationString()
{
return("HID: " + location);
}
std::string ZalmanZSyncController::GetSerialString()
{
return("");
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void ZalmanZSyncController::SetLEDs(unsigned char channel, RGBColor* colors)
void ZalmanZSyncController::SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2,
unsigned char red3,
unsigned char grn3,
unsigned char blu3
)
{
SendDirectFrame(channel, ZALMAN_Z_SYNC_COLOR_CHANNEL_RED, colors);
SendDirectFrame(channel, ZALMAN_Z_SYNC_COLOR_CHANNEL_GREEN, colors);
SendDirectFrame(channel, ZALMAN_Z_SYNC_COLOR_CHANNEL_BLUE, colors);
/*-----------------------------------------------------*\
| Send Reset packet |
\*-----------------------------------------------------*/
SendReset(channel);
SendApply();
/*-----------------------------------------------------*\
| Send Begin packet |
\*-----------------------------------------------------*/
SendBegin(channel);
/*-----------------------------------------------------*\
| Set Port State packet |
\*-----------------------------------------------------*/
SendPortState(channel, ZALMAN_Z_SYNC_PORT_STATE_HARDWARE);
/*-----------------------------------------------------*\
| Set Effect Configuration packet |
\*-----------------------------------------------------*/
SendEffectConfig
(
channel,
0,
num_leds,
mode,
speed,
direction,
random,
red1,
grn1,
blu1,
red2,
grn2,
blu2,
red3,
grn3,
blu3,
0,
0,
0
);
/*-----------------------------------------------------*\
| Send Commit packet |
\*-----------------------------------------------------*/
SendCommit();
}
void ZalmanZSyncController::SendApply()
void ZalmanZSyncController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
{
unsigned char usb_buf[65];
unsigned char red_color_data[50];
unsigned char grn_color_data[50];
unsigned char blu_color_data[50];
unsigned char pkt_offset = 0;
unsigned char pkt_size = 0;
unsigned int colors_remaining = num_colors;
usb_buf[0] = 0x00;
usb_buf[1] = 0x33;
usb_buf[2] = 0xFF;
/*-----------------------------------------------------*\
| Send Port State packet |
\*-----------------------------------------------------*/
SendPortState(channel, ZALMAN_Z_SYNC_PORT_STATE_SOFTWARE);
hid_write(dev, usb_buf, 65);
}
void ZalmanZSyncController::SendDirectFrame(unsigned char channel, unsigned char color_channel, RGBColor* colors)
{
unsigned char usb_buf[65];
usb_buf[0] = 0x00;
usb_buf[1] = 0x32;
usb_buf[2] = channel;
usb_buf[3] = 0x00;
usb_buf[4] = 0x18;
usb_buf[5] = color_channel;
switch(color_channel)
/*-----------------------------------------------------*\
| Loop through colors and send 50 at a time |
\*-----------------------------------------------------*/
while(colors_remaining > 0)
{
case ZALMAN_Z_SYNC_COLOR_CHANNEL_RED:
for(unsigned int color_idx = 0; color_idx < 24; color_idx++)
{
usb_buf[6 + color_idx] = RGBGetRValue(colors[color_idx]);
}
break;
if(colors_remaining < 50)
{
pkt_size = colors_remaining;
}
else
{
pkt_size = 50;
}
for(int color_idx = 0; color_idx < pkt_size; color_idx++)
{
red_color_data[color_idx] = RGBGetRValue(colors[pkt_offset + color_idx]);
grn_color_data[color_idx] = RGBGetGValue(colors[pkt_offset + color_idx]);
blu_color_data[color_idx] = RGBGetBValue(colors[pkt_offset + color_idx]);
}
case ZALMAN_Z_SYNC_COLOR_CHANNEL_GREEN:
for(unsigned int color_idx = 0; color_idx < 24; color_idx++)
{
usb_buf[6 + color_idx] = RGBGetGValue(colors[color_idx]);
}
break;
SendDirect(channel, pkt_offset, pkt_size, ZALMAN_Z_SYNC_DIRECT_CHANNEL_RED, red_color_data);
SendDirect(channel, pkt_offset, pkt_size, ZALMAN_Z_SYNC_DIRECT_CHANNEL_GREEN, grn_color_data);
SendDirect(channel, pkt_offset, pkt_size, ZALMAN_Z_SYNC_DIRECT_CHANNEL_BLUE, blu_color_data);
case ZALMAN_Z_SYNC_COLOR_CHANNEL_BLUE:
for(unsigned int color_idx = 0; color_idx < 24; color_idx++)
{
usb_buf[6 + color_idx] = RGBGetBValue(colors[color_idx]);
}
break;
colors_remaining -= pkt_size;
pkt_offset += pkt_size;
}
/*-----------------------------------------------------*\
| Send Commit packet |
\*-----------------------------------------------------*/
SendCommit();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void ZalmanZSyncController::SendFirmwareRequest()
{
int actual;
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Firmware Version Request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = ZALMAN_Z_SYNC_PACKET_ID_FIRMWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
actual = hid_read(dev, usb_buf, 17);
if(actual > 0)
{
firmware_version = std::to_string(usb_buf[0x01]) + "." + std::to_string(usb_buf[0x02]) + "." + std::to_string(usb_buf[0x03]);
}
}
void ZalmanZSyncController::SendDirect
(
unsigned char channel,
unsigned char start,
unsigned char count,
unsigned char color_channel,
unsigned char* color_data
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Direct packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = ZALMAN_Z_SYNC_PACKET_ID_DIRECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = start;
usb_buf[0x04] = count;
usb_buf[0x05] = color_channel;
/*-----------------------------------------------------*\
| Copy in color data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x06], color_data, count);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void ZalmanZSyncController::SendCommit()
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Update last commit time |
\*-----------------------------------------------------*/
last_commit_time = std::chrono::steady_clock::now();
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = ZALMAN_Z_SYNC_PACKET_ID_COMMIT;
usb_buf[0x02] = 0xFF;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void ZalmanZSyncController::SendBegin
(
unsigned char channel
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Begin packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = ZALMAN_Z_SYNC_PACKET_ID_BEGIN;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void ZalmanZSyncController::SendEffectConfig
(
unsigned char channel,
unsigned char count,
unsigned char led_type,
unsigned char mode,
unsigned char speed,
unsigned char direction,
unsigned char change_style,
unsigned char color_0_red,
unsigned char color_0_green,
unsigned char color_0_blue,
unsigned char color_1_red,
unsigned char color_1_green,
unsigned char color_1_blue,
unsigned char color_2_red,
unsigned char color_2_green,
unsigned char color_2_blue,
unsigned short temperature_0,
unsigned short temperature_1,
unsigned short temperature_2
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Effect Config packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = ZALMAN_Z_SYNC_PACKET_ID_EFFECT_CONFIG;
usb_buf[0x02] = channel;
usb_buf[0x03] = count;
usb_buf[0x04] = led_type;
/*-----------------------------------------------------*\
| Set up mode parameters |
\*-----------------------------------------------------*/
usb_buf[0x05] = mode;
usb_buf[0x06] = speed;
usb_buf[0x07] = direction;
usb_buf[0x08] = change_style;
usb_buf[0x09] = 0;
/*-----------------------------------------------------*\
| Set up mode colors |
\*-----------------------------------------------------*/
usb_buf[0x0A] = color_0_red;
usb_buf[0x0B] = color_0_green;
usb_buf[0x0C] = color_0_blue;
usb_buf[0x0D] = color_1_red;
usb_buf[0x0E] = color_1_green;
usb_buf[0x0F] = color_1_blue;
usb_buf[0x10] = color_2_red;
usb_buf[0x11] = color_2_green;
usb_buf[0x12] = color_2_blue;
/*-----------------------------------------------------*\
| Set up temperatures |
\*-----------------------------------------------------*/
usb_buf[0x13] = (temperature_0 >> 8);
usb_buf[0x14] = (temperature_0 & 0xFF);
usb_buf[0x15] = (temperature_1 >> 8);
usb_buf[0x16] = (temperature_1 & 0xFF);
usb_buf[0x17] = (temperature_2 >> 8);
usb_buf[0x18] = (temperature_2 & 0xFF);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void ZalmanZSyncController::SendTemperature()
{
}
void ZalmanZSyncController::SendReset
(
unsigned char channel
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Reset packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = ZALMAN_Z_SYNC_PACKET_ID_RESET;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void ZalmanZSyncController::SendPortState
(
unsigned char channel,
unsigned char state
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Port State packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = ZALMAN_Z_SYNC_PACKET_ID_PORT_STATE;
usb_buf[0x02] = channel;
usb_buf[0x03] = state;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void ZalmanZSyncController::SendBrightness()
{
}
void ZalmanZSyncController::SendLEDCount()
{
}
void ZalmanZSyncController::SendProtocol()
{
}

View file

@ -4,21 +4,92 @@
| Definitions and types for Zalman Z Sync |
| lighting controller |
| |
| The Zalman Z Sync device uses the same |
| protocol as the Corsair Lighting Node |
| devices except supports 8 channels. |
| |
| This code copied from the |
| CorsairLightingNodeController files |
| |
| Adam Honse (CalcProgrammer1) 1/30/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <chrono>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
ZALMAN_Z_SYNC_COLOR_CHANNEL_RED = 0x00,
ZALMAN_Z_SYNC_COLOR_CHANNEL_GREEN = 0x01,
ZALMAN_Z_SYNC_COLOR_CHANNEL_BLUE = 0x02,
ZALMAN_Z_SYNC_PACKET_ID_FIRMWARE = 0x02, /* Get firmware version */
ZALMAN_Z_SYNC_PACKET_ID_DIRECT = 0x32, /* Direct mode LED update packet */
ZALMAN_Z_SYNC_PACKET_ID_COMMIT = 0x33, /* Commit changes packet */
ZALMAN_Z_SYNC_PACKET_ID_BEGIN = 0x34, /* Begin effect packet */
ZALMAN_Z_SYNC_PACKET_ID_EFFECT_CONFIG = 0x35, /* Effect mode configuration packet */
ZALMAN_Z_SYNC_PACKET_ID_TEMPERATURE = 0x36, /* Update temperature value packet */
ZALMAN_Z_SYNC_PACKET_ID_RESET = 0x37, /* Reset channel packet */
ZALMAN_Z_SYNC_PACKET_ID_PORT_STATE = 0x38, /* Set port state packet */
ZALMAN_Z_SYNC_PACKET_ID_BRIGHTNESS = 0x39, /* Set brightness packet */
ZALMAN_Z_SYNC_PACKET_ID_LED_COUNT = 0x3A, /* Set LED count packet */
ZALMAN_Z_SYNC_PACKET_ID_PROTOCOL = 0x3B, /* Set protocol packet */
};
enum
{
ZALMAN_Z_SYNC_DIRECT_CHANNEL_RED = 0x00, /* Red channel for direct update */
ZALMAN_Z_SYNC_DIRECT_CHANNEL_GREEN = 0x01, /* Green channel for direct update */
ZALMAN_Z_SYNC_DIRECT_CHANNEL_BLUE = 0x02, /* Blue channel for direct update */
};
enum
{
ZALMAN_Z_SYNC_PORT_STATE_HARDWARE = 0x01, /* Effect hardware control of channel */
ZALMAN_Z_SYNC_PORT_STATE_SOFTWARE = 0x02, /* Direct software control of channel */
};
enum
{
ZALMAN_Z_SYNC_LED_TYPE_LED_STRIP = 0x0A, /* Corsair LED Strip Type */
ZALMAN_Z_SYNC_LED_TYPE_HD_FAN = 0x0C, /* Corsair HD-series Fan Type */
ZALMAN_Z_SYNC_LED_TYPE_SP_FAN = 0x01, /* Corsair SP-series Fan Type */
ZALMAN_Z_SYNC_LED_TYPE_ML_FAN = 0x02, /* Corsair ML-series Fan Type */
};
enum
{
ZALMAN_Z_SYNC_CHANNEL_1 = 0x00, /* Channel 1 */
ZALMAN_Z_SYNC_CHANNEL_2 = 0x01, /* Channel 2 */
ZALMAN_Z_SYNC_CHANNEL_3 = 0x02, /* Channel 3 */
ZALMAN_Z_SYNC_CHANNEL_4 = 0x03, /* Channel 4 */
ZALMAN_Z_SYNC_CHANNEL_5 = 0x04, /* Channel 5 */
ZALMAN_Z_SYNC_CHANNEL_6 = 0x05, /* Channel 6 */
ZALMAN_Z_SYNC_CHANNEL_7 = 0x06, /* Channel 7 */
ZALMAN_Z_SYNC_CHANNEL_8 = 0x07, /* Channel 8 */
ZALMAN_Z_SYNC_NUM_CHANNELS = 0x08, /* Number of channels */
};
enum
{
ZALMAN_Z_SYNC_SPEED_FAST = 0x00, /* Fast speed */
ZALMAN_Z_SYNC_SPEED_MEDIUM = 0x01, /* Medium speed */
ZALMAN_Z_SYNC_SPEED_SLOW = 0x02, /* Slow speed */
};
enum
{
ZALMAN_Z_SYNC_MODE_RAINBOW_WAVE = 0x00, /* Rainbow Wave mode */
ZALMAN_Z_SYNC_MODE_COLOR_SHIFT = 0x01, /* Color Shift mode */
ZALMAN_Z_SYNC_MODE_COLOR_PULSE = 0x02, /* Color Pulse mode */
ZALMAN_Z_SYNC_MODE_COLOR_WAVE = 0x03, /* Color Wave mode */
ZALMAN_Z_SYNC_MODE_STATIC = 0x04, /* Static mode */
ZALMAN_Z_SYNC_MODE_TEMPERATURE = 0x05, /* Temperature mode */
ZALMAN_Z_SYNC_MODE_VISOR = 0x06, /* Visor mode */
ZALMAN_Z_SYNC_MODE_MARQUEE = 0x07, /* Marquee mode */
ZALMAN_Z_SYNC_MODE_BLINK = 0x08, /* Blink mode */
ZALMAN_Z_SYNC_MODE_SEQUENTIAL = 0x09, /* Sequential mode */
ZALMAN_Z_SYNC_MODE_RAINBOW = 0x0A, /* Rainbow mode */
};
class ZalmanZSyncController
@ -27,15 +98,98 @@ public:
ZalmanZSyncController(hid_device* dev_handle, const char* path);
~ZalmanZSyncController();
std::string GetDeviceLocation();
std::string GetSerialString();
std::string GetFirmwareString();
std::string GetLocationString();
std::string GetSerialString();
void SetLEDs(unsigned char channel, RGBColor* colors);
unsigned int GetStripsOnChannel(unsigned int channel);
void SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
unsigned char speed,
unsigned char direction,
bool random,
unsigned char red1,
unsigned char grn1,
unsigned char blu1,
unsigned char red2,
unsigned char grn2,
unsigned char blu2,
unsigned char red3,
unsigned char grn3,
unsigned char blu3
);
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
void KeepaliveThread();
private:
hid_device* dev;
std::string firmware_version;
std::string location;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
void SendApply();
void SendDirectFrame(unsigned char channel, unsigned char color_channel, RGBColor* colors);
void SendFirmwareRequest();
void SendDirect
(
unsigned char channel,
unsigned char start,
unsigned char count,
unsigned char color_channel,
unsigned char* color_data
);
void SendCommit();
void SendBegin
(
unsigned char channel
);
void SendEffectConfig
(
unsigned char channel,
unsigned char count,
unsigned char led_type,
unsigned char mode,
unsigned char speed,
unsigned char direction,
unsigned char change_style,
unsigned char color_0_red,
unsigned char color_0_green,
unsigned char color_0_blue,
unsigned char color_1_red,
unsigned char color_1_green,
unsigned char color_1_blue,
unsigned char color_2_red,
unsigned char color_2_green,
unsigned char color_2_blue,
unsigned short temperature_0,
unsigned short temperature_1,
unsigned short temperature_2
);
void SendTemperature();
void SendReset
(
unsigned char channel
);
void SendPortState
(
unsigned char channel,
unsigned char state
);
void SendBrightness();
void SendLEDCount();
void SendProtocol();
};