91 lines
2.4 KiB
C
91 lines
2.4 KiB
C
#define LOG_MODULE "aciodrv-proc-panb"
|
|
|
|
#include <string.h>
|
|
|
|
#include "aciodrv/device.h"
|
|
#include "aciodrv/panb.h"
|
|
|
|
#include "util/log.h"
|
|
#include "util/thread.h"
|
|
|
|
static int auto_poll_proc(void *auto_poll_param);
|
|
static int auto_poll_threadid;
|
|
|
|
static CRITICAL_SECTION keypair_lock;
|
|
static struct ac_io_panb_keypair _keypair[AC_IO_PANB_MAX_KEYPAIRS];
|
|
|
|
static CRITICAL_SECTION auto_poll_stop_lock;
|
|
static bool auto_poll_stop;
|
|
|
|
static int auto_poll_proc(void *param)
|
|
{
|
|
struct aciodrv_device_ctx *device = (struct aciodrv_device_ctx *) param;
|
|
struct ac_io_panb_poll_in poll_in;
|
|
bool stop;
|
|
|
|
do {
|
|
aciodrv_panb_recv_poll(device, &poll_in);
|
|
|
|
EnterCriticalSection(&keypair_lock);
|
|
memcpy(_keypair, poll_in.keypair, AC_IO_PANB_MAX_KEYPAIRS);
|
|
LeaveCriticalSection(&keypair_lock);
|
|
|
|
EnterCriticalSection(&auto_poll_stop_lock);
|
|
stop = auto_poll_stop;
|
|
LeaveCriticalSection(&auto_poll_stop_lock);
|
|
} while (!stop);
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool aciodrv_proc_panb_init(struct aciodrv_device_ctx *device)
|
|
{
|
|
log_assert(device);
|
|
|
|
if (!aciodrv_panb_start_auto_input(device, 0, AC_IO_PANB_NUM_NODES)) {
|
|
return false;
|
|
}
|
|
|
|
auto_poll_stop = false;
|
|
InitializeCriticalSection(&keypair_lock);
|
|
InitializeCriticalSection(&auto_poll_stop_lock);
|
|
auto_poll_threadid =
|
|
thread_create(auto_poll_proc, (void *) device, 0x4000, 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool aciodrv_proc_panb_get_state(uint8_t *button_state)
|
|
{
|
|
struct ac_io_panb_keypair keypair[AC_IO_PANB_MAX_KEYPAIRS];
|
|
|
|
EnterCriticalSection(&keypair_lock);
|
|
memcpy(keypair, _keypair, AC_IO_PANB_MAX_KEYPAIRS);
|
|
LeaveCriticalSection(&keypair_lock);
|
|
|
|
/* splice the keypairs into separate button values */
|
|
for (int i = 0; i < AC_IO_PANB_MAX_KEYPAIRS; i++) {
|
|
uint8_t but1 = keypair[i].key1;
|
|
uint8_t but2 = keypair[i].key2;
|
|
button_state[2 * i] = but1;
|
|
button_state[2 * i + 1] = but2;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void aciodrv_proc_panb_fini(struct aciodrv_device_ctx *device)
|
|
{
|
|
EnterCriticalSection(&auto_poll_stop_lock);
|
|
auto_poll_stop = true;
|
|
LeaveCriticalSection(&auto_poll_stop_lock);
|
|
|
|
thread_join(auto_poll_threadid, NULL);
|
|
thread_destroy(auto_poll_threadid);
|
|
|
|
DeleteCriticalSection(&keypair_lock);
|
|
DeleteCriticalSection(&auto_poll_stop_lock);
|
|
|
|
/* reset is the only way to disable the auto polling on device side */
|
|
aciodrv_device_reset(device);
|
|
} |