Skip to content

Commit dccf6f9

Browse files
committed
Add code for SNES mouse to USB HID with CircuitPython
1 parent 498f3f0 commit dccf6f9

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

CircuitPython_SNES_Mouse/code.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import time
2+
import board
3+
import digitalio
4+
from adafruit_hid.mouse import Mouse
5+
from usb_hid import devices
6+
7+
SCALE = 3
8+
9+
def delta(value): # Convert 8 bit value to signed number of distance steps
10+
value = ~value # All value is inverted on the bus
11+
if value & 0x80: # and is in sign-magnitude format
12+
return -(value & 0x7f)
13+
else:
14+
return value & 0x7f
15+
16+
mouse = Mouse(devices)
17+
18+
spi = board.SPI()
19+
strobe = digitalio.DigitalInOut(board.RX)
20+
strobe.switch_to_output(False)
21+
22+
if not spi.try_lock():
23+
raise SystemExit("could not lock SPI bus")
24+
25+
spi.configure(baudrate=100_000, polarity=1)
26+
27+
# Wait for the mouse to be ready at power-on
28+
time.sleep(2)
29+
30+
# A buffer to fetch mouse data into
31+
data = bytearray(4)
32+
33+
print("Mouse is ready!")
34+
while True:
35+
# Request fresh data
36+
strobe.value = True
37+
strobe.value = False
38+
39+
# Must do read in 2 pieces with delay in between
40+
spi.readinto(data, end=2)
41+
spi.readinto(data, start=2)
42+
lmb = bool(~data[1] & 0x40) # data is inverted on the bus
43+
rmb = bool(~data[1] & 0x80)
44+
dy = delta(data[2])
45+
dx = delta(data[3])
46+
47+
48+
# Pressing both buttons together emulates the wheel
49+
wheel = lmb and rmb
50+
51+
# Compute the new button state
52+
old_buttons = mouse.report[0]
53+
mouse.report[0] = (
54+
0 if wheel else
55+
mouse.LEFT_BUTTON if lmb else
56+
mouse.RIGHT_BUTTON if rmb else
57+
0)
58+
59+
# If there's any movement, send a move event
60+
if dx or dy:
61+
if wheel:
62+
mouse.move(dx * SCALE, 0, wheel=-dy)
63+
else:
64+
mouse.move(dx * SCALE, dy * SCALE)
65+
elif old_buttons != mouse.report[0]:
66+
mouse.press(0) # Send buttons previously set via report[0]

0 commit comments

Comments
 (0)