2019-12-01 01:02:08 -07:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <signal.h>
|
2019-12-06 21:25:15 -07:00
|
|
|
#include <string.h>
|
2019-12-01 01:02:08 -07:00
|
|
|
#include <pthread.h>
|
2019-12-05 18:21:37 -07:00
|
|
|
#include "scode.h"
|
2019-12-06 22:45:01 -07:00
|
|
|
#include "config.h"
|
2019-12-01 01:02:08 -07:00
|
|
|
#include "log.h"
|
|
|
|
#include "msg_queue.h"
|
|
|
|
#include "gpio.h"
|
2019-12-06 21:25:15 -07:00
|
|
|
#include "time_func.h"
|
|
|
|
|
2019-12-01 01:36:07 -07:00
|
|
|
PMSG_QUEUE Sys_Queue = NULL;
|
2019-12-01 01:02:08 -07:00
|
|
|
|
|
|
|
static pthread_t ithread;
|
|
|
|
static volatile sig_atomic_t running = 1;
|
2019-12-05 18:21:37 -07:00
|
|
|
static UINT32 last_bstate = 0;
|
2019-12-01 01:02:08 -07:00
|
|
|
|
|
|
|
static void *input_thread(void *arg)
|
|
|
|
{
|
2019-12-05 18:21:37 -07:00
|
|
|
UINT32 st, down, up, mask;
|
|
|
|
UINT_PTR attr;
|
2019-12-06 21:25:15 -07:00
|
|
|
TIMESTAMP now;
|
|
|
|
TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT];
|
|
|
|
|
|
|
|
memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
|
2019-12-01 01:02:08 -07:00
|
|
|
|
|
|
|
while (running)
|
|
|
|
{
|
|
|
|
/* poll hardware buttons */
|
|
|
|
st = Gpio_read_buttons();
|
|
|
|
if (st != last_bstate)
|
|
|
|
{
|
2019-12-06 21:25:15 -07:00
|
|
|
now = Time_since_start();
|
2019-12-01 01:18:59 -07:00
|
|
|
up = last_bstate & ~st;
|
|
|
|
down = st & ~last_bstate;
|
2019-12-01 15:43:05 -07:00
|
|
|
for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
|
2019-12-01 01:02:08 -07:00
|
|
|
{
|
2019-12-06 21:25:15 -07:00
|
|
|
if (now < button_event_ok[attr - 1])
|
|
|
|
continue;
|
2019-12-01 01:18:59 -07:00
|
|
|
if (up & mask)
|
2019-12-06 21:25:15 -07:00
|
|
|
{
|
2019-12-06 22:06:05 -07:00
|
|
|
button_event_ok[attr - 1] = now + Gconfig.button_debounce;
|
2019-12-01 15:43:05 -07:00
|
|
|
Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
|
2019-12-06 21:25:15 -07:00
|
|
|
}
|
2019-12-01 01:18:59 -07:00
|
|
|
else if (down & mask)
|
2019-12-01 15:43:05 -07:00
|
|
|
Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr);
|
2019-12-01 01:02:08 -07:00
|
|
|
}
|
|
|
|
last_bstate = st;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* additional poll activity here */
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-12-06 22:06:05 -07:00
|
|
|
static void do_disable_input(void)
|
|
|
|
{
|
|
|
|
running = 0;
|
|
|
|
pthread_join(ithread, NULL);
|
|
|
|
Mq_destroy(Sys_Queue);
|
|
|
|
Sys_Queue = NULL;
|
|
|
|
}
|
|
|
|
|
2019-12-05 18:21:37 -07:00
|
|
|
HRESULT Sys_enable_input(void)
|
2019-12-01 01:02:08 -07:00
|
|
|
{
|
2019-12-05 18:21:37 -07:00
|
|
|
HRESULT rc = S_OK;
|
|
|
|
int threadrc;
|
2019-12-01 01:02:08 -07:00
|
|
|
|
2019-12-06 22:06:05 -07:00
|
|
|
Sys_Queue = Mq_alloc(Gconfig.sys_mq_length);
|
2019-12-01 01:02:08 -07:00
|
|
|
if (!Sys_Queue)
|
|
|
|
{
|
|
|
|
Log(LFATAL, "Unable to allocate system message queue.");
|
2019-12-05 18:21:37 -07:00
|
|
|
return E_OUTOFMEMORY;
|
2019-12-01 01:02:08 -07:00
|
|
|
}
|
|
|
|
running = 1;
|
2019-12-05 18:21:37 -07:00
|
|
|
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);
|
|
|
|
}
|
2019-12-06 22:06:05 -07:00
|
|
|
if (SUCCEEDED(rc))
|
|
|
|
{
|
|
|
|
rc = Config_exitfunc(do_disable_input);
|
|
|
|
if (FAILED(rc))
|
|
|
|
do_disable_input();
|
|
|
|
}
|
2019-12-01 01:02:08 -07:00
|
|
|
return rc;
|
|
|
|
}
|