64 lines
2.4 KiB
C
64 lines
2.4 KiB
C
#include "mgos.h"
|
|
#include "mgos_gpio.h"
|
|
#include "mgos_timers.h"
|
|
#include "buttonHandler.h"
|
|
#include <math.h>
|
|
|
|
#define ON_BOARD_BUTTON_PIN 0
|
|
#define MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS 0.3 /* seconds */
|
|
|
|
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, uptime=%f", buttonPressCounter, mgos_uptime()));
|
|
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);
|
|
}
|
|
}
|
|
buttonPressCounter = 0;
|
|
}
|
|
|
|
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 = 1;
|
|
}
|
|
// LOG(LL_DEBUG, ("buttonHandler, lastButtonPressTime=%f, uptime=%f", lastButtonPressTime, mgos_uptime()));
|
|
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(floor(1000 * MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS), 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);
|
|
} |