From 84de7ebc3ea7186d9d4da4397b6ff7bf8ed180d0 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 16 Jul 2021 10:20:35 +1000 Subject: [PATCH] Splitting out the WootingTwoKeyboardController * Added WootingOneKeyboardController.h * Added WootingOneKeyboardController.cpp * Added WootingTwoKeyboardController.h * Added WootingTwoKeyboardController.cpp * Unified the WootingKeyboardController as a virtual class * Modified WootingKeyboardControllerDetect to use the new controllers * Wooting One & Two use the old controller * Wooting Two LE & HE use the new controller * Adding Udev rules for the WootingTwo LE & HE --- 60-openrgb.rules | 6 +- .../RGBController_WootingKeyboard.cpp | 42 +-- .../WootingKeyboardController.cpp | 246 ++---------------- .../WootingKeyboardController.h | 97 ++++--- .../WootingKeyboardControllerDetect.cpp | 49 +++- .../WootingOneKeyboardController.cpp | 216 +++++++++++++++ .../WootingOneKeyboardController.h | 25 ++ .../WootingTwoKeyboardController.cpp | 95 +++++++ .../WootingTwoKeyboardController.h | 25 ++ OpenRGB.pro | 4 + 10 files changed, 498 insertions(+), 307 deletions(-) create mode 100644 Controllers/WootingKeyboardController/WootingOneKeyboardController.cpp create mode 100644 Controllers/WootingKeyboardController/WootingOneKeyboardController.h create mode 100644 Controllers/WootingKeyboardController/WootingTwoKeyboardController.cpp create mode 100644 Controllers/WootingKeyboardController/WootingTwoKeyboardController.h diff --git a/60-openrgb.rules b/60-openrgb.rules index b11c9cde..c6583d80 100644 --- a/60-openrgb.rules +++ b/60-openrgb.rules @@ -765,8 +765,10 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="226[0-3]", TAG+="ua #---------------------------------------------------------------# # Wooting Devices # #---------------------------------------------------------------# -SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff01", TAG+="uaccess" -SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff02", TAG+="uaccess" +SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff01", TAG+="uaccess" #WootingOne +SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff02", TAG+="uaccess" #WootingTwo +SUBSYSTEMS=="usb", ATTR{idVendor}=="31e3", ATTR{idProduct}=="1210", TAG+="uaccess" #WootingTwo LE +SUBSYSTEMS=="usb", ATTR{idVendor}=="31e3", ATTR{idProduct}=="1220", TAG+="uaccess" #WootingTwo HE #---------------------------------------------------------------# # Zalman ZSync Devices # diff --git a/Controllers/WootingKeyboardController/RGBController_WootingKeyboard.cpp b/Controllers/WootingKeyboardController/RGBController_WootingKeyboard.cpp index 663e86aa..541e15c0 100644 --- a/Controllers/WootingKeyboardController/RGBController_WootingKeyboard.cpp +++ b/Controllers/WootingKeyboardController/RGBController_WootingKeyboard.cpp @@ -26,12 +26,12 @@ static unsigned int matrix_map_tkl[6][17] = static unsigned int matrix_map_full[6][21] = { - { 0, NA, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 91, 90, 103, 109, 115, 96}, - { 1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 92, 98, 104, 110, 116, 122}, - { 2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 86, 93, 99, 105, 111, 117, 123}, - { 3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, NA, NA, NA, 106, 112, 118, NA}, - { 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, NA, 82, NA, 94, NA, 107, 113, 119, 125}, - { 5, 11, 17, NA, NA, NA, 41, NA, NA, NA, 65, 71, 77, 83, 89, 95, 102, NA, 114, 120, NA} + { 0, NA, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 100, 102, 108, 114, 120}, + { 1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 91, 97, 103, 109, 115, 121}, + { 2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 86, 92, 98, 104, 110, 116, 122}, + { 3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, NA, NA, NA, 105, 111, 117, NA}, + { 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, NA, 82, NA, 94, NA, 106, 112, 118, 124}, + { 5, 11, 17, NA, NA, NA, 41, NA, NA, NA, 65, 71, 77, 83, 89, 95, 101, NA, 113, 119, NA} }; static const unsigned int zone_sizes[] = @@ -132,8 +132,7 @@ static const char *led_names[] = "Unused", "Unused", "Key: Left Arrow", - "Key: Scroll Lock", //90 - "Key: Pause/Break", + "Key: Pause/Break", //90 "Key: Home", "Key: End", "Unused", @@ -142,8 +141,8 @@ static const char *led_names[] = "Key: Mode", "Key: Page Up", "Key: Page Down", - "Unused", //100 "Unused", + "Key: Scroll Lock", //100 - Scroll lock for WootingTwo KB's "Key: Right Arrow", "Key: A1", "Key: Num Lock", @@ -152,8 +151,8 @@ static const char *led_names[] = "Key: Number Pad 1", "Unused", "Key: A2", - "Key: Number Pad /", //110 - "Key: Number Pad 8", + "Key: Number Pad /", + "Key: Number Pad 8", //110 "Key: Number Pad 5", "Key: Number Pad 2", "Key: Number Pad 0", @@ -162,8 +161,8 @@ static const char *led_names[] = "Key: Number Pad 9", "Key: Number Pad 6", "Key: Number Pad 3", - "Key: Number Pad .", //120 - "Unused", + "Key: Number Pad .", + "Key: Mode", //120 - Mode key for WootingTwo KB's "Key: Number Pad -", "Key: Number Pad +", "Unused", @@ -175,7 +174,7 @@ RGBController_WootingKeyboard::RGBController_WootingKeyboard(WootingKeyboardCont { wooting = wooting_ptr; - LOG_DEBUG("[Wooting KB] Adding meta data"); + LOG_DEBUG("%sAdding meta data", WOOTING_CONTROLLER_NAME); name = wooting_ptr->GetName(); vendor = wooting_ptr->GetVendor(); type = DEVICE_TYPE_KEYBOARD; @@ -183,7 +182,7 @@ RGBController_WootingKeyboard::RGBController_WootingKeyboard(WootingKeyboardCont location = wooting_ptr->GetLocation(); serial = wooting_ptr->GetSerial(); - LOG_DEBUG("[Wooting KB] Adding modes"); + LOG_DEBUG("%sAdding modes", WOOTING_CONTROLLER_NAME); mode Direct; Direct.name = "Direct"; Direct.value = 0xFFFF; @@ -216,7 +215,7 @@ void RGBController_WootingKeyboard::SetupZones() uint8_t wooting_type = wooting->GetWootingType(); unsigned int total_led_count = zone_sizes[wooting_type]; - LOG_DEBUG("[Wooting KB] Creating New Zone"); + LOG_DEBUG("%sCreating New Zone", WOOTING_CONTROLLER_NAME); zone new_zone; new_zone.name = name.append(" zone"); @@ -225,32 +224,33 @@ void RGBController_WootingKeyboard::SetupZones() new_zone.leds_max = total_led_count; new_zone.leds_count = total_led_count; new_zone.matrix_map = new matrix_map_type; - new_zone.matrix_map->height = 6; + new_zone.matrix_map->height = WOOTING_RGB_ROWS; if(wooting_type == WOOTING_KB_TKL) { - new_zone.matrix_map->width = 17; + new_zone.matrix_map->width = WOOTING_ONE_RGB_COLUMNS; new_zone.matrix_map->map = (unsigned int *)&matrix_map_tkl; } else { - new_zone.matrix_map->width = 21; + new_zone.matrix_map->width = WOOTING_TWO_RGB_COLUMNS; new_zone.matrix_map->map = (unsigned int *)&matrix_map_full; } zones.push_back(new_zone); - LOG_DEBUG("[Wooting KB] Creating LED array"); + LOG_DEBUG("%sCreating LED array - total_led_count %03i", WOOTING_CONTROLLER_NAME, total_led_count); for (unsigned int led_idx = 0; led_idx < total_led_count; led_idx++) { led new_led; new_led.name = led_names[led_idx]; + LOG_DEBUG("%sPushing LED %03i - %s into vector", WOOTING_CONTROLLER_NAME, led_idx, new_led.name.c_str()); leds.push_back(new_led); } - LOG_DEBUG("[Wooting KB V2] LEDs created - Initialising Colours"); + LOG_DEBUG("%sLEDs created - Initialising Colours", WOOTING_CONTROLLER_NAME); SetupColors(); } diff --git a/Controllers/WootingKeyboardController/WootingKeyboardController.cpp b/Controllers/WootingKeyboardController/WootingKeyboardController.cpp index 8d92bf36..1d666bb7 100644 --- a/Controllers/WootingKeyboardController/WootingKeyboardController.cpp +++ b/Controllers/WootingKeyboardController/WootingKeyboardController.cpp @@ -1,90 +1,18 @@ -/*-----------------------------------------*\ -| WootingKeyboardController.cpp | -| | -| Driver for Wooting RGB keyboardlighting | -| controller | -| | -| Diogo Trindade (diogotr7) 3/4/2021 | -\*-----------------------------------------*/ +/*-------------------------------------------------------------------*\ +| WootingKeyboardController.cpp | +| | +| OpenRGB driver for Wooting RGB keyboardlighting controller | +| https://github.com/WootingKb/wooting-rgb-sdk | +| | +| Chris M (Dr_No) 9th July 2021 | +\*-------------------------------------------------------------------*/ #include #include "WootingKeyboardController.h" -#define WOOTING_COMMAND_SIZE 8 -#define WOOTING_REPORT_SIZE 129 -#define WOOTING_RAW_COLORS_REPORT 11 -#define WOOTING_SINGLE_COLOR_COMMAND 30 -#define WOOTING_SINGLE_RESET_COMMAND 31 -#define WOOTING_RESET_ALL_COMMAND 32 -#define WOOTING_COLOR_INIT_COMMAND 33 -#define WOOTING_ONE_KEY_CODE_LIMIT 95 -#define WOOTING_TWO_KEY_CODE_LIMIT 116 -#define RGB_RAW_BUFFER_SIZE 96 - -#define WOOTING_RGB_ROWS 6 -#define WOOTING_RGB_COLUMNS 21 -#define WOOTING_ONE_RGB_COLUMNS 17 -#define WOOTING_TWO_RGB_COLUMNS 21 - -//0xFFFFFFFF indicates an unused entry in matrix -#define NA 0xFFFFFFFF - -static const unsigned int rgb_led_index[WOOTING_RGB_ROWS][WOOTING_RGB_COLUMNS] = +WootingKeyboardController::WootingKeyboardController() { - { 0, NA, 11, 12, 23, 24, 36, 47, 85, 84, 49, 48, 59, 61, 73, 81, 80, 113, 114, 115, 116 }, - { 2, 1, 14, 13, 26, 25, 35, 38, 37, 87, 86, 95, 51, 63, 75, 72, 74, 96, 97, 98, 99 }, - { 3, 4, 15, 16, 27, 28, 39, 42, 40, 88, 89, 52, 53, 71, 76, 83, 77, 102, 103, 104, 100 }, - { 5, 6, 17, 18, 29, 30, 41, 46, 44, 90, 93, 54, 57, 65, NA, NA, NA, 105, 106, 107, NA }, - { 9, 8, 19, 20, 31, 34, 32, 45, 43, 91, 92, 55, NA, 66, NA, 78, NA, 108, 109, 110, 101 }, - { 10, 22, 21, NA, NA, NA, 33, NA, NA, NA, 94, 58, 67, 68, 70, 79, 82, NA, 111, 112, NA } -}; -static uint16_t getCrc16ccitt(const uint8_t* buffer, uint16_t size) -{ - uint16_t crc = 0; - - 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; -} - -WootingKeyboardController::WootingKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type) -{ - const int szTemp = 256; - wchar_t tmpName[szTemp]; - - dev = dev_handle; - location = path; - key_code_limit = (wooting_type == WOOTING_KB_TKL) ? WOOTING_ONE_KEY_CODE_LIMIT : WOOTING_TWO_KEY_CODE_LIMIT; - - hid_get_manufacturer_string(dev, tmpName, szTemp); - std::wstring wName = std::wstring(tmpName); - vendor = std::string(wName.begin(), wName.end()); - - hid_get_product_string(dev, tmpName, szTemp); - wName = std::wstring(tmpName); - description = std::string(wName.begin(), wName.end()); - - hid_get_serial_number_string(dev, tmpName, szTemp); - wName = std::wstring(tmpName); - serial = std::string(wName.begin(), wName.end()); - - SendInitialize(); } WootingKeyboardController::~WootingKeyboardController() @@ -122,77 +50,6 @@ uint8_t WootingKeyboardController::GetWootingType() return wooting_type; } -void WootingKeyboardController::SendDirect(RGBColor* colors, unsigned int num_colors) -{ - const uint8_t pwm_mem_map[48] = - { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D - }; - - unsigned char buffer0[RGB_RAW_BUFFER_SIZE] = {0}; - unsigned char buffer1[RGB_RAW_BUFFER_SIZE] = {0}; - unsigned char buffer2[RGB_RAW_BUFFER_SIZE] = {0}; - unsigned char buffer3[RGB_RAW_BUFFER_SIZE] = {0}; - unsigned char buffer4[RGB_RAW_BUFFER_SIZE] = {0}; - - for(std::size_t color_idx = 0; color_idx < num_colors; color_idx++) - { - unsigned char led_index = rgb_led_index[color_idx % 6][color_idx / 6]; - - if(led_index > key_code_limit) - { - continue; - } - - unsigned char *buffer_pointer = buffer0; - - if(led_index >= 96) - { - buffer_pointer = buffer4; - } - else if(led_index >= 72) - { - buffer_pointer = buffer3; - } - else if(led_index >= 48) - { - buffer_pointer = buffer2; - } - else if(led_index >= 24) - { - buffer_pointer = buffer1; - } - else - { - buffer_pointer = buffer0; - } - - unsigned char buffer_index = pwm_mem_map[led_index % 24]; - buffer_pointer[buffer_index + 0x00] = RGBGetRValue(colors[color_idx]); - buffer_pointer[buffer_index + 0x10] = RGBGetGValue(colors[color_idx]); - buffer_pointer[buffer_index + 0x20] = RGBGetBValue(colors[color_idx]); - } - - wooting_usb_send_buffer(RGB_PARTS::PART0, buffer0); - wooting_usb_send_buffer(RGB_PARTS::PART1, buffer1); - wooting_usb_send_buffer(RGB_PARTS::PART2, buffer2); - wooting_usb_send_buffer(RGB_PARTS::PART3, buffer3); - if(key_code_limit > WOOTING_ONE_KEY_CODE_LIMIT) - { - wooting_usb_send_buffer(RGB_PARTS::PART4, buffer4); - } -} - -void WootingKeyboardController::SendInitialize() -{ - wooting_usb_send_feature(WOOTING_COLOR_INIT_COMMAND, 0,0,0,0); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); -} - bool WootingKeyboardController::wooting_usb_send_feature(uint8_t commandId, uint8_t parameter0, uint8_t parameter1, uint8_t parameter2, uint8_t parameter3) { /*---------------------------------------------------------*\ @@ -210,88 +67,21 @@ bool WootingKeyboardController::wooting_usb_send_feature(uint8_t commandId, uint return true; } - unsigned char report_buffer[WOOTING_COMMAND_SIZE] = {0}; + uint8_t feature_buffer[WOOTING_COMMAND_SIZE] = { 0, 0xD0, 0xDA }; /*---------------------------------------------------------*\ | Set up the Send Feature packet | \*---------------------------------------------------------*/ - report_buffer[0] = 0; // HID report index (unused) - report_buffer[1] = 0xD0; // Magic word - report_buffer[2] = 0xDA; // Magic word - report_buffer[3] = commandId; - report_buffer[4] = parameter3; - report_buffer[5] = parameter2; - report_buffer[6] = parameter1; - report_buffer[7] = parameter0; + feature_buffer[3] = commandId; + feature_buffer[4] = parameter3; + feature_buffer[5] = parameter2; + feature_buffer[6] = parameter1; + feature_buffer[7] = parameter0; /*---------------------------------------------------------*\ | Send packet | \*---------------------------------------------------------*/ - hid_send_feature_report(dev, report_buffer, WOOTING_COMMAND_SIZE); - - return true; -} - -bool WootingKeyboardController::wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t rgb_buffer[]) -{ - unsigned char report_buffer[WOOTING_REPORT_SIZE] = {0}; - - /*---------------------------------------------------------*\ - | Set up the Send Buffer packet | - \*---------------------------------------------------------*/ - report_buffer[0] = 0; // HID report index (unused) - report_buffer[1] = 0xD0; // Magic word - report_buffer[2] = 0xDA; // Magic word - report_buffer[3] = WOOTING_RAW_COLORS_REPORT; // Report ID - - switch(part_number) - { - case PART0: - report_buffer[4] = 0; // Slave nr - report_buffer[5] = 0; // Reg start address - break; - - case PART1: - report_buffer[4] = 0; // Slave nr - report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address - break; - - case PART2: - report_buffer[4] = 1; // Slave nr - report_buffer[5] = 0; // Reg start address - break; - - case PART3: - report_buffer[4] = 1; // Slave nr - report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address - break; - - case PART4: - report_buffer[4] = 2; // Slave nr - report_buffer[5] = 0; // Reg start address - break; - - default: - return false; - break; - } - - /*---------------------------------------------------------*\ - | Copy in the buffer data | - \*---------------------------------------------------------*/ - memcpy(&report_buffer[6], rgb_buffer, RGB_RAW_BUFFER_SIZE); - - /*---------------------------------------------------------*\ - | Calculate the CRC and append it to the packet | - \*---------------------------------------------------------*/ - unsigned short crc = getCrc16ccitt((unsigned char*)&report_buffer, WOOTING_REPORT_SIZE - 2); - report_buffer[127] = (unsigned char)crc; - report_buffer[128] = crc >> 8; - - /*---------------------------------------------------------*\ - | Send packet | - \*---------------------------------------------------------*/ - hid_write(dev, report_buffer, WOOTING_REPORT_SIZE); - - return true; + uint8_t report_size = hid_send_feature_report(dev, feature_buffer, WOOTING_COMMAND_SIZE); + LOG_DEBUG("%sSend feature returned - %04i expected %04i", WOOTING_CONTROLLER_NAME, report_size, WOOTING_COMMAND_SIZE); + return (report_size == WOOTING_COMMAND_SIZE); } diff --git a/Controllers/WootingKeyboardController/WootingKeyboardController.h b/Controllers/WootingKeyboardController/WootingKeyboardController.h index 79708144..7bb09885 100644 --- a/Controllers/WootingKeyboardController/WootingKeyboardController.h +++ b/Controllers/WootingKeyboardController/WootingKeyboardController.h @@ -1,19 +1,40 @@ -/*-----------------------------------------*\ -| WootingKeyboardController.h | -| | -| Definitions and types for Wooting RGB | -| keyboard lighting controller | -| | -| Diogo Trindade (diogotr7) 3/4/2021 | -\*-----------------------------------------*/ +/*-------------------------------------------------------------------*\ +| WootingKeyboardController.h | +| | +| OpenRGB driver for Wooting RGB keyboardlighting controller | +| https://github.com/WootingKb/wooting-rgb-sdk | +| | +| Chris M (Dr_No) 9th July 2021 | +\*-------------------------------------------------------------------*/ #include "RGBController.h" - +#include "LogManager.h" #include #include #pragma once +#define WOOTING_COMMAND_SIZE 8 +#define WOOTING_REPORT_SIZE 129 +#define WOOTING_RAW_COLORS_REPORT 11 +#define WOOTING_SINGLE_COLOR_COMMAND 30 +#define WOOTING_SINGLE_RESET_COMMAND 31 +#define WOOTING_RESET_ALL_COMMAND 32 +#define WOOTING_COLOR_INIT_COMMAND 33 +#define WOOTING_ONE_KEY_CODE_LIMIT 95 +#define WOOTING_TWO_KEY_CODE_LIMIT 116 +#define RGB_RAW_BUFFER_SIZE 96 + +#define WOOTING_RGB_ROWS 6 +#define WOOTING_RGB_COLUMNS 21 +#define WOOTING_ONE_RGB_COLUMNS 17 +#define WOOTING_TWO_RGB_COLUMNS 21 + +/*---------------------------------------------------------*\ +| Placeholder for compilation. Redefined by each subclass | +\*---------------------------------------------------------*/ +#define WOOTING_CONTROLLER_NAME "[Wooting] " + enum WOOTING_DEVICE_TYPE { WOOTING_KB_TKL = 0, @@ -32,40 +53,30 @@ enum RGB_PARTS class WootingKeyboardController { public: - WootingKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type); - ~WootingKeyboardController(); + WootingKeyboardController(); + virtual ~WootingKeyboardController(); + + hid_device* dev; + std::string name; + std::string vendor; + std::string description; + std::string location; + std::string serial; + uint8_t wooting_type; + uint8_t key_code_limit; + + std::string GetName(); + std::string GetVendor(); + std::string GetDescription(); + std::string GetLocation(); + std::string GetSerial(); + uint8_t GetWootingType(); + bool wooting_usb_send_feature(uint8_t command, uint8_t param0, + uint8_t param1, uint8_t param2, uint8_t param3); + + virtual void SendDirect(RGBColor* colors, uint8_t color_count) = 0; - void SendDirect(RGBColor* colors, unsigned int num_colors); - std::string GetName(); - std::string GetVendor(); - std::string GetDescription(); - std::string GetLocation(); - std::string GetSerial(); - uint8_t GetWootingType(); private: - hid_device* dev; - std::string name; - std::string vendor; - std::string description; - std::string location; - std::string serial; - uint8_t wooting_type; - uint8_t key_code_limit; - - void SendInitialize(); - - bool wooting_usb_send_feature - ( - unsigned char command, - unsigned char param0, - unsigned char param1, - unsigned char param2, - unsigned char param3 - ); - - bool wooting_usb_send_buffer - ( - RGB_PARTS part_number, - unsigned char rgb_buffer[] - ); + virtual void SendInitialize() = 0; + virtual bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* rgb_buffer) = 0; }; diff --git a/Controllers/WootingKeyboardController/WootingKeyboardControllerDetect.cpp b/Controllers/WootingKeyboardController/WootingKeyboardControllerDetect.cpp index ebd18e5a..317d7062 100644 --- a/Controllers/WootingKeyboardController/WootingKeyboardControllerDetect.cpp +++ b/Controllers/WootingKeyboardController/WootingKeyboardControllerDetect.cpp @@ -1,5 +1,6 @@ #include "Detector.h" -#include "WootingKeyboardController.h" +#include "WootingOneKeyboardController.h" +#include "WootingTwoKeyboardController.h" #include "RGBController.h" #include "RGBController_WootingKeyboard.h" #include "LogManager.h" @@ -20,9 +21,10 @@ #define WOOTING_TWO_LE_PID 0x1210 #define WOOTING_TWO_HE_PID 0x1220 -void DetectWootingKeyboardControllers(hid_device_info* info, const std::string& name) +void DetectWootingOneKeyboardControllers(hid_device_info* info, const std::string& name) { - LOG_DEBUG("[Wooting KB] Interface %i\tPage %04X\tUsage %i\tPath %s", info->interface_number, info->usage_page, info->usage, info->path); + static const char* controller_name = "WootingONE"; + LOG_DEBUG("[%s] Interface %i\tPage %04X\tUsage %i\tPath %s", controller_name, info->interface_number, info->usage_page, info->usage, info->path); hid_device* dev = hid_open_path(info->path); @@ -30,19 +32,40 @@ void DetectWootingKeyboardControllers(hid_device_info* info, const std::string& { uint8_t wooting_type = (info->product_id == WOOTING_ONE_PID) ? WOOTING_KB_TKL : WOOTING_KB_FULL; - LOG_DEBUG("[Wooting KB] Device type %i opened - creating Controller", wooting_type); - WootingKeyboardController* controller = new WootingKeyboardController(dev, info->path, wooting_type); + LOG_DEBUG("[%s] Device type %i opened - creating Controller", controller_name, wooting_type); + WootingOneKeyboardController* controller = new WootingOneKeyboardController(dev, info->path, wooting_type); - LOG_DEBUG("[Wooting KB] Controller created - creating RGBController"); - RGBController_WootingKeyboard* rgb_controller = new RGBController_WootingKeyboard(controller); + LOG_DEBUG("[%s] Controller created - creating RGBController", controller_name); + RGBController_WootingKeyboard* rgb_controller = new RGBController_WootingKeyboard(controller); rgb_controller->name = name; - LOG_DEBUG("[Wooting KB] Initialization complete - Registering controller\t%s", name.c_str()); + LOG_DEBUG("[%s] Initialization complete - Registering controller\t%s", controller_name, name.c_str()); ResourceManager::get()->RegisterRGBController(rgb_controller); } -} /* DetectWootingKeyboardControllers */ +} -REGISTER_HID_DETECTOR_PU("Wooting ONE Keyboard", DetectWootingKeyboardControllers, WOOTING_OLD_VID, WOOTING_ONE_PID, 0x1337, 1); -REGISTER_HID_DETECTOR_PU("Wooting TWO Keyboard", DetectWootingKeyboardControllers, WOOTING_OLD_VID, WOOTING_TWO_PID, 0x1337, 1); -REGISTER_HID_DETECTOR_PU("Wooting TWO Keyboard LE", DetectWootingKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_LE_PID, 0x1337, 1); -REGISTER_HID_DETECTOR_PU("Wooting TWO Keyboard HE", DetectWootingKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_PID, 0x1337, 1); +void DetectWootingTwoKeyboardControllers(hid_device_info* info, const std::string& name) +{ + static const char* controller_name = "WootingTWO"; + LOG_DEBUG("[%s] Interface %i\tPage %04X\tUsage %i\tPath %s", controller_name, info->interface_number, info->usage_page, info->usage, info->path); + + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + LOG_DEBUG("[%s] Device type %i opened - creating Controller", controller_name, WOOTING_KB_FULL); + WootingTwoKeyboardController* controller = new WootingTwoKeyboardController(dev, info->path, WOOTING_KB_FULL); + + LOG_DEBUG("[%s] Controller created - creating RGBController", controller_name); + RGBController_WootingKeyboard* rgb_controller = new RGBController_WootingKeyboard(controller); + rgb_controller->name = name; + + LOG_DEBUG("[%s] Initialization complete - Registering controller\t%s", controller_name, name.c_str()); + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_PU("Wooting ONE Keyboard", DetectWootingOneKeyboardControllers, WOOTING_OLD_VID, WOOTING_ONE_PID, 0x1337, 1); +REGISTER_HID_DETECTOR_PU("Wooting TWO Keyboard", DetectWootingOneKeyboardControllers, WOOTING_OLD_VID, WOOTING_TWO_PID, 0x1337, 1); +REGISTER_HID_DETECTOR_PU("Wooting TWO Keyboard LE", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_LE_PID, 0x1337, 1); +REGISTER_HID_DETECTOR_PU("Wooting TWO Keyboard HE", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_PID, 0x1337, 1); diff --git a/Controllers/WootingKeyboardController/WootingOneKeyboardController.cpp b/Controllers/WootingKeyboardController/WootingOneKeyboardController.cpp new file mode 100644 index 00000000..2ecc7f90 --- /dev/null +++ b/Controllers/WootingKeyboardController/WootingOneKeyboardController.cpp @@ -0,0 +1,216 @@ +/*-----------------------------------------*\ +| WootingKeyboardController.cpp | +| | +| Driver for Wooting RGB keyboardlighting | +| controller | +| | +| Diogo Trindade (diogotr7) 3/4/2021 | +\*-----------------------------------------*/ + +#include +#include "WootingOneKeyboardController.h" + +#undef WOOTING_CONTROLLER_NAME +#define WOOTING_CONTROLLER_NAME "[WootingONE] " + +//0xFFFFFFFF indicates an unused entry in matrix +#define NA 0xFFFFFFFF + +static const unsigned int rgb_led_index[WOOTING_RGB_ROWS][WOOTING_RGB_COLUMNS] = +{ + { 0, NA, 11, 12, 23, 24, 36, 47, 85, 84, 49, 48, 59, 61, 73, 81, 80, 113, 114, 115, 116 }, + { 2, 1, 14, 13, 26, 25, 35, 38, 37, 87, 86, 95, 51, 63, 75, 72, 74, 96, 97, 98, 99 }, + { 3, 4, 15, 16, 27, 28, 39, 42, 40, 88, 89, 52, 53, 71, 76, 83, 77, 102, 103, 104, 100 }, + { 5, 6, 17, 18, 29, 30, 41, 46, 44, 90, 93, 54, 57, 65, NA, NA, NA, 105, 106, 107, NA }, + { 9, 8, 19, 20, 31, 34, 32, 45, 43, 91, 92, 55, NA, 66, NA, 78, NA, 108, 109, 110, 101 }, + { 10, 22, 21, NA, NA, NA, 33, NA, NA, NA, 94, 58, 67, 68, 70, 79, 82, NA, 111, 112, NA } +}; + +static uint16_t getCrc16ccitt(const uint8_t* buffer, uint16_t size) +{ + uint16_t crc = 0; + + 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; +} + +WootingOneKeyboardController::WootingOneKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type) +{ + const int szTemp = 256; + wchar_t tmpName[szTemp]; + + dev = dev_handle; + location = path; + this->wooting_type = wooting_type; + key_code_limit = (wooting_type == WOOTING_KB_TKL) ? WOOTING_ONE_KEY_CODE_LIMIT : WOOTING_TWO_KEY_CODE_LIMIT; + + hid_get_manufacturer_string(dev, tmpName, szTemp); + std::wstring wName = std::wstring(tmpName); + vendor = std::string(wName.begin(), wName.end()); + + hid_get_product_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + description = std::string(wName.begin(), wName.end()); + + hid_get_serial_number_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + serial = std::string(wName.begin(), wName.end()); + + SendInitialize(); +} + +WootingOneKeyboardController::~WootingOneKeyboardController() +{ + +} + +void WootingOneKeyboardController::SendDirect(RGBColor* colors, uint8_t colour_count) +{ + const uint8_t pwm_mem_map[48] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D + }; + + unsigned char buffer0[RGB_RAW_BUFFER_SIZE] = {0}; + unsigned char buffer1[RGB_RAW_BUFFER_SIZE] = {0}; + unsigned char buffer2[RGB_RAW_BUFFER_SIZE] = {0}; + unsigned char buffer3[RGB_RAW_BUFFER_SIZE] = {0}; + unsigned char buffer4[RGB_RAW_BUFFER_SIZE] = {0}; + + for(std::size_t color_idx = 0; color_idx < colour_count; color_idx++) + { + unsigned char led_index = rgb_led_index[color_idx % 6][color_idx / 6]; + + if(led_index > key_code_limit) + { + continue; + } + + unsigned char *buffer_pointer = buffer0; + + if(led_index >= 96) + { + buffer_pointer = buffer4; + } + else if(led_index >= 72) + { + buffer_pointer = buffer3; + } + else if(led_index >= 48) + { + buffer_pointer = buffer2; + } + else if(led_index >= 24) + { + buffer_pointer = buffer1; + } + else + { + buffer_pointer = buffer0; + } + + unsigned char buffer_index = pwm_mem_map[led_index % 24]; + buffer_pointer[buffer_index + 0x00] = RGBGetRValue(colors[color_idx]); + buffer_pointer[buffer_index + 0x10] = RGBGetGValue(colors[color_idx]); + buffer_pointer[buffer_index + 0x20] = RGBGetBValue(colors[color_idx]); + } + + wooting_usb_send_buffer(RGB_PARTS::PART0, buffer0); + wooting_usb_send_buffer(RGB_PARTS::PART1, buffer1); + wooting_usb_send_buffer(RGB_PARTS::PART2, buffer2); + wooting_usb_send_buffer(RGB_PARTS::PART3, buffer3); + if(key_code_limit > WOOTING_ONE_KEY_CODE_LIMIT) + { + wooting_usb_send_buffer(RGB_PARTS::PART4, buffer4); + } +} + +void WootingOneKeyboardController::SendInitialize() +{ + wooting_usb_send_feature(WOOTING_COLOR_INIT_COMMAND, 0,0,0,0); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); +} + +bool WootingOneKeyboardController::wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* rgb_buffer) +{ + unsigned char report_buffer[WOOTING_REPORT_SIZE] = {0}; + + /*---------------------------------------------------------*\ + | Set up the Send Buffer packet | + \*---------------------------------------------------------*/ + report_buffer[0] = 0; // HID report index (unused) + report_buffer[1] = 0xD0; // Magic word + report_buffer[2] = 0xDA; // Magic word + report_buffer[3] = WOOTING_RAW_COLORS_REPORT; // Report ID + + switch(part_number) + { + case PART0: + report_buffer[4] = 0; // Slave nr + report_buffer[5] = 0; // Reg start address + break; + + case PART1: + report_buffer[4] = 0; // Slave nr + report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address + break; + + case PART2: + report_buffer[4] = 1; // Slave nr + report_buffer[5] = 0; // Reg start address + break; + + case PART3: + report_buffer[4] = 1; // Slave nr + report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address + break; + + case PART4: + report_buffer[4] = 2; // Slave nr + report_buffer[5] = 0; // Reg start address + break; + + default: + return false; + break; + } + + /*---------------------------------------------------------*\ + | Copy in the buffer data | + \*---------------------------------------------------------*/ + memcpy(&report_buffer[6], rgb_buffer, RGB_RAW_BUFFER_SIZE); + + /*---------------------------------------------------------*\ + | Calculate the CRC and append it to the packet | + \*---------------------------------------------------------*/ + unsigned short crc = getCrc16ccitt((unsigned char*)&report_buffer, WOOTING_REPORT_SIZE - 2); + report_buffer[127] = (unsigned char)crc; + report_buffer[128] = crc >> 8; + + /*---------------------------------------------------------*\ + | Send packet | + \*---------------------------------------------------------*/ + hid_write(dev, report_buffer, WOOTING_REPORT_SIZE); + + return true; +} diff --git a/Controllers/WootingKeyboardController/WootingOneKeyboardController.h b/Controllers/WootingKeyboardController/WootingOneKeyboardController.h new file mode 100644 index 00000000..9799f5c8 --- /dev/null +++ b/Controllers/WootingKeyboardController/WootingOneKeyboardController.h @@ -0,0 +1,25 @@ +/*-----------------------------------------*\ +| WootingKeyboardController.h | +| | +| Definitions and types for Wooting RGB | +| keyboard lighting controller | +| | +| Diogo Trindade (diogotr7) 3/4/2021 | +\*-----------------------------------------*/ + +#include "WootingKeyboardController.h" + +#pragma once + +class WootingOneKeyboardController : public WootingKeyboardController +{ +public: + WootingOneKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type); + ~WootingOneKeyboardController(); + + void SendDirect(RGBColor* colors, uint8_t colour_count); + +private: + void SendInitialize(); + bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* report_buffer); +}; diff --git a/Controllers/WootingKeyboardController/WootingTwoKeyboardController.cpp b/Controllers/WootingKeyboardController/WootingTwoKeyboardController.cpp new file mode 100644 index 00000000..82d2f786 --- /dev/null +++ b/Controllers/WootingKeyboardController/WootingTwoKeyboardController.cpp @@ -0,0 +1,95 @@ +/*-------------------------------------------------------------------*\ +| WootingTwoKeyboardController.cpp | +| | +| OpenRGB driver for Wooting RGB keyboardlighting controller | +| https://github.com/WootingKb/wooting-rgb-sdk | +| | +| Chris M (Dr_No) 9th July 2021 | +\*-------------------------------------------------------------------*/ + +#include +#include "WootingTwoKeyboardController.h" + +#define WOOTING_TWO_REPORT_SIZE 257 + +#undef WOOTING_CONTROLLER_NAME +#define WOOTING_CONTROLLER_NAME "[WootingTWO] " + +//Indicates an unused entry in matrix +#define NA 0x7D + +//WootingTwo uses a 16bit color space +typedef uint16_t R5G6B5_color; +#define RGB888ToRGBcolor16(r, g, b) ((R5G6B5_color)((red & 0xF8) << 8 | (green & 0xFC) << 3 | (b & 0xF8) >> 3)) +#define RGB32ToRGBcolor16(color32) ((R5G6B5_color)((color32 & 0xF8) << 8 | (color32 & 0xFC00) >> 5 | (color32 & 0xF80000) >> 19)) + +static unsigned int matrix_to_led_index_map_full[WOOTING_RGB_ROWS * WOOTING_TWO_RGB_COLUMNS] = +{ + 0, 21, 42, 63, 84, 105, NA, 22, 43, 64, 85, 106, 2, 23, 44, 65, 86, 107, 3, 24, 45, + 66, 87, NA, 4, 25, 46, 67, 88, NA, 5, 26, 47, 68, 89, NA, 6, 27, 48, 69, 90, 111, + 7, 28, 49, 70, 91, NA, 8, 29, 50, 71, 92, NA, 9, 30, 51, 72, 93, NA, 10, 31, 52, + 73, 94, 115, 11, 32, 53, 74, 95, 116, 12, 33, 54, 75, NA, 117, 13, 34, 55, 76, 97, 118, + 14, 35, 56, NA, NA, 119, 15, 36, 57, NA, 99, 120, NA, 37, 58, NA, 16, 121, 17, 38, 59, + 80, 101, NA, 18, 39, 60, 81, 102, 123, 19, 40, 61, 82, 103, 124, 20, 41, 62, NA, 104, NA +}; + +WootingTwoKeyboardController::WootingTwoKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type) +{ + const int szTemp = 256; + wchar_t tmpName[szTemp]; + + dev = dev_handle; + location = path; + this->wooting_type = wooting_type; + key_code_limit = (wooting_type == WOOTING_KB_TKL) ? WOOTING_ONE_KEY_CODE_LIMIT : WOOTING_TWO_KEY_CODE_LIMIT; + + hid_get_manufacturer_string(dev, tmpName, szTemp); + std::wstring wName = std::wstring(tmpName); + vendor = std::string(wName.begin(), wName.end()); + + hid_get_product_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + description = std::string(wName.begin(), wName.end()); + + hid_get_serial_number_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + serial = std::string(wName.begin(), wName.end()); + + SendInitialize(); +} + +WootingTwoKeyboardController::~WootingTwoKeyboardController() +{ + +} + +void WootingTwoKeyboardController::SendDirect(RGBColor* colors, uint8_t color_count) +{ + uint8_t rgb_buffer[WOOTING_TWO_REPORT_SIZE] = { 0, 0xD0, 0xDA, WOOTING_RAW_COLORS_REPORT}; + + for(std::size_t index = 0; index < color_count; index++) + { + uint8_t buffer_index = 4 + (matrix_to_led_index_map_full[index] * 2); + R5G6B5_color color16 = RGB32ToRGBcolor16(colors[index]); + + LOG_TRACE("%sSetting LED %03i @ buffer %03i - RGB32 %08X RGB16 %04X", WOOTING_CONTROLLER_NAME, index, buffer_index, colors[index], color16); + rgb_buffer[buffer_index] = color16 & 0xFF; + rgb_buffer[buffer_index+1] = color16 >> 8; + } + + uint8_t result = wooting_usb_send_buffer(RGB_PARTS::PART0, rgb_buffer); +} + +void WootingTwoKeyboardController::SendInitialize() +{ + wooting_usb_send_feature(WOOTING_COLOR_INIT_COMMAND, 0,0,0,0); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); +} + +bool WootingTwoKeyboardController::wooting_usb_send_buffer(RGB_PARTS /*part_number*/, uint8_t* report_buffer) +{ + uint16_t report_size = hid_write(dev, report_buffer, WOOTING_TWO_REPORT_SIZE); + LOG_DEBUG("%sSend buffer returned - %04i expected %04i", WOOTING_CONTROLLER_NAME, report_size, WOOTING_TWO_REPORT_SIZE); + return (report_size == WOOTING_TWO_REPORT_SIZE); +} diff --git a/Controllers/WootingKeyboardController/WootingTwoKeyboardController.h b/Controllers/WootingKeyboardController/WootingTwoKeyboardController.h new file mode 100644 index 00000000..45ff1a20 --- /dev/null +++ b/Controllers/WootingKeyboardController/WootingTwoKeyboardController.h @@ -0,0 +1,25 @@ +/*-------------------------------------------------------------------*\ +| WootingTwoKeyboardController.h | +| | +| OpenRGB driver for Wooting RGB keyboardlighting controller | +| https://github.com/WootingKb/wooting-rgb-sdk | +| | +| Chris M (Dr_No) 9th July 2021 | +\*-------------------------------------------------------------------*/ + +#include "WootingKeyboardController.h" + +#pragma once + +class WootingTwoKeyboardController : public WootingKeyboardController +{ +public: + WootingTwoKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type); + ~WootingTwoKeyboardController(); + + void SendDirect(RGBColor* colors, uint8_t colour_count); + +private: + void SendInitialize(); + bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* report_buffer); +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index cba19a75..128136e4 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -402,6 +402,8 @@ HEADERS += Controllers/ThermaltakeRiingController/ThermaltakeRiingQuadController.h \ Controllers/ThermaltakeRiingController/RGBController_ThermaltakeRiing.h \ Controllers/WootingKeyboardController/WootingKeyboardController.h \ + Controllers/WootingKeyboardController/WootingOneKeyboardController.h \ + Controllers/WootingKeyboardController/WootingTwoKeyboardController.h \ Controllers/WootingKeyboardController/RGBController_WootingKeyboard.h \ Controllers/ThermaltakeRiingController/RGBController_ThermaltakeRiingQuad.h \ Controllers/YeelightController/YeelightController.h \ @@ -770,6 +772,8 @@ SOURCES += Controllers/ThermaltakeRiingController/RGBController_ThermaltakeRiing.cpp \ Controllers/WootingKeyboardController/WootingKeyboardController.cpp \ Controllers/WootingKeyboardController/WootingKeyboardControllerDetect.cpp \ + Controllers/WootingKeyboardController/WootingOneKeyboardController.cpp \ + Controllers/WootingKeyboardController/WootingTwoKeyboardController.cpp \ Controllers/WootingKeyboardController/RGBController_WootingKeyboard.cpp \ Controllers/ThermaltakeRiingController/RGBController_ThermaltakeRiingQuad.cpp \ Controllers/YeelightController/YeelightController.cpp \