MSIMonitorController: idle the control pipe between feature reports

This commit is contained in:
Ken Sanislo
2026-07-27 03:07:33 +00:00
committed by Adam Honse
parent 3b2466ba10
commit 05fbe381dd
2 changed files with 34 additions and 2 deletions

View File

@@ -10,10 +10,31 @@
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <chrono>
#include <string.h>
#include <thread>
#include "MSIMonitorController.h"
#include "StringUtils.h"
/*---------------------------------------------------------*\
| Feature reports are control transfers and this panel |
| holds one outstanding for tens of milliseconds. Back |
| to back writes pin the shared control pipe at full |
| duty and starve other non periodic traffic: a device |
| with no interrupt OUT endpoint writes by SET_REPORT |
| and stops answering, while its isochronous endpoints |
| keep running. |
| |
| Idle a fixed interval after each write to leave the |
| control pipe free. |
\*---------------------------------------------------------*/
void MSIMonitorController::SendFeatureReport(uint8_t *data, size_t length)
{
hid_send_feature_report(dev, data, length);
std::this_thread::sleep_for(std::chrono::milliseconds(MSI_MONITOR_PIPE_IDLE_MS));
}
MSIMonitorController::MSIMonitorController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
{
dev = dev_handle;
@@ -118,7 +139,7 @@ void MSIMonitorController::Set(uint8_t mode_value, const std::vector<RGBColor> c
| Send the data (1 packet) |
\*---------------------------------------------------------*/
hid_send_feature_report(dev, data, MSI_MONITOR_PACKET_SIZE);
SendFeatureReport(data, MSI_MONITOR_PACKET_SIZE);
}
uint8_t MSIMonitorController::GetLayoutVersion()
@@ -238,5 +259,5 @@ void MSIMonitorController::SetMode72(uint8_t mode_value, uint8_t speed, uint8_t
\*-----------------------------------------------------*/
data[MSI_MONITOR_72_STORE_INDEX] = save ? 0x01 : 0x00;
hid_send_feature_report(dev, data, MSI_MONITOR_72_PACKET_SIZE);
SendFeatureReport(data, MSI_MONITOR_72_PACKET_SIZE);
}

View File

@@ -19,6 +19,15 @@
#define MSI_MONITOR_LEDS 9
#define MSI_MONITOR_PACKET_SIZE 78
/*---------------------------------------------------------*\
| This panel holds each feature report outstanding for |
| tens of ms while its MCU applies the frame, pinning the |
| shared control pipe. Idle briefly after each write so |
| other non periodic traffic on the bus is not starved. |
| See SendFeatureReport. |
\*---------------------------------------------------------*/
#define MSI_MONITOR_PIPE_IDLE_MS 5
/*---------------------------------------------------------*\
| 0x72 layout (dual control block, e.g. MPG 322URX QD-OLED) |
\*---------------------------------------------------------*/
@@ -132,6 +141,8 @@ public:
void SetMode72(uint8_t mode_value, uint8_t speed, uint8_t brightness, RGBColor color1, RGBColor color2, bool user_palette, bool save, const std::vector<RGBColor>& led_colors, bool fill_both_arrays);
private:
void SendFeatureReport(uint8_t *data, size_t length);
hid_device *dev;
std::string description;
std::string location;