From 4104ba296f480be9c480e9bb21466a16c6ad9648 Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Tue, 12 Sep 2023 20:49:03 -0600 Subject: [PATCH] pin_control: fix error handling --- pin_control/include/pin_control.h | 2 +- pin_control/main.c | 13 ------ pin_control/src/pin_control.c | 73 ++++++++++++++++++++----------- 3 files changed, 49 insertions(+), 39 deletions(-) delete mode 100644 pin_control/main.c diff --git a/pin_control/include/pin_control.h b/pin_control/include/pin_control.h index 0ca9250..cbfce67 100644 --- a/pin_control/include/pin_control.h +++ b/pin_control/include/pin_control.h @@ -13,6 +13,6 @@ int turn_on_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 */ diff --git a/pin_control/main.c b/pin_control/main.c deleted file mode 100644 index 2b70c82..0000000 --- a/pin_control/main.c +++ /dev/null @@ -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; -} diff --git a/pin_control/src/pin_control.c b/pin_control/src/pin_control.c index e583bd9..80d1ebd 100644 --- a/pin_control/src/pin_control.c +++ b/pin_control/src/pin_control.c @@ -1,6 +1,8 @@ #include #include +#include + // https://docs.kernel.org/driver-api/gpio/using-gpio.html #define GPIO_CHIP "gpiochip0" @@ -8,45 +10,59 @@ struct gpiod_chip *chip; int init_gpio() { + cleanup_gpio(); + // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_chip_open_by_name.html chip = gpiod_chip_open_by_name(GPIO_CHIP); if (!chip) { - printf("Error opening GPIO chip"); + perror("[pin_control] gpiod_chip_open_by_name(\"" GPIO_CHIP "\")"); return -1; } + return 0; } void cleanup_gpio() { // 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) { + 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 struct gpiod_line *line = gpiod_chip_get_line(chip, pin); // this may need an offset if (!line) { - printf("Error getting GPIO line"); - return -1; + perror("[pin_control] gpiod_chip_get_line()"); + goto exit; } // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_request_output.html if (gpiod_line_request_output(line, "house-leds", state) < 0) { - printf("Error setting GPIO line direction"); - gpiod_line_release(line); - return -1; + perror("[pin_control] gpiod_line_request_output()"); + goto exit_line; } // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_set_value.html if (gpiod_line_set_value(line, state) < 0) { - printf("Error setting GPIO line value"); - gpiod_line_release(line); - return -1; + perror("[pin_control] gpiod_line_set_value()"); + goto exit_line; } + ret = 0; + +exit_line: // https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_line_release.html gpiod_line_release(line); - return 0; +exit: + return ret; } int turn_on_pin(int pin) { @@ -58,10 +74,10 @@ int turn_off_pin(int pin) { } 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) return -1; - } + 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; } -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 int pressed_pin = -1; @@ -90,15 +106,22 @@ int wait_for_button_press(unsigned int pins[]) { .tv_nsec = 0, }; - return gpiod_ctxless_event_monitor_multiple(GPIO_CHIP, - GPIOD_CTXLESS_EVENT_FALLING_EDGE, - pins, - 5, - true, - "house-leds", - &ts, // big timout - NULL, - button_presssed, - &pressed_pin - ); + int ret = gpiod_ctxless_event_monitor_multiple( + GPIO_CHIP, + GPIOD_CTXLESS_EVENT_FALLING_EDGE, + pins, + 5, + true, + "house-leds", + &ts, // big timout + NULL, + button_presssed, + &pressed_pin); + + if (ret < 0) { + perror("[pin_control] gpiod_ctxless_event_monitor_multiple()"); + return -1; + } + + return pressed_pin; }