Fix support for SteelSeries Apex Pro TKL 2023

master
filipesn 4 months ago committed by Adam Honse
parent 5a484a0ef3
commit c13f031119

@ -1,19 +1,27 @@
/*---------------------------------------------------------*\
| SteelSeriesApexController.cpp |
| |
| Driver for SteelSeries Apex 7 |
| Driver for SteelSeries Apex Keyboards |
| |
| New driver based on SignalRGB Plugins |
| https://gitlab.com/signalrgb/signal-plugins/ |
| |
| Eric Samuelson (edbgon) 05 Jul 2020 |
| Filipe S. (filipesn) 5 Jan 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include <cstdio>
#include "SteelSeriesApexController.h"
#include "LogManager.h"
using namespace std::chrono_literals;
#define FIRMWARE_REQ_LEN 645
static unsigned int keys[] = {0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, //20
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,
@ -29,7 +37,10 @@ static unsigned int keys[] = {0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x
SteelSeriesApexController::SteelSeriesApexController(hid_device* dev_handle, steelseries_type type, const char* path, std::string dev_name) : SteelSeriesApexBaseController(dev_handle, path, dev_name)
{
proto_type = type;
proto_type = type;
use_new_protocol = false;
SendInitialization();
}
SteelSeriesApexController::~SteelSeriesApexController()
@ -55,8 +66,23 @@ void SteelSeriesApexController::SetLEDsDirect(std::vector<RGBColor> colors)
unsigned char buf[643];
int num_keys = 0;
unsigned char packet_id = APEX_PACKET_ID_DIRECT;
num_keys = sizeof(keys) / sizeof(*keys);
if(use_new_protocol)
{
struct hid_device_info* info = hid_get_device_info(dev);
if(info && (info->product_id == 0x162C || info->product_id == 0x162D)) // Aparently Gen 3 wireless models reuse this protocol, make sure to place their PID here and further below when developing.
{
packet_id = APEX_2023_PACKET_ID_DIRECT_WIRELESS;
}
else
{
packet_id = APEX_2023_PACKET_ID_DIRECT;
}
}
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
@ -66,8 +92,8 @@ void SteelSeriesApexController::SetLEDsDirect(std::vector<RGBColor> colors)
| Set up Direct packet |
\*-----------------------------------------------------*/
buf[0x00] = 0;
buf[0x01] = APEX_PACKET_ID_DIRECT;
buf[0x02] = num_keys;
buf[0x01] = packet_id;
buf[0x02] = (use_new_protocol) ? (unsigned char)colors.size() : num_keys;
/*-----------------------------------------------------*\
| Fill in color data |
@ -106,3 +132,96 @@ void SteelSeriesApexController::SelectProfile
buf[0x02] = profile;
hid_send_feature_report(dev, buf, 65);
}
void SteelSeriesApexController::SendInitialization()
{
unsigned char buf[FIRMWARE_REQ_LEN];
unsigned char read_buf[65];
int res = 0;
char version_str[32] = "Unknown";
struct hid_device_info* info = hid_get_device_info(dev);
unsigned short pid = (info) ? info->product_id : 0;
// Firmware check
if(pid == 0x1628)
{
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
buf[0x00] = 0x00;
buf[0x01] = 0x90;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, buf, 65);
/*-----------------------------------------------------*\
| Read Response |
\*-----------------------------------------------------*/
memset(read_buf, 0x00, sizeof(read_buf));
res = hid_read_timeout(dev, read_buf, sizeof(read_buf), 200);
/*-----------------------------------------------------*\
| Firmware Check |
\*-----------------------------------------------------*/
if(res > 2 && read_buf[0] == 0x90)
{
int major = 0, minor = 0, patch = 0;
char* fw_ptr = (char*)&read_buf[2];
snprintf(version_str, sizeof(version_str), "%s", fw_ptr);
int count = sscanf(version_str, "%d.%d.%d", &major, &minor, &patch);
if(count == 3)
{
// Currently set to 1.19.7 or newer.
if(major > 1)
{
use_new_protocol = true;
}
else if(major == 1)
{
if(minor > 19)
{
use_new_protocol = true;
}
else if(minor == 19 && patch >= 7)
{
use_new_protocol = true;
}
}
}
}
}
// // Aparently Gen 3 models reuse this protocol, make sure to place their PID here and further above for wireless when developing.
else if(pid == 0x162C || pid == 0x162D)
{
use_new_protocol = true;
}
/*-----------------------------------------------------*\
| Send Initialization packet on new protocol. |
\*-----------------------------------------------------*/
if(use_new_protocol)
{
memset(buf, 0x00, sizeof(buf));
buf[0x00] = 0x00;
buf[0x01] = APEX_2023_PACKET_ID_INIT;
hid_send_feature_report(dev, buf, APEX_2023_PACKET_LENGTH);
LOG_DEBUG("[%s] Using Apex 2023 protocol. FW: %s", name.c_str(), version_str);
}
else
{
LOG_DEBUG("[%s] Using Apex Legacy protocol. FW: %s", name.c_str(), version_str);
}
}
std::string SteelSeriesApexController::GetSerial()
{
return "64865";
}

