Preliminary support for Logitech FP8071
* Updated detection for differences in FP8071
This commit is contained in:
parent
366adce39e
commit
7b454ce5f4
3 changed files with 180 additions and 12 deletions
|
|
@ -168,6 +168,7 @@ void RGBController_LogitechLightspeed::SetupZones()
|
|||
const std::string led_string = "LED";
|
||||
uint8_t led_count = controller->lightspeed->getLED_count();
|
||||
|
||||
LOG_DEBUG("[%s] Setting up %d LEDs", name.c_str(), led_count);
|
||||
if(led_count > 0)
|
||||
{
|
||||
for(size_t i = 0; i < led_count; i++)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,14 @@ const char* logitech_led_locations[] =
|
|||
"Primary",
|
||||
"Logo",
|
||||
"Left",
|
||||
"Right"
|
||||
"Right",
|
||||
"Combined",
|
||||
"Group One",
|
||||
"Group Two",
|
||||
"Group Three",
|
||||
"Group Four",
|
||||
"Group Five",
|
||||
"Group Six"
|
||||
};
|
||||
|
||||
const int NUM_LOGITECH_LED_LOCATIONS = sizeof(logitech_led_locations);
|
||||
|
|
@ -589,11 +596,11 @@ void logitech_device::getRGBconfig()
|
|||
|
||||
result = hid_write(dev_use2, get_count.buffer, get_count.size());
|
||||
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
|
||||
LOG_DEBUG("[%s] FP8071 - LED Count - %02X : %02X %02X %04X %04X %04X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(),
|
||||
response.data[2], response.data[0], response.data[1], (response.data[3] << 8 | response.data[4]), (response.data[5] << 8 | response.data[6]),
|
||||
LOG_DEBUG("[%s] FP8071 - LED Count - %04X : %02X %04X %04X %04X %04X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(),
|
||||
(response.data[1] << 8 | response.data[2]), response.data[0], (response.data[1] << 8 | response.data[2]), (response.data[3] << 8 | response.data[4]), (response.data[5] << 8 | response.data[6]),
|
||||
(response.data[7] << 8 | response.data[8]), response.data[9], response.data[10], response.data[11], response.data[12], response.data[13], response.data[14], response.data[15]);
|
||||
|
||||
led_response = response.data[2];
|
||||
led_response = (response.data[1] << 8 | response.data[2]);
|
||||
for(size_t i = 0; i < led_response; i++)
|
||||
{
|
||||
get_count.data[0] = (uint8_t)i;
|
||||
|
|
@ -602,7 +609,7 @@ void logitech_device::getRGBconfig()
|
|||
|
||||
result = hid_write(dev_use2, get_count.buffer, get_count.size());
|
||||
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
|
||||
LOG_DEBUG("[%s] FP8071 - LED %02i - %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(), led_counter,
|
||||
LOG_DEBUG("[%s] FP8071 - LED %02i - %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(), i,
|
||||
response.data[0], response.data[1], response.data[2], response.data[3], response.data[4], response.data[5], response.data[6], response.data[7],
|
||||
response.data[8], response.data[9], response.data[10], response.data[11], response.data[12], response.data[13], response.data[14], response.data[15]);
|
||||
|
||||
|
|
@ -617,7 +624,7 @@ void logitech_device::getRGBconfig()
|
|||
fx_response.init();
|
||||
|
||||
longFAPrequest get_effect;
|
||||
get_effect.init(device_index, RGB_feature_index, LOGITECH_CMD_RGB_EFFECTS_GET_INFO);
|
||||
get_effect.init(device_index, RGB_feature_index, LOGITECH_CMD_RGB_EFFECTS_GET_COUNT);
|
||||
|
||||
get_effect.data[0] = get_count.data[0];
|
||||
get_effect.data[1] = i;
|
||||
|
|
@ -638,6 +645,10 @@ void logitech_device::getRGBconfig()
|
|||
|
||||
leds.emplace(response.data[0], new_led);
|
||||
}
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Set the config to SW control mode |
|
||||
\*-----------------------------------------------------------------*/
|
||||
set8071Effects(5);
|
||||
}
|
||||
|
||||
/*get_count.feature_command = LOGITECH_CMD_RGB_EFFECTS_GET_STATE;
|
||||
|
|
@ -682,7 +693,7 @@ uint8_t logitech_device::setDirectMode(bool direct)
|
|||
| Turn the direct mode on or off via the RGB_feature_index |
|
||||
\*-----------------------------------------------------------------*/
|
||||
longFAPrequest set_direct;
|
||||
set_direct.init(device_index, RGB_feature_index, LOGITECH_CMD_RGB_EFFECTS_UNKNOWN);
|
||||
set_direct.init(device_index, RGB_feature_index, LOGITECH_FP8070_SET_SW_CTL);
|
||||
set_direct.data[0] = (direct) ? 1 : 0;
|
||||
set_direct.data[1] = set_direct.data[0];
|
||||
|
||||
|
|
@ -733,7 +744,13 @@ uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uin
|
|||
| Set the mode via the RGB_feature_index |
|
||||
\*-----------------------------------------------------------------*/
|
||||
longFAPrequest set_mode;
|
||||
set_mode.init(device_index, RGB_feature_index, ((feature_page == LOGITECH_HIDPP_PAGE_RGB_EFFECTS1) ? LOGITECH_CMD_RGB_EFFECTS_SET_CONTROL : LOGITECH_CMD_RGB_EFFECTS_GET_INFO));
|
||||
bool fp8070 = (feature_page == LOGITECH_HIDPP_PAGE_RGB_EFFECTS1);
|
||||
|
||||
set_mode.init(
|
||||
device_index,
|
||||
RGB_feature_index,
|
||||
(fp8070 ? LOGITECH_FP8070_SET_EFFECT : LOGITECH_FP8071_SET_LED_EFFECT)
|
||||
);
|
||||
set_mode.data[0] = zone;
|
||||
set_mode.data[1] = mode;
|
||||
|
||||
|
|
@ -741,12 +758,13 @@ uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uin
|
|||
set_mode.data[3] = green;
|
||||
set_mode.data[4] = blue;
|
||||
|
||||
set_mode.data[12] = fp8070 ? 0x00 : 0x01; //Bit 2-3 Power Mode : Bit 1-0 Persistence
|
||||
|
||||
speed *= 100;
|
||||
switch(fx)
|
||||
{
|
||||
case LOGITECH_DEVICE_LED_ON:
|
||||
set_mode.data[5] = 0x02; //zone;
|
||||
//set_mode.data[12] = 0x01; //Save to flash testing
|
||||
//set_mode.data[5] = 0x02; //zone;
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_LED_SPECTRUM:
|
||||
|
|
@ -795,5 +813,108 @@ uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uin
|
|||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t logitech_device::set8071Effects(uint8_t control)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Check the usage map for usage2 (0x11 Long FAP Message) |
|
||||
| then set the device into direct mode via register 0x80 |
|
||||
\*-----------------------------------------------------------------*/
|
||||
hid_device* dev_use2 = getDevice(2);
|
||||
|
||||
if(dev_use2)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Create a buffer for reads |
|
||||
\*-----------------------------------------------------------------*/
|
||||
blankFAPmessage response;
|
||||
response.init();
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Turn the direct mode on or off via the RGB_feature_index |
|
||||
\*-----------------------------------------------------------------*/
|
||||
shortFAPrequest set_effects;
|
||||
set_effects.init(device_index, RGB_feature_index);
|
||||
set_effects.feature_command = LOGITECH_FP8071_CONTROL;
|
||||
set_effects.data[0] = 1;
|
||||
set_effects.data[1] = 3; //Disables all FW control for PWR (0x02) and RGB (0x01)
|
||||
set_effects.data[2] = control;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| This code has to be protected to avoid crashes when |
|
||||
| this is called at the same time to change a powerplay |
|
||||
| mat and its paired wireless mouse leds. It will |
|
||||
| happen when using effects engines with high framerate |
|
||||
\*-----------------------------------------------------*/
|
||||
if(mutex)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(*mutex);
|
||||
|
||||
result = hid_write(dev_use2, set_effects.buffer, set_effects.size());
|
||||
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = hid_write(dev_use2, set_effects.buffer, set_effects.size());
|
||||
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t logitech_device::set8071TimeoutControl(uint8_t control)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Check the usage map for usage2 (0x11 Long FAP Message) |
|
||||
| then set the device into direct mode via register 0x80 |
|
||||
\*-----------------------------------------------------------------*/
|
||||
hid_device* dev_use2 = getDevice(2);
|
||||
|
||||
if(dev_use2)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Create a buffer for reads |
|
||||
\*-----------------------------------------------------------------*/
|
||||
blankFAPmessage response;
|
||||
response.init();
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Turn the direct mode on or off via the RGB_feature_index |
|
||||
\*-----------------------------------------------------------------*/
|
||||
longFAPrequest set_control;
|
||||
set_control.init(device_index, RGB_feature_index, LOGITECH_FP8071_PWR_CFG);
|
||||
set_control.data[0] = 1; //1;
|
||||
set_control.data[3] = 0; //0x3C; //Inactive Lighting timeout MSB
|
||||
set_control.data[4] = 5; //0x3C; //Inactive Lighting timeout LSB
|
||||
set_control.data[5] = 0; //1; //Lights off timeout MSB
|
||||
set_control.data[6] = 20; //0x2C; //Lights off timeout LSB
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| This code has to be protected to avoid crashes when |
|
||||
| this is called at the same time to change a powerplay |
|
||||
| mat and its paired wireless mouse leds. It will |
|
||||
| happen when using effects engines with high framerate |
|
||||
\*-----------------------------------------------------*/
|
||||
if(mutex)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(*mutex);
|
||||
|
||||
result = hid_write(dev_use2, set_control.buffer, set_control.size());
|
||||
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = hid_write(dev_use2, set_control.buffer, set_control.size());
|
||||
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
#define LOGITECH_CMD_RGB_EFFECTS_SET_STATE 0x50
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_CONFIG 0x60
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_SET_CONFIG 0x70
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_UNKNOWN 0x80 //Used to set "direct" mode
|
||||
|
||||
enum LOGITECH_DEVICE_TYPE
|
||||
{
|
||||
|
|
@ -79,6 +78,51 @@ enum LOGITECH_DEVICE_MODE
|
|||
LOGITECH_DEVICE_LED_CUSTOM = 0x000C
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8070
|
||||
{
|
||||
LOGITECH_FP8070_INFO = 0x00,
|
||||
LOGITECH_FP8070_ZONE_INFO = 0x10,
|
||||
LOGITECH_FP8070_EFFECT_INFO = 0x20,
|
||||
LOGITECH_FP8070_SET_EFFECT = 0x30,
|
||||
LOGITECH_FP8070_SET_CFG = 0x40,
|
||||
LOGITECH_FP8070_GET_CFG = 0x50,
|
||||
LOGITECH_FP8070_GET_BIN_INFO = 0x60,
|
||||
LOGITECH_FP8070_GET_SW_CTL = 0x70,
|
||||
LOGITECH_FP8070_SET_SW_CTL = 0x80,
|
||||
LOGITECH_FP8070_GET_STATUS = 0x90,
|
||||
LOGITECH_FP8070_CLEAR_EFFECT = 0xA0,
|
||||
LOGITECH_FP8070_SET_DIR = 0xB0,
|
||||
LOGITECH_FP8070_GET_COLOUR = 0xC0,
|
||||
LOGITECH_FP8070_SYNC_CFG = 0xD0,
|
||||
LOGITECH_FP8070_GET_EFFECT = 0xE0,
|
||||
LOGITECH_FP8070_SET_BIN_INFO = 0xF0,
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8071
|
||||
{
|
||||
LOGITECH_FP8071_INFO = 0x00,
|
||||
LOGITECH_FP8071_SET_LED_EFFECT = 0x10,
|
||||
LOGITECH_FP8071_ZONE_PATTERN = 0x20,
|
||||
LOGITECH_FP8071_CONFIG = 0x30,
|
||||
LOGITECH_FP8070_BIN_INFO = 0x40,
|
||||
LOGITECH_FP8071_CONTROL = 0x50,
|
||||
LOGITECH_FP8071_SYNC_CFG = 0x60,
|
||||
LOGITECH_FP8071_PWR_CFG = 0x70,
|
||||
LOGITECH_FP8071_PWR_MODE = 0x80,
|
||||
LOGITECH_FP8071_SHUTDOWN = 0x90
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8071_FLAGS
|
||||
{
|
||||
FP8071_SUPPORTS_GET_STATUS = 0x01,
|
||||
FP8071_RESERVED = 0x02,
|
||||
FP8071_SUPPORTS_SET_BIN_INFO = 0x04,
|
||||
FP8071_MONOCHROME_ONLY = 0x08,
|
||||
FP8071_NO_SYNC_SUPPORT = 0x10,
|
||||
FP8071_SUPPORTS_SHUTDOWN = 0x20,
|
||||
FP8071_SUPPORTS_CLUSTER_CHANGED = 0x40,
|
||||
};
|
||||
|
||||
extern const char* logitech_led_locations[];
|
||||
extern const int NUM_LOGITECH_LED_LOCATIONS;
|
||||
|
||||
|
|
@ -122,7 +166,7 @@ union shortFAPrequest
|
|||
this->report_id = LOGITECH_SHORT_MESSAGE;
|
||||
this->device_index = device_index;
|
||||
this->feature_index = feature_index;
|
||||
this->feature_command = 0;
|
||||
this->feature_command = feature_command;
|
||||
for(size_t i = 0; i < sizeof(data); i++)
|
||||
{
|
||||
this->data[i] = 0;
|
||||
|
|
@ -258,6 +302,8 @@ public:
|
|||
logitech_led getLED_info(uint8_t LED_num);
|
||||
uint8_t setDirectMode(bool direct);
|
||||
uint8_t setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness);
|
||||
uint8_t set8071Effects(uint8_t control);
|
||||
uint8_t set8071TimeoutControl(uint8_t control);
|
||||
int getDeviceName();
|
||||
private:
|
||||
std::map<uint8_t, logitech_led> leds;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue