Add VSG Mintaka keyboard
parent
7dcdef28c8
commit
d7e467a37f
@ -0,0 +1,301 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| MintakaKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for VSG Mintaka Devices keyboard lighting |
|
||||
| Based on KeychronKeyboardController |
|
||||
| |
|
||||
| Federico Scodelaro (pudymody) 08 Oct 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
#include "MintakaKeyboardController.h"
|
||||
#include <string.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
MintakaKeyboardController::MintakaKeyboardController(hid_device* dev_handle, const hid_device_info& info)
|
||||
{
|
||||
dev = dev_handle;
|
||||
version = "";
|
||||
location = info.path;
|
||||
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
serial_number = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring return_wstring = serial_string;
|
||||
serial_number = std::string(return_wstring.begin(), return_wstring.end());
|
||||
}
|
||||
}
|
||||
|
||||
MintakaKeyboardController::~MintakaKeyboardController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string MintakaKeyboardController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string MintakaKeyboardController::GetSerialString()
|
||||
{
|
||||
return(serial_number);
|
||||
}
|
||||
|
||||
std::string MintakaKeyboardController::GetFirmwareVersion()
|
||||
{
|
||||
return(version);
|
||||
}
|
||||
|
||||
void MintakaKeyboardController:: SetLedSequencePositions(std::vector<unsigned int> positions)
|
||||
{
|
||||
led_sequence_positions = positions;
|
||||
}
|
||||
|
||||
void MintakaKeyboardController::SetMode(std::vector<mode> modes, int active_mode, std::vector<RGBColor> colors)
|
||||
{
|
||||
/*-----------------------------------------*\
|
||||
| Turn customization on/off |
|
||||
| Custom mode needs to turn it on |
|
||||
\*-----------------------------------------*/
|
||||
SetCustomization(modes[active_mode].value == CUSTOM_MODE_VALUE);
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Tells the device we're about to send the |
|
||||
| pages (18 pages) |
|
||||
\*-----------------------------------------*/
|
||||
StartEffectPage();
|
||||
|
||||
unsigned char usb_buf[PACKET_DATA_LENGTH];
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Configure the modes |
|
||||
| LED Effect Page structure: |
|
||||
| |
|
||||
| OK.. this was from the original PDF |
|
||||
| which appears to not be exact/up to date |
|
||||
|-------------------------------------------|
|
||||
| [0] Specialeffects mode1-32 |
|
||||
| [1] colorFull color: 0x00 Monochrome:0x01 |
|
||||
| [2] R Color ratio 0x00-0xFF |
|
||||
| [3] G Color Ratio0x00-0xFF |
|
||||
| [4] B Colour ratio0x00-0xFF |
|
||||
| full color is 0,invalid |
|
||||
| [5] dynamicdirection |
|
||||
| left to right: 0x00 |
|
||||
| right to left: 0x01 |
|
||||
| down to up: 0x02 |
|
||||
| up to down: 0x03 |
|
||||
| [6] brightnesscontrol 0x00-0x0F |
|
||||
| 0x0F brightest |
|
||||
| [7] Periodiccontrol0x00-0x0F |
|
||||
| 0x0F longest cycle |
|
||||
| [8:13] Reserved |
|
||||
| [14] Checkcode_L0xAA |
|
||||
| [15] Checkcode_H0x55 |
|
||||
|-------------------------------------------|
|
||||
| Fixes: |
|
||||
| color mode is 8th byte |
|
||||
| brightness is 9th byte |
|
||||
| speed is 10th byte |
|
||||
| direction is 11th byte |
|
||||
\*-----------------------------------------*/
|
||||
unsigned char selected_mode[EFFECT_PAGE_LENGTH];
|
||||
|
||||
for(unsigned int i = 0; i < 5; i++) // 5 packets
|
||||
{
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
|
||||
|
||||
for(unsigned int j = 0; j < 4; j++) // of 4 effects
|
||||
{
|
||||
const mode& m = modes[1 + j + i * 4]; // skip 1 first mode (Custom)
|
||||
|
||||
int offset = j * EFFECT_PAGE_LENGTH;
|
||||
|
||||
usb_buf[offset + 0] = m.value; // mode value
|
||||
|
||||
if(m.flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
usb_buf[offset + 1] = RGBGetRValue(m.colors[0]);
|
||||
usb_buf[offset + 2] = RGBGetGValue(m.colors[0]);
|
||||
usb_buf[offset + 3] = RGBGetBValue(m.colors[0]);
|
||||
}
|
||||
|
||||
usb_buf[offset + 8] = m.color_mode == MODE_COLORS_RANDOM; // random switch
|
||||
usb_buf[offset + 9] = m.brightness;
|
||||
usb_buf[offset + 10] = m.speed;
|
||||
usb_buf[offset + 11] = m.direction;
|
||||
|
||||
usb_buf[offset + 14] = EFFECT_PAGE_CHECK_CODE_L;
|
||||
usb_buf[offset + 15] = EFFECT_PAGE_CHECK_CODE_H;
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Backup active mode values for later use |
|
||||
| Custom and off share the same mode value |
|
||||
\*-----------------------------------------*/
|
||||
if(m.value == modes[active_mode].value || (m.value == LIGHTS_OFF_MODE_VALUE && modes[active_mode].value == CUSTOM_MODE_VALUE))
|
||||
{
|
||||
usb_buf[offset + 9] = modes[active_mode].brightness;
|
||||
|
||||
for(unsigned int x = 0; x < EFFECT_PAGE_LENGTH; x++)
|
||||
{
|
||||
selected_mode[x] = usb_buf[offset+x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Send(usb_buf); // Sends the packet
|
||||
}
|
||||
|
||||
// packets count sent: 5
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| 3 times an empty packet - guess why... |
|
||||
\*-----------------------------------------*/
|
||||
for(unsigned int i = 0; i < 3; i++)
|
||||
{
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
|
||||
Send(usb_buf);
|
||||
}
|
||||
|
||||
// packets count sent: 8
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Customization stuff |
|
||||
| 9 times * 16 blocks 80 RR GG BB |
|
||||
\*-----------------------------------------*/
|
||||
unsigned char color_buf[COLOR_BUF_SIZE];
|
||||
memset(color_buf, 0x00, COLOR_BUF_SIZE);
|
||||
|
||||
for(unsigned int i = 0; i < COLOR_BUF_SIZE; i += 4)
|
||||
{
|
||||
color_buf[i] = 0x80;
|
||||
}
|
||||
|
||||
for(unsigned int c = 0; c < colors.size(); c++)
|
||||
{
|
||||
int offset = led_sequence_positions[c] * 4;
|
||||
|
||||
color_buf[offset + 1] = RGBGetRValue(colors[c]);
|
||||
color_buf[offset + 2] = RGBGetGValue(colors[c]);
|
||||
color_buf[offset + 3] = RGBGetBValue(colors[c]);
|
||||
}
|
||||
|
||||
for(unsigned int p = 0; p < 9; p++)
|
||||
{
|
||||
memcpy(usb_buf, &color_buf[p * PACKET_DATA_LENGTH], PACKET_DATA_LENGTH);
|
||||
Send(usb_buf);
|
||||
}
|
||||
|
||||
// packets count sent: 17
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Tells the device what the active mode is |
|
||||
| This is the last packet |
|
||||
\*-----------------------------------------*/
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
|
||||
memcpy(usb_buf, &selected_mode[0], EFFECT_PAGE_LENGTH);
|
||||
Send(usb_buf);
|
||||
|
||||
// packets count sent: 18 - let's hope the keyboard ACK in next frame
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Tells the device that the pages are sent |
|
||||
\*-----------------------------------------*/
|
||||
EndCommunication();
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Tells the device to apply what we've sent |
|
||||
\*-----------------------------------------*/
|
||||
StartEffectCommand();
|
||||
}
|
||||
|
||||
void MintakaKeyboardController::StartEffectCommand()
|
||||
{
|
||||
unsigned char usb_buf[PACKET_DATA_LENGTH];
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
|
||||
|
||||
usb_buf[0x00] = PACKET_HEADER;
|
||||
usb_buf[0x01] = LED_EFFECT_START_COMMAND;
|
||||
|
||||
Send(usb_buf);
|
||||
}
|
||||
|
||||
void MintakaKeyboardController::StartEffectPage()
|
||||
{
|
||||
/*-----------------------------------------*\
|
||||
| LED_SPECIAL_EFFECT_PACKETS: |
|
||||
| Packet amount that will be sent in this |
|
||||
| transaction |
|
||||
\*-----------------------------------------*/
|
||||
unsigned char usb_buf[PACKET_DATA_LENGTH];
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
|
||||
|
||||
usb_buf[0x00] = PACKET_HEADER;
|
||||
usb_buf[0x01] = WRITE_LED_SPECIAL_EFFECT_AREA_COMMAND;
|
||||
usb_buf[0x08] = LED_SPECIAL_EFFECT_PACKETS;
|
||||
|
||||
Send(usb_buf);
|
||||
|
||||
Read();
|
||||
}
|
||||
|
||||
void MintakaKeyboardController::SetCustomization(bool state)
|
||||
{
|
||||
unsigned char usb_buf[PACKET_DATA_LENGTH];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
|
||||
usb_buf[0x00] = PACKET_HEADER;
|
||||
usb_buf[0x01] = state ? TURN_ON_CUSTOMIZATION_COMMAND : TURN_OFF_CUSTOMIZATION_COMMAND;
|
||||
Send(usb_buf);
|
||||
|
||||
Read();
|
||||
}
|
||||
|
||||
void MintakaKeyboardController::EndCommunication()
|
||||
{
|
||||
unsigned char usb_buf[PACKET_DATA_LENGTH];
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
|
||||
|
||||
usb_buf[0x00] = PACKET_HEADER;
|
||||
usb_buf[0x01] = COMMUNICATION_END_COMMAND;
|
||||
|
||||
Send(usb_buf);
|
||||
|
||||
Read();
|
||||
}
|
||||
|
||||
void MintakaKeyboardController::Read()
|
||||
{
|
||||
unsigned char usb_buf[PACKET_DATA_LENGTH+1];
|
||||
memset(usb_buf, 0x00, PACKET_DATA_LENGTH+1);
|
||||
|
||||
usb_buf[0x00] = REPORT_ID;
|
||||
|
||||
hid_get_feature_report(dev, usb_buf, PACKET_DATA_LENGTH+1);
|
||||
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
void MintakaKeyboardController::Send(unsigned char data[PACKET_DATA_LENGTH])
|
||||
{
|
||||
unsigned char usb_buf[PACKET_DATA_LENGTH+1];
|
||||
|
||||
usb_buf[0] = REPORT_ID;
|
||||
|
||||
for(unsigned int x = 0; x < PACKET_DATA_LENGTH; x++)
|
||||
{
|
||||
usb_buf[x+1] = data[x];
|
||||
}
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, PACKET_DATA_LENGTH+1);
|
||||
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| MintakaKeyboardController.h |
|
||||
| |
|
||||
| Driver for VSG Mintaka Devices keyboard lighting |
|
||||
| Based on KeychronKeyboardController |
|
||||
| |
|
||||
| Federico Scodelaro (pudymody) 08 Oct 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define REPORT_ID 0x00
|
||||
#define PACKET_DATA_LENGTH 64
|
||||
#define COLOR_BUF_SIZE 576
|
||||
#define EFFECT_PAGE_LENGTH 16
|
||||
#define LED_SPECIAL_EFFECT_PACKETS 0x12
|
||||
#define PACKET_HEADER 0x04
|
||||
#define EFFECT_PAGE_CHECK_CODE_L 0xAA
|
||||
#define EFFECT_PAGE_CHECK_CODE_H 0x55
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Commands |
|
||||
\*-----------------------------------------*/
|
||||
enum
|
||||
{
|
||||
COMMUNICATION_END_COMMAND = 0x02,
|
||||
GET_BASIC_INFO_COMMAND = 0x05,
|
||||
READ_KEY_DEFINITION_AREA_COMMAND = 0x10,
|
||||
WRITE_KEY_DEFINITION_AREA_COMMAND = 0x11,
|
||||
READ_LED_EFFECT_DEFINITION_AREA_COMMAND = 0x12,
|
||||
WRITE_LED_SPECIAL_EFFECT_AREA_COMMAND = 0x13,
|
||||
READ_MACRO_DEFINITION_AREA_COMMAND = 0x14,
|
||||
WRITE_MACRO_DEFINITION_AREA_COMMAND = 0x15,
|
||||
READ_GAME_MODE_AREA_COMMAND = 0x16,
|
||||
WRITE_GAME_MODE_AREA_COMMAND = 0x17,
|
||||
TURN_ON_CUSTOMIZATION_COMMAND = 0x18,
|
||||
TURN_OFF_CUSTOMIZATION_COMMAND = 0x19,
|
||||
LED_EFFECT_START_COMMAND = 0xF0,
|
||||
LED_SYNC_INITIAL_COMMAND = 0xF1,
|
||||
LED_SYNC_START_COMMAND = 0xF2,
|
||||
LED_SYNC_STOP_COMMAND = 0xF3,
|
||||
RANDOM_PACKET_START_COMMAND = 0xAB,
|
||||
};
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Modes |
|
||||
\*-----------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CUSTOM_MODE_VALUE = 0x00,
|
||||
STATIC_MODE_VALUE = 0x01,
|
||||
KEYSTROKE_LIGHT_UP_MODE_VALUE = 0x02,
|
||||
KEYSTROKE_DIM_MODE_VALUE = 0x03,
|
||||
SPARKLE_MODE_VALUE = 0x04,
|
||||
RAIN_MODE_VALUE = 0x05,
|
||||
RANDOM_COLORS_MODE_VALUE = 0x06,
|
||||
BREATHING_MODE_VALUE = 0x07,
|
||||
SPECTRUM_CYCLE_MODE_VALUE = 0x08,
|
||||
RING_GRADIENT_MODE_VALUE = 0x09,
|
||||
VERTICAL_GRADIENT_MODE_VALUE = 0x0A,
|
||||
HORIZONTAL_GRADIENT_WAVE_MODE_VALUE = 0x0B,
|
||||
AROUND_EDGES_MODE_VALUE = 0x0C,
|
||||
KEYSTROKE_HORIZONTAL_LINES_VALUE = 0x0D,
|
||||
KEYSTROKE_TITLED_LINES_MODE_VALUE = 0x0E,
|
||||
KEYSTROKE_RIPPLES_MODE_VALUE = 0x0F,
|
||||
SEQUENCE_MODE_VALUE = 0x10,
|
||||
WAVE_LINE_MODE_VALUE = 0x11,
|
||||
TILTED_LINES_MODE_VALUE = 0x12,
|
||||
BACK_AND_FORTH_MODE_VALUE = 0x13,
|
||||
LIGHTS_OFF_MODE_VALUE = 0x80,
|
||||
};
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Other settings |
|
||||
\*-----------------------------------------*/
|
||||
enum
|
||||
{
|
||||
MINTAKA_MIN_SPEED = 0x00,
|
||||
MINTAKA_MAX_SPEED = 0x0F,
|
||||
MINTAKA_MIN_BRIGHTNESS = 0x00,
|
||||
MINTAKA_MAX_BRIGHTNESS = 0x0F,
|
||||
};
|
||||
|
||||
|
||||
class MintakaKeyboardController
|
||||
{
|
||||
public:
|
||||
MintakaKeyboardController(hid_device* dev_handle, const hid_device_info& info);
|
||||
~MintakaKeyboardController();
|
||||
|
||||
std::string GetSerialString();
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
void SetLedSequencePositions(std::vector<unsigned int> positions);
|
||||
void SetMode(std::vector<mode> modes, int active_mode, std::vector<RGBColor> colors);
|
||||
|
||||
protected:
|
||||
hid_device* dev;
|
||||
|
||||
private:
|
||||
std::string location;
|
||||
std::string serial_number;
|
||||
std::string version;
|
||||
std::vector<unsigned int> led_sequence_positions;
|
||||
|
||||
void SetCustomization(bool state);
|
||||
void StartEffectPage();
|
||||
void StartEffectCommand();
|
||||
void EndCommunication();
|
||||
|
||||
void Read();
|
||||
void Send(unsigned char data[PACKET_DATA_LENGTH]);
|
||||
};
|
||||
@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| MintakaKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for VSG Mintaka Devices keyboard lighting |
|
||||
| Based on KeychronKeyboardController |
|
||||
| |
|
||||
| Federico Scodelaro (pudymody) 08 Oct 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
#include "Detector.h"
|
||||
#include "MintakaKeyboardController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_MintakaKeyboard.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| MintakaKeyboard vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define MINTAKA_KEYBOARD_VID 0x05AC
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Product ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define VSG_MINTAKA_PID 0x0256
|
||||
|
||||
void DetectMintakaKeyboardControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
MintakaKeyboardController* controller = new MintakaKeyboardController(dev, *info);
|
||||
RGBController_MintakaKeyboard* rgb_controller = new RGBController_MintakaKeyboard(controller);
|
||||
rgb_controller->name = name;
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("VSG Mintaka", DetectMintakaKeyboardControllers, MINTAKA_KEYBOARD_VID, VSG_MINTAKA_PID, 0, 0x0001, 0x06);
|
||||
@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_MintakaKeyboard.h |
|
||||
| |
|
||||
| Driver for VSG Mintaka Devices keyboard lighting |
|
||||
| Based on KeychronKeyboardController |
|
||||
| |
|
||||
| Federico Scodelaro (pudymody) 08 Oct 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "MintakaKeyboardController.h"
|
||||
|
||||
class RGBController_MintakaKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_MintakaKeyboard(MintakaKeyboardController* controller_ptr);
|
||||
~RGBController_MintakaKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
MintakaKeyboardController* controller;
|
||||
};
|
||||
Loading…
Reference in New Issue