@ -1,9 +1,13 @@
/*---------------------------------------------------------*\
| SteelSeriesApexController.h |
| SteelSeriesApexController.cpp |
| |
| Driver for SteelSeries Apex 7 |
| Driver for SteelSeries Apex Keyboards |
| |
| New driver based on SignalRGB Plugins |
| https://gitlab.com/signalrgb/signal-plugins/ |
| |
| Eric Samuelson (edbgon) 05 Jul 2020 |
| Filipe S. (filipesn) 5 Jan 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@ -19,7 +23,11 @@
enum
{
APEX_PACKET_ID_DIRECT = 0x3a, /* Direct mode */
APEX_PACKET_ID_DIRECT = 0x3a, /* Direct mode */
APEX_2023_PACKET_ID_DIRECT = 0x40, /* New Wired Direct mode */
APEX_2023_PACKET_ID_DIRECT_WIRELESS = 0x61, /* New Wireless Direct mode */
APEX_2023_PACKET_ID_INIT = 0x4B, /* New Initialization */
APEX_2023_PACKET_LENGTH = 643,
};
class SteelSeriesApexController : public SteelSeriesApexBaseController
@ -36,10 +44,16 @@ public:
void SetLEDsDirect(std::vector<RGBColor> colors);
std::string GetSerial() override;
private:
void SelectProfile
(
unsigned char profile
);
void SendInitialization();
bool use_new_protocol;
};

@ -116,6 +116,8 @@
#define STEELSERIES_APEX_PRO_PID 0x1610
#define STEELSERIES_APEX_PRO_TKL_PID 0x1614
#define STEELSERIES_APEX_PRO_TKL_2023_PID 0x1628
#define STEELSERIES_APEX_PRO_TKL_2023_WL_PID_1 0x1630
#define STEELSERIES_APEX_PRO_TKL_2023_WL_PID_2 0x1632
#define STEELSERIES_APEX_M750_PID 0x0616
#define STEELSERIES_APEX_OG_PID 0x1202
#define STEELSERIES_APEX_350_PID 0x1206
@ -504,7 +506,9 @@ REGISTER_HID_DETECTOR_I ("SteelSeries Apex 9 TKL", Dete
REGISTER_HID_DETECTOR_I ("SteelSeries Apex 9 Mini", DetectSteelSeriesApex9Mini, STEELSERIES_VID, STEELSERIES_APEX_9_MINI_PID, 1 );
REGISTER_HID_DETECTOR_I ("SteelSeries Apex Pro", DetectSteelSeriesApex, STEELSERIES_VID, STEELSERIES_APEX_PRO_PID, 1 );
REGISTER_HID_DETECTOR_I ("SteelSeries Apex Pro TKL", DetectSteelSeriesApex, STEELSERIES_VID, STEELSERIES_APEX_PRO_TKL_PID, 1 );
REGISTER_HID_DETECTOR_I ("SteelSeries Apex Pro TKL 2023", DetectSteelSeriesApex, STEELSERIES_VID, STEELSERIES_APEX_PRO_TKL_2023_PID, 1 );
REGISTER_HID_DETECTOR_I ("SteelSeries Apex Pro TKL 2023 Wired", DetectSteelSeriesApex, STEELSERIES_VID, STEELSERIES_APEX_PRO_TKL_2023_PID, 1 );
REGISTER_HID_DETECTOR_IPU("SteelSeries Apex Pro TKL 2023 Wireless", DetectSteelSeriesApex, STEELSERIES_VID, STEELSERIES_APEX_PRO_TKL_2023_WL_PID_1, 3, 0xFFC0, 1);
REGISTER_HID_DETECTOR_IPU("SteelSeries Apex Pro TKL 2023 Wireless", DetectSteelSeriesApex, STEELSERIES_VID, STEELSERIES_APEX_PRO_TKL_2023_WL_PID_2, 3, 0xFFC0, 1);
REGISTER_HID_DETECTOR_I ("SteelSeries Apex M750", DetectSteelSeriesApexM, STEELSERIES_VID, STEELSERIES_APEX_M750_PID, 2 );
REGISTER_HID_DETECTOR_I ("SteelSeries Apex (OG)/Apex Fnatic", DetectSteelSeriesApexOld, STEELSERIES_VID, STEELSERIES_APEX_OG_PID, 0 );
REGISTER_HID_DETECTOR_I ("SteelSeries Apex 350", DetectSteelSeriesApexOld, STEELSERIES_VID, STEELSERIES_APEX_350_PID, 0 );

Loading…
Cancel
Save