diff --git a/Controllers/MSIMonitorController/MSIMonitorController.cpp b/Controllers/MSIMonitorController/MSIMonitorController.cpp index b98ccbc4d..8bfa845ce 100644 --- a/Controllers/MSIMonitorController/MSIMonitorController.cpp +++ b/Controllers/MSIMonitorController/MSIMonitorController.cpp @@ -10,10 +10,31 @@ | SPDX-License-Identifier: GPL-2.0-or-later | \*---------------------------------------------------------*/ +#include #include +#include #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 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); } diff --git a/Controllers/MSIMonitorController/MSIMonitorController.h b/Controllers/MSIMonitorController/MSIMonitorController.h index 591ab13e4..7b8191355 100644 --- a/Controllers/MSIMonitorController/MSIMonitorController.h +++ b/Controllers/MSIMonitorController/MSIMonitorController.h @@ -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& led_colors, bool fill_both_arrays); private: + void SendFeatureReport(uint8_t *data, size_t length); + hid_device *dev; std::string description; std::string location;