66 lines
1.6 KiB
Python
66 lines
1.6 KiB
Python
import time
|
|
import board
|
|
import digitalio
|
|
from adafruit_hid.mouse import Mouse
|
|
from usb_hid import devices
|
|
|
|
SCALE = 3
|
|
|
|
def delta(value): # Convert 8 bit value to signed number of distance steps
|
|
value = ~value # All value is inverted on the bus
|
|
if value & 0x80: # and is in sign-magnitude format
|
|
return -(value & 0x7f)
|
|
else:
|
|
return value & 0x7f
|
|
|
|
mouse = Mouse(devices)
|
|
|
|
spi = board.SPI()
|
|
strobe = digitalio.DigitalInOut(board.RX)
|
|
strobe.switch_to_output(False)
|
|
|
|
if not spi.try_lock():
|
|
raise SystemExit("could not lock SPI bus")
|
|
|
|
spi.configure(baudrate=100_000, polarity=1)
|
|
|
|
# Wait for the mouse to be ready at power-on
|
|
time.sleep(2)
|
|
|
|
# A buffer to fetch mouse data into
|
|
data = bytearray(4)
|
|
|
|
print("Mouse is ready!")
|
|
while True:
|
|
# Request fresh data
|
|
strobe.value = True
|
|
strobe.value = False
|
|
|
|
# Must do read in 2 pieces with delay in between
|
|
spi.readinto(data, end=2)
|
|
spi.readinto(data, start=2)
|
|
lmb = bool(~data[1] & 0x40) # data is inverted on the bus
|
|
rmb = bool(~data[1] & 0x80)
|
|
dy = delta(data[2])
|
|
dx = delta(data[3])
|
|
|
|
|
|
# Pressing both buttons together emulates the wheel
|
|
wheel = lmb and rmb
|
|
|
|
# Compute the new button state
|
|
old_buttons = mouse.report[0]
|
|
mouse.report[0] = (
|
|
0 if wheel else
|
|
mouse.LEFT_BUTTON if lmb else
|
|
mouse.RIGHT_BUTTON if rmb else
|
|
0)
|
|
|
|
# If there's any movement, send a move event
|
|
if dx or dy:
|
|
if wheel:
|
|
mouse.move(dx * SCALE, 0, wheel=-dy)
|
|
else:
|
|
mouse.move(dx * SCALE, dy * SCALE)
|
|
elif old_buttons != mouse.report[0]:
|
|
mouse.press(0) # Send buttons previously set via report[0]
|