mirror of
https://github.com/dekuNukem/USB4VC.git
synced 2025-10-31 11:26:46 -07:00
trying out async device scan
This commit is contained in:
@@ -1,89 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import RPi.GPIO as GPIO
|
||||
from demo_opts import get_device
|
||||
from luma.core.render import canvas
|
||||
from PIL import ImageFont
|
||||
|
||||
OLED_WIDTH = 128
|
||||
OLED_HEIGHT = 32
|
||||
|
||||
my_arg = ['--display', 'ssd1306', '--interface', 'spi', '--spi-port', '0', '--spi-device', '1', '--gpio-reset', '6', '--gpio-data-command', '5', '--width', str(OLED_WIDTH), '--height', str(OLED_HEIGHT), '--spi-bus-speed', '2000000']
|
||||
oled_device = get_device(my_arg)
|
||||
time.sleep(0.5)
|
||||
oled_device = get_device(my_arg)
|
||||
|
||||
font_regular = ImageFont.truetype("ProggyTiny.ttf", 16)
|
||||
font_medium = ImageFont.truetype("ChiKareGo2.ttf", 16)
|
||||
font_large = ImageFont.truetype("ProggyTiny.ttf", 32)
|
||||
|
||||
max_char_per_line = {font_regular:21, font_medium:17, font_large:11}
|
||||
width_per_char = {font_regular:6, font_medium:7, font_large:12}
|
||||
|
||||
def oled_print_centered(text, font, y, this_canvas):
|
||||
text = text.strip()[:max_char_per_line[font]]
|
||||
start_x = int((OLED_WIDTH - (len(text) * width_per_char[font]))/2)
|
||||
if start_x < 0:
|
||||
start_x = 0
|
||||
this_canvas.text((start_x, y), text, font=font, fill="white")
|
||||
|
||||
class my_button(object):
|
||||
def __init__(self, bcm_pin):
|
||||
super(my_button, self).__init__()
|
||||
self.pin_number = bcm_pin
|
||||
GPIO.setup(self.pin_number, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
self.prev_state = GPIO.input(self.pin_number)
|
||||
|
||||
def is_pressed(self):
|
||||
result = False
|
||||
current_state = GPIO.input(self.pin_number)
|
||||
if self.prev_state == 1 and current_state == 0:
|
||||
result = True
|
||||
self.prev_state = current_state
|
||||
return result
|
||||
|
||||
PLUS_BUTTON_PIN = 27
|
||||
MINUS_BUTTON_PIN = 19
|
||||
ENTER_BUTTON_PIN = 22
|
||||
SHUTDOWN_BUTTON_PIN = 21
|
||||
PCARD_CS_PIN = 8
|
||||
SLEEP_LED_PIN = 26
|
||||
|
||||
GPIO.setup(SLEEP_LED_PIN, GPIO.OUT)
|
||||
GPIO.output(SLEEP_LED_PIN, GPIO.LOW)
|
||||
GPIO.setup(PCARD_CS_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||
|
||||
plus_button = my_button(PLUS_BUTTON_PIN)
|
||||
minus_button = my_button(MINUS_BUTTON_PIN)
|
||||
enter_button = my_button(ENTER_BUTTON_PIN)
|
||||
shutdown_button = my_button(SHUTDOWN_BUTTON_PIN)
|
||||
|
||||
loop_count = 0
|
||||
def print_pattern():
|
||||
global loop_count
|
||||
loop_count = (loop_count + 1) % 2
|
||||
oled_device = get_device(my_arg)
|
||||
if loop_count:
|
||||
GPIO.output(SLEEP_LED_PIN, GPIO.HIGH)
|
||||
with canvas(oled_device) as draw:
|
||||
draw.text((0, 0), "ABCDEFGHIJKLMNO", font=font_medium, fill="white")
|
||||
draw.text((0, 15), "PQRSTUVWXYZ0123", font=font_medium, fill="white")
|
||||
else:
|
||||
GPIO.output(SLEEP_LED_PIN, GPIO.LOW)
|
||||
with canvas(oled_device) as draw:
|
||||
draw.text((0, 0), "===================", font=font_medium, fill="white")
|
||||
draw.text((0, 15), "===================", font=font_medium, fill="white")
|
||||
|
||||
print_pattern()
|
||||
|
||||
while 1:
|
||||
time.sleep(0.05)
|
||||
if GPIO.input(PCARD_CS_PIN) == 0:
|
||||
GPIO.output(SLEEP_LED_PIN, GPIO.LOW)
|
||||
exit()
|
||||
if plus_button.is_pressed() or \
|
||||
minus_button.is_pressed() or \
|
||||
enter_button.is_pressed() or \
|
||||
shutdown_button.is_pressed():
|
||||
print_pattern()
|
||||
@@ -1,122 +0,0 @@
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
LINUX_EXIT_CODE_TIMEOUT = 124
|
||||
|
||||
def bt_setup():
|
||||
rfkill_str = subprocess.getoutput("/usr/sbin/rfkill -n")
|
||||
if 'bluetooth' not in rfkill_str:
|
||||
return 1, "no BT receiver found"
|
||||
os.system('/usr/sbin/rfkill unblock bluetooth')
|
||||
time.sleep(0.1)
|
||||
exit_code = os.system('timeout 1 bluetoothctl agent NoInputNoOutput')
|
||||
if exit_code == LINUX_EXIT_CODE_TIMEOUT:
|
||||
return 2, 'bluetoothctl stuck'
|
||||
return 0, ''
|
||||
|
||||
def scan_bt_devices(timeout_sec = 5):
|
||||
exit_code = os.system(f"timeout {timeout_sec} bluetoothctl --agent NoInputNoOutput scan on") >> 8
|
||||
if exit_code != LINUX_EXIT_CODE_TIMEOUT:
|
||||
return None, 'scan error'
|
||||
device_str = subprocess.getoutput("bluetoothctl --agent NoInputNoOutput devices")
|
||||
dev_list = []
|
||||
for line in device_str.replace('\r', '').split('\n'):
|
||||
if 'device' not in line.lower():
|
||||
continue
|
||||
line_split = line.split(' ', maxsplit=2)
|
||||
# skip if device has no name
|
||||
if len(line_split) < 3 or line_split[2].count('-') == 5:
|
||||
continue
|
||||
dev_list.append((line_split[1], line_split[2]))
|
||||
if len(dev_list) == 0:
|
||||
return None, 'Nothing was found'
|
||||
return dev_list, ''
|
||||
|
||||
def delete_all_devices():
|
||||
dev_set = set()
|
||||
device_str = subprocess.getoutput(f"bluetoothctl --agent NoInputNoOutput devices")
|
||||
device_str2 = subprocess.getoutput(f"bluetoothctl --agent NoInputNoOutput paired-devices")
|
||||
|
||||
for line in (device_str + '\n' + device_str2).replace('\r', '').split('\n'):
|
||||
if 'device' not in line.lower():
|
||||
continue
|
||||
line_split = line.split(' ', maxsplit=2)
|
||||
# skip if device has no name
|
||||
if len(line_split) < 3 or line_split[2].count('-') == 5:
|
||||
continue
|
||||
dev_set.add((line_split[1], line_split[2]))
|
||||
|
||||
print('vvvvv')
|
||||
print(device_str)
|
||||
print(device_str2)
|
||||
print(dev_set)
|
||||
print('^^^^^')
|
||||
|
||||
for item in dev_set:
|
||||
os.system(f'bluetoothctl --agent NoInputNoOutput block {item[0]}')
|
||||
os.system(f'bluetoothctl --agent NoInputNoOutput remove {item[0]}')
|
||||
os.system(f'bluetoothctl --agent NoInputNoOutput unblock {item[0]}')
|
||||
print('done')
|
||||
|
||||
|
||||
def pair_device(mac_addr):
|
||||
is_ready = False
|
||||
is_sent = False
|
||||
fail_phrases = ['fail', 'error', 'not available', 'excep']
|
||||
with Popen(["bluetoothctl", "--agent", "NoInputNoOutput"], stdout=PIPE, stdin=PIPE, bufsize=1,
|
||||
universal_newlines=True, shell=True) as p:
|
||||
for line in p.stdout:
|
||||
print(line, end='')
|
||||
line_lo = line.lower()
|
||||
if 'registered' in line_lo:
|
||||
is_ready = True
|
||||
if is_ready is False:
|
||||
continue
|
||||
if '#' in line_lo and is_sent == False:
|
||||
p.stdin.write(f'pair {mac_addr}\n')
|
||||
is_sent = True
|
||||
if 'successful' in line_lo:
|
||||
p.stdin.write('exit\n')
|
||||
return True, 'Success!'
|
||||
for item in fail_phrases:
|
||||
if item in line_lo:
|
||||
p.stdin.write('exit\n')
|
||||
return False, line
|
||||
return False, "wtf"
|
||||
|
||||
# if len(sys.argv) > 1:
|
||||
# print("deleting all devices..")
|
||||
# delete_all_devices()
|
||||
# else:
|
||||
# print(pair_device('20:20:01:01:3C:0C'))
|
||||
|
||||
# [agent] PIN: 027004
|
||||
# [agent] Enter passkey (number in 0-999999):
|
||||
|
||||
|
||||
def get_paired_devices():
|
||||
dev_set = set()
|
||||
try:
|
||||
device_str = subprocess.getoutput(f"timeout 5 bluetoothctl --agent NoInputNoOutput paired-devices")
|
||||
for line in device_str.replace('\r', '').split('\n'):
|
||||
if 'device' not in line.lower():
|
||||
continue
|
||||
line_split = line.split(' ', maxsplit=2)
|
||||
# skip if device has no name
|
||||
if len(line_split) < 3 or line_split[2].count('-') == 5:
|
||||
continue
|
||||
dev_set.add((line_split[1], line_split[2]))
|
||||
except Exception as e:
|
||||
print('get_paired_devices exception:', e)
|
||||
return dev_set
|
||||
|
||||
print(get_paired_devices())
|
||||
|
||||
# for item in dev_set:
|
||||
# os.system(f'bluetoothctl --agent NoInputNoOutput block {item[0]}')
|
||||
# os.system(f'bluetoothctl --agent NoInputNoOutput remove {item[0]}')
|
||||
# os.system(f'bluetoothctl --agent NoInputNoOutput unblock {item[0]}')
|
||||
# print('done')
|
||||
@@ -1,36 +0,0 @@
|
||||
import time
|
||||
import sys
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
PLUS_BUTTON_PIN = 27
|
||||
MINUS_BUTTON_PIN = 19
|
||||
ENTER_BUTTON_PIN = 22
|
||||
SHUTDOWN_BUTTON_PIN = 21
|
||||
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
|
||||
GPIO.setup(PLUS_BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
GPIO.add_event_detect(PLUS_BUTTON_PIN, GPIO.FALLING, bouncetime=250)
|
||||
|
||||
GPIO.setup(MINUS_BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
GPIO.add_event_detect(MINUS_BUTTON_PIN, GPIO.FALLING, bouncetime=250)
|
||||
|
||||
GPIO.setup(ENTER_BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
GPIO.add_event_detect(ENTER_BUTTON_PIN, GPIO.FALLING, bouncetime=250)
|
||||
|
||||
GPIO.setup(SHUTDOWN_BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
GPIO.add_event_detect(SHUTDOWN_BUTTON_PIN, GPIO.FALLING, bouncetime=250)
|
||||
|
||||
while 1:
|
||||
time.sleep(0.1)
|
||||
if GPIO.event_detected(PLUS_BUTTON_PIN):
|
||||
print(time.time(), "PLUS_BUTTON pressed!")
|
||||
|
||||
if GPIO.event_detected(MINUS_BUTTON_PIN):
|
||||
print(time.time(), "MINUS_BUTTON pressed!")
|
||||
|
||||
if GPIO.event_detected(ENTER_BUTTON_PIN):
|
||||
print(time.time(), "ENTER_BUTTON pressed!")
|
||||
|
||||
if GPIO.event_detected(SHUTDOWN_BUTTON_PIN):
|
||||
print(time.time(), "SHUTDOWN_BUTTON pressed!")
|
||||
@@ -1,79 +0,0 @@
|
||||
I: Bus=0003 Vendor=05ac Product=0250 Version=0111
|
||||
N: Name="Apple Inc. Apple Keyboard"
|
||||
P: Phys=usb-3f980000.usb-1.3.2/input0
|
||||
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3.2/1-1.3.2:1.0/0003:05AC:0250.0001/input/input0
|
||||
U: Uniq=
|
||||
H: Handlers=sysrq kbd leds event0
|
||||
B: PROP=0
|
||||
B: EV=120013
|
||||
B: KEY=10000 0 0 0 0 0 0 1007b 1007 ff9f207a c14057ff ffbeffdf ffefffff ffffffff fffffffe
|
||||
B: MSC=10
|
||||
B: LED=1f
|
||||
|
||||
I: Bus=0003 Vendor=05ac Product=0250 Version=0111
|
||||
N: Name="Apple Inc. Apple Keyboard"
|
||||
P: Phys=usb-3f980000.usb-1.3.2/input1
|
||||
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3.2/1-1.3.2:1.1/0003:05AC:0250.0002/input/input1
|
||||
U: Uniq=
|
||||
H: Handlers=kbd event1
|
||||
B: PROP=0
|
||||
B: EV=13
|
||||
B: KEY=3a 0 e0000 0 0 0
|
||||
B: MSC=10
|
||||
|
||||
I: Bus=0003 Vendor=17ef Product=6039 Version=0111
|
||||
N: Name="Lenovo Laser Wireless Mouse"
|
||||
P: Phys=usb-3f980000.usb-1.4/input0
|
||||
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:17EF:6039.0004/input/input3
|
||||
U: Uniq=
|
||||
H: Handlers=mouse0 event3
|
||||
B: PROP=0
|
||||
B: EV=1f
|
||||
B: KEY=1f0000 0 0 0 0 0 0 0 0
|
||||
B: REL=1943
|
||||
B: ABS=100 0
|
||||
B: MSC=10
|
||||
|
||||
I: Bus=0003 Vendor=0483 Product=d11c Version=0111
|
||||
N: Name="dekuNukem duckyPad(2020) Keyboard"
|
||||
P: Phys=usb-3f980000.usb-1.2/input0
|
||||
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:0483:D11C.0006/input/input5
|
||||
U: Uniq=DP20_774c6600
|
||||
H: Handlers=sysrq kbd event2
|
||||
B: PROP=0
|
||||
B: EV=100013
|
||||
B: KEY=7 ff800000 0 e0b0ffdf 1cfffff ffffffff fffffffe
|
||||
B: MSC=10
|
||||
|
||||
I: Bus=0003 Vendor=0483 Product=d11c Version=0111
|
||||
N: Name="dekuNukem duckyPad(2020) Consumer Control"
|
||||
P: Phys=usb-3f980000.usb-1.2/input0
|
||||
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:0483:D11C.0006/input/input6
|
||||
U: Uniq=DP20_774c6600
|
||||
H: Handlers=kbd event4
|
||||
B: PROP=0
|
||||
B: EV=13
|
||||
B: KEY=7a 0 e0000 0 0 0
|
||||
B: MSC=10
|
||||
|
||||
I: Bus=0003 Vendor=0483 Product=d11c Version=0111
|
||||
N: Name="dekuNukem duckyPad(2020) Mouse"
|
||||
P: Phys=usb-3f980000.usb-1.2/input0
|
||||
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:0483:D11C.0006/input/input7
|
||||
U: Uniq=DP20_774c6600
|
||||
H: Handlers=mouse1 event5
|
||||
B: PROP=0
|
||||
B: EV=17
|
||||
B: KEY=70000 0 0 0 0 0 0 0 0
|
||||
B: REL=903
|
||||
B: MSC=10
|
||||
|
||||
I: Bus=0003 Vendor=0483 Product=d11c Version=0111
|
||||
N: Name="dekuNukem duckyPad(2020)"
|
||||
P: Phys=usb-3f980000.usb-1.2/input0
|
||||
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:0483:D11C.0006/input/input8
|
||||
U: Uniq=DP20_774c6600
|
||||
H: Handlers=event6
|
||||
B: PROP=0
|
||||
B: EV=9
|
||||
B: ABS=100 0
|
||||
@@ -1,36 +0,0 @@
|
||||
import time
|
||||
import evdev
|
||||
|
||||
# sh sync.sh; ssh -t pi@192.168.1.56 "pkill python3;cd ~/usb4vc;python3 evdev_test.py"
|
||||
# sh sync.sh; ssh -t pi@192.168.1.56 "pkill python3;cd ~/usb4vc;python3 usb4vc_main.py"
|
||||
|
||||
def get_input_devices():
|
||||
result = []
|
||||
available_devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
|
||||
for this_device in available_devices:
|
||||
dev_dict = {
|
||||
'path':this_device.path,
|
||||
'name':this_device.name,
|
||||
'axes_info':{},
|
||||
'is_kb':False,
|
||||
'is_mouse':False,
|
||||
'is_gp':False,
|
||||
}
|
||||
cap_str = str(this_device.capabilities(verbose=True))
|
||||
if 'BTN_LEFT' in cap_str and "EV_REL" in cap_str:
|
||||
dev_dict['is_mouse'] = True
|
||||
if 'KEY_ENTER' in cap_str and "KEY_Y" in cap_str:
|
||||
dev_dict['is_kb'] = True
|
||||
if 'EV_ABS' in cap_str and "BTN_SOUTH" in cap_str:
|
||||
dev_dict['is_gp'] = True
|
||||
try:
|
||||
for item in this_device.capabilities()[EV_ABS]:
|
||||
dev_dict['axes_info'][item[0]] = item[1]._asdict()
|
||||
except Exception as e:
|
||||
print('get_input_devices exception:', e)
|
||||
result.append(dev_dict)
|
||||
return result
|
||||
|
||||
start = time.time_ns()
|
||||
get_input_devices()
|
||||
print((time.time_ns() - start) / 1000000)
|
||||
@@ -1,108 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import spidev
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
PBOARD_RESET_PIN = 25
|
||||
PBOARD_BOOT0_PIN = 12
|
||||
|
||||
SLAVE_REQ_PIN = 16
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(PBOARD_RESET_PIN, GPIO.IN)
|
||||
GPIO.setup(PBOARD_BOOT0_PIN, GPIO.IN)
|
||||
GPIO.setup(SLAVE_REQ_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||
|
||||
is_dfu = False
|
||||
|
||||
def enter_dfu():
|
||||
# RESET LOW: Enter reset
|
||||
GPIO.setup(PBOARD_RESET_PIN, GPIO.OUT)
|
||||
GPIO.output(PBOARD_RESET_PIN, GPIO.LOW)
|
||||
time.sleep(0.05)
|
||||
# BOOT0 HIGH: Boot into DFU mode
|
||||
GPIO.setup(PBOARD_BOOT0_PIN, GPIO.OUT)
|
||||
GPIO.output(PBOARD_BOOT0_PIN, GPIO.HIGH)
|
||||
time.sleep(0.05)
|
||||
# Release RESET, BOOT0 still HIGH, STM32 now in DFU mode
|
||||
GPIO.setup(PBOARD_RESET_PIN, GPIO.IN)
|
||||
time.sleep(1)
|
||||
|
||||
def exit_dfu():
|
||||
# Release BOOT0
|
||||
GPIO.setup(PBOARD_BOOT0_PIN, GPIO.IN)
|
||||
# Activate RESET
|
||||
GPIO.setup(PBOARD_RESET_PIN, GPIO.OUT)
|
||||
GPIO.output(PBOARD_RESET_PIN, GPIO.LOW)
|
||||
time.sleep(0.05)
|
||||
# Release RESET, BOOT0 is LOW, STM32 boots in normal mode
|
||||
GPIO.setup(PBOARD_RESET_PIN, GPIO.IN)
|
||||
time.sleep(0.2)
|
||||
|
||||
def flash_firmware(fw_path):
|
||||
for x in range(5):
|
||||
print(f"----------------- {fw_path.split('/')[-1]} -----------------")
|
||||
enter_dfu()
|
||||
if is_dfu:
|
||||
exit_code = os.system(f'sudo dfu-util --device ,0483:df11 -a 0 -D {fw_path}') >> 8
|
||||
else:
|
||||
exit_code = os.system(f'sudo stm32flash -w {fw_path} -a 0x3b /dev/i2c-1') >> 8
|
||||
exit_dfu()
|
||||
if exit_code != 0:
|
||||
for x in range(5):
|
||||
print("!!!!!!!!!!!!!!!!! TEST FLASH FAILED !!!!!!!!!!!!!!!!!")
|
||||
exit()
|
||||
|
||||
if(len(sys.argv) < 3):
|
||||
print (__file__ + ' payload_fw test_fw')
|
||||
exit()
|
||||
|
||||
os.system("clear")
|
||||
|
||||
pcard_spi = spidev.SpiDev(0, 0)
|
||||
pcard_spi.max_speed_hz = 2000000
|
||||
|
||||
payload_fw_path = sys.argv[1]
|
||||
test_fw_path = sys.argv[2]
|
||||
|
||||
if '.dfu' in payload_fw_path.lower() or '.dfu' in test_fw_path.lower():
|
||||
is_dfu = True
|
||||
|
||||
flash_firmware(test_fw_path)
|
||||
req_result = []
|
||||
for x in range(10):
|
||||
req_result.append(GPIO.input(SLAVE_REQ_PIN))
|
||||
time.sleep(0.1)
|
||||
|
||||
print(req_result)
|
||||
|
||||
if 0 not in req_result or 1 not in req_result or req_result.count(0) <= 3 or req_result.count(1) <= 3:
|
||||
for x in range(5):
|
||||
print("!!!!!!!!!!!!!!!!! SLAVE REQ ERROR !!!!!!!!!!!!!!!!!")
|
||||
exit()
|
||||
|
||||
while 1:
|
||||
if len(input("Press enter to continue\n")) == 0:
|
||||
break;
|
||||
|
||||
flash_firmware(payload_fw_path)
|
||||
|
||||
SPI_MOSI_MAGIC = 0xde
|
||||
SPI_MOSI_MSG_TYPE_INFO_REQUEST = 1
|
||||
|
||||
nop_spi_msg_template = [SPI_MOSI_MAGIC] + [0]*31
|
||||
info_request_spi_msg_template = [SPI_MOSI_MAGIC, 0, SPI_MOSI_MSG_TYPE_INFO_REQUEST] + [0]*29
|
||||
|
||||
this_msg = list(info_request_spi_msg_template)
|
||||
pcard_spi.xfer(this_msg)
|
||||
time.sleep(0.1)
|
||||
response = pcard_spi.xfer(list(nop_spi_msg_template))
|
||||
time.sleep(0.1)
|
||||
print(response)
|
||||
|
||||
if response[0] != 205:
|
||||
for x in range(5):
|
||||
print("!!!!!!!!!!!!!!!!! WRONG RESPONSE !!!!!!!!!!!!!!!!!")
|
||||
else:
|
||||
print("----------------- OK OK OK OK OK OK -----------------")
|
||||
print("----------------- OK OK OK OK OK OK -----------------")
|
||||
@@ -1,12 +0,0 @@
|
||||
import usb4vc_shared
|
||||
|
||||
default_map_dict = {}
|
||||
|
||||
for item in usb4vc_shared.gamepad_event_code_name_list:
|
||||
this_name = item
|
||||
this_value = usb4vc_shared.code_name_to_value_lookup.get(item)
|
||||
if this_value is None:
|
||||
continue
|
||||
default_map_dict[this_name] = {'code':f'IBM_GGP_BTN_{(this_value[0]%4) + 1}'}
|
||||
|
||||
print(default_map_dict)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +0,0 @@
|
||||
very useful video:
|
||||
https://youtu.be/wdgULBpRoXk
|
||||
|
||||
search for PID ACK for data packet
|
||||
|
||||
from keypress to PID ACK on USB line: 10 to 20ms
|
||||
|
||||
catting /dev/input/event0 in bash: 490us
|
||||
printing via python3: 1ms
|
||||
|
||||
script below:
|
||||
|
||||
fff = open("/dev/input/event0", "rb" )
|
||||
while 1:
|
||||
data = fff.read(24)
|
||||
print(data)
|
||||
|
||||
using queue to despatch SPI on raspberry 3: 700 to 800us
|
||||
on lichee 3.5ms
|
||||
|
||||
libevdev is SUPER SLOW! 20ms delay in parsing keyboard events. might write about it or do some more testing.
|
||||
|
||||
hand parse raw dev/input: 470us on pi3, 1ms on lichee
|
||||
|
||||
black PS2 extension cable both male:
|
||||
|
||||
purple clk
|
||||
black data
|
||||
brown GND
|
||||
|
||||
ps2 driver based on https://github.com/Harvie/ps2dev
|
||||
no parity check for speed
|
||||
|
||||
raspberry pi gpio linux pin numbers is BCM pin number, check use `gpio readall`
|
||||
|
||||
in allwinner chips, linux gpio number = (position of letter in alphabet - 1) * 32 + pin number
|
||||
|
||||
PA3 = (1-1) * 32 + 3 = gpio3
|
||||
|
||||
PE3 = (5-1) * 32 + 3 = 128+3 = gpio131
|
||||
|
||||
echo 131 > /sys/class/gpio/export
|
||||
|
||||
echo in > /sys/class/gpio/gpio131/direction
|
||||
|
||||
cat /sys/class/gpio/gpio131/value
|
||||
|
||||
to see list of all interrupts
|
||||
cat /proc/interrupts
|
||||
|
||||
change keyboard LED
|
||||
sudo bash -c 'echo 1 > /sys/class/leds/input5\:\:capslock/brightness'
|
||||
|
||||
|
||||
run script on launch:
|
||||
|
||||
https://raspberrypi-guide.github.io/programming/run-script-on-boot
|
||||
|
||||
sudo nano /etc/rc.local
|
||||
|
||||
cd /home/pi/usb4vc; sudo python3 usb4vc_main.py &
|
||||
|
||||
kill -SIGINT pid
|
||||
|
||||
ps2 mouse todo:
|
||||
|
||||
add remote mode data report
|
||||
add scale/resolution change
|
||||
test remote/wrap mode
|
||||
|
||||
|
||||
supported protocols:
|
||||
|
||||
PS/2 Keyboard:
|
||||
Scancode set 2
|
||||
|
||||
PS/2 Mouse:
|
||||
generic id0
|
||||
MS intellimouse id3
|
||||
|
||||
Serial Mouse:
|
||||
Microsoft serial mouse (3 byte 1200bps 7n1)
|
||||
|
||||
|
||||
|
||||
rfkill returns nothing with no bluetooth on rpi 2
|
||||
|
||||
bluetoothctrl gets stuck if no bluetooth
|
||||
|
||||
check rfkill first, then put a timeout on first btctl command
|
||||
|
||||
|
||||
bluetoothctl --agent NoInputNoOutput
|
||||
scan on
|
||||
trust <MAC-Address>
|
||||
connect <MAC-Address>
|
||||
@@ -1,195 +0,0 @@
|
||||
CODE_UNUSED, // KEY_RESERVED 0
|
||||
0x8, // KEY_ESC 1
|
||||
0x16, // KEY_1 2
|
||||
0x1e, // KEY_2 3
|
||||
0x26, // KEY_3 4
|
||||
0x25, // KEY_4 5
|
||||
0x2e, // KEY_5 6
|
||||
0x36, // KEY_6 7
|
||||
0x3d, // KEY_7 8
|
||||
0x3e, // KEY_8 9
|
||||
0x46, // KEY_9 10
|
||||
0x45, // KEY_0 11
|
||||
0x4e, // KEY_MINUS 12
|
||||
0x55, // KEY_EQUAL 13
|
||||
0x66, // KEY_BACKSPACE 14
|
||||
0xd, // KEY_TAB 15
|
||||
0x15, // KEY_Q 16
|
||||
0x1d, // KEY_W 17
|
||||
0x24, // KEY_E 18
|
||||
0x2d, // KEY_R 19
|
||||
0x2c, // KEY_T 20
|
||||
0x35, // KEY_Y 21
|
||||
0x3c, // KEY_U 22
|
||||
0x43, // KEY_I 23
|
||||
0x44, // KEY_O 24
|
||||
0x4d, // KEY_P 25
|
||||
0x54, // KEY_LEFTBRACE 26
|
||||
0x5b, // KEY_RIGHTBRACE 27
|
||||
0x5a, // KEY_ENTER 28
|
||||
0x11, // KEY_LEFTCTRL 29
|
||||
0x1c, // KEY_A 30
|
||||
0x1b, // KEY_S 31
|
||||
0x23, // KEY_D 32
|
||||
0x2b, // KEY_F 33
|
||||
0x34, // KEY_G 34
|
||||
0x33, // KEY_H 35
|
||||
0x3b, // KEY_J 36
|
||||
0x42, // KEY_K 37
|
||||
0x4b, // KEY_L 38
|
||||
0x4c, // KEY_SEMICOLON 39
|
||||
0x52, // KEY_APOSTROPHE 40
|
||||
0xe, // KEY_GRAVE 41
|
||||
0x12, // KEY_LEFTSHIFT 42
|
||||
0x5c, // KEY_BACKSLASH 43
|
||||
0x1a, // KEY_Z 44
|
||||
0x22, // KEY_X 45
|
||||
0x21, // KEY_C 46
|
||||
0x2a, // KEY_V 47
|
||||
0x32, // KEY_B 48
|
||||
0x31, // KEY_N 49
|
||||
0x3a, // KEY_M 50
|
||||
0x41, // KEY_COMMA 51
|
||||
0x49, // KEY_DOT 52
|
||||
0x4a, // KEY_SLASH 53
|
||||
0x59, // KEY_RIGHTSHIFT 54
|
||||
0x7e, // KEY_KPASTERISK 55
|
||||
0x19, // KEY_LEFTALT 56
|
||||
0x29, // KEY_SPACE 57
|
||||
0x14, // KEY_CAPSLOCK 58
|
||||
0x7, // KEY_F1 59
|
||||
0xf, // KEY_F2 60
|
||||
0x17, // KEY_F3 61
|
||||
0x1f, // KEY_F4 62
|
||||
0x27, // KEY_F5 63
|
||||
0x2f, // KEY_F6 64
|
||||
0x37, // KEY_F7 65
|
||||
0x3f, // KEY_F8 66
|
||||
0x47, // KEY_F9 67
|
||||
0x4f, // KEY_F10 68
|
||||
0x76, // KEY_NUMLOCK 69
|
||||
0x5f, // KEY_SCROLLLOCK 70
|
||||
0x6c, // KEY_KP7 71
|
||||
0x75, // KEY_KP8 72
|
||||
0x7d, // KEY_KP9 73
|
||||
0x4e, // KEY_KPMINUS 74
|
||||
0x6b, // KEY_KP4 75
|
||||
0x73, // KEY_KP5 76
|
||||
0x74, // KEY_KP6 77
|
||||
0x7c, // KEY_KPPLUS 78
|
||||
0x69, // KEY_KP1 79
|
||||
0x72, // KEY_KP2 80
|
||||
0x7a, // KEY_KP3 81
|
||||
0x70, // KEY_KP0 82
|
||||
0x71, // KEY_KPDOT 83
|
||||
CODE_UNUSED, // KEY_UNUSED 84
|
||||
CODE_UNUSED, // KEY_ZENKAKUHANKAKU 85
|
||||
0x13, // KEY_102ND 86
|
||||
0x56, // KEY_F11 87
|
||||
0x5e, // KEY_F12 88
|
||||
CODE_UNUSED, // KEY_RO 89
|
||||
CODE_UNUSED, // KEY_KATAKANA 90
|
||||
CODE_UNUSED, // KEY_HIRAGANA 91
|
||||
CODE_UNUSED, // KEY_HENKAN 92
|
||||
CODE_UNUSED, // KEY_KATAKANAHIRAGANA 93
|
||||
CODE_UNUSED, // KEY_MUHENKAN 94
|
||||
CODE_UNUSED, // KEY_KPJPCOMMA 95
|
||||
0x79, // KEY_KPENTER 96
|
||||
0x58, // KEY_RIGHTCTRL 97
|
||||
0x4a, // KEY_KPSLASH 98
|
||||
0x57, // KEY_SYSRQ 99
|
||||
0x39, // KEY_RIGHTALT 100
|
||||
CODE_UNUSED, // KEY_LINEFEED 101
|
||||
0x6e, // KEY_HOME 102
|
||||
0x63, // KEY_UP 103
|
||||
0x6f, // KEY_PAGEUP 104
|
||||
0x61, // KEY_LEFT 105
|
||||
0x6a, // KEY_RIGHT 106
|
||||
0x65, // KEY_END 107
|
||||
0x60, // KEY_DOWN 108
|
||||
0x6d, // KEY_PAGEDOWN 109
|
||||
0x67, // KEY_INSERT 110
|
||||
0x64, // KEY_DELETE 111
|
||||
CODE_UNUSED, // KEY_MACRO 112
|
||||
CODE_UNUSED, // KEY_MUTE 113
|
||||
CODE_UNUSED, // KEY_VOLUMEDOWN 114
|
||||
CODE_UNUSED, // KEY_VOLUMEUP 115
|
||||
CODE_UNUSED, // KEY_POWER 116
|
||||
CODE_UNUSED, // KEY_KPEQUAL 117
|
||||
CODE_UNUSED, // KEY_KPPLUSMINUS 118
|
||||
0x62, // KEY_PAUSE 119
|
||||
CODE_UNUSED, // KEY_SCALE 120
|
||||
CODE_UNUSED, // KEY_KPCOMMA 121
|
||||
CODE_UNUSED, // KEY_HANGEUL 122
|
||||
CODE_UNUSED, // KEY_HANJA 123
|
||||
CODE_UNUSED, // KEY_YEN 124
|
||||
0x8b, // KEY_LEFTMETA 125
|
||||
0x8c, // KEY_RIGHTMETA 126
|
||||
0x8d, // KEY_COMPOSE 127
|
||||
CODE_UNUSED, // KEY_STOP 128
|
||||
CODE_UNUSED, // KEY_AGAIN 129
|
||||
CODE_UNUSED, // KEY_PROPS 130
|
||||
CODE_UNUSED, // KEY_UNDO 131
|
||||
CODE_UNUSED, // KEY_FRONT 132
|
||||
CODE_UNUSED, // KEY_COPY 133
|
||||
CODE_UNUSED, // KEY_OPEN 134
|
||||
CODE_UNUSED, // KEY_PASTE 135
|
||||
CODE_UNUSED, // KEY_FIND 136
|
||||
CODE_UNUSED, // KEY_CUT 137
|
||||
CODE_UNUSED, // KEY_HELP 138
|
||||
CODE_UNUSED, // KEY_MENU 139
|
||||
CODE_UNUSED, // KEY_CALC 140
|
||||
CODE_UNUSED, // KEY_SETUP 141
|
||||
CODE_UNUSED, // KEY_SLEEP 142
|
||||
CODE_UNUSED, // KEY_WAKEUP 143
|
||||
CODE_UNUSED, // KEY_FILE 144
|
||||
CODE_UNUSED, // KEY_SENDFILE 145
|
||||
CODE_UNUSED, // KEY_DELETEFILE 146
|
||||
CODE_UNUSED, // KEY_XFER 147
|
||||
CODE_UNUSED, // KEY_PROG1 148
|
||||
CODE_UNUSED, // KEY_PROG2 149
|
||||
CODE_UNUSED, // KEY_WWW 150
|
||||
CODE_UNUSED, // KEY_MSDOS 151
|
||||
CODE_UNUSED, // KEY_COFFEE 152
|
||||
CODE_UNUSED, // KEY_ROTATE_DISPLAY 153
|
||||
CODE_UNUSED, // KEY_CYCLEWINDOWS 154
|
||||
CODE_UNUSED, // KEY_MAIL 155
|
||||
CODE_UNUSED, // KEY_BOOKMARKS 156
|
||||
CODE_UNUSED, // KEY_COMPUTER 157
|
||||
CODE_UNUSED, // KEY_BACK 158
|
||||
CODE_UNUSED, // KEY_FORWARD 159
|
||||
CODE_UNUSED, // KEY_CLOSECD 160
|
||||
CODE_UNUSED, // KEY_EJECTCD 161
|
||||
CODE_UNUSED, // KEY_EJECTCLOSECD 162
|
||||
CODE_UNUSED, // KEY_NEXTSONG 163
|
||||
CODE_UNUSED, // KEY_PLAYPAUSE 164
|
||||
CODE_UNUSED, // KEY_PREVIOUSSONG 165
|
||||
CODE_UNUSED, // KEY_STOPCD 166
|
||||
CODE_UNUSED, // KEY_RECORD 167
|
||||
CODE_UNUSED, // KEY_REWIND 168
|
||||
CODE_UNUSED, // KEY_PHONE 169
|
||||
CODE_UNUSED, // KEY_ISO 170
|
||||
CODE_UNUSED, // KEY_CONFIG 171
|
||||
CODE_UNUSED, // KEY_HOMEPAGE 172
|
||||
CODE_UNUSED, // KEY_REFRESH 173
|
||||
CODE_UNUSED, // KEY_EXIT 174
|
||||
CODE_UNUSED, // KEY_MOVE 175
|
||||
CODE_UNUSED, // KEY_EDIT 176
|
||||
CODE_UNUSED, // KEY_SCROLLUP 177
|
||||
CODE_UNUSED, // KEY_SCROLLDOWN 178
|
||||
CODE_UNUSED, // KEY_KPLEFTPAREN 179
|
||||
CODE_UNUSED, // KEY_KPRIGHTPAREN 180
|
||||
CODE_UNUSED, // KEY_NEW 181
|
||||
CODE_UNUSED, // KEY_REDO 182
|
||||
0x08, // KEY_F13 183
|
||||
0x10, // KEY_F14 184
|
||||
0x18, // KEY_F15 185
|
||||
0x20, // KEY_F16 186
|
||||
0x28, // KEY_F17 187
|
||||
0x30, // KEY_F18 188
|
||||
0x38, // KEY_F19 189
|
||||
0x40, // KEY_F20 190
|
||||
0x48, // KEY_F21 191
|
||||
0x50, // KEY_F22 192
|
||||
0x57, // KEY_F23 193
|
||||
0x5f, // KEY_F24 194
|
||||
@@ -1,213 +0,0 @@
|
||||
CODE_UNUSED = 255
|
||||
|
||||
tttttt = [
|
||||
(CODE_UNUSED, "KEY_RESERVED", 0),
|
||||
(0x8, "KEY_ESC", 1),
|
||||
(0x16, "KEY_1", 2),
|
||||
(0x1e, "KEY_2", 3),
|
||||
(0x26, "KEY_3", 4),
|
||||
(0x25, "KEY_4", 5),
|
||||
(0x2e, "KEY_5", 6),
|
||||
(0x36, "KEY_6", 7),
|
||||
(0x3d, "KEY_7", 8),
|
||||
(0x3e, "KEY_8", 9),
|
||||
(0x46, "KEY_9", 10),
|
||||
(0x45, "KEY_0", 11),
|
||||
(0x4e, "KEY_MINUS", 12),
|
||||
(0x55, "KEY_EQUAL", 13),
|
||||
(0x66, "KEY_BACKSPACE", 14),
|
||||
(0xd, "KEY_TAB", 15),
|
||||
(0x15, "KEY_Q", 16),
|
||||
(0x1d, "KEY_W", 17),
|
||||
(0x24, "KEY_E", 18),
|
||||
(0x2d, "KEY_R", 19),
|
||||
(0x2c, "KEY_T", 20),
|
||||
(0x35, "KEY_Y", 21),
|
||||
(0x3c, "KEY_U", 22),
|
||||
(0x43, "KEY_I", 23),
|
||||
(0x44, "KEY_O", 24),
|
||||
(0x4d, "KEY_P", 25),
|
||||
(0x54, "KEY_LEFTBRACE", 26),
|
||||
(0x5b, "KEY_RIGHTBRACE", 27),
|
||||
(0x5a, "KEY_ENTER", 28),
|
||||
(0x11, "KEY_LEFTCTRL", 29),
|
||||
(0x1c, "KEY_A", 30),
|
||||
(0x1b, "KEY_S", 31),
|
||||
(0x23, "KEY_D", 32),
|
||||
(0x2b, "KEY_F", 33),
|
||||
(0x34, "KEY_G", 34),
|
||||
(0x33, "KEY_H", 35),
|
||||
(0x3b, "KEY_J", 36),
|
||||
(0x42, "KEY_K", 37),
|
||||
(0x4b, "KEY_L", 38),
|
||||
(0x4c, "KEY_SEMICOLON", 39),
|
||||
(0x52, "KEY_APOSTROPHE", 40),
|
||||
(0xe, "KEY_GRAVE", 41),
|
||||
(0x12, "KEY_LEFTSHIFT", 42),
|
||||
(0x5c, "KEY_BACKSLASH", 43),
|
||||
(0x1a, "KEY_Z", 44),
|
||||
(0x22, "KEY_X", 45),
|
||||
(0x21, "KEY_C", 46),
|
||||
(0x2a, "KEY_V", 47),
|
||||
(0x32, "KEY_B", 48),
|
||||
(0x31, "KEY_N", 49),
|
||||
(0x3a, "KEY_M", 50),
|
||||
(0x41, "KEY_COMMA", 51),
|
||||
(0x49, "KEY_DOT", 52),
|
||||
(0x4a, "KEY_SLASH", 53),
|
||||
(0x59, "KEY_RIGHTSHIFT", 54),
|
||||
(0x7e, "KEY_KPASTERISK", 55),
|
||||
(0x19, "KEY_LEFTALT", 56),
|
||||
(0x29, "KEY_SPACE", 57),
|
||||
(0x14, "KEY_CAPSLOCK", 58),
|
||||
(0x7, "KEY_F1", 59),
|
||||
(0xf, "KEY_F2", 60),
|
||||
(0x17, "KEY_F3", 61),
|
||||
(0x1f, "KEY_F4", 62),
|
||||
(0x27, "KEY_F5", 63),
|
||||
(0x2f, "KEY_F6", 64),
|
||||
(0x37, "KEY_F7", 65),
|
||||
(0x3f, "KEY_F8", 66),
|
||||
(0x47, "KEY_F9", 67),
|
||||
(0x4f, "KEY_F10", 68),
|
||||
(0x76, "KEY_NUMLOCK", 69),
|
||||
(0x5f, "KEY_SCROLLLOCK", 70),
|
||||
(0x6c, "KEY_KP7", 71),
|
||||
(0x75, "KEY_KP8", 72),
|
||||
(0x7d, "KEY_KP9", 73),
|
||||
(0x4e, "KEY_KPMINUS", 74),
|
||||
(0x6b, "KEY_KP4", 75),
|
||||
(0x73, "KEY_KP5", 76),
|
||||
(0x74, "KEY_KP6", 77),
|
||||
(0x7c, "KEY_KPPLUS", 78),
|
||||
(0x69, "KEY_KP1", 79),
|
||||
(0x72, "KEY_KP2", 80),
|
||||
(0x7a, "KEY_KP3", 81),
|
||||
(0x70, "KEY_KP0", 82),
|
||||
(0x71, "KEY_KPDOT", 83),
|
||||
(CODE_UNUSED, "KEY_UNUSED", 84),
|
||||
(CODE_UNUSED, "KEY_ZENKAKUHANKAKU", 85),
|
||||
(0x13, "KEY_102ND", 86),
|
||||
(0x56, "KEY_F11", 87),
|
||||
(0x5e, "KEY_F12", 88),
|
||||
(CODE_UNUSED, "KEY_RO", 89),
|
||||
(CODE_UNUSED, "KEY_KATAKANA", 90),
|
||||
(CODE_UNUSED, "KEY_HIRAGANA", 91),
|
||||
(CODE_UNUSED, "KEY_HENKAN", 92),
|
||||
(CODE_UNUSED, "KEY_KATAKANAHIRAGANA", 93),
|
||||
(CODE_UNUSED, "KEY_MUHENKAN", 94),
|
||||
(CODE_UNUSED, "KEY_KPJPCOMMA", 95),
|
||||
(0x79, "KEY_KPENTER", 96),
|
||||
(0x58, "KEY_RIGHTCTRL", 97),
|
||||
(0x4a, "KEY_KPSLASH", 98),
|
||||
(0x57, "KEY_SYSRQ", 99),
|
||||
(0x39, "KEY_RIGHTALT", 100),
|
||||
(CODE_UNUSED, "KEY_LINEFEED", 101),
|
||||
(0x6e, "KEY_HOME", 102),
|
||||
(0x63, "KEY_UP", 103),
|
||||
(0x6f, "KEY_PAGEUP", 104),
|
||||
(0x61, "KEY_LEFT", 105),
|
||||
(0x6a, "KEY_RIGHT", 106),
|
||||
(0x65, "KEY_END", 107),
|
||||
(0x60, "KEY_DOWN", 108),
|
||||
(0x6d, "KEY_PAGEDOWN", 109),
|
||||
(0x67, "KEY_INSERT", 110),
|
||||
(0x64, "KEY_DELETE", 111),
|
||||
(CODE_UNUSED, "KEY_MACRO", 112),
|
||||
(CODE_UNUSED, "KEY_MUTE", 113),
|
||||
(CODE_UNUSED, "KEY_VOLUMEDOWN", 114),
|
||||
(CODE_UNUSED, "KEY_VOLUMEUP", 115),
|
||||
(CODE_UNUSED, "KEY_POWER", 116),
|
||||
(CODE_UNUSED, "KEY_KPEQUAL", 117),
|
||||
(CODE_UNUSED, "KEY_KPPLUSMINUS", 118),
|
||||
(0x62, "KEY_PAUSE", 119),
|
||||
(CODE_UNUSED, "KEY_SCALE", 120),
|
||||
(CODE_UNUSED, "KEY_KPCOMMA", 121),
|
||||
(CODE_UNUSED, "KEY_HANGEUL", 122),
|
||||
(CODE_UNUSED, "KEY_HANJA", 123),
|
||||
(CODE_UNUSED, "KEY_YEN", 124),
|
||||
(0x8b, "KEY_LEFTMETA", 125),
|
||||
(0x8c, "KEY_RIGHTMETA", 126),
|
||||
(0x8d, "KEY_COMPOSE", 127),
|
||||
(CODE_UNUSED, "KEY_STOP", 128),
|
||||
(CODE_UNUSED, "KEY_AGAIN", 129),
|
||||
(CODE_UNUSED, "KEY_PROPS", 130),
|
||||
(CODE_UNUSED, "KEY_UNDO", 131),
|
||||
(CODE_UNUSED, "KEY_FRONT", 132),
|
||||
(CODE_UNUSED, "KEY_COPY", 133),
|
||||
(CODE_UNUSED, "KEY_OPEN", 134),
|
||||
(CODE_UNUSED, "KEY_PASTE", 135),
|
||||
(CODE_UNUSED, "KEY_FIND", 136),
|
||||
(CODE_UNUSED, "KEY_CUT", 137),
|
||||
(CODE_UNUSED, "KEY_HELP", 138),
|
||||
(CODE_UNUSED, "KEY_MENU", 139),
|
||||
(CODE_UNUSED, "KEY_CALC", 140),
|
||||
(CODE_UNUSED, "KEY_SETUP", 141),
|
||||
(CODE_UNUSED, "KEY_SLEEP", 142),
|
||||
(CODE_UNUSED, "KEY_WAKEUP", 143),
|
||||
(CODE_UNUSED, "KEY_FILE", 144),
|
||||
(CODE_UNUSED, "KEY_SENDFILE", 145),
|
||||
(CODE_UNUSED, "KEY_DELETEFILE", 146),
|
||||
(CODE_UNUSED, "KEY_XFER", 147),
|
||||
(CODE_UNUSED, "KEY_PROG1", 148),
|
||||
(CODE_UNUSED, "KEY_PROG2", 149),
|
||||
(CODE_UNUSED, "KEY_WWW", 150),
|
||||
(CODE_UNUSED, "KEY_MSDOS", 151),
|
||||
(CODE_UNUSED, "KEY_COFFEE", 152),
|
||||
(CODE_UNUSED, "KEY_ROTATE_DISPLAY", 153),
|
||||
(CODE_UNUSED, "KEY_CYCLEWINDOWS", 154),
|
||||
(CODE_UNUSED, "KEY_MAIL", 155),
|
||||
(CODE_UNUSED, "KEY_BOOKMARKS", 156),
|
||||
(CODE_UNUSED, "KEY_COMPUTER", 157),
|
||||
(CODE_UNUSED, "KEY_BACK", 158),
|
||||
(CODE_UNUSED, "KEY_FORWARD", 159),
|
||||
(CODE_UNUSED, "KEY_CLOSECD", 160),
|
||||
(CODE_UNUSED, "KEY_EJECTCD", 161),
|
||||
(CODE_UNUSED, "KEY_EJECTCLOSECD", 162),
|
||||
(CODE_UNUSED, "KEY_NEXTSONG", 163),
|
||||
(CODE_UNUSED, "KEY_PLAYPAUSE", 164),
|
||||
(CODE_UNUSED, "KEY_PREVIOUSSONG", 165),
|
||||
(CODE_UNUSED, "KEY_STOPCD", 166),
|
||||
(CODE_UNUSED, "KEY_RECORD", 167),
|
||||
(CODE_UNUSED, "KEY_REWIND", 168),
|
||||
(CODE_UNUSED, "KEY_PHONE", 169),
|
||||
(CODE_UNUSED, "KEY_ISO", 170),
|
||||
(CODE_UNUSED, "KEY_CONFIG", 171),
|
||||
(CODE_UNUSED, "KEY_HOMEPAGE", 172),
|
||||
(CODE_UNUSED, "KEY_REFRESH", 173),
|
||||
(CODE_UNUSED, "KEY_EXIT", 174),
|
||||
(CODE_UNUSED, "KEY_MOVE", 175),
|
||||
(CODE_UNUSED, "KEY_EDIT", 176),
|
||||
(CODE_UNUSED, "KEY_SCROLLUP", 177),
|
||||
(CODE_UNUSED, "KEY_SCROLLDOWN", 178),
|
||||
(CODE_UNUSED, "KEY_KPLEFTPAREN", 179),
|
||||
(CODE_UNUSED, "KEY_KPRIGHTPAREN", 180),
|
||||
(CODE_UNUSED, "KEY_NEW", 181),
|
||||
(CODE_UNUSED, "KEY_REDO", 182),
|
||||
(0x08, "KEY_F13", 183),
|
||||
(0x10, "KEY_F14", 184),
|
||||
(0x18, "KEY_F15", 185),
|
||||
(0x20, "KEY_F16", 186),
|
||||
(0x28, "KEY_F17", 187),
|
||||
(0x30, "KEY_F18", 188),
|
||||
(0x38, "KEY_F19", 189),
|
||||
(0x40, "KEY_F20", 190),
|
||||
(0x48, "KEY_F21", 191),
|
||||
(0x50, "KEY_F22", 192),
|
||||
(0x57, "KEY_F23", 193),
|
||||
(0x5f, "KEY_F24", 194),
|
||||
]
|
||||
|
||||
# (set3 scan code, key name, linux ev code)
|
||||
|
||||
sorted_list = sorted(tttttt, key=lambda x: x[0])
|
||||
|
||||
set3_dict = {}
|
||||
for item in sorted_list:
|
||||
set3_dict[item[0]] = item
|
||||
|
||||
for x in range(255):
|
||||
if x in set3_dict:
|
||||
print(f'SET3_KEY_STATE_TYPEMATIC, // ({x}, {hex(x)}), {set3_dict[x][1]}, ({set3_dict[x][2]}, {hex(set3_dict[x][2])})')
|
||||
else:
|
||||
print(f'SET3_KEY_STATE_TYPEMATIC, // ({x}, {hex(x)}), UNUSED')
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
for x in range(32):
|
||||
print(hex(x), '', end='')
|
||||
@@ -1,67 +0,0 @@
|
||||
import sys
|
||||
import time
|
||||
import spidev
|
||||
import threading
|
||||
|
||||
is_on_raspberry_pi = False
|
||||
with open('/etc/os-release') as os_version_file:
|
||||
is_on_raspberry_pi = 'raspbian' in os_version_file.read().lower()
|
||||
|
||||
spi = None
|
||||
if is_on_raspberry_pi:
|
||||
spi = spidev.SpiDev(0, 0) # rasp
|
||||
print("I'm on Raspberry Pi!")
|
||||
else:
|
||||
spi = spidev.SpiDev(1, 0) # lichee
|
||||
print("I'm on custom board!")
|
||||
|
||||
spi.max_speed_hz = 2000000
|
||||
|
||||
fff = open(sys.argv[1], "rb" )
|
||||
|
||||
|
||||
"""
|
||||
https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h#L38
|
||||
|
||||
xbox gamepad:
|
||||
EVENT TYPE: EV_ABS
|
||||
dpad: ABS_HAT0X ABS_HAT1X
|
||||
buttons: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h#L385
|
||||
sticks: ABS_X, ABS_Y, ABS_RX, ABS_RY
|
||||
"""
|
||||
|
||||
EV_KEY = 0x01
|
||||
EV_REL = 0x02
|
||||
EV_ABS = 0x03
|
||||
|
||||
SPI_MSG_KEYBOARD_EVENT = 1
|
||||
SPI_MSG_MOUSE_EVENT = 2
|
||||
SPI_MSG_GAMEPAD_EVENT = 3
|
||||
|
||||
KEYBOARD_ID_PLACEHOLDER = 0
|
||||
|
||||
keyboard_spi_msg_header = [0xde, 0, SPI_MSG_KEYBOARD_EVENT, KEYBOARD_ID_PLACEHOLDER]
|
||||
|
||||
def keyboard_worker():
|
||||
print("keyboard_thread started")
|
||||
while 1:
|
||||
data = list(fff.read(16)[8:])
|
||||
if data[0] == EV_KEY:
|
||||
spi.xfer(keyboard_spi_msg_header + data)
|
||||
# print(data)
|
||||
# print('----')
|
||||
|
||||
def mouse_worker():
|
||||
print("mouse_thread started")
|
||||
while 1:
|
||||
time.sleep(0.2)
|
||||
|
||||
keyboard_thread = threading.Thread(target=keyboard_worker, daemon=True)
|
||||
keyboard_thread.start()
|
||||
|
||||
mouse_thread = threading.Thread(target=mouse_worker, daemon=True)
|
||||
mouse_thread.start()
|
||||
|
||||
while 1:
|
||||
# print("main loop")
|
||||
time.sleep(1)
|
||||
@@ -1,17 +0,0 @@
|
||||
import select
|
||||
|
||||
gpio_path = "/sys/class/gpio/gpio131/value"
|
||||
|
||||
gpio_file = open(gpio_path, 'rb')
|
||||
|
||||
epoll = select.epoll()
|
||||
epoll.register(gpio_file, select.EPOLLET)
|
||||
|
||||
while 1:
|
||||
events = epoll.poll(timeout=0.2)
|
||||
for df, event_type in events:
|
||||
print(df, event_type)
|
||||
print('here')
|
||||
|
||||
epoll.unregister(gpio_file)
|
||||
gpio_file.close()
|
||||
@@ -1,10 +0,0 @@
|
||||
import sys
|
||||
import libevdev
|
||||
|
||||
fd = open(sys.argv[1], "rb" )
|
||||
|
||||
d = libevdev.Device(fd)
|
||||
|
||||
while True:
|
||||
for e in d.events():
|
||||
print(e)
|
||||
@@ -1,47 +0,0 @@
|
||||
import sys
|
||||
import time
|
||||
import libevdev
|
||||
import spidev
|
||||
import threading
|
||||
|
||||
is_on_raspberry_pi = False
|
||||
with open('/etc/os-release') as os_version_file:
|
||||
is_on_raspberry_pi = 'raspbian' in os_version_file.read().lower()
|
||||
|
||||
spi = None
|
||||
if is_on_raspberry_pi:
|
||||
spi = spidev.SpiDev(0, 0) # rasp
|
||||
print("I'm on Raspberry Pi!")
|
||||
else:
|
||||
spi = spidev.SpiDev(1, 0) # lichee
|
||||
print("I'm on custom board!")
|
||||
|
||||
spi.max_speed_hz = 2000000
|
||||
|
||||
# fff = open("/dev/input/event1", "rb" )
|
||||
fff = open(sys.argv[1], "rb" )
|
||||
this_device = libevdev.Device(fff)
|
||||
# this_device.disable(libevdev.EV_MSC)
|
||||
|
||||
def keyboard_worker():
|
||||
print("keyboard_thread started")
|
||||
while 1:
|
||||
for e in this_device.events():
|
||||
spi.xfer([0x5]*32)
|
||||
print(e)
|
||||
|
||||
def mouse_worker():
|
||||
print("mouse_thread started")
|
||||
while 1:
|
||||
time.sleep(0.2)
|
||||
# print("sent")
|
||||
|
||||
keyboard_thread = threading.Thread(target=keyboard_worker, daemon=True)
|
||||
keyboard_thread.start()
|
||||
|
||||
mouse_thread = threading.Thread(target=mouse_worker, daemon=True)
|
||||
mouse_thread.start()
|
||||
|
||||
while 1:
|
||||
# print("main loop")
|
||||
time.sleep(1)
|
||||
@@ -1,16 +0,0 @@
|
||||
import time
|
||||
import sys
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
BUTTON_GPIO = 16
|
||||
|
||||
def button_pressed_callback(channel):
|
||||
print(time.time(), "Button pressed!")
|
||||
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
|
||||
GPIO.add_event_detect(BUTTON_GPIO, GPIO.FALLING, callback=button_pressed_callback, bouncetime=100)
|
||||
|
||||
while 1:
|
||||
time.sleep(1)
|
||||
@@ -1,15 +0,0 @@
|
||||
import time
|
||||
import sys
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
SLAVE_REQ_PIN = 16
|
||||
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(SLAVE_REQ_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
|
||||
GPIO.add_event_detect(SLAVE_REQ_PIN, GPIO.FALLING, bouncetime=100)
|
||||
|
||||
while 1:
|
||||
time.sleep(0.1)
|
||||
if GPIO.event_detected(SLAVE_REQ_PIN):
|
||||
print(time.time(), "Button pressed!")
|
||||
@@ -1,9 +0,0 @@
|
||||
echo 131 > /sys/class/gpio/unexport
|
||||
cat /proc/interrupts
|
||||
echo 131 > /sys/class/gpio/export
|
||||
echo in > /sys/class/gpio/gpio131/direction
|
||||
echo rising > /sys/class/gpio/gpio131/edge
|
||||
cat /proc/interrupts
|
||||
|
||||
# (letter in alfabet - 1) * 32 + number
|
||||
# PE3: (5-1) * 32 + 3 = 131
|
||||
@@ -1,116 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import spidev
|
||||
import threading
|
||||
|
||||
is_on_raspberry_pi = False
|
||||
with open('/etc/os-release') as os_version_file:
|
||||
is_on_raspberry_pi = 'raspbian' in os_version_file.read().lower()
|
||||
|
||||
spi = None
|
||||
if is_on_raspberry_pi:
|
||||
spi = spidev.SpiDev(0, 0) # rasp
|
||||
print("I'm on Raspberry Pi!")
|
||||
os.system("echo 16 > /sys/class/gpio/export")
|
||||
os.system("echo in > /sys/class/gpio/gpio16/direction")
|
||||
print("GPIO init done")
|
||||
else:
|
||||
spi = spidev.SpiDev(1, 0) # lichee
|
||||
print("I'm on custom board!")
|
||||
|
||||
spi.max_speed_hz = 2000000
|
||||
|
||||
keyboard_opened_device_dict = {}
|
||||
mouse_opened_device_dict = {}
|
||||
gamepad_opened_device_dict = {}
|
||||
|
||||
slave_ready_gpio_file = open("/sys/class/gpio/gpio16/value", 'rb')
|
||||
|
||||
"""
|
||||
def send kb
|
||||
|
||||
def send mouse
|
||||
|
||||
def send js
|
||||
|
||||
read data first, if exception, skip it
|
||||
"""
|
||||
|
||||
"""
|
||||
https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h#L38
|
||||
|
||||
xbox gamepad:
|
||||
EVENT TYPE: EV_ABS
|
||||
dpad: ABS_HAT0X ABS_HAT1X
|
||||
buttons: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h#L385
|
||||
sticks: ABS_X, ABS_Y, ABS_RX, ABS_RY
|
||||
"""
|
||||
|
||||
EV_KEY = 0x01
|
||||
EV_REL = 0x02
|
||||
EV_ABS = 0x03
|
||||
|
||||
SPI_MSG_KEYBOARD_EVENT = 1
|
||||
SPI_MSG_MOUSE_EVENT = 2
|
||||
SPI_MSG_GAMEPAD_EVENT = 3
|
||||
|
||||
keyboard_spi_msg_header = [0xde, 0, SPI_MSG_KEYBOARD_EVENT, 0]
|
||||
def raw_input_event_worker():
|
||||
print("raw_input_event_parser_thread started")
|
||||
to_delete = []
|
||||
while 1:
|
||||
for key in list(keyboard_opened_device_dict):
|
||||
try:
|
||||
data = keyboard_opened_device_dict[key][0].read(16)
|
||||
except OSError:
|
||||
keyboard_opened_device_dict[key][0].close()
|
||||
del keyboard_opened_device_dict[key]
|
||||
print("device disappeared:", key)
|
||||
if data is None:
|
||||
continue
|
||||
data = list(data[8:])
|
||||
if data[0] == EV_KEY:
|
||||
to_transfer = keyboard_spi_msg_header + data + [0]*20
|
||||
to_transfer[3] = keyboard_opened_device_dict[key][1]
|
||||
spi.xfer(to_transfer)
|
||||
print(time.time(), 'sent')
|
||||
# print(key)
|
||||
# print(to_transfer)
|
||||
# print('----')
|
||||
|
||||
raw_input_event_parser_thread = threading.Thread(target=raw_input_event_worker, daemon=True)
|
||||
raw_input_event_parser_thread.start()
|
||||
|
||||
input_device_path = '/dev/input/by-path/'
|
||||
|
||||
while 1:
|
||||
try:
|
||||
device_file_list = os.listdir(input_device_path)
|
||||
except Exception as e:
|
||||
print('list input device exception:', e)
|
||||
time.sleep(0.75)
|
||||
continue
|
||||
mouse_list = [os.path.join(input_device_path, x) for x in device_file_list if 'event-mouse' in x]
|
||||
keyboard_list = [os.path.join(input_device_path, x) for x in device_file_list if 'event-kbd' in x]
|
||||
gamepad_list = [os.path.join(input_device_path, x) for x in device_file_list if 'event-joystick' in x]
|
||||
# print(mouse_list)
|
||||
# print(keyboard_list)
|
||||
|
||||
for item in keyboard_list:
|
||||
if item not in keyboard_opened_device_dict:
|
||||
try:
|
||||
this_file = open(item, "rb")
|
||||
os.set_blocking(this_file.fileno(), False)
|
||||
kb_index = 0
|
||||
try:
|
||||
kb_index = sum([int(x) for x in item.split(':')[1].split('.')][:2])
|
||||
except:
|
||||
pass
|
||||
keyboard_opened_device_dict[item] = (this_file, kb_index)
|
||||
print("opened keyboard", keyboard_opened_device_dict[item][1], ':' , item)
|
||||
except Exception as e:
|
||||
print("keyboard open exception:", e)
|
||||
continue
|
||||
|
||||
time.sleep(0.75)
|
||||
@@ -1,244 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import select
|
||||
import spidev
|
||||
import threading
|
||||
|
||||
is_on_raspberry_pi = False
|
||||
with open('/etc/os-release') as os_version_file:
|
||||
is_on_raspberry_pi = 'raspbian' in os_version_file.read().lower()
|
||||
|
||||
spi = None
|
||||
gpio_file = None
|
||||
|
||||
if is_on_raspberry_pi:
|
||||
spi = spidev.SpiDev(0, 0) # rasp
|
||||
print("I'm on Raspberry Pi!")
|
||||
os.system("echo 16 > /sys/class/gpio/export")
|
||||
os.system("echo in > /sys/class/gpio/gpio16/direction")
|
||||
os.system("echo rising > /sys/class/gpio/gpio16/edge")
|
||||
gpio_file = open("/sys/class/gpio/gpio16/value", 'rb')
|
||||
print("GPIO init done")
|
||||
else:
|
||||
spi = spidev.SpiDev(0, 0) # lichee
|
||||
print("I'm on custom board!")
|
||||
print("DONT FORGET TO RUN gpio_setup.sh!")
|
||||
gpio_file = open("/sys/class/gpio/gpio131/value", 'rb')
|
||||
|
||||
spi.max_speed_hz = 2000000
|
||||
|
||||
keyboard_opened_device_dict = {}
|
||||
mouse_opened_device_dict = {}
|
||||
gamepad_opened_device_dict = {}
|
||||
|
||||
|
||||
epoll = select.epoll()
|
||||
epoll.register(gpio_file, select.EPOLLET)
|
||||
|
||||
"""
|
||||
def send kb
|
||||
|
||||
def send mouse
|
||||
|
||||
def send js
|
||||
|
||||
read data first, if exception, skip it
|
||||
"""
|
||||
|
||||
"""
|
||||
https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h#L38
|
||||
|
||||
xbox gamepad:
|
||||
EVENT TYPE: EV_ABS
|
||||
dpad: ABS_HAT0X ABS_HAT1X
|
||||
buttons: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h#L385
|
||||
sticks: ABS_X, ABS_Y, ABS_RX, ABS_RY
|
||||
"""
|
||||
|
||||
# https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
|
||||
EV_SYN = 0
|
||||
EV_KEY = 1
|
||||
EV_REL = 2
|
||||
EV_ABS = 3
|
||||
|
||||
SYN_REPORT = 0
|
||||
|
||||
REL_X = 0x00
|
||||
REL_Y = 0x01
|
||||
REL_WHEEL = 0x08
|
||||
|
||||
SPI_BUF_INDEX_MAGIC = 0
|
||||
SPI_BUF_INDEX_SEQNUM = 1
|
||||
SPI_BUF_INDEX_MSG_TYPE = 2
|
||||
|
||||
SPI_MOSI_MSG_KEYBOARD_EVENT = 1
|
||||
SPI_MOSI_MSG_MOUSE_EVENT = 2
|
||||
SPI_MOSI_MSG_GAMEPAD_EVENT = 3
|
||||
SPI_MOSI_MSG_REQ_ACK = 4
|
||||
|
||||
SPI_MISO_MSG_INFO_REPLY = 0
|
||||
SPI_MISO_MSG_KB_LED_REQ = 1
|
||||
|
||||
SPI_MOSI_MAGIC = 0xde
|
||||
SPI_MISO_MAGIC = 0xcd
|
||||
|
||||
keyboard_spi_msg_header = [SPI_MOSI_MAGIC, 0, SPI_MOSI_MSG_KEYBOARD_EVENT, 0]
|
||||
mouse_spi_msg_template = [SPI_MOSI_MAGIC, 0, SPI_MOSI_MSG_MOUSE_EVENT, 0] + [0]*28
|
||||
|
||||
def make_spi_msg_ack():
|
||||
return [SPI_MOSI_MAGIC, 0, SPI_MOSI_MSG_REQ_ACK] + [0]*29
|
||||
|
||||
led_device_path = '/sys/class/leds'
|
||||
|
||||
def get_01(value):
|
||||
if value:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def change_kb_led(ps2kb_led_byte):
|
||||
led_file_list = os.listdir(led_device_path)
|
||||
capslock_list = [os.path.join(led_device_path, x) for x in led_file_list if 'capslock' in x]
|
||||
numlock_list = [os.path.join(led_device_path, x) for x in led_file_list if 'numlock' in x]
|
||||
scrolllock_list = [os.path.join(led_device_path, x) for x in led_file_list if 'scrolllock' in x]
|
||||
|
||||
for item in scrolllock_list:
|
||||
if is_on_raspberry_pi:
|
||||
os.system(f"sudo bash -c 'echo {get_01(ps2kb_led_byte & 0x1)} > {os.path.join(item, 'brightness')}'")
|
||||
else:
|
||||
os.system(f"echo {get_01(ps2kb_led_byte & 0x1)} > {os.path.join(item, 'brightness')}")
|
||||
|
||||
for item in numlock_list:
|
||||
if is_on_raspberry_pi:
|
||||
os.system(f"sudo bash -c 'echo {get_01(ps2kb_led_byte & 0x2)} > {os.path.join(item, 'brightness')}'")
|
||||
else:
|
||||
os.system(f"echo {get_01(ps2kb_led_byte & 0x2)} > {os.path.join(item, 'brightness')}")
|
||||
|
||||
for item in capslock_list:
|
||||
if is_on_raspberry_pi:
|
||||
os.system(f"sudo bash -c 'echo {get_01(ps2kb_led_byte & 0x4)} > {os.path.join(item, 'brightness')}'")
|
||||
else:
|
||||
os.system(f"echo {get_01(ps2kb_led_byte & 0x4)} > {os.path.join(item, 'brightness')}")
|
||||
|
||||
|
||||
def raw_input_event_worker():
|
||||
mouse_spi_packet_dict = {}
|
||||
mouse_button_state_list = [0] * 5
|
||||
print("raw_input_event_parser_thread started")
|
||||
while 1:
|
||||
for key in list(keyboard_opened_device_dict):
|
||||
try:
|
||||
data = keyboard_opened_device_dict[key][0].read(16)
|
||||
except OSError:
|
||||
keyboard_opened_device_dict[key][0].close()
|
||||
del keyboard_opened_device_dict[key]
|
||||
print("keyboard disappeared:", key)
|
||||
if data is None:
|
||||
continue
|
||||
data = list(data[8:])
|
||||
if data[0] == EV_KEY:
|
||||
to_transfer = keyboard_spi_msg_header + data + [0]*20
|
||||
to_transfer[3] = keyboard_opened_device_dict[key][1]
|
||||
spi.xfer(to_transfer)
|
||||
|
||||
for key in list(mouse_opened_device_dict):
|
||||
try:
|
||||
data = mouse_opened_device_dict[key][0].read(16)
|
||||
except OSError:
|
||||
mouse_opened_device_dict[key][0].close()
|
||||
del mouse_opened_device_dict[key]
|
||||
print("mouse disappeared:", key)
|
||||
if data is None:
|
||||
continue
|
||||
data = list(data[8:])
|
||||
# print(data)
|
||||
if data[0] == EV_REL:
|
||||
if data[2] == REL_X:
|
||||
mouse_spi_packet_dict["x"] = data[4:6]
|
||||
if data[2] == REL_Y:
|
||||
mouse_spi_packet_dict["y"] = data[4:6]
|
||||
if data[2] == REL_WHEEL:
|
||||
mouse_spi_packet_dict["scroll"] = data[4:6]
|
||||
if data[0] == EV_KEY:
|
||||
mouse_button_state_list[data[2]-16] = data[4]
|
||||
to_transfer = list(mouse_spi_msg_template)
|
||||
to_transfer[10:13] = data[2:5]
|
||||
to_transfer[13:18] = mouse_button_state_list[:]
|
||||
to_transfer[3] = mouse_opened_device_dict[key][1]
|
||||
spi.xfer(to_transfer)
|
||||
|
||||
if data[0] == EV_SYN and data[2] == SYN_REPORT and len(mouse_spi_packet_dict) > 0:
|
||||
to_transfer = list(mouse_spi_msg_template)
|
||||
if 'x' in mouse_spi_packet_dict:
|
||||
to_transfer[4:6] = mouse_spi_packet_dict['x']
|
||||
if 'y' in mouse_spi_packet_dict:
|
||||
to_transfer[6:8] = mouse_spi_packet_dict['y']
|
||||
if 'scroll' in mouse_spi_packet_dict:
|
||||
to_transfer[8:10] = mouse_spi_packet_dict['scroll']
|
||||
to_transfer[13:18] = mouse_button_state_list[:]
|
||||
to_transfer[3] = mouse_opened_device_dict[key][1]
|
||||
mouse_spi_packet_dict.clear()
|
||||
spi.xfer(to_transfer)
|
||||
|
||||
events = epoll.poll(timeout=0)
|
||||
for df, event_type in events:
|
||||
if 0x8 & event_type:
|
||||
slave_result = None
|
||||
for x in range(2):
|
||||
slave_result = spi.xfer(make_spi_msg_ack())
|
||||
print(slave_result)
|
||||
if slave_result[SPI_BUF_INDEX_MAGIC] == SPI_MISO_MAGIC and slave_result[SPI_BUF_INDEX_MSG_TYPE] == SPI_MISO_MSG_KB_LED_REQ:
|
||||
change_kb_led(slave_result[3])
|
||||
change_kb_led(slave_result[3])
|
||||
|
||||
raw_input_event_parser_thread = threading.Thread(target=raw_input_event_worker, daemon=True)
|
||||
raw_input_event_parser_thread.start()
|
||||
|
||||
input_device_path = '/dev/input/by-path/'
|
||||
|
||||
while 1:
|
||||
try:
|
||||
device_file_list = os.listdir(input_device_path)
|
||||
except Exception as e:
|
||||
print('list input device exception:', e)
|
||||
time.sleep(0.75)
|
||||
continue
|
||||
mouse_list = [os.path.join(input_device_path, x) for x in device_file_list if 'event-mouse' in x]
|
||||
keyboard_list = [os.path.join(input_device_path, x) for x in device_file_list if 'event-kbd' in x]
|
||||
gamepad_list = [os.path.join(input_device_path, x) for x in device_file_list if 'event-joystick' in x]
|
||||
# print(mouse_list)
|
||||
# print(keyboard_list)
|
||||
|
||||
for item in keyboard_list:
|
||||
if item not in keyboard_opened_device_dict:
|
||||
try:
|
||||
this_file = open(item, "rb")
|
||||
os.set_blocking(this_file.fileno(), False)
|
||||
device_index = 0
|
||||
try:
|
||||
device_index = sum([int(x) for x in item.split(':')[1].split('.')][:2])
|
||||
except:
|
||||
pass
|
||||
keyboard_opened_device_dict[item] = (this_file, device_index)
|
||||
print("opened keyboard", keyboard_opened_device_dict[item][1], ':' , item)
|
||||
except Exception as e:
|
||||
print("keyboard open exception:", e)
|
||||
continue
|
||||
|
||||
for item in mouse_list:
|
||||
if item not in mouse_opened_device_dict:
|
||||
try:
|
||||
this_file = open(item, "rb")
|
||||
os.set_blocking(this_file.fileno(), False)
|
||||
device_index = 0
|
||||
try:
|
||||
device_index = sum([int(x) for x in item.split(':')[1].split('.')][:2])
|
||||
except:
|
||||
pass
|
||||
mouse_opened_device_dict[item] = (this_file, device_index)
|
||||
print("opened mouse", mouse_opened_device_dict[item][1], ':' , item)
|
||||
except Exception as e:
|
||||
print("mouse open exception:", e)
|
||||
continue
|
||||
|
||||
time.sleep(0.75)
|
||||
@@ -1,29 +0,0 @@
|
||||
import os
|
||||
|
||||
dev_path = '/proc/bus/input/devices'
|
||||
|
||||
if 'nt' in os.name:
|
||||
dev_path = 'devices.txt'
|
||||
|
||||
dev_file = open(dev_path)
|
||||
file_content = dev_file.readlines()
|
||||
dev_file.close()
|
||||
|
||||
current_line_num = 0
|
||||
max_lines = len(file_content)
|
||||
|
||||
while current_line_num < max_lines:
|
||||
this_line = file_content[current_line_num]
|
||||
|
||||
if this_line.startswith('I: '):
|
||||
print("-------- New block! --------")
|
||||
while len(this_line) != 1:
|
||||
current_line_num += 1
|
||||
if current_line_num >= max_lines:
|
||||
print("-------- EOF --------")
|
||||
break
|
||||
this_line = file_content[current_line_num]
|
||||
print(this_line)
|
||||
print("-------- Block end --------")
|
||||
|
||||
current_line_num += 1
|
||||
@@ -1,30 +0,0 @@
|
||||
import sys
|
||||
import spidev
|
||||
import time
|
||||
|
||||
is_on_raspberry_pi = False
|
||||
|
||||
with open('/etc/os-release') as os_version_file:
|
||||
is_on_raspberry_pi = 'raspbian' in os_version_file.read().lower()
|
||||
|
||||
spi = None
|
||||
if is_on_raspberry_pi:
|
||||
spi = spidev.SpiDev(0, 0) # rasp
|
||||
print("I'm on Raspberry Pi!")
|
||||
else:
|
||||
spi = spidev.SpiDev(1, 0) # lichee
|
||||
print("I'm on custom board!")
|
||||
|
||||
spi.max_speed_hz = 2000000
|
||||
|
||||
EV_SYN = 0
|
||||
EV_KEY = 1
|
||||
EV_REL = 2
|
||||
EV_ABS = 3
|
||||
|
||||
fff = open(sys.argv[1], "rb" )
|
||||
while 1:
|
||||
data = list(fff.read(16))
|
||||
print(data)
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# import sys
|
||||
import time
|
||||
import queue
|
||||
import spidev
|
||||
import threading
|
||||
|
||||
is_on_raspberry_pi = False
|
||||
|
||||
with open('/etc/os-release') as os_version_file:
|
||||
is_on_raspberry_pi = 'raspbian' in os_version_file.read().lower()
|
||||
|
||||
spi = None
|
||||
if is_on_raspberry_pi:
|
||||
spi = spidev.SpiDev(0, 0) # rasp
|
||||
print("I'm on Raspberry Pi!")
|
||||
else:
|
||||
spi = spidev.SpiDev(1, 0) # lichee
|
||||
print("I'm on custom board!")
|
||||
|
||||
spi.max_speed_hz = 500000
|
||||
MAX_SPI_QUEUE_SIZE = 32
|
||||
spi_out_queue = queue.Queue(maxsize=MAX_SPI_QUEUE_SIZE)
|
||||
|
||||
# sys.setswitchinterval(0.005)
|
||||
|
||||
fff = open("/dev/input/event0", "rb" )
|
||||
|
||||
|
||||
def keyboard_worker():
|
||||
print("keyboard_thread started")
|
||||
while 1:
|
||||
data = fff.read(24)
|
||||
data = list(data)
|
||||
try:
|
||||
spi_out_queue.put(data, block=False)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
def spi_worker():
|
||||
print("spi_thread started")
|
||||
while 1:
|
||||
spi.xfer(spi_out_queue.get())
|
||||
# print("sent")
|
||||
|
||||
keyboard_thread = threading.Thread(target=keyboard_worker, daemon=True)
|
||||
keyboard_thread.start()
|
||||
|
||||
spi_thread = threading.Thread(target=spi_worker, daemon=True)
|
||||
spi_thread.start()
|
||||
|
||||
while 1:
|
||||
# print("main loop")
|
||||
time.sleep(1)
|
||||
@@ -1,2 +0,0 @@
|
||||
import sys
|
||||
import time
|
||||
@@ -1,53 +0,0 @@
|
||||
# https://luma-oled.readthedocs.io/en/latest/software.html
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from demo_opts import get_device
|
||||
from luma.core.render import canvas
|
||||
from PIL import ImageFont
|
||||
import json
|
||||
|
||||
OLED_WIDTH = 128
|
||||
OLED_HEIGHT = 32
|
||||
|
||||
my_arg = ['--display', 'ssd1306', '--interface', 'spi', '--spi-port', '0', '--spi-device', '1', '--gpio-reset', '6', '--gpio-data-command', '5', '--width', str(OLED_WIDTH), '--height', str(OLED_HEIGHT), '--spi-bus-speed', '2000000']
|
||||
oled_device = get_device(my_arg)
|
||||
|
||||
|
||||
font_regular = ImageFont.truetype("ProggyTiny.ttf", 16)
|
||||
font_medium = ImageFont.truetype("ChiKareGo2.ttf", 16)
|
||||
font_large = ImageFont.truetype("ProggyTiny.ttf", 32)
|
||||
|
||||
max_char_per_line = {font_regular:21, font_medium:17, font_large:11}
|
||||
width_per_char = {font_regular:6, font_medium:7, font_large:12}
|
||||
|
||||
def oled_print_centered(text, font, y, this_canvas):
|
||||
text = text.strip()[:max_char_per_line[font]]
|
||||
start_x = int((OLED_WIDTH - (len(text) * width_per_char[font]))/2)
|
||||
if start_x < 0:
|
||||
start_x = 0
|
||||
this_canvas.text((start_x, y), text, font=font, fill="white")
|
||||
|
||||
curve_vertial_axis_x_pos = 80
|
||||
curve_horizontal_axis_width = 32
|
||||
|
||||
linear_curve = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23, 24: 24, 25: 25, 26: 26, 27: 27, 28: 28, 29: 29, 30: 30, 31: 31, 32: 32, 33: 33, 34: 34, 35: 35, 36: 36, 37: 37, 38: 38, 39: 39, 40: 40, 41: 41, 42: 42, 43: 43, 44: 44, 45: 45, 46: 46, 47: 47, 48: 48, 49: 49, 50: 50, 51: 51, 52: 52, 53: 53, 54: 54, 55: 55, 56: 56, 57: 57, 58: 58, 59: 59, 60: 60, 61: 61, 62: 62, 63: 63, 64: 64, 65: 65, 66: 66, 67: 67, 68: 68, 69: 69, 70: 70, 71: 71, 72: 72, 73: 73, 74: 74, 75: 75, 76: 76, 77: 77, 78: 78, 79: 79, 80: 80, 81: 81, 82: 82, 83: 83, 84: 84, 85: 85, 86: 86, 87: 87, 88: 88, 89: 89, 90: 90, 91: 91, 92: 92, 93: 93, 94: 94, 95: 95, 96: 96, 97: 97, 98: 98, 99: 99, 100: 100, 101: 101, 102: 102, 103: 103, 104: 104, 105: 105, 106: 106, 107: 107, 108: 108, 109: 109, 110: 110, 111: 111, 112: 112, 113: 113, 114: 114, 115: 115, 116: 116, 117: 117, 118: 118, 119: 119, 120: 120, 121: 121, 122: 122, 123: 123, 124: 124, 125: 125, 126: 126, 127: 127}
|
||||
mid_curve = {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 2, 10: 2, 11: 2, 12: 2, 13: 2, 14: 3, 15: 3, 16: 3, 17: 3, 18: 3, 19: 4, 20: 4, 21: 4, 22: 4, 23: 5, 24: 5, 25: 5, 26: 5, 27: 6, 28: 6, 29: 6, 30: 6, 31: 7, 32: 7, 33: 7, 34: 8, 35: 8, 36: 8, 37: 9, 38: 9, 39: 9, 40: 10, 41: 10, 42: 10, 43: 11, 44: 11, 45: 12, 46: 12, 47: 12, 48: 13, 49: 13, 50: 14, 51: 14, 52: 14, 53: 15, 54: 15, 55: 16, 56: 16, 57: 17, 58: 17, 59: 18, 60: 18, 61: 19, 62: 20, 63: 20, 64: 21, 65: 21, 66: 22, 67: 23, 68: 23, 69: 24, 70: 25, 71: 25, 72: 26, 73: 27, 74: 28, 75: 29, 76: 30, 77: 31, 78: 32, 79: 33, 80: 34, 81: 35, 82: 36, 83: 37, 84: 38, 85: 39, 86: 40, 87: 42, 88: 43, 89: 44, 90: 45, 91: 47, 92: 48, 93: 50, 94: 51, 95: 52, 96: 54, 97: 56, 98: 57, 99: 59, 100: 60, 101: 62, 102: 64, 103: 66, 104: 67, 105: 69, 106: 71, 107: 73, 108: 75, 109: 77, 110: 79, 111: 81, 112: 83, 113: 86, 114: 88, 115: 90, 116: 93, 117: 95, 118: 98, 119: 101, 120: 103, 121: 106, 122: 110, 123: 112, 124: 116, 125: 119, 126: 122, 127: 126}
|
||||
curve3 = {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1, 11: 1, 12: 1, 13: 1, 14: 1, 15: 1, 16: 1, 17: 1, 18: 2, 19: 2, 20: 2, 21: 2, 22: 2, 23: 2, 24: 2, 25: 2, 26: 2, 27: 3, 28: 3, 29: 3, 30: 3, 31: 3, 32: 3, 33: 4, 34: 4, 35: 4, 36: 4, 37: 4, 38: 5, 39: 5, 40: 5, 41: 5, 42: 5, 43: 6, 44: 6, 45: 6, 46: 6, 47: 7, 48: 7, 49: 7, 50: 8, 51: 8, 52: 8, 53: 8, 54: 9, 55: 9, 56: 10, 57: 10, 58: 10, 59: 11, 60: 11, 61: 11, 62: 12, 63: 12, 64: 13, 65: 13, 66: 14, 67: 14, 68: 15, 69: 15, 70: 16, 71: 16, 72: 17, 73: 17, 74: 18, 75: 19, 76: 19, 77: 20, 78: 21, 79: 22, 80: 23, 81: 23, 82: 24, 83: 25, 84: 26, 85: 27, 86: 29, 87: 30, 88: 31, 89: 32, 90: 33, 91: 34, 92: 36, 93: 37, 94: 38, 95: 40, 96: 41, 97: 43, 98: 44, 99: 46, 100: 48, 101: 49, 102: 51, 103: 53, 104: 55, 105: 57, 106: 59, 107: 61, 108: 63, 109: 65, 110: 67, 111: 69, 112: 72, 113: 74, 114: 77, 115: 79, 116: 82, 117: 85, 118: 88, 119: 92, 120: 94, 121: 99, 122: 101, 123: 105, 124: 110, 125: 114, 126: 118, 127: 126}
|
||||
|
||||
joystick_curve_list = [linear_curve, mid_curve, curve3]
|
||||
|
||||
with canvas(oled_device) as draw:
|
||||
draw.text((0, 0), "Joystick", font=font_medium, fill="white")
|
||||
draw.text((0, 15), "Curve", font=font_medium, fill="white")
|
||||
draw.line((curve_vertial_axis_x_pos, 0, curve_vertial_axis_x_pos, curve_vertial_axis_x_pos), fill="white")
|
||||
draw.line((curve_vertial_axis_x_pos, 31, curve_vertial_axis_x_pos+curve_horizontal_axis_width, 31), fill="white")
|
||||
for xxx in range(curve_horizontal_axis_width):
|
||||
dict_key = xxx*4
|
||||
this_point_x = xxx + curve_vertial_axis_x_pos
|
||||
this_point_y = OLED_HEIGHT - linear_curve[dict_key]//4 - 1
|
||||
print(this_point_x, this_point_y)
|
||||
draw.line((this_point_x,this_point_y,this_point_x,this_point_y), fill="white")
|
||||
while 1:
|
||||
time.sleep(1)
|
||||
@@ -1,96 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import serial
|
||||
import subprocess
|
||||
import base64
|
||||
import threading
|
||||
|
||||
import usb4vc_shared
|
||||
# import usb4vc_usb_scan
|
||||
# import usb4vc_ui
|
||||
|
||||
ser = None
|
||||
try:
|
||||
ser = serial.Serial('/dev/serial0', 115200)
|
||||
except Exception as e:
|
||||
print("SERIAL OPEN EXCEPTION:", e)
|
||||
|
||||
def uart_worker():
|
||||
if ser is None:
|
||||
return
|
||||
while 1:
|
||||
received = ser.readline().decode().replace('\r', '').replace('\n', '')
|
||||
# print("I received:", received)
|
||||
line_split = received.split(' ', maxsplit=2)
|
||||
if len(line_split) < 2:
|
||||
continue
|
||||
magic = line_split[0]
|
||||
cmd_type = line_split[1]
|
||||
payload = line_split[-1]
|
||||
|
||||
if magic != 'U4':
|
||||
continue
|
||||
|
||||
if cmd_type == "QUIT":
|
||||
exit()
|
||||
|
||||
# read file
|
||||
if cmd_type == 'RF':
|
||||
file_path = line_split[-1].strip()
|
||||
content = None
|
||||
try:
|
||||
with open(file_path, 'rb') as myfile:
|
||||
content = myfile.read()
|
||||
except Exception as e:
|
||||
ser.write(f"U4 ERR {e}\n".encode('utf-8'))
|
||||
continue
|
||||
base64_bytes = base64.standard_b64encode(content)
|
||||
base64_message = base64_bytes.decode('utf-8')
|
||||
ser.write(f"U4 OK {base64_message}\n".encode('utf-8'))
|
||||
|
||||
# write file
|
||||
if cmd_type == 'WF':
|
||||
wf_args = payload.split(' ', maxsplit=2)
|
||||
if len(wf_args) < 2:
|
||||
ser.write("U4 ERR missing file content\n".encode('utf-8'))
|
||||
continue
|
||||
file_path = wf_args[0].strip()
|
||||
base64_message = wf_args[1].strip()
|
||||
try:
|
||||
base64_bytes = base64.standard_b64decode(base64_message)
|
||||
with open(file_path, 'wb') as myfile:
|
||||
myfile.write(base64_bytes)
|
||||
ser.write("U4 OK\n".encode('utf-8'))
|
||||
except Exception as e:
|
||||
ser.write(f"U4 ERR {e}\n".encode('utf-8'))
|
||||
continue
|
||||
|
||||
# delete file
|
||||
if cmd_type == 'DF':
|
||||
file_path = line_split[-1].strip()
|
||||
try:
|
||||
os.remove(file_path)
|
||||
except Exception as e:
|
||||
ser.write(f"U4 ERR {e}\n".encode('utf-8'))
|
||||
continue
|
||||
ser.write("U4 OK\n".encode('utf-8'))
|
||||
|
||||
if cmd_type == 'SC':
|
||||
try:
|
||||
shell_result = subprocess.getoutput(payload).strip()
|
||||
base64_bytes = base64.standard_b64encode(shell_result.encode('utf-8'))
|
||||
base64_message = base64_bytes.decode('utf-8')
|
||||
ser.write(f"U4 OK {base64_message}\n".encode('utf-8'))
|
||||
except Exception as e:
|
||||
ser.write(f"U4 ERR {e}\n".encode('utf-8'))
|
||||
continue
|
||||
|
||||
if cmd_type == 'INFO':
|
||||
try:
|
||||
ser.write(f"U4 OK USB4VC RPi App v{usb4vc_shared.RPI_APP_VERSION_TUPLE[0]}.{usb4vc_shared.RPI_APP_VERSION_TUPLE[1]}.{usb4vc_shared.RPI_APP_VERSION_TUPLE[2]} dekuNukem 2022\n".encode('utf-8'))
|
||||
except Exception as e:
|
||||
ser.write(f"U4 ERR {e}\n".encode('utf-8'))
|
||||
continue
|
||||
|
||||
uart_thread = threading.Thread(target=uart_worker, daemon=True)
|
||||
@@ -108,25 +108,116 @@ PID_GENERIC_GAMEPORT_GAMEPAD = 7
|
||||
PID_BBC_MICRO_JOYSTICK = 14
|
||||
PID_RAW_USB_GAMEPAD = 127
|
||||
|
||||
devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
|
||||
# devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
|
||||
|
||||
for device in devices:
|
||||
print(device.path, device.name, device.phys)
|
||||
# for device in devices:
|
||||
# print(device.path, device.name, device.phys)
|
||||
|
||||
# import asyncio, evdev
|
||||
|
||||
# mouse = evdev.InputDevice('/dev/input/event0')
|
||||
# keybd = evdev.InputDevice('/dev/input/event6')
|
||||
|
||||
# mouse = evdev.InputDevice('/dev/input/event4')
|
||||
# keybd = evdev.InputDevice('/dev/input/event1')
|
||||
|
||||
# async def print_events(device):
|
||||
# async for event in device.async_read_loop():
|
||||
# empty = list(keyboard_event_spi_msg_template)
|
||||
# xfer_when_not_busy(empty)
|
||||
# # empty = list(keyboard_event_spi_msg_template)
|
||||
# # xfer_when_not_busy(empty)
|
||||
# print(device.path, evdev.categorize(event), sep=': ')
|
||||
|
||||
# for device in mouse, keybd:
|
||||
# asyncio.ensure_future(print_events(device))
|
||||
|
||||
# loop = asyncio.get_event_loop()
|
||||
# loop.run_forever()
|
||||
# loop.run_forever()
|
||||
|
||||
|
||||
import asyncio
|
||||
import evdev
|
||||
from evdev import categorize
|
||||
|
||||
POLL_INTERVAL_SEC = 1.0 # how often we rescan for devices
|
||||
|
||||
async def read_device_events(path: str):
|
||||
"""
|
||||
Open a single device and print its events until it goes away
|
||||
(or this task is cancelled).
|
||||
"""
|
||||
dev = None
|
||||
try:
|
||||
dev = evdev.InputDevice(path)
|
||||
# Announce the device
|
||||
print(f"[attach] {path} — name='{dev.name}' phys='{dev.phys}'")
|
||||
|
||||
# Async loop over input events
|
||||
async for event in dev.async_read_loop():
|
||||
# Skip non-value events if you want; here we show everything
|
||||
print(f"!!!!!!!!!!!!!!! {path}: {categorize(event)}")
|
||||
empty = list(keyboard_event_spi_msg_template)
|
||||
xfer_when_not_busy(empty)
|
||||
|
||||
|
||||
except (FileNotFoundError, OSError) as e:
|
||||
# Common when the device is unplugged (e.g. [Errno 19] No such device)
|
||||
print(f"[disconnect] {path}: {e}")
|
||||
except asyncio.CancelledError:
|
||||
# We were asked to stop (e.g. device disappeared or program exiting)
|
||||
raise
|
||||
finally:
|
||||
if dev is not None:
|
||||
try:
|
||||
dev.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
ignored_hid_device_name = ['pwr_button', 'hdmi', 'motion']
|
||||
|
||||
def is_ignored_device(dev_path):
|
||||
dev_name = evdev.InputDevice(dev_path).name.lower()
|
||||
for item in ignored_hid_device_name:
|
||||
if item.lower() in dev_name:
|
||||
return True
|
||||
return False
|
||||
|
||||
async def watch_all_devices():
|
||||
"""
|
||||
Periodically rescan /dev/input for devices, starting and stopping
|
||||
per-device reader tasks as paths appear/disappear.
|
||||
"""
|
||||
tasks: dict[str, asyncio.Task] = {}
|
||||
known_paths: set[str] = set()
|
||||
|
||||
while True:
|
||||
try:
|
||||
current_paths = set([x for x in evdev.list_devices() if is_ignored_device(x) is False])
|
||||
except Exception as e:
|
||||
# Very rare, but if listing fails, keep previous state and retry
|
||||
print(f"[warn] list_devices failed: {e}")
|
||||
current_paths = known_paths
|
||||
|
||||
# New devices -> start a reader task
|
||||
for path in current_paths - known_paths:
|
||||
tasks[path] = asyncio.create_task(read_device_events(path))
|
||||
|
||||
# Removed devices -> cancel the reader task (if still running)
|
||||
for path in known_paths - current_paths:
|
||||
print(f"[detach] {path}")
|
||||
task = tasks.pop(path, None)
|
||||
if task is not None and not task.done():
|
||||
task.cancel()
|
||||
|
||||
known_paths = current_paths
|
||||
await asyncio.sleep(POLL_INTERVAL_SEC)
|
||||
|
||||
async def main():
|
||||
# Kick off the watcher; it will create per-device reader tasks
|
||||
watcher = asyncio.create_task(watch_all_devices())
|
||||
try:
|
||||
await watcher
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except KeyboardInterrupt:
|
||||
print("\n[exit] keyboard interrupt")
|
||||
|
||||
@@ -84,7 +84,7 @@ usb4vc_ui.ui_init()
|
||||
usb4vc_ui.ui_thread.start()
|
||||
|
||||
usb4vc_usb_scan.usb_device_scan_thread.start()
|
||||
usb4vc_usb_scan.raw_input_event_parser_thread.start()
|
||||
# usb4vc_usb_scan.raw_input_event_parser_thread.start()
|
||||
|
||||
while 1:
|
||||
time.sleep(2)
|
||||
|
||||
@@ -35,8 +35,6 @@ GPIO.setup(PCARD_BUSY_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||
pcard_spi = spidev.SpiDev(0, 0)
|
||||
pcard_spi.max_speed_hz = 2000000
|
||||
|
||||
opened_device_dict = {}
|
||||
|
||||
led_device_path = '/sys/class/leds'
|
||||
input_device_path = '/dev/input/by-path/'
|
||||
|
||||
@@ -741,137 +739,6 @@ def multiply_round_up_0(number, multi):
|
||||
new_number = -1
|
||||
return int(new_number)
|
||||
|
||||
USB_GAMEPAD_STICK_AXES_NAMES = ["ABS_X", "ABS_Y", "ABS_RX", "ABS_RY"]
|
||||
|
||||
gamepad_status_dict = {}
|
||||
gamepad_hold_check_interval = 0.02
|
||||
def raw_input_event_worker():
|
||||
last_usb_event = 0
|
||||
mouse_status_dict = {'x': [0, 0], 'y': [0, 0], 'scroll': 0, 'hscroll': 0, BTN_LEFT:0, BTN_RIGHT:0, BTN_MIDDLE:0, BTN_SIDE:0, BTN_EXTRA:0, BTN_FORWARD:0, BTN_BACK:0, BTN_TASK:0}
|
||||
next_gamepad_hold_check = time.time() + gamepad_hold_check_interval
|
||||
last_mouse_msg = []
|
||||
last_gamepad_msg = None
|
||||
last_mouse_button_msg = None
|
||||
print("raw_input_event_worker started")
|
||||
while 1:
|
||||
now = time.time()
|
||||
if now > next_gamepad_hold_check:
|
||||
joystick_hold_update()
|
||||
next_gamepad_hold_check = now + gamepad_hold_check_interval
|
||||
|
||||
# give other threads some breathing room if
|
||||
# no USB input events
|
||||
if now - last_usb_event > 1:
|
||||
time.sleep(0.005)
|
||||
|
||||
for key in list(opened_device_dict):
|
||||
this_device = opened_device_dict[key]
|
||||
this_id = this_device['id']
|
||||
try:
|
||||
data = this_device['file'].read(16)
|
||||
except OSError:
|
||||
print("Device disappeared:", this_device['name'])
|
||||
this_device['file'].close()
|
||||
del opened_device_dict[key]
|
||||
continue
|
||||
if data is None:
|
||||
continue
|
||||
|
||||
usb4vc_ui.my_oled.kick()
|
||||
last_usb_event = now
|
||||
|
||||
if this_device['is_gp'] and this_id not in gamepad_status_dict:
|
||||
gamepad_status_dict[this_id] = {}
|
||||
|
||||
data = list(data[8:])
|
||||
event_code = data[3] * 256 + data[2]
|
||||
|
||||
# event is a key press
|
||||
if data[0] == EV_KEY:
|
||||
# keyboard keys
|
||||
if 0x1 <= event_code <= 248 and event_code not in gamepad_buttons_as_kb_codes:
|
||||
xfer_when_not_busy(make_keyboard_spi_packet(data, this_id))
|
||||
# Mouse buttons
|
||||
elif 0x110 <= event_code <= 0x117:
|
||||
mouse_status_dict[event_code] = data[4]
|
||||
next_gamepad_hold_check = now + gamepad_hold_check_interval
|
||||
if data[4] != 2:
|
||||
clear_mouse_movement(mouse_status_dict)
|
||||
last_mouse_button_msg = make_mouse_spi_packet(mouse_status_dict, this_id)
|
||||
xfer_when_not_busy(list(last_mouse_button_msg))
|
||||
# Gamepad buttons
|
||||
elif is_gamepad_button(event_code) or event_code in gamepad_buttons_as_kb_codes:
|
||||
this_btn_status = data[4]
|
||||
if this_btn_status != 0:
|
||||
this_btn_status = 1
|
||||
gamepad_status_dict[this_id][event_code] = this_btn_status
|
||||
|
||||
# event is relative axes AKA mouse
|
||||
elif data[0] == EV_REL and event_code == REL_X:
|
||||
rawx = int.from_bytes(data[4:6], byteorder='little', signed=True)
|
||||
rawx = multiply_round_up_0(rawx, usb4vc_ui.get_mouse_sensitivity()) & 0xffff
|
||||
mouse_status_dict["x"] = list(rawx.to_bytes(2, byteorder='little'))
|
||||
elif data[0] == EV_REL and event_code == REL_Y:
|
||||
rawy = int.from_bytes(data[4:6], byteorder='little', signed=True)
|
||||
rawy = multiply_round_up_0(rawy, usb4vc_ui.get_mouse_sensitivity()) & 0xffff
|
||||
mouse_status_dict["y"] = list(rawy.to_bytes(2, byteorder='little'))
|
||||
elif data[0] == EV_REL and event_code == REL_WHEEL:
|
||||
mouse_status_dict['scroll'] = data[4]
|
||||
elif data[0] == EV_REL and event_code == REL_HWHEEL:
|
||||
mouse_status_dict['hscroll'] = data[4]
|
||||
|
||||
# event is absolute axes AKA joystick
|
||||
elif this_device['is_gp'] and data[0] == EV_ABS:
|
||||
abs_value = int.from_bytes(data[4:8], byteorder='little', signed=True)
|
||||
abs_value_midpoint127 = convert_to_8bit_midpoint127(abs_value, this_device['axes_info'], event_code)
|
||||
gamepad_status_dict[this_id][event_code] = abs_value_midpoint127
|
||||
|
||||
# SYNC event
|
||||
elif data[0] == EV_SYN and event_code == SYN_REPORT:
|
||||
if this_device['is_mouse']:
|
||||
this_mouse_msg = make_mouse_spi_packet(mouse_status_dict, this_id)
|
||||
if this_mouse_msg == last_mouse_button_msg:
|
||||
pass
|
||||
# send spi mouse message if there is moment, or the button is not typematic
|
||||
elif (max(this_mouse_msg[13:18]) != 2 or sum(this_mouse_msg[4:10]) != 0) and (this_mouse_msg[4:] != last_mouse_msg[4:] or sum(this_mouse_msg[4:]) != 0):
|
||||
xfer_when_not_busy(list(this_mouse_msg))
|
||||
next_gamepad_hold_check = now + gamepad_hold_check_interval
|
||||
clear_mouse_movement(mouse_status_dict)
|
||||
last_mouse_msg = list(this_mouse_msg)
|
||||
if this_device['is_gp']:
|
||||
for axis_name in USB_GAMEPAD_STICK_AXES_NAMES:
|
||||
axis_code = code_name_to_value_lookup.get(axis_name)[0]
|
||||
this_gp_dict = gamepad_status_dict[this_device['id']]
|
||||
if axis_code in this_gp_dict and 127 - 10 <= this_gp_dict[axis_code] <= 127 + 10:
|
||||
this_gp_dict[axis_code] = 127
|
||||
gamepad_output = make_gamepad_spi_packet(gamepad_status_dict, this_device)
|
||||
if gamepad_output != last_gamepad_msg:
|
||||
# print(gamepad_output)
|
||||
gp_to_transfer, kb_to_transfer, mouse_to_transfer = gamepad_output
|
||||
xfer_when_not_busy(list(gp_to_transfer))
|
||||
if kb_to_transfer is not None:
|
||||
time.sleep(0.001)
|
||||
xfer_when_not_busy(list(kb_to_transfer))
|
||||
if mouse_to_transfer is not None:
|
||||
time.sleep(0.001)
|
||||
xfer_when_not_busy(list(mouse_to_transfer))
|
||||
next_gamepad_hold_check = now + gamepad_hold_check_interval
|
||||
last_gamepad_msg = gamepad_output
|
||||
|
||||
# ----------------- PBOARD INTERRUPT -----------------
|
||||
if GPIO.event_detected(SLAVE_REQ_PIN):
|
||||
# send out ACK to turn off P-Card interrupt
|
||||
slave_result = xfer_when_not_busy(make_spi_msg_ack())
|
||||
time.sleep(0.001)
|
||||
# send another to shift response into RPi
|
||||
slave_result = xfer_when_not_busy(make_spi_msg_ack())
|
||||
print(int(time.time()), slave_result)
|
||||
if slave_result[SPI_BUF_INDEX_MAGIC] == SPI_MISO_MAGIC and slave_result[SPI_BUF_INDEX_MSG_TYPE] == SPI_MISO_MSG_TYPE_KB_LED_REQUEST:
|
||||
try:
|
||||
change_kb_led(slave_result[3], slave_result[4], slave_result[5])
|
||||
change_kb_led(slave_result[3], slave_result[4], slave_result[5])
|
||||
except Exception as e:
|
||||
print('exception change_kb_led:', e)
|
||||
|
||||
def check_is_gamepad(capability_dict):
|
||||
keys_and_buttons = capability_dict.get(('EV_KEY', 1))
|
||||
@@ -888,6 +755,12 @@ def check_is_gamepad(capability_dict):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_device_count():
|
||||
mouse_count = 69
|
||||
kb_count = 69
|
||||
gp_count = 69
|
||||
return (mouse_count, kb_count, gp_count)
|
||||
|
||||
def get_input_devices():
|
||||
result = []
|
||||
available_devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
|
||||
@@ -922,49 +795,16 @@ def get_input_devices():
|
||||
result.append(dev_dict)
|
||||
return result
|
||||
|
||||
def get_device_count():
|
||||
mouse_count = 0
|
||||
kb_count = 0
|
||||
gp_count = 0
|
||||
for key in opened_device_dict:
|
||||
if opened_device_dict[key]['is_mouse']:
|
||||
mouse_count += 1
|
||||
elif opened_device_dict[key]['is_kb']:
|
||||
kb_count += 1
|
||||
elif opened_device_dict[key]['is_gp']:
|
||||
gp_count += 1
|
||||
return (mouse_count, kb_count, gp_count)
|
||||
|
||||
def usb_device_scan_worker():
|
||||
print("usb_device_scan_worker started")
|
||||
while 1:
|
||||
time.sleep(0.75)
|
||||
try:
|
||||
device_list = get_input_devices()
|
||||
except Exception as e:
|
||||
print('exception get_input_devices:', e)
|
||||
continue
|
||||
if len(device_list) == 0:
|
||||
print('No input devices found')
|
||||
continue
|
||||
wwwww = get_input_devices()
|
||||
for item in wwwww:
|
||||
print(item)
|
||||
print("-----------------")
|
||||
|
||||
for item in device_list:
|
||||
if item['path'] in opened_device_dict:
|
||||
continue
|
||||
try:
|
||||
this_file = open(item['path'], "rb")
|
||||
os.set_blocking(this_file.fileno(), False)
|
||||
item['file'] = this_file
|
||||
try:
|
||||
item['id'] = int(item['path'][len(item['path'].rstrip('0123456789')):])
|
||||
except:
|
||||
item['id'] = 255
|
||||
opened_device_dict[item['path']] = item
|
||||
print("opened device:", hex(item['vendor_id']), hex(item['product_id']), item['name'])
|
||||
except Exception as e:
|
||||
print("exception Device open:", e, item)
|
||||
|
||||
raw_input_event_parser_thread = threading.Thread(target=raw_input_event_worker, daemon=True)
|
||||
# raw_input_event_parser_thread = threading.Thread(target=raw_input_event_worker, daemon=True)
|
||||
usb_device_scan_thread = threading.Thread(target=usb_device_scan_worker, daemon=True)
|
||||
|
||||
def get_pboard_info():
|
||||
|
||||
Reference in New Issue
Block a user