Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pmw3360 trackball and h scroll #793

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions boot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# boot.py
import usb_hid

POINTER_REPORT_DESCRIPTOR = bytes((
0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
0x09, 0x01, # Usage (Pointer)
0xA1, 0x01, # Collection (Application)
0x09, 0x01, # Usage (Pointer)
0xA1, 0x00, # Collection (Physical)
0x85, 0x05, # 10, 11 Report ID (5)
0x05, 0x09, # Usage Page (Button)
0x19, 0x01, # Usage Minimum (0x01)
0x29, 0x05, # Usage Maximum (0x05)
0x15, 0x00, # Logical Minimum (0)
0x25, 0x01, # Logical Maximum (1)
0x95, 0x05, # Report Count (5)
0x75, 0x01, # Report Size (1)
0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, # Report Count (1)
0x75, 0x03, # Report Size (3)
0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
0x09, 0x30, # Usage (X)
0x09, 0x31, # Usage (Y)
0x15, 0x81, # Logical Minimum (-127)
0x25, 0x7F, # Logical Maximum (127)
0x75, 0x08, # Report Size (8)
0x95, 0x02, # Report Count (2)
0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38, # Usage (Wheel)
0x15, 0x81, # Logical Minimum (-127)
0x25, 0x7F, # Logical Maximum (127)
0x75, 0x08, # Report Size (8)
0x95, 0x01, # Report Count (1)
0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0C, # Usage Page (Consumer Page)
0x0A, 0x38, 0x02, # Usage (Pan)
0x15, 0x81, # Logical Minimum (-127)
0x25, 0x7F, # Logical Maximum (127)
0x75, 0x08, # Report Size (8)
0x95, 0x01, # Report Count (1)
0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0, # End Collection
0xC0, # End Collection
))

pointer = usb_hid.Device(
report_descriptor=POINTER_REPORT_DESCRIPTOR,
usage_page=0x01, # Generic Desktop Control
usage=0x01, # Pointer
report_ids=(5,), # Descriptor uses report ID 2
in_report_lengths=(5,), # This pointer sends 5 bytes in its report
out_report_lengths=(0,), # It does not receive any reports
)

usb_hid.enable(
(usb_hid.Device.KEYBOARD,
usb_hid.Device.MOUSE,
usb_hid.Device.CONSUMER_CONTROL,
pointer)
)
42 changes: 30 additions & 12 deletions kmk/hid.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
from storage import getmount

from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey, MouseKey
from kmk.utils import Debug, clamp
from kmk.utils import clamp, Debug

debug = Debug(__name__)

try:
from adafruit_ble import BLERadio
Expand All @@ -30,25 +32,28 @@ class HIDModes:
class HIDReportTypes:
KEYBOARD = 1
MOUSE = 2
POINTER = 5
CONSUMER = 3
SYSCONTROL = 4


class HIDUsage:
KEYBOARD = 0x06
MOUSE = 0x02
POINTER = 0x01
CONSUMER = 0x01
SYSCONTROL = 0x80


class HIDUsagePage:
CONSUMER = 0x0C
KEYBOARD = MOUSE = SYSCONTROL = 0x01
KEYBOARD = MOUSE = POINTER = SYSCONTROL = 0x01


HID_REPORT_SIZES = {
HIDReportTypes.KEYBOARD: 8,
HIDReportTypes.MOUSE: 4,
HIDReportTypes.POINTER: 5,
HIDReportTypes.CONSUMER: 2,
HIDReportTypes.SYSCONTROL: 8, # TODO find the correct value for this
}
Expand Down Expand Up @@ -91,9 +96,9 @@ def __init__(self, **kwargs):
self._cc_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.CONSUMER] + 1)
self._cc_report[0] = HIDReportTypes.CONSUMER
self._cc_pending = False

self._pd_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.MOUSE] + 1)
self._pd_report[0] = HIDReportTypes.MOUSE
if self._pd_report is None:
self._pd_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.MOUSE] + 1)
self._pd_report[0] = HIDReportTypes.MOUSE
self._pd_pending = False

def __repr__(self):
Expand Down Expand Up @@ -230,8 +235,10 @@ def remove_pd(self):
def move_axis(self, axis):
delta = clamp(axis.delta, -127, 127)
axis.delta -= delta
self._pd_report[axis.code + 2] = 0xFF & delta
self._pd_pending = True
# the built in mouse doesn't have a Pan (P) axis. only add Pan axis to report if using a custom Pointer Device Report with at least 5 bytes
if len(self._pd_report) > axis.code + 2:
self._pd_report[axis.code + 2] = 0xFF & delta
self._pd_pending = True

def clear_axis(self):
for idx in range(2, len(self._pd_report)):
Expand Down Expand Up @@ -260,13 +267,18 @@ def __init__(self, **kwargs):
for device in usb_hid.devices:
us = device.usage
up = device.usage_page
print('init device:', up, us)

if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER:
self.devices[HIDReportTypes.CONSUMER] = device
elif up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD:
self.devices[HIDReportTypes.KEYBOARD] = device
elif up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE:
self.devices[HIDReportTypes.MOUSE] = device
elif up == HIDUsagePage.POINTER and us == HIDUsage.POINTER:
self.devices[HIDReportTypes.POINTER] = device
self._pd_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.POINTER] + 1)
self._pd_report[0] = HIDReportTypes.POINTER
elif up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL:
self.devices[HIDReportTypes.SYSCONTROL] = device

Expand All @@ -275,13 +287,13 @@ def __init__(self, **kwargs):
def hid_send(self, evt):
if not supervisor.runtime.usb_connected:
return

# int, can be looked up in HIDReportTypes
reporting_device_const = evt[0]

return self.devices[reporting_device_const].send_report(
evt[1 : HID_REPORT_SIZES[reporting_device_const] + 1]
)
report = evt[1 : HID_REPORT_SIZES[reporting_device_const] + 1]
debug('reporting:')
debug(' device: ', evt[0])
debug(' report: ', report)
return self.devices[reporting_device_const].send_report(report)


class BLEHID(AbstractHID):
Expand Down Expand Up @@ -333,6 +345,12 @@ def devices(self):
result[HIDReportTypes.MOUSE] = device
continue

if up == HIDUsagePage.POINTER and us == HIDUsage.POINTER:
self.devices[HIDReportTypes.POINTER] = device
self._pd_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.POINTER] + 1)
self._pd_report[0] = HIDReportTypes.POINTER
continue

if up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL:
result[HIDReportTypes.SYSCONTROL] = device
continue
Expand Down
7 changes: 4 additions & 3 deletions kmk/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ def move(self, keyboard: Keyboard, delta: int):


class AX:
W = Axis(2)
X = Axis(0)
Y = Axis(1)
W = Axis(2) # wheel
P = Axis(3) # pan
X = Axis(0) # move x
Y = Axis(1) # move y


def maybe_make_key(
Expand Down
Loading