From 029a04cee83e780d7440b8974e70b900c32fdc62 Mon Sep 17 00:00:00 2001 From: denk_mal Date: Tue, 2 Feb 2021 08:57:01 +0100 Subject: [PATCH] Das Keyboard version check and udev rules Commits squashed and amended for code style by Adam Honse --- 60-openrgb.rules | 6 + .../DasKeyboardController.cpp | 153 ++++++++++++++---- .../DasKeyboardController.h | 5 +- .../DasKeyboardControllerDetect.cpp | 16 +- .../RGBController_DasKeyboard.cpp | 5 - 5 files changed, 147 insertions(+), 38 deletions(-) diff --git a/60-openrgb.rules b/60-openrgb.rules index 55ed4a47..d23b3323 100644 --- a/60-openrgb.rules +++ b/60-openrgb.rules @@ -205,6 +205,12 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c088", TAG+="uacces SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c53a", TAG+="uaccess" +#---------------------------------------------------------------# +# Metadot Das Keyboard 4Q + 5Q # +#---------------------------------------------------------------# +SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="2037", TAG+="uaccess" +SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="202b", TAG+="uaccess" + #---------------------------------------------------------------# # MSI Mysticlight # #---------------------------------------------------------------# diff --git a/Controllers/DasKeyboardController/DasKeyboardController.cpp b/Controllers/DasKeyboardController/DasKeyboardController.cpp index 40eb413d..f88a46bb 100644 --- a/Controllers/DasKeyboardController/DasKeyboardController.cpp +++ b/Controllers/DasKeyboardController/DasKeyboardController.cpp @@ -10,10 +10,14 @@ #include #include "DasKeyboardController.h" +using namespace std::chrono_literals; + DasKeyboardController::DasKeyboardController(hid_device *dev_handle, const char *path) { - dev = dev_handle; - location = path; + dev = dev_handle; + location = path; + version = ""; + useTraditionalSendData = false; SendInitialize(); } @@ -30,11 +34,15 @@ std::string DasKeyboardController::GetDeviceLocation() std::string DasKeyboardController::GetSerialString() { - wchar_t serial_string[128]; - hid_get_serial_number_string(dev, serial_string, 128); + wchar_t serial_string[128] = {}; + int err = 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()); + std::string return_string; + if(!err) + { + std::wstring return_wstring = serial_string; + return_string = std::string(return_wstring.begin(), return_wstring.end()); + } if(return_string.empty()) { @@ -46,11 +54,16 @@ std::string DasKeyboardController::GetSerialString() std::string DasKeyboardController::GetVersionString() { - std::string fw_version = "V"; - fw_version += version.substr(6, 2); - fw_version += "."; - fw_version += version.substr(15, 2); - fw_version += ".0"; + if(version.length() < 17) + { + return version; + } + + std::string fw_version = "V"; + fw_version += version.substr(6, 2); + fw_version += "."; + fw_version += version.substr(15, 2); + fw_version += ".0"; return fw_version; } @@ -61,9 +74,13 @@ std::string DasKeyboardController::GetLayoutString() | Experimental for now; should be '16' for US and '28' | | for EU layout | \*-----------------------------------------------------*/ + if(version.length() < 17) + { + return "NONE"; + } std::string layout_id = version.substr(3, 2); - if (layout_id == "16") + if(layout_id == "16") { return "US"; } @@ -115,16 +132,33 @@ void DasKeyboardController::SendInitialize() \*-----------------------------------------------------*/ memset(usb_buf, 0x00, sizeof(usb_buf)); - /*-----------------------------------------------------*\ - | Set up Initialize connection | - \*-----------------------------------------------------*/ - unsigned char usb_init[] = {0xEA, 0x02, 0xB0}; - SendData(usb_init, sizeof(usb_init)); + int cnt_receive = 0; - /*-----------------------------------------------------*\ - | Get Version String | - \*-----------------------------------------------------*/ - ReceiveData(usb_buf); + while(!cnt_receive) + { + /*-----------------------------------------------------*\ + | Set up Initialize connection | + \*-----------------------------------------------------*/ + unsigned char usb_init[] = {0xEA, 0x02, 0xB0}; + SendData(usb_init, sizeof(usb_init)); + + /*-----------------------------------------------------*\ + | Get Version String | + \*-----------------------------------------------------*/ + cnt_receive = ReceiveData(usb_buf); + + /*-----------------------------------------------------*\ + | check if the faster modern transfer method is working | + \*-----------------------------------------------------*/ + if(!cnt_receive) + { + if(useTraditionalSendData) + { + break; + } + useTraditionalSendData = true; + } + } std::string fw_version(reinterpret_cast(&usb_buf[2])); version = fw_version; @@ -135,15 +169,33 @@ void DasKeyboardController::SendApply() /*-----------------------------------------------------*\ | Set up Terminate Color packet | \*-----------------------------------------------------*/ - unsigned char usb_buf2[] = {0xEA, 0x03, 0x78, 0x0a}; - SendData(usb_buf2, sizeof(usb_buf2)); + unsigned char usb_buf_send[] = {0xEA, 0x03, 0x78, 0x0a}; + unsigned char usb_buf_receive[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char usb_buf[256] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - ReceiveData(usb_buf); + do + { + SendData(usb_buf_send, sizeof(usb_buf_send)); + ReceiveData(usb_buf_receive); + } while(usb_buf_receive[0] == 0); } -void DasKeyboardController::SendData(const unsigned char *data, int length) +void DasKeyboardController::SendData(const unsigned char *data, unsigned int length) { + if(useTraditionalSendData) + { + SendDataTraditional(data, length); + } + else + { + SendDataModern(data, length); + } +} + +void DasKeyboardController::SendDataModern(const unsigned char *data, unsigned int length) +{ + /*-----------------------------------------------------*\ + | modern SendData (send whole bytes in one transfer) | + \*-----------------------------------------------------*/ unsigned char usb_buf[65]; /*-----------------------------------------------------*\ @@ -162,6 +214,51 @@ void DasKeyboardController::SendData(const unsigned char *data, int length) length++; hid_send_feature_report(dev, usb_buf, length); + + /*-----------------------------------------------------*\ + | Hack to work around a firmware bug in v21.27.0 | + \*-----------------------------------------------------*/ + std::this_thread::sleep_for(0.3ms); +} + +void DasKeyboardController::SendDataTraditional(const unsigned char *data, unsigned int length) +{ + /*-----------------------------------------------------*\ + | traditional SendData (split into chunks of 8 byte) | + \*-----------------------------------------------------*/ + unsigned char usb_buf[9]; + + /*-----------------------------------------------------*\ + | Fill data into send buffer | + \*-----------------------------------------------------*/ + unsigned int chk_sum = 0; + usb_buf[8] = 0; + + for(unsigned int idx = 0; idx < length + 1; idx += 7) + { + usb_buf[0] = 1; + for (unsigned int fld_idx = 1; fld_idx < 8; fld_idx++) + { + unsigned int tmp_idx = idx + fld_idx - 1; + if (tmp_idx < length) + { + usb_buf[fld_idx] = data[tmp_idx]; + chk_sum ^= data[tmp_idx]; + } else if (tmp_idx == length) + { + usb_buf[fld_idx] = chk_sum; + } else + { + usb_buf[fld_idx] = 0; + } + } + hid_send_feature_report(dev, usb_buf, 8); + + /*-----------------------------------------------------*\ + | Hack to work around a firmware bug in v21.27.0 | + \*-----------------------------------------------------*/ + std::this_thread::sleep_for(0.3ms); + } } int DasKeyboardController::ReceiveData(unsigned char *data) @@ -196,7 +293,7 @@ int DasKeyboardController::ReceiveData(unsigned char *data) \*-----------------------------------------------------*/ if(chk_sum) { - for (unsigned int ii = 0; ii < idx; ii++) + for (int ii = 0; ii < idx; ii++) { data[ii] = 0; } @@ -210,7 +307,7 @@ int DasKeyboardController::ReceiveData(unsigned char *data) /*-----------------------------------------------------*\ | Remove first two bytes (signature?) and content length| \*-----------------------------------------------------*/ - for(unsigned int ii = 0; ii < idx - 1; ii++) + for(int ii = 0; ii < idx - 1; ii++) { data[ii] = data[ii + 2]; } diff --git a/Controllers/DasKeyboardController/DasKeyboardController.h b/Controllers/DasKeyboardController/DasKeyboardController.h index 56297aae..6c7b1f37 100644 --- a/Controllers/DasKeyboardController/DasKeyboardController.h +++ b/Controllers/DasKeyboardController/DasKeyboardController.h @@ -38,10 +38,13 @@ private: hid_device *dev; std::string location; std::string version; + bool useTraditionalSendData; void SendInitialize(); - void SendData(const unsigned char *data, int length); + void SendData(const unsigned char *data, unsigned int length); + void SendDataTraditional(const unsigned char *data, unsigned int length); + void SendDataModern(const unsigned char *data, unsigned int length); int ReceiveData(unsigned char *data); }; diff --git a/Controllers/DasKeyboardController/DasKeyboardControllerDetect.cpp b/Controllers/DasKeyboardController/DasKeyboardControllerDetect.cpp index 13d2aa12..cc0e657f 100644 --- a/Controllers/DasKeyboardController/DasKeyboardControllerDetect.cpp +++ b/Controllers/DasKeyboardController/DasKeyboardControllerDetect.cpp @@ -48,11 +48,19 @@ void DetectDasKeyboardControllers(hid_device_info *info_in, const std::string &n if(dev) { - DasKeyboardController* controller = new DasKeyboardController(dev, info->path); - RGBController_DasKeyboard* rgb_controller = new RGBController_DasKeyboard(controller); - rgb_controller->name = name; + DasKeyboardController* controller = new DasKeyboardController(dev, info->path); - ResourceManager::get()->RegisterRGBController(rgb_controller); + if(controller->GetLayoutString() == "NONE") + { + delete controller; + } + else + { + RGBController_DasKeyboard *rgb_controller = new RGBController_DasKeyboard(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } } } /* DetectDasKeyboardControllers() */ diff --git a/Controllers/DasKeyboardController/RGBController_DasKeyboard.cpp b/Controllers/DasKeyboardController/RGBController_DasKeyboard.cpp index 6dd1305f..35d233b0 100644 --- a/Controllers/DasKeyboardController/RGBController_DasKeyboard.cpp +++ b/Controllers/DasKeyboardController/RGBController_DasKeyboard.cpp @@ -309,11 +309,6 @@ void RGBController_DasKeyboard::UpdateZoneLEDs(int /*zone*/) for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++) { UpdateSingleLED(static_cast(led_idx)); - - /*---------------------------------------------------------*\ - | Hack to work around a firmware bug in v21.27.0 | - \*---------------------------------------------------------*/ - std::this_thread::sleep_for(0.3ms); } updateDevice = true;