From 9e5bbc7598d3b0d8a932d775490fade43002515e Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Wed, 30 Oct 2024 20:16:22 -0500 Subject: [PATCH] Initial HYTE Keyboard controller --- .../HYTEKeyboardController.cpp | 196 ++++++++++++++++++ .../HYTEKeyboardController.h | 40 ++++ .../HYTEKeyboardControllerDetect.cpp | 41 ++++ .../RGBController_HYTEKeyboard.cpp | 191 +++++++++++++++++ .../RGBController_HYTEKeyboard.h | 34 +++ 5 files changed, 502 insertions(+) create mode 100644 Controllers/HYTEKeyboardController/HYTEKeyboardController.cpp create mode 100644 Controllers/HYTEKeyboardController/HYTEKeyboardController.h create mode 100644 Controllers/HYTEKeyboardController/HYTEKeyboardControllerDetect.cpp create mode 100644 Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.cpp create mode 100644 Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.h diff --git a/Controllers/HYTEKeyboardController/HYTEKeyboardController.cpp b/Controllers/HYTEKeyboardController/HYTEKeyboardController.cpp new file mode 100644 index 00000000..499e927b --- /dev/null +++ b/Controllers/HYTEKeyboardController/HYTEKeyboardController.cpp @@ -0,0 +1,196 @@ +/*---------------------------------------------------------*\ +| HYTEKeyboardController.cpp | +| | +| Driver for HYTE keyboard | +| | +| Adam Honse (calcprogrammer1@gmail.com) 30 Oct 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include +#include "HYTEKeyboardController.h" + +HYTEKeyboardController::HYTEKeyboardController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +HYTEKeyboardController::~HYTEKeyboardController() +{ + +} + +std::string HYTEKeyboardController::GetDeviceLocation() +{ + return("HID " + location); +} + +void HYTEKeyboardController::LEDStreaming(unsigned int zone, RGBColor* colors) +{ + /*-----------------------------------------------------*\ + | Call the appropriate LEDStreaming function for the | + | given zone | + \*-----------------------------------------------------*/ + switch(zone) + { + case HYTE_KEYBOARD_ZONE_KEYBOARD: + LEDStreaming_Keyboard(colors); + break; + + case HYTE_KEYBOARD_ZONE_SURROUND: + LEDStreaming_Surround(colors); + break; + } +} + +void HYTEKeyboardController::LEDStreaming_Keyboard(RGBColor* colors) +{ + /*-----------------------------------------------------*\ + | LED Streaming - Keyboard RGB | + | | + | Set Feature (9 bytes, the first byte is 0x00) | + | 0x04 0xF0 0x00 0x00 0x00 0x00 0x00 0x00 | + | | + | EP6 Write (6 pages, 65 bytes/page) | + | 0xRR 0xGG 0xBB 0xRR 0xGG 0xBB ... | + \*-----------------------------------------------------*/ + unsigned char usb_feature_buf[9]; + unsigned char usb_buf[6][65]; + + /*-----------------------------------------------------*\ + | Set up feature report | + \*-----------------------------------------------------*/ + memset(usb_feature_buf, 0, sizeof(usb_feature_buf)); + + usb_feature_buf[0] = 0x00; + usb_feature_buf[1] = 0x04; + usb_feature_buf[2] = 0xF0; + + /*-----------------------------------------------------*\ + | Set up data packets | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + usb_buf[0][0] = 0x00; + usb_buf[1][0] = 0x00; + usb_buf[2][0] = 0x00; + usb_buf[3][0] = 0x00; + usb_buf[4][0] = 0x00; + usb_buf[5][0] = 0x00; + + /*-----------------------------------------------------*\ + | Fill in color data | + \*-----------------------------------------------------*/ + unsigned int color_idx = 0; + unsigned int channel_idx = 0; + + for(unsigned int pkt_idx = 0; pkt_idx < 6; pkt_idx++) + { + for(unsigned int byte_idx = 0; byte_idx < 64; byte_idx++) + { + switch(channel_idx) + { + case 0: + usb_buf[pkt_idx][1 + byte_idx] = RGBGetRValue(colors[color_idx]); + break; + + case 1: + usb_buf[pkt_idx][1 + byte_idx] = RGBGetGValue(colors[color_idx]); + break; + + case 2: + usb_buf[pkt_idx][1 + byte_idx] = RGBGetBValue(colors[color_idx]); + color_idx++; + break; + } + + channel_idx = ( channel_idx + 1 ) % 3; + } + } + + /*-----------------------------------------------------*\ + | Send the data | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_feature_buf, sizeof(usb_feature_buf)); + hid_write(dev, usb_buf[0], sizeof(usb_buf[0])); + hid_write(dev, usb_buf[1], sizeof(usb_buf[1])); + hid_write(dev, usb_buf[2], sizeof(usb_buf[2])); + hid_write(dev, usb_buf[3], sizeof(usb_buf[3])); + hid_write(dev, usb_buf[4], sizeof(usb_buf[4])); + hid_write(dev, usb_buf[5], sizeof(usb_buf[5])); +} + +void HYTEKeyboardController::LEDStreaming_Surround(RGBColor* colors) +{ + /*-----------------------------------------------------*\ + | LED Streaming - Surround RGB | + | | + | Set Feature (9 bytes, the first byte is 0x00) | + | 0x04 0xF1 0x00 0x00 0x00 0x00 0x00 0x00 | + | | + | EP6 Write (3 pages, 65 bytes/page) | + | 0xRR 0xGG 0xBB 0xRR 0xGG 0xBB ... | + \*-----------------------------------------------------*/ + unsigned char usb_feature_buf[9]; + unsigned char usb_buf[3][65]; + + /*-----------------------------------------------------*\ + | Set up feature report | + \*-----------------------------------------------------*/ + memset(usb_feature_buf, 0, sizeof(usb_feature_buf)); + + usb_feature_buf[0] = 0x00; + usb_feature_buf[1] = 0x04; + usb_feature_buf[2] = 0xF1; + + /*-----------------------------------------------------*\ + | Set up data packets | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + usb_buf[0][0] = 0x00; + usb_buf[1][0] = 0x00; + usb_buf[2][0] = 0x00; + + /*-----------------------------------------------------*\ + | Fill in color data | + \*-----------------------------------------------------*/ + unsigned int color_idx = 0; + unsigned int channel_idx = 0; + + for(unsigned int pkt_idx = 0; pkt_idx < 3; pkt_idx++) + { + for(unsigned int byte_idx = 0; byte_idx < 64; byte_idx++) + { + switch(channel_idx) + { + case 0: + usb_buf[pkt_idx][1 + byte_idx] = RGBGetRValue(colors[color_idx]); + break; + + case 1: + usb_buf[pkt_idx][1 + byte_idx] = RGBGetGValue(colors[color_idx]); + break; + + case 2: + usb_buf[pkt_idx][1 + byte_idx] = RGBGetBValue(colors[color_idx]); + color_idx++; + break; + } + + channel_idx = ( channel_idx + 1 ) % 3; + } + } + + /*-----------------------------------------------------*\ + | Send the data | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_feature_buf, sizeof(usb_feature_buf)); + hid_write(dev, usb_buf[0], sizeof(usb_buf[0])); + hid_write(dev, usb_buf[1], sizeof(usb_buf[1])); + hid_write(dev, usb_buf[2], sizeof(usb_buf[2])); +} + diff --git a/Controllers/HYTEKeyboardController/HYTEKeyboardController.h b/Controllers/HYTEKeyboardController/HYTEKeyboardController.h new file mode 100644 index 00000000..30932e20 --- /dev/null +++ b/Controllers/HYTEKeyboardController/HYTEKeyboardController.h @@ -0,0 +1,40 @@ +/*---------------------------------------------------------*\ +| HYTEKeyboardController.h | +| | +| Driver for HYTE keyboard | +| | +| Adam Honse (calcprogrammer1@gmail.com) 30 Oct 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include +#include "RGBController.h" + +enum +{ + HYTE_KEYBOARD_ZONE_KEYBOARD, + HYTE_KEYBOARD_ZONE_SURROUND +}; + +class HYTEKeyboardController +{ +public: + HYTEKeyboardController(hid_device* dev_handle, const char* path); + ~HYTEKeyboardController(); + + std::string GetDeviceLocation(); + + void LEDStreaming(unsigned int zone, RGBColor* colors); + +private: + hid_device* dev; + std::string location; + + void LEDStreaming_Keyboard(RGBColor* colors); + void LEDStreaming_Surround(RGBColor* colors); +}; diff --git a/Controllers/HYTEKeyboardController/HYTEKeyboardControllerDetect.cpp b/Controllers/HYTEKeyboardController/HYTEKeyboardControllerDetect.cpp new file mode 100644 index 00000000..f4599054 --- /dev/null +++ b/Controllers/HYTEKeyboardController/HYTEKeyboardControllerDetect.cpp @@ -0,0 +1,41 @@ +/*---------------------------------------------------------*\ +| HYTEKeyboardControllerDetect.cpp | +| | +| Detector for HYTE keyboard | +| | +| Adam Honse (calcprogrammer1@gmail.com) 30 Oct 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include +#include "Detector.h" +#include "HYTEKeyboardController.h" +#include "RGBController_HYTEKeyboard.h" + +/*---------------------------------------------------------*\ +| HYTE vendor ID | +\*---------------------------------------------------------*/ +#define HYTE_VID 0x3402 + +/*---------------------------------------------------------*\ +| HYTE keyboard product IDs | +\*---------------------------------------------------------*/ +#define HYTE_KEEB_TKL_PID 0x0300 + +void DetectHYTEKeyboard(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + HYTEKeyboardController* controller = new HYTEKeyboardController(dev, info->path); + RGBController_HYTEKeyboard* rgb_controller = new RGBController_HYTEKeyboard(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_PU("HYTE Keeb TKL", DetectHYTEKeyboard, HYTE_VID, HYTE_KEEB_TKL_PID, 0xFF11, 0xF0); diff --git a/Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.cpp b/Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.cpp new file mode 100644 index 00000000..a51ebec7 --- /dev/null +++ b/Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.cpp @@ -0,0 +1,191 @@ +/*---------------------------------------------------------*\ +| RGBController_HYTEKeyboard.cpp | +| | +| RGBController for HYTE keyboard | +| | +| Adam Honse (calcprogrammer1@gmail.com) 30 Oct 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "KeyboardLayoutManager.h" +#include "RGBController_HYTEKeyboard.h" + +/*---------------------------------------------------------------------*\ +| HYTE Keeb TKL KLM Layout | +\*---------------------------------------------------------------------*/ +const std::vector hyte_keeb_tkl_values = +{ + /* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */ + 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + /* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC INS HOME PGUP */ + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + /* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN */ + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* CPLK A S D F G H J K L ; " # ENTR */ + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* LSFT \ Z X C V B N M , . / RSFT ARWU */ + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 97, 99, + /* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */ + 105, 106, 107, 111, 115, 116, 117, 118, 119, 120, 121, +}; + +keyboard_keymap_overlay_values hyte_keeb_tkl_layout = +{ + KEYBOARD_SIZE::KEYBOARD_SIZE_TKL, + { + hyte_keeb_tkl_values, + { + /* Add more regional layout fixes here */ + } + }, + { + /*---------------------------------------------------------------------------------------------------------*\ + | Edit Keys - Add additional LEDs for space bar underglow and media keys | + | Zone, Row, Column, Value, Key, OpCode, | + \*---------------------------------------------------------------------------------------------------------*/ + { 0, 5, 4, 109, KEY_EN_SPACE, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 5, 5, 110, KEY_EN_SPACE, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 5, 7, 112, KEY_EN_SPACE, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 5, 8, 113, KEY_EN_SPACE, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 0, 0, 77, KEY_EN_MEDIA_STOP, KEYBOARD_OPCODE_INSERT_ROW, }, + { 0, 0, 1, 78, KEY_EN_MEDIA_PREVIOUS, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 0, 2, 79, KEY_EN_MEDIA_PLAY_PAUSE, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 0, 3, 98, KEY_EN_MEDIA_NEXT, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 0, 4, 100, KEY_EN_MEDIA_MUTE, KEYBOARD_OPCODE_SWAP_ONLY, }, + } +}; + +RGBController_HYTEKeyboard::RGBController_HYTEKeyboard(HYTEKeyboardController* controller_ptr) +{ + controller = controller_ptr; + + name = "HYTE Keyboard Device"; + vendor = "HYTE"; + type = DEVICE_TYPE_KEYBOARD; + description = "HYTE Keyboard Device"; + location = controller->GetDeviceLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0xFFFF; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_HYTEKeyboard::~RGBController_HYTEKeyboard() +{ + +} + +void RGBController_HYTEKeyboard::SetupZones() +{ + KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_DEFAULT, hyte_keeb_tkl_layout.base_size, hyte_keeb_tkl_layout.key_values); + new_kb.ChangeKeys(hyte_keeb_tkl_layout.edit_keys); + + zone keyboard_zone; + + keyboard_zone.name = "Keyboard"; + keyboard_zone.type = ZONE_TYPE_MATRIX; + + matrix_map_type * keyboard_map = new matrix_map_type; + keyboard_zone.matrix_map = keyboard_map; + keyboard_zone.matrix_map->height = new_kb.GetRowCount(); + keyboard_zone.matrix_map->width = new_kb.GetColumnCount(); + + keyboard_zone.matrix_map->map = new unsigned int[keyboard_map->height * keyboard_map->width]; + keyboard_zone.leds_count = new_kb.GetKeyCount(); + keyboard_zone.leds_min = keyboard_zone.leds_count; + keyboard_zone.leds_max = keyboard_zone.leds_count; + + zones.push_back(keyboard_zone); + + /*---------------------------------------------------------*\ + | Matrix map still uses declared zone rows and columns | + | as the packet structure depends on the matrix map | + \*---------------------------------------------------------*/ + new_kb.GetKeyMap(keyboard_map->map, KEYBOARD_MAP_FILL_TYPE_COUNT, keyboard_map->height, keyboard_map->width); + + /*---------------------------------------------------------*\ + | Create LEDs for the Matrix zone | + | Place keys in the layout to populate the matrix | + \*---------------------------------------------------------*/ + for(unsigned int led_idx = 0; led_idx < keyboard_zone.leds_count; led_idx++) + { + led new_led; + + new_led.name = new_kb.GetKeyNameAt(led_idx); + new_led.value = new_kb.GetKeyValueAt(led_idx); + + leds.push_back(new_led); + } + + zone surround_zone; + + surround_zone.name = "Underglow"; + surround_zone.type = ZONE_TYPE_LINEAR; + surround_zone.leds_min = 63; + surround_zone.leds_max = 63; + surround_zone.leds_count = 63; + surround_zone.matrix_map = NULL; + + zones.push_back(surround_zone); + + for(unsigned int led_idx = 0; led_idx < surround_zone.leds_count; led_idx++) + { + led new_led; + + new_led.name = surround_zone.name; + + leds.push_back(new_led); + } + + + SetupColors(); +} + +void RGBController_HYTEKeyboard::ResizeZone(int zone, int new_size) +{ + +} + +void RGBController_HYTEKeyboard::DeviceUpdateLEDs() +{ + for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + UpdateZoneLEDs(zone_idx); + } +} + +void RGBController_HYTEKeyboard::UpdateZoneLEDs(int zone) +{ + if(zone == HYTE_KEYBOARD_ZONE_KEYBOARD) + { + RGBColor color_buf[127]; + + for(unsigned int led_idx = 0; led_idx < zones[HYTE_KEYBOARD_ZONE_KEYBOARD].leds_count; led_idx++) + { + color_buf[leds[led_idx].value] = colors[led_idx]; + } + + controller->LEDStreaming(zone, &color_buf[0]); + } + else + { + controller->LEDStreaming(zone, zones[zone].colors); + } +} + +void RGBController_HYTEKeyboard::UpdateSingleLED(int led) +{ + +} + +void RGBController_HYTEKeyboard::DeviceUpdateMode() +{ + +} diff --git a/Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.h b/Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.h new file mode 100644 index 00000000..cbf3abba --- /dev/null +++ b/Controllers/HYTEKeyboardController/RGBController_HYTEKeyboard.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------*\ +| RGBController_HYTEKeyboard.h | +| | +| RGBController for HYTE keyboard | +| | +| Adam Honse (calcprogrammer1@gmail.com) 30 Oct 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include "HYTEKeyboardController.h" +#include "RGBController.h" + +class RGBController_HYTEKeyboard : public RGBController +{ +public: + RGBController_HYTEKeyboard(HYTEKeyboardController* controller_ptr); + ~RGBController_HYTEKeyboard(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + HYTEKeyboardController* controller; +};