pin_control: fix error handling

This commit is contained in:
Alejandro Soto 2023-09-12 20:49:03 -06:00
parent 7d81d8e9b6
commit 4104ba296f
No known key found for this signature in database
GPG key ID: 570448E3382BDEC5
3 changed files with 49 additions and 39 deletions

View file

@ -13,6 +13,6 @@ int turn_on_all_pins();
int turn_off_all_pins(); int turn_off_all_pins();
int wait_for_button_press(int button_pin); int wait_for_button_press(const unsigned pins[static 5]);
#endif /* GPIO_CONTROL_H */ #endif /* GPIO_CONTROL_H */

View file

@ -1,13 +0,0 @@
#include "pin_control.h"
int main() {
int button_pin = 5;
int button_response;
button_response = wait_for_button_press(button_pin);
printf("Button press detected on pin: %d\n", button_response);
cleanup_gpio();
return 0;
}

View file

@ -1,6 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include <gpiod.h> #include <gpiod.h>
#include <pin_control.h>
// https://docs.kernel.org/driver-api/gpio/using-gpio.html // https://docs.kernel.org/driver-api/gpio/using-gpio.html
#define GPIO_CHIP "gpiochip0" #define GPIO_CHIP "gpiochip0"
@ -8,45 +10,59 @@
struct gpiod_chip *chip; struct gpiod_chip *chip;
int init_gpio() { int init_gpio() {
cleanup_gpio();
// https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_chip_open_by_name.html // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_chip_open_by_name.html
chip = gpiod_chip_open_by_name(GPIO_CHIP); chip = gpiod_chip_open_by_name(GPIO_CHIP);
if (!chip) { if (!chip) {
printf("Error opening GPIO chip"); perror("[pin_control] gpiod_chip_open_by_name(\"" GPIO_CHIP "\")");
return -1; return -1;
} }
return 0; return 0;
} }
void cleanup_gpio() { void cleanup_gpio() {
// https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_chip_close.html // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_chip_close.html
gpiod_chip_close(chip); if (chip) {
gpiod_chip_close(chip);
chip = NULL;
}
} }
static int set_pin_state(int pin, int state) { static int set_pin_state(int pin, int state) {
int ret = -1;
if (!chip) {
perror("[pin_control] attempt to set GPIO line for invalid chip");
goto exit;
}
// https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_chip_get_line.html // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_chip_get_line.html
struct gpiod_line *line = gpiod_chip_get_line(chip, pin); // this may need an offset struct gpiod_line *line = gpiod_chip_get_line(chip, pin); // this may need an offset
if (!line) { if (!line) {
printf("Error getting GPIO line"); perror("[pin_control] gpiod_chip_get_line()");
return -1; goto exit;
} }
// https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_request_output.html // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_request_output.html
if (gpiod_line_request_output(line, "house-leds", state) < 0) { if (gpiod_line_request_output(line, "house-leds", state) < 0) {
printf("Error setting GPIO line direction"); perror("[pin_control] gpiod_line_request_output()");
gpiod_line_release(line); goto exit_line;
return -1;
} }
// https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_set_value.html // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_set_value.html
if (gpiod_line_set_value(line, state) < 0) { if (gpiod_line_set_value(line, state) < 0) {
printf("Error setting GPIO line value"); perror("[pin_control] gpiod_line_set_value()");
gpiod_line_release(line); goto exit_line;
return -1;
} }
ret = 0;
exit_line:
// https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_release.html // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_release.html
gpiod_line_release(line); gpiod_line_release(line);
return 0; exit:
return ret;
} }
int turn_on_pin(int pin) { int turn_on_pin(int pin) {
@ -58,10 +74,10 @@ int turn_off_pin(int pin) {
} }
int turn_on_all_pins() { int turn_on_all_pins() {
for (int pin = 0; pin <= 5; pin++) { for (int pin = 0; pin <= 5; pin++)
if (turn_on_pin(pin) < 0) if (turn_on_pin(pin) < 0)
return -1; return -1;
}
return 0; return 0;
} }
@ -80,7 +96,7 @@ static int button_presssed(int event, unsigned int pin, const struct timespec *
return GPIOD_CTXLESS_EVENT_POLL_RET_STOP; return GPIOD_CTXLESS_EVENT_POLL_RET_STOP;
} }
int wait_for_button_press(unsigned int pins[]) { int wait_for_button_press(const unsigned pins[static 5]) {
// https://www.lane-fu.com/linuxmirror/libgpiod/doc/html/group______high__level____.html#ga3ac28eb59bbd31b8b2298f76047d377d // https://www.lane-fu.com/linuxmirror/libgpiod/doc/html/group______high__level____.html#ga3ac28eb59bbd31b8b2298f76047d377d
int pressed_pin = -1; int pressed_pin = -1;
@ -90,15 +106,22 @@ int wait_for_button_press(unsigned int pins[]) {
.tv_nsec = 0, .tv_nsec = 0,
}; };
return gpiod_ctxless_event_monitor_multiple(GPIO_CHIP, int ret = gpiod_ctxless_event_monitor_multiple(
GPIOD_CTXLESS_EVENT_FALLING_EDGE, GPIO_CHIP,
pins, GPIOD_CTXLESS_EVENT_FALLING_EDGE,
5, pins,
true, 5,
"house-leds", true,
&ts, // big timout "house-leds",
NULL, &ts, // big timout
button_presssed, NULL,
&pressed_pin button_presssed,
); &pressed_pin);
if (ret < 0) {
perror("[pin_control] gpiod_ctxless_event_monitor_multiple()");
return -1;
}
return pressed_pin;
} }