mg_sonoff/src/buttonHandler.c

61 lines
2.2 KiB
C

#include "mgos.h"
#include "mgos_gpio.h"
#include "mgos_timers.h"
#include "buttonHandler.h"
#define ON_BOARD_BUTTON_PIN 5
#define MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS 200
static double lastButtonPressTime = 0;
static uint8_t buttonPressCounter = 0;
static mgos_timer_id multiPressTimerId = 0;
static uint8_t callbacksRegistered = 0;
#define MAX_CALLBACKS 10
struct callbackReg_s {
int numberPressed;
button_press_callback callback;
};
static struct callbackReg_s callbacks[MAX_CALLBACKS];
void add_button_press_callback(int numberPressed, button_press_callback cb) {
if (callbacksRegistered < MAX_CALLBACKS) {
callbacks[callbacksRegistered].callback = cb;
callbacks[callbacksRegistered].numberPressed = numberPressed;
++callbacksRegistered;
} else {
LOG(LL_ERROR, ("ERROR: Too many callbacks for button press! -- ignored this on for %d presses", numberPressed));
}
}
static void multiPressButtonHandler(void *arg) {
(void) arg;
LOG(LL_DEBUG, ("multiPressButtonHandler called after %d presses", buttonPressCounter));
multiPressTimerId = 0; // timer used only once, thus we clear it
for (int i=0; i<callbacksRegistered; ++i) {
if (callbacks[i].numberPressed == buttonPressCounter) {
LOG(LL_DEBUG, ("Calling button press callback for %d presses, index %d", buttonPressCounter, i));
callbacks[i].callback(buttonPressCounter);
}
}
}
static void buttonHandler(int pin, void *arg) {
(void) pin;
(void) arg;
// button release event occured
if (mgos_uptime() - lastButtonPressTime < MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS) {
++buttonPressCounter;
} else {
buttonPressCounter = 0;
}
lastButtonPressTime = mgos_uptime();
// at this point we do not know if more press events will come that we need to count, therefore we wait before we act
if (multiPressTimerId != 0) mgos_clear_timer(multiPressTimerId);
multiPressTimerId = mgos_set_timer(MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS + 1, 0, multiPressButtonHandler, NULL);
}
void init_button_handler() {
mgos_gpio_set_button_handler(ON_BOARD_BUTTON_PIN, MGOS_GPIO_PULL_UP, MGOS_GPIO_INT_EDGE_POS, 50, buttonHandler, NULL);
}