#include #include #include #include #include "scode.h" #include "log.h" #include "msg_queue.h" #include "gpio.h" #include "time_func.h" #define DEBOUNCE_BUTTON_MSEC 350 PMSG_QUEUE Sys_Queue = NULL; static pthread_t ithread; static volatile sig_atomic_t running = 1; static UINT32 last_bstate = 0; static void *input_thread(void *arg) { UINT32 st, down, up, mask; UINT_PTR attr; TIMESTAMP now; TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP)); while (running) { /* poll hardware buttons */ st = Gpio_read_buttons(); if (st != last_bstate) { now = Time_since_start(); up = last_bstate & ~st; down = st & ~last_bstate; for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) { if (now < button_event_ok[attr - 1]) continue; if (up & mask) { button_event_ok[attr - 1] = now + DEBOUNCE_BUTTON_MSEC; Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); } else if (down & mask) Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); } last_bstate = st; } /* additional poll activity here */ } return NULL; } HRESULT Sys_enable_input(void) { HRESULT rc = S_OK; int threadrc; Sys_Queue = Mq_alloc(64); if (!Sys_Queue) { Log(LFATAL, "Unable to allocate system message queue."); return E_OUTOFMEMORY; } running = 1; threadrc = pthread_create(&ithread, NULL, input_thread, NULL); if (threadrc != 0) { rc = SCODE_FROM_ERRNO(threadrc); Log(LFATAL, "Unable to start system input thread (%08X).", rc); } return rc; } void Sys_disable_input(void) { running = 0; pthread_join(ithread, NULL); Mq_destroy(Sys_Queue); Sys_Queue = NULL; }