mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-23 23:37:48 -05:00
141 lines
3.8 KiB
C++
141 lines
3.8 KiB
C++
/*---------------------------------------------------------*\
|
|
| SkyloongGK104ProController.cpp |
|
|
| |
|
|
| Driver for Skyloong GK104 Pro |
|
|
| |
|
|
| Givo (givowo) 30 Jun 2024 |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-or-later |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#include <cstring>
|
|
#include "SkyloongGK104ProController.h"
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
enum command
|
|
{
|
|
ping = 0x0C,
|
|
mode = 0xB,
|
|
le_define = 0x1A
|
|
};
|
|
|
|
SkyloongGK104ProController::SkyloongGK104ProController(hid_device* dev_handle, const char* path, std::string dev_name)
|
|
{
|
|
dev = dev_handle;
|
|
location = path;
|
|
name = dev_name;
|
|
|
|
SendCommand(command::ping, SUBCOMMAND_NONE);
|
|
SendCommand(command::mode, MODE_ONLINE);
|
|
SendCommand(command::ping, SUBCOMMAND_NONE);
|
|
}
|
|
|
|
SkyloongGK104ProController::~SkyloongGK104ProController()
|
|
{
|
|
SendCommand(command::mode, MODE_OFFLINE);
|
|
hid_close(dev);
|
|
}
|
|
|
|
std::string SkyloongGK104ProController::GetDeviceLocation()
|
|
{
|
|
return("HID: " + location);
|
|
}
|
|
|
|
std::string SkyloongGK104ProController::GetDeviceName()
|
|
{
|
|
return(name);
|
|
}
|
|
|
|
void SkyloongGK104ProController::SendCommand(char command, char sub_command)
|
|
{
|
|
unsigned char buf[PACKET_SIZE];
|
|
memset(buf, 0x00, PACKET_SIZE);
|
|
|
|
buf[0x01] = command;
|
|
buf[0x02] = sub_command;
|
|
|
|
uint16_t crc = Crc16CcittFalse(buf, PACKET_SIZE);
|
|
|
|
buf[0x07] = crc & 0xFF;
|
|
buf[0x08] = crc >> 8;
|
|
|
|
hid_write(dev, buf, PACKET_SIZE);
|
|
}
|
|
|
|
void SkyloongGK104ProController::SendColorPacket(std::vector<RGBColor> colors, std::vector<led> *leds, int brightness)
|
|
{
|
|
unsigned char le_data[TOTAL_LED_BYTES];
|
|
memset(le_data, 0x00, TOTAL_LED_BYTES);
|
|
|
|
for(unsigned int i = 0; i < leds->size(); i++)
|
|
{
|
|
int index = leds->at(i).value * 4;
|
|
le_data[index++] = RGBGetRValue(colors[i]);
|
|
le_data[index++] = RGBGetGValue(colors[i]);
|
|
le_data[index++] = RGBGetBValue(colors[i]);
|
|
le_data[index++] = brightness;
|
|
}
|
|
|
|
for(int n = 0; n < TOTAL_LED_BYTES; n += LED_BYTES_IN_CHUNK) {
|
|
if(n + LED_BYTES_IN_CHUNK <= TOTAL_LED_BYTES)
|
|
{
|
|
SetLEDefine(n, &le_data[n], LED_BYTES_IN_CHUNK);
|
|
}
|
|
else
|
|
{
|
|
SetLEDefine(n, &le_data[n], TOTAL_LED_BYTES - n);
|
|
}
|
|
}
|
|
|
|
SendCommand(command::le_define, LE_DEFINE_SAVE);
|
|
}
|
|
|
|
void SkyloongGK104ProController::SetLEDefine(int address, unsigned char *le_data, int le_data_length)
|
|
{
|
|
unsigned char buf[PACKET_SIZE];
|
|
memset(buf, 0x00, PACKET_SIZE);
|
|
|
|
buf[0x01] = command::le_define;
|
|
buf[0x02] = LE_DEFINE_SET;
|
|
|
|
int header = (address + ((le_data_length << 24) & 0xFF000000)) | 0;
|
|
buf[0x03] = header & 0xFF;
|
|
buf[0x04] = (header >> 8) & 0xFF;
|
|
buf[0x05] = (header >> 16) & 0xFF;
|
|
buf[0x06] = (header >> 24) & 0xFF;
|
|
|
|
std::copy(le_data, le_data + le_data_length, buf + 9);
|
|
|
|
uint16_t crc = Crc16CcittFalse(buf, PACKET_SIZE);
|
|
buf[0x07] = crc & 0xFF;
|
|
buf[0x08] = crc >> 8;
|
|
|
|
hid_write(dev, buf, PACKET_SIZE);
|
|
}
|
|
|
|
uint16_t SkyloongGK104ProController::Crc16CcittFalse(const uint8_t *buffer, uint16_t size)
|
|
{
|
|
uint16_t crc = 0xFFFF;
|
|
|
|
while(size--)
|
|
{
|
|
crc ^= (*buffer++ << 8);
|
|
|
|
for(uint8_t i = 0; i < 8; ++i)
|
|
{
|
|
if(crc & 0x8000)
|
|
{
|
|
crc = (crc << 1) ^ 0x1021;
|
|
}
|
|
else
|
|
{
|
|
crc = crc << 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return crc;
|
|
}
|