Das Keyboard version check and udev rules

Commits squashed and amended for code style by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
denk_mal 2021-02-02 08:57:01 +01:00 committed by Adam Honse
parent ae4857e24e
commit 029a04cee8
5 changed files with 147 additions and 38 deletions

View file

@ -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 #
#---------------------------------------------------------------#

View file

@ -10,10 +10,14 @@
#include <cstring>
#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<char *>(&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];
}

View file

@ -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);
};

View file

@ -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() */

View file

@ -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<int>(led_idx));
/*---------------------------------------------------------*\
| Hack to work around a firmware bug in v21.27.0 |
\*---------------------------------------------------------*/
std::this_thread::sleep_for(0.3ms);
}
updateDevice = true;