Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from RogueM/gamepads
using $1 for configload
- Loading branch information
Showing
3 changed files
with
175 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
#!/usr/bin/env python | ||
|
||
# Adafruit PiGRRL PCB alternative configuration | ||
# maps buttons to GPIO for connection to PiTFT | ||
# or mounting back to back to a Raspberry Pi Zero | ||
# soft shutdown is supported through L bumper | ||
|
||
import time | ||
import signal | ||
import os | ||
import sys | ||
from datetime import datetime | ||
from threading import Timer | ||
|
||
try: | ||
from evdev import uinput, UInput, ecodes as e | ||
except ImportError: | ||
exit("This library requires the evdev module\nInstall with: sudo pip install evdev") | ||
|
||
try: | ||
import RPi.GPIO as gpio | ||
except ImportError: | ||
exit("This library requires the RPi.GPIO module\nInstall with: sudo pip install RPi.GPIO") | ||
|
||
|
||
#time.sleep(30) | ||
|
||
os.system("sudo modprobe uinput") | ||
|
||
DEBUG = False | ||
|
||
PIDFILE = "/var/run/picadehatd.pid" | ||
LOGFILE = "/var/log/picadehatd.log" | ||
|
||
BOUNCE_TIME = 0.01 # Debounce time in seconds | ||
SHUTDOWN_HOLD_TIME = 3 # Time in seconds that power button must be held | ||
|
||
SHUTDOWN = 4 | ||
BUTTON_POWER = 12 | ||
|
||
UP = 16 | ||
DOWN = 26 | ||
LEFT = 4 | ||
RIGHT = 19 | ||
|
||
BUTTON1 = 14 | ||
BUTTON2 = 15 | ||
BUTTON3 = 20 | ||
BUTTON4 = 18 | ||
|
||
ENTER = 5 | ||
START= 6 | ||
|
||
BUTTONS = [ENTER,START,BUTTON1,BUTTON2,BUTTON3,BUTTON4,UP,DOWN,LEFT,RIGHT] | ||
|
||
KEYS = { | ||
ENTER: e.KEY_ENTER, | ||
START: e.KEY_S, | ||
UP: e.KEY_UP, | ||
DOWN: e.KEY_DOWN, | ||
LEFT: e.KEY_LEFT, | ||
RIGHT: e.KEY_RIGHT, | ||
BUTTON1: e.KEY_LEFTCTRL, | ||
BUTTON2: e.KEY_LEFTALT, | ||
BUTTON3: e.KEY_SPACE, | ||
BUTTON4: e.KEY_LEFTSHIFT, | ||
} | ||
|
||
states = [False for b in BUTTONS] | ||
|
||
shutdown_timer = None | ||
|
||
try: | ||
pid = os.fork() | ||
if pid > 0: | ||
sys.exit(0) | ||
|
||
except OSError, e: | ||
print("Fork #1 failed: {} ({})".format(e.errno, e.strerror)) | ||
sys.exit(1) | ||
|
||
os.chdir("/") | ||
os.setsid() | ||
os.umask(0) | ||
|
||
try: | ||
pid = os.fork() | ||
if pid > 0: | ||
fpid = open(PIDFILE, 'w') | ||
fpid.write(str(pid)) | ||
fpid.close() | ||
sys.exit(0) | ||
except OSError, e: | ||
print("Fork #2 failed: {} ({})".format(e.errno, e.strerror)) | ||
sys.exit(1) | ||
|
||
si = file("/dev/null", 'r') | ||
so = file(LOGFILE, 'a+') | ||
se = file("/dev/null", 'a+', 0) | ||
|
||
os.dup2(si.fileno(), sys.stdin.fileno()) | ||
os.dup2(so.fileno(), sys.stdout.fileno()) | ||
os.dup2(se.fileno(), sys.stderr.fileno()) | ||
|
||
gpio.setmode(gpio.BCM) | ||
gpio.setwarnings(False) | ||
gpio.setup(BUTTONS, gpio.IN, pull_up_down=gpio.PUD_UP) | ||
gpio.setup(BUTTON_POWER, gpio.IN, pull_up_down=gpio.PUD_UP) | ||
|
||
try: | ||
ui = UInput({e.EV_KEY: KEYS.values()}, name="PiGRRL-PCB", bustype=e.BUS_USB) | ||
|
||
except uinput.UInputError as e: | ||
sys.stdout.write(e.message) | ||
sys.stdout.write("Have you tried running as root? sudo {}".format(sys.argv[0])) | ||
sys.exit(0) | ||
|
||
def log(msg): | ||
sys.stdout.write(str(datetime.now())) | ||
sys.stdout.write(": ") | ||
sys.stdout.write(msg) | ||
sys.stdout.write("\n") | ||
sys.stdout.flush() | ||
|
||
def handle_button(pin): | ||
key = KEYS[pin] | ||
time.sleep(BOUNCE_TIME) | ||
state = 0 if gpio.input(pin) else 1 | ||
ui.write(e.EV_KEY, key, state) | ||
ui.syn() | ||
if DEBUG: | ||
log("Pin: {}, KeyCode: {}, Event: {}".format(pin, key, 'press' if state else 'release')) | ||
|
||
def perform_shutdown(): | ||
log("Shutting down...") | ||
os.system("sudo shutdown -h now") | ||
|
||
def handle_shutdown(pin): | ||
global shutdown_timer | ||
|
||
time.sleep(BOUNCE_TIME) | ||
state = 0 if gpio.input(pin) else 1 | ||
|
||
if DEBUG: | ||
log("Power button: {}".format('pressed' if state else 'released')) | ||
|
||
if state and shutdown_timer is None: | ||
shutdown_timer = Timer(SHUTDOWN_HOLD_TIME, perform_shutdown) | ||
shutdown_timer.start() | ||
|
||
elif not state and shutdown_timer is not None: | ||
shutdown_timer.cancel() | ||
shutdown_timer = None | ||
|
||
for button in BUTTONS: | ||
gpio.add_event_detect(button, gpio.BOTH, callback=handle_button, bouncetime=1) | ||
|
||
gpio.add_event_detect(BUTTON_POWER, gpio.BOTH, callback=handle_shutdown, bouncetime=1) | ||
|
||
log("Picade HAT daemon running...") | ||
|
||
try: | ||
signal.pause() | ||
except KeyboardInterrupt: | ||
pass | ||
|
||
log("daemon shutting down...") | ||
|
||
ui.close() |