Adafruit_Learning_System_Gu.../CircuitPython_SNES_Mouse/code.py

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]