Skip to content

Commit

Permalink
device: add extended report rate setting
Browse files Browse the repository at this point in the history
  • Loading branch information
pfps committed Jan 28, 2024
1 parent 0db84f5 commit 91d0cfa
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/logitech_receiver/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def update_pairing_information(self):
if not self._kind:
self._kind = kind
if not self._polling_rate:
self._polling_rate = polling_rate
self._polling_rate = str(polling_rate) + 'ms'

def update_extended_pairing_information(self):
if self.receiver:
Expand Down
8 changes: 7 additions & 1 deletion lib/logitech_receiver/hidpp20.py
Original file line number Diff line number Diff line change
Expand Up @@ -1555,7 +1555,13 @@ def get_polling_rate(device):
state = feature_request(device, FEATURE.REPORT_RATE, 0x10)
if state:
rate = _unpack('!B', state[:1])[0]
return rate
return str(rate) + 'ms'
else:
rates = ['8ms', '4ms', '2ms', '1ms', '500us', '250us', '125us']
state = feature_request(device, FEATURE.EXTENDED_ADJUSTABLE_REPORT_RATE, 0x20)
if state:
rate = _unpack('!B', state[:1])[0]
return rates[rate]


def get_remaining_pairing(device):
Expand Down
2 changes: 1 addition & 1 deletion lib/logitech_receiver/receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def device_pairing_information(self, n):
if pair_info: # may be either a Unifying receiver, or an Unifying-ready receiver
wpid = _strhex(pair_info[3:5])
kind = _hidpp10.DEVICE_KIND[ord(pair_info[7:8]) & 0x0F]
polling_rate = ord(pair_info[2:3])
polling_rate = str(ord(pair_info[2:3])) + 'ms'
elif self.receiver_kind == '27Mz': # 27Mhz receiver, fill extracting WPID from udev path
wpid = _hid.find_paired_node_wpid(self.path, n)
if not wpid:
Expand Down
62 changes: 55 additions & 7 deletions lib/logitech_receiver/settings_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,14 +327,19 @@ class OnboardProfiles(_Setting):

class ReportRate(_Setting):
name = 'report_rate'
label = _('Polling Rate (ms)')
description = (
_('Frequency of device polling, in milliseconds') + '\n' +
_('May need Onboard Profiles set to Disable to be effective.')
)
label = _('Polling Rate')
description = (_('Frequency of device polling') + '\n' + _('May need Onboard Profiles set to Disable to be effective.'))
feature = _F.REPORT_RATE
rw_options = {'read_fnid': 0x10, 'write_fnid': 0x20}
choices_universe = _NamedInts.range(1, 8)
choices_universe = _NamedInts()
choices_universe[1] = '1ms'
choices_universe[2] = '2ms'
choices_universe[3] = '3ms'
choices_universe[4] = '4ms'
choices_universe[5] = '5ms'
choices_universe[6] = '6ms'
choices_universe[7] = '7ms'
choices_universe[8] = '8ms'

class _rw_class(_FeatureRW): # no longer needed - set Onboard Profiles to disable

Expand All @@ -356,7 +361,49 @@ def build(cls, setting_class, device):
rate_flags = _bytes2int(reply[0:1])
for i in range(0, 8):
if (rate_flags >> i) & 0x01:
rate_list.append(i + 1)
rate_list.append(setting_class.choices_universe[i + 1])
return cls(choices=_NamedInts.list(rate_list), byte_count=1) if rate_list else None


class ExtendedReportRate(_Setting):
name = 'report_rate_extended'
label = _('Polling Frequency')
description = (_('Frequency of device polling') + '\n' + _('May need Onboard Profiles set to Disable to be effective.'))
feature = _F.EXTENDED_ADJUSTABLE_REPORT_RATE
rw_options = {'read_fnid': 0x20, 'write_fnid': 0x30}
choices_universe = _NamedInts()
choices_universe[0] = '8ms'
choices_universe[1] = '4ms'
choices_universe[2] = '2ms'
choices_universe[3] = '1ms'
choices_universe[4] = '500us'
choices_universe[5] = '250us'
choices_universe[6] = '125us'

class _rw_class(_FeatureRW):

def read(self, device, data_bytes=b''):
# need connection type from device to get actual report rate
self.read_prefix = b'\x00' if device.receiver else b'\x01'
super().read(device, data_bytes)

def write(self, device, data_bytes):
# Host mode is required for report rate to be adjustable
if _hidpp20.get_onboard_mode(device) != _hidpp20.ONBOARD_MODES.MODE_HOST:
_hidpp20.set_onboard_mode(device, _hidpp20.ONBOARD_MODES.MODE_HOST)
return super().write(device, data_bytes)

class validator_class(_ChoicesV):

@classmethod
def build(cls, setting_class, device):
reply = device.feature_request(_F.EXTENDED_ADJUSTABLE_REPORT_RATE, 0x10)
assert reply, 'Oops, report rate choices cannot be retrieved!'
rate_list = []
rate_flags = _bytes2int(reply[0:2])
for i in range(0, 6):
if (rate_flags & (0x01 << i)):
rate_list.append(setting_class.choices_universe[i])
return cls(choices=_NamedInts.list(rate_list), byte_count=1) if rate_list else None


Expand Down Expand Up @@ -1222,6 +1269,7 @@ class ADCPower(_Setting):
ThumbMode, # working
OnboardProfiles,
ReportRate, # working
ExtendedReportRate,
PointerSpeed, # simple
AdjustableDpi, # working
SpeedChange,
Expand Down
6 changes: 3 additions & 3 deletions lib/solaar/cli/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def _print_device(dev, num=None):
else:
print(' Protocol : unknown (device is offline)')
if dev.polling_rate:
print(' Polling rate :', dev.polling_rate, 'ms (%dHz)' % (1000 // dev.polling_rate))
print(' Polling rate :', dev.polling_rate)
print(' Serial number:', dev.serial)
if dev.modelId:
print(' Model ID: ', dev.modelId)
Expand Down Expand Up @@ -217,8 +217,8 @@ def _print_device(dev, num=None):
if ids:
unitId, modelId, tid_map = ids
print(' Unit ID: %s Model ID: %s Transport IDs: %s' % (unitId, modelId, tid_map))
elif feature == _hidpp20.FEATURE.REPORT_RATE:
print(' Polling Rate (ms): %d' % _hidpp20.get_polling_rate(dev))
elif feature == _hidpp20.FEATURE.REPORT_RATE or feature == _hidpp20.FEATURE.EXTENDED_ADJUSTABLE_REPORT_RATE:
print(' Polling Rate: %s' % _hidpp20.get_polling_rate(dev))
elif feature == _hidpp20.FEATURE.REMAINING_PAIRING:
print(' Remaining Pairings: %d' % _hidpp20.get_remaining_pairing(dev))
elif feature == _hidpp20.FEATURE.ONBOARD_PROFILES:
Expand Down
7 changes: 1 addition & 6 deletions lib/solaar/ui/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,12 +550,7 @@ def _details_items(device, read_all=False):
hid_version = device.protocol
yield (_('Protocol'), 'HID++ %1.1f' % hid_version if hid_version else _('Unknown'))
if read_all and device.polling_rate:
yield (
_('Polling rate'), _('%(rate)d ms (%(rate_hz)dHz)') % {
'rate': device.polling_rate,
'rate_hz': 1000 // device.polling_rate
}
)
yield (_('Polling rate'), device.polling_rate)

if read_all or not device.online:
yield (_('Serial'), device.serial)
Expand Down

0 comments on commit 91d0cfa

Please sign in to comment.