/* * button.c - Call functions if GPIO pins are high * Copyright (C) 2024 Alexander Rosenberg * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. See the LICENSE file for more information. */ #include "button.h" #include "util.h" #include static const struct timespec DEBOUNCE_TIME = { .tv_sec = 0, .tv_nsec = 10 * 1000 * 1000, // 10ms }; Button *button_new(gpio_handle_t handle, gpio_pin_t pin) { Button *button = malloc_checked(sizeof(Button)); button->handle = handle; button->pin = pin; gpio_config_t cfg = { .g_pin = pin, .g_flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP, }; gpio_pin_set_flags(handle, &cfg); button->is_down = false; timespecclear(&button->last_detect); return button; } void button_delete(Button *button) { free(button); } bool button_pressed(Button *button) { struct timespec cur_time, diff_time; clock_gettime(CLOCK_UPTIME, &cur_time); timespecsub(&cur_time, &button->last_detect, &diff_time); if (timespeccmp(&diff_time, &DEBOUNCE_TIME, >=)) { gpio_value_t status = gpio_pin_get(button->handle, button->pin); if (!button->is_down && status == GPIO_PIN_LOW) { button->is_down = true; button->last_detect= cur_time; return true; } else if (button->is_down && status == GPIO_PIN_HIGH) { button->last_detect = cur_time; button->is_down = false; } } return false; }