Skip to content

Commit

Permalink
Inky impression button handler (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusandra committed Jan 20, 2024
1 parent e29702e commit 425efc9
Show file tree
Hide file tree
Showing 14 changed files with 5,983 additions and 141 deletions.
5 changes: 3 additions & 2 deletions backend/app/drivers/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

def drivers_for_device(device: str) -> Dict[str, Driver]:
device_drivers: Dict[str, Driver] = {}
if device == "pimoroni.inky_impression":
if device == "pimoroni.inky_impression" or device == "pimoroni.inky_python":
device_drivers = {
"inkyPython": DRIVERS["inkyPython"],
"spi": DRIVERS["spi"],
"i2c": DRIVERS["i2c"],
"gpioButton": DRIVERS["gpioButton"]
}
if device == "pimoroni.inky_impression":
device_drivers["gpioButton"] = DRIVERS["gpioButton"]
elif device == "pimoroni.hyperpixel2r":
device_drivers = {"inkyHyperPixel2r": DRIVERS["inkyHyperPixel2r"]}
elif device == "framebuffer":
Expand Down
12 changes: 0 additions & 12 deletions backend/app/tasks/deploy_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,18 +295,6 @@ def create_local_build_archive(frame: Frame, build_dir: str, build_id: str, nim_
for file in files:
shutil.copy(os.path.join(source_dir, "src", "drivers", "waveshare", "ePaper", file), os.path.join(build_dir, file))

if waveshare := drivers.get('gpioButton'):
files = [
"gpioHandler.c", "gpioHandler.h"
]
for file in files:
shutil.copy(os.path.join(source_dir, "src", "drivers", "gpioButton", "gpioHandler", file), os.path.join(build_dir, file))

if waveshare.variant:
files = [f"{waveshare.variant}.nim", f"{waveshare.variant}.c", f"{waveshare.variant}.h"]
for file in files:
shutil.copy(os.path.join(source_dir, "src", "drivers", "waveshare", "ePaper", file), os.path.join(build_dir, file))

# Update the compilation script for verbose output
script_path = os.path.join(build_dir, "compile_frameos.sh")
log(frame.id, "stdout", f"Cleaning build script at {script_path}")
Expand Down
3 changes: 2 additions & 1 deletion backend/list_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
list = [
{"value": 'web_only', "label": 'Web only'},
{"value": 'framebuffer', "label": 'HDMI / Framebuffer'},
{"value": 'pimoroni.inky_impression', "label": 'Pimoroni Inky Impression e-ink frames'},
{"value": 'pimoroni.inky_impression', "label": 'Pimoroni Inky Impression (Python driver + Buttons)'},
{"value": 'pimoroni.inky_python', "label": 'Pimoroni Inky other (Python driver)'},
{"value": 'pimoroni.hyperpixel2r', "label": 'Pimoroni HyperPixel 2.1" Round'},
]
for output in list:
Expand Down
77 changes: 56 additions & 21 deletions frameos/src/drivers/gpioButton/gpioButton.nim
Original file line number Diff line number Diff line change
@@ -1,32 +1,67 @@
import pixie, json, strformat, strutils
import pixie, json, strformat, strutils, tables
import lib/lgpio
import frameos/types
import frameos/channels

import gpioHandler/gpioHandler as gpioHandler
# TODO: make this configurable in the UI
let inputPins = [
# pin, line flags, edge, debounce
(5, LG_SET_PULL_UP, LG_FALLING_EDGE, 100000),
(6, LG_SET_PULL_UP, LG_FALLING_EDGE, 100000),
(16, LG_SET_PULL_UP, LG_FALLING_EDGE, 100000),
(24, LG_SET_PULL_UP, LG_FALLING_EDGE, 100000)
]
let pinLabels = {
5: "A",
6: "B",
16: "C",
24: "D"
}.toTable

type Driver* = ref object of FrameOSDriver
logger: Logger
handler: int

proc log(logger: Logger, message: string) =
logger.log(%*{"event": "driver:gpioButton", "log": message})
proc log(message: string) =
log(%*{"event": "driver:gpioButton", "log": message})

proc init*(frameOS: FrameOS): Driver =
log(frameOS.logger, "Initializing GPIO button driver")
proc alertsHandler(num_alerts: cint, alerts: lgGpioAlert_p, userdata: pointer) {.cdecl.} =
let alerts = cast[ptr UncheckedArray[lgGpioAlert_t]](alerts)
for i in 0 .. num_alerts - 1:
let gpio = alerts[i].report.gpio.int
let level = alerts[i].report.level.int
let label = pinLabels.getOrDefault(gpio)
sendEvent("button", %*{"pin": gpio, "label": label, "level": level})

let callback = proc (pin: cint, value: cint) =
frameOS.logger.log(%*{"event": "gpio:press", "pin": $pin, "value": $value})
proc determineGPIODevice(): int =
try:
if readFile("/proc/cpuinfo").find("Raspberry Pi 5") >= 0:
return 4
except:
discard
return 0

let handler = gpioHandler.init(callback).int
if handler == -1:
log(frameOS.logger, "Failed to initialize GPIO button driver")
proc init*(frameOS: FrameOS): Driver =
log("Initializing GPIO button driver")
let gpioDevice = determineGPIODevice()

result = Driver(
name: "gpioButton",
logger: frameOS.logger,
handler: handler
)
let h = lgGpiochipOpen(gpioDevice.cint)
result = Driver(name: "gpioButton", handler: h)
if h < 0:
log(&"gpiochip{gpioDevice} open failed")
return

let pins = [5.cint, 6.cint, 16.cint, 24.cint]
for pin in pins:
if gpioHandler.registerButton(pin.cint).int == -1:
log(frameOS.logger, &"Failed to register GPIO button {pin}")
for (pin, lineFlags, edge, debounce) in inputPins:
log(&"Listening on GPIO {pin}")
if lgGpioClaimInput(h, lineFlags.cint, pin.cint) < 0:
log(&"Unable to claim GPIO {pin} for input")
continue
let res = lgGpioClaimAlert(h, 0, edge.cint, pin.cint, -1)
if res < 0:
log(&"Unable to claim GPIO {pin} for alerts: {lguErrorText(res)}")
continue
if lgGpioSetAlertsFunc(h, pin.cint, alertsHandler, nil) < 0:
log(&"Unable to set alerts handler for GPIO {pin}")
continue
if lgGpioSetDebounce(h, pin.cint, debounce.cint) < 0:
log(&"Unable to set debounce for GPIO {pin}")
continue
2 changes: 0 additions & 2 deletions frameos/src/drivers/gpioButton/gpioHandler/Makefile

This file was deleted.

70 changes: 0 additions & 70 deletions frameos/src/drivers/gpioButton/gpioHandler/gpioHandler.c

This file was deleted.

16 changes: 0 additions & 16 deletions frameos/src/drivers/gpioButton/gpioHandler/gpioHandler.h

This file was deleted.

15 changes: 0 additions & 15 deletions frameos/src/drivers/gpioButton/gpioHandler/gpioHandler.nim

This file was deleted.

4 changes: 3 additions & 1 deletion frameos/src/frameos/runner.nim
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ proc startMessageLoop*(self: RunnerThread): Future[void] {.async.} =
payload["x"] = %*((self.frameConfig.width.float * payload["x"].getInt().float / 32767.0).int)
payload["y"] = %*((self.frameConfig.height.float * payload["y"].getInt().float / 32767.0).int)
self.dispatchSceneEvent(event, payload)
of "mouseUp", "mouseDown", "keyUp", "keyDown":
of "mouseUp", "mouseDown", "keyUp", "keyDown", "button":
if event == "button":
self.logger.log(%*{"event": "event:" & event, "payload": payload})
self.dispatchSceneEvent(event, payload)
else:
self.logger.log(%*{"event": "event:" & event, "payload": payload})
Expand Down
2 changes: 2 additions & 0 deletions frameos/src/lib/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
c2nim:
`nimble path c2nim`/c2nim --importc gpioHandler.h
Loading

0 comments on commit 425efc9

Please sign in to comment.