Skip to content

Commit

Permalink
gpio handler
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusandra committed Jan 20, 2024
1 parent e29702e commit ab31cb8
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 119 deletions.
9 changes: 2 additions & 7 deletions backend/app/tasks/deploy_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,17 +295,12 @@ 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'):
if 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))
shutil.copy(os.path.join(source_dir, "src", "drivers", "gpioHandler", file), os.path.join(build_dir, file))

# Update the compilation script for verbose output
script_path = os.path.join(build_dir, "compile_frameos.sh")
Expand Down
23 changes: 14 additions & 9 deletions frameos/src/drivers/gpioButton/gpioButton.nim
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import pixie, json, strformat, strutils
import frameos/types
import frameos/channels

import gpioHandler/gpioHandler as gpioHandler
import ../gpioHandler/gpioHandler as gpioHandler

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")
log("Initializing GPIO button driver")

let callback = proc (pin: cint, value: cint) =
frameOS.logger.log(%*{"event": "gpio:press", "pin": $pin, "value": $value})
let eventCallback = proc (pin: cint, value: cint) {.cdecl.} =
log(%*{"event": "gpio:press", "pin": pin.int, "value": value.int})

let handler = gpioHandler.init(callback).int
let logCallback = proc (message: cstring) {.cdecl.} =
log($message)

let handler = gpioHandler.init(eventCallback, logCallback).int
if handler == -1:
log(frameOS.logger, "Failed to initialize GPIO button driver")
log("Failed to initialize GPIO button driver")

result = Driver(
name: "gpioButton",
Expand All @@ -28,5 +32,6 @@ proc init*(frameOS: FrameOS): Driver =

let pins = [5.cint, 6.cint, 16.cint, 24.cint]
for pin in pins:
log(&"Listening on GPIO {pin}")
if gpioHandler.registerButton(pin.cint).int == -1:
log(frameOS.logger, &"Failed to register GPIO button {pin}")
log(&"Failed to register GPIO button {pin}")
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.

7 changes: 7 additions & 0 deletions frameos/src/drivers/gpioHandler/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
debug:
rm -f debug
gcc -o debug debug.c gpioHandler.c -llgpio
./debug
c2nim:
# `nimble path c2nim`/c2nim --importc gpioHandler.h
`nimble path c2nim`/c2nim --importc lgpio.h
3 changes: 3 additions & 0 deletions frameos/src/drivers/gpioHandler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# GPIO Handler

The folder contains GPIO code shared between different drivers.
54 changes: 54 additions & 0 deletions frameos/src/drivers/gpioHandler/debug.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <stdio.h>
#include <unistd.h> // For sleep()
#include "gpioHandler.h"
#include <lgpio.h>

// User-defined callback function for button press
void event_callback(int gpio, int level) {
printf("Button on GPIO %d changed to level %d\n", gpio, level);
}

// User-defined callback function for button press
void log_callback(char *message) {
printf(message);
}

int main() {
// Initialize GPIO system
if (gpioHandler_init(event_callback, log_callback) < 0) {
fprintf(stderr, "Failed to initialize GPIO\n");
return 1;
}

if (gpioHandler_registerButton(16) < 0) {
fprintf(stderr, "Failed to register button\n");
gpioHandler_cleanup();
return 1;
}
if (gpioHandler_registerButton(24) < 0) {
fprintf(stderr, "Failed to register button\n");
gpioHandler_cleanup();
return 1;
}
if (gpioHandler_registerButton(5) < 0) {
fprintf(stderr, "Failed to register button\n");
gpioHandler_cleanup();
return 1;
}
if (gpioHandler_registerButton(6) < 0) {
fprintf(stderr, "Failed to register button\n");
gpioHandler_cleanup();
return 1;
}

// Main loop
printf("Waiting for button press. Press CTRL+C to exit.\n");
while (1) {
fprintf(stdout, "GPIO value: %d", gpioHandler_readValue(5));
sleep(100); // Wait for button press (callback handles the press)
}

// Cleanup (not reachable in this example, but good practice)
gpioHandler_cleanup();
return 0;
}
87 changes: 87 additions & 0 deletions frameos/src/drivers/gpioHandler/gpioHandler.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include <stdio.h>
#include <stdlib.h>
#include <lgpio.h>

#include "gpioHandler.h"

#define NUM_MAXBUF 1024

int h; // Handle for gpiochip

event_callback_t global_event_callback;
log_callback_t global_log_callback;

int gpioHandler_init(event_callback_t event_callback, log_callback_t log_callback) {
global_event_callback = event_callback;
global_log_callback = log_callback;

char buffer[NUM_MAXBUF];
FILE *fp;
int gpioDevice = 0; // Default to gpiochip0

// Determine the Raspberry Pi model
fp = popen("grep 'Raspberry Pi 5' /proc/cpuinfo", "r");
if (fp == NULL) {
log_callback("It is not possible to determine the model of the Raspberry PI");
return -1;
}

if (fgets(buffer, sizeof(buffer), fp) != NULL) {
// Raspberry Pi 5 detected, use gpiochip4
gpioDevice = 4;
}

pclose(fp);

// Open the appropriate gpiochip device
h = lgGpiochipOpen(gpioDevice);
if (h < 0) {
log_callback("gpiochip open failed");
return -1;
}
int i;
return h;
}

// Intermediate function to handle alerts
void gpioHandler_alertsHandler(int num_alerts, lgGpioAlert_p alerts, void *userdata) {
for (int i = 0; i < num_alerts; i++) {
int gpio = alerts[i].report.gpio;
int level = alerts[i].report.level;
global_event_callback(gpio, level);
}
}

// Register a button for alerts
int gpioHandler_registerButton(int button) {
int res;
printf("Claiming GPIO %d\n", button);

res = lgGpioClaimInput(h, 0, button);
if (res < 0) {
printf("Unable to claim GPIO %d for input\n", button);
return res;
}

res = lgGpioClaimAlert(h, 0, LG_FALLING_EDGE, button, -1);
if (res < 0)
{
printf("can't claim GPIO %d (%s)\n", button, lguErrorText(res));
return -1;
}

// Set the intermediate function as the callback for button presses
lgGpioSetAlertsFunc(h, button, gpioHandler_alertsHandler, NULL);
lgGpioSetDebounce(h, button, 100000); // 100ms debounce

return 0;
}

int gpioHandler_readValue(int button) {
return lgGpioRead(h, button);
}

// Cleanup resources
void gpioHandler_cleanup() {
lgGpiochipClose(h);
}
15 changes: 15 additions & 0 deletions frameos/src/drivers/gpioHandler/gpioHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef GPIO_HANDLER_H
#define GPIO_HANDLER_H

typedef void (*event_callback_t)(int gpio, int level);
typedef void (*log_callback_t)(char *message);

int gpioHandler_init(event_callback_t event_callback, log_callback_t log_callback);

int gpioHandler_registerButton(int button);

int gpioHandler_readValue(int button);

void gpioHandler_cleanup();

#endif // GPIO_HANDLER_H
8 changes: 8 additions & 0 deletions frameos/src/drivers/gpioHandler/gpioHandler.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type
event_callback_t* = proc (gpio: cint; level: cint) {.cdecl.}
log_callback_t* = proc (message: cstring) {.cdecl.}

proc init*(event_callback: event_callback_t; log_callback: log_callback_t): cint {.importc: "gpioHandler_init".}
proc registerButton*(button: cint): cint {.importc: "gpioHandler_registerButton".}
proc readValue*(button: cint): cint {.importc: "gpioHandler_readValue".}
proc cleanup*() {.importc: "gpioHandler_cleanup".}

0 comments on commit ab31cb8

Please sign in to comment.