mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-22 18:19:03 +00:00
feat(core): add event polling to button driver
[no changelog]
This commit is contained in:
parent
b9d15cb343
commit
8d7a25e5eb
core
embed
io/button
projects
site_scons/models
86
core/embed/io/button/button_fsm.c
Normal file
86
core/embed/io/button/button_fsm.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <sys/systick.h>
|
||||
|
||||
#include "button_fsm.h"
|
||||
|
||||
void button_fsm_init(button_fsm_t* fsm) {
|
||||
memset(fsm, 0, sizeof(button_fsm_t));
|
||||
}
|
||||
|
||||
bool button_fsm_event_ready(button_fsm_t* fsm, uint32_t new_state) {
|
||||
// Remember state changes
|
||||
fsm->pressed |= new_state & ~fsm->state;
|
||||
fsm->released |= ~new_state & fsm->state;
|
||||
fsm->time = systick_us();
|
||||
// Return true if there are any state changes
|
||||
return (fsm->pressed | fsm->released) != 0;
|
||||
}
|
||||
|
||||
bool button_fsm_get_event(button_fsm_t* fsm, uint32_t new_state,
|
||||
button_event_t* event) {
|
||||
uint64_t now = systick_us();
|
||||
|
||||
if ((now - fsm->time) > 100000) {
|
||||
// Reset the history if the button was not read for 100ms
|
||||
fsm->pressed = 0;
|
||||
fsm->released = 0;
|
||||
}
|
||||
|
||||
// Remember state changes and the time of the last read
|
||||
fsm->pressed |= new_state & ~fsm->state;
|
||||
fsm->released |= ~new_state & fsm->state;
|
||||
|
||||
// Bring the automaton out of invalid states,
|
||||
// in case it somehow ends up in one.
|
||||
fsm->released &= fsm->pressed | fsm->state;
|
||||
fsm->pressed &= fsm->released | ~fsm->state;
|
||||
|
||||
uint8_t button_idx = 0;
|
||||
while (fsm->pressed | fsm->released) {
|
||||
uint32_t mask = 1 << button_idx;
|
||||
|
||||
if ((fsm->pressed & mask) != 0 && (fsm->state & mask) == 0) {
|
||||
// Button press was not signalled yet
|
||||
fsm->pressed &= ~mask;
|
||||
fsm->state |= mask;
|
||||
event->button = (button_t)button_idx;
|
||||
event->event_type = BTN_EVENT_DOWN;
|
||||
return true;
|
||||
} else if ((fsm->released & mask) != 0 && (fsm->state & mask) != 0) {
|
||||
// Button release was not signalled yet
|
||||
fsm->released &= ~mask;
|
||||
fsm->state &= ~mask;
|
||||
event->button = (button_t)button_idx;
|
||||
event->event_type = BTN_EVENT_UP;
|
||||
return true;
|
||||
}
|
||||
|
||||
++button_idx;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // KERNEL_MODE
|
59
core/embed/io/button/button_fsm.h
Normal file
59
core/embed/io/button/button_fsm.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <io/button.h>
|
||||
|
||||
// This module is a simple finite state machine for buttons.
|
||||
//
|
||||
// It is designed to be used in a polling loop, where the state of the buttons
|
||||
// is read periodically. The module keeps track of the state changes and
|
||||
// provides a simple interface to get the events that happened since the last
|
||||
// call to button_fsm_get_event().
|
||||
//
|
||||
// The structure is designed to be used in a multi-threaded environment, where
|
||||
// each thread has its own state machine. The state machines are stored in an
|
||||
// array indexed by the task ID.
|
||||
|
||||
typedef struct {
|
||||
// Time of last update of pressed/released data
|
||||
uint64_t time;
|
||||
// Button presses that were detected since last get_event call
|
||||
uint32_t pressed;
|
||||
// Button releases that were detected since last get_event call
|
||||
uint32_t released;
|
||||
// State of buttons signalled to the poller
|
||||
uint32_t state;
|
||||
} button_fsm_t;
|
||||
|
||||
// Initializes button finite state machine
|
||||
void button_fsm_init(button_fsm_t* fsm);
|
||||
|
||||
// Checks if button_fsm_get_event() would return `true` on the next call
|
||||
bool button_fsm_event_ready(button_fsm_t* fsm, uint32_t new_state);
|
||||
|
||||
// Processes the new_state of the button and fills the event structure.
|
||||
//
|
||||
// `new_state` is the current state of the buttons - each bit represents
|
||||
// the state of one button (up to 32 buttons can be handled simultaneously).
|
||||
//
|
||||
// Returns `true` if the event structure was filled.
|
||||
bool button_fsm_get_event(button_fsm_t* fsm, uint32_t new_state,
|
||||
button_event_t* event);
|
@ -68,8 +68,4 @@ void button_deinit(void);
|
||||
bool button_get_event(button_event_t* event);
|
||||
|
||||
// Checks if the specified button is currently pressed
|
||||
//
|
||||
// The current implementation returns the state of the button at the time
|
||||
// `button_get_event()` was called. In the future, we may fix this limitation.
|
||||
// For now, `button_get_event()` must be called before `button_is_down()`.
|
||||
bool button_is_down(button_t button);
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <io/button.h>
|
||||
#include <sys/irq.h>
|
||||
#include <sys/mpu.h>
|
||||
#include <sys/sysevent_source.h>
|
||||
|
||||
#include "../button_fsm.h"
|
||||
|
||||
#ifdef USE_POWERCTL
|
||||
#include <sys/wakeup_flags.h>
|
||||
@ -34,15 +37,8 @@
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
|
||||
#ifdef BTN_LEFT_PIN
|
||||
bool left_down;
|
||||
#endif
|
||||
#ifdef BTN_RIGHT_PIN
|
||||
bool right_down;
|
||||
#endif
|
||||
#ifdef BTN_POWER_PIN
|
||||
bool power_down;
|
||||
#endif
|
||||
// Each task has its own state machine
|
||||
button_fsm_t tls[SYSTASK_MAX_TASKS];
|
||||
|
||||
} button_driver_t;
|
||||
|
||||
@ -51,7 +47,10 @@ static button_driver_t g_button_driver = {
|
||||
.initialized = false,
|
||||
};
|
||||
|
||||
static void button_setup_pin(GPIO_TypeDef *port, uint16_t pin) {
|
||||
// Forward declarations
|
||||
static const syshandle_vmt_t g_button_handle_vmt;
|
||||
|
||||
static void button_setup_pin(GPIO_TypeDef* port, uint16_t pin) {
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
|
||||
@ -62,7 +61,7 @@ static void button_setup_pin(GPIO_TypeDef *port, uint16_t pin) {
|
||||
}
|
||||
|
||||
bool button_init(void) {
|
||||
button_driver_t *drv = &g_button_driver;
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return true;
|
||||
@ -99,106 +98,76 @@ bool button_init(void) {
|
||||
NVIC_EnableIRQ(BTN_EXTI_INTERRUPT_NUM);
|
||||
#endif // BTN_EXTI_INTERRUPT_HANDLER
|
||||
|
||||
drv->initialized = true;
|
||||
if (!syshandle_register(SYSHANDLE_BUTTON, &g_button_handle_vmt, drv)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
drv->initialized = true;
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
button_deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
void button_deinit(void) {
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
|
||||
syshandle_unregister(SYSHANDLE_BUTTON);
|
||||
|
||||
#ifdef BTN_EXIT_INTERRUPT_HANDLER
|
||||
NVIC_DisableIRQ(BTN_EXTI_INTERRUPT_NUM);
|
||||
#endif
|
||||
|
||||
memset(drv, 0, sizeof(button_driver_t));
|
||||
}
|
||||
|
||||
bool button_get_event(button_event_t *event) {
|
||||
button_driver_t *drv = &g_button_driver;
|
||||
static uint32_t button_read_state(button_driver_t* drv) {
|
||||
UNUSED(drv);
|
||||
uint32_t state = 0;
|
||||
|
||||
#ifdef BTN_LEFT_PIN
|
||||
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_LEFT_PORT, BTN_LEFT_PIN)) {
|
||||
state |= (1U << BTN_LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BTN_RIGHT_PIN
|
||||
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_RIGHT_PORT, BTN_RIGHT_PIN)) {
|
||||
state |= (1U << BTN_RIGHT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BTN_POWER_PIN
|
||||
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_POWER_PORT, BTN_POWER_PIN)) {
|
||||
state |= (1U << BTN_POWER);
|
||||
}
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
|
||||
bool button_get_event(button_event_t* event) {
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
memset(event, 0, sizeof(*event));
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef BTN_LEFT_PIN
|
||||
bool left_down =
|
||||
(GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_LEFT_PORT, BTN_LEFT_PIN));
|
||||
uint32_t new_state = button_read_state(drv);
|
||||
|
||||
if (drv->left_down != left_down) {
|
||||
drv->left_down = left_down;
|
||||
if (left_down) {
|
||||
event->button = BTN_LEFT;
|
||||
event->event_type = BTN_EVENT_DOWN;
|
||||
return true;
|
||||
} else {
|
||||
event->button = BTN_LEFT;
|
||||
event->event_type = BTN_EVENT_UP;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BTN_RIGHT_PIN
|
||||
bool right_down =
|
||||
(GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_RIGHT_PORT, BTN_RIGHT_PIN));
|
||||
|
||||
if (drv->right_down != right_down) {
|
||||
drv->right_down = right_down;
|
||||
if (right_down) {
|
||||
event->button = BTN_RIGHT;
|
||||
event->event_type = BTN_EVENT_DOWN;
|
||||
return true;
|
||||
} else {
|
||||
event->button = BTN_RIGHT;
|
||||
event->event_type = BTN_EVENT_UP;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BTN_POWER_PIN
|
||||
bool power_down =
|
||||
(GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_POWER_PORT, BTN_POWER_PIN));
|
||||
|
||||
if (drv->power_down != power_down) {
|
||||
drv->power_down = power_down;
|
||||
if (power_down) {
|
||||
event->button = BTN_POWER;
|
||||
event->event_type = BTN_EVENT_DOWN;
|
||||
return true;
|
||||
} else {
|
||||
event->button = BTN_POWER;
|
||||
event->event_type = BTN_EVENT_UP;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
button_fsm_t* fsm = &drv->tls[systask_id(systask_active())];
|
||||
return button_fsm_get_event(fsm, new_state, event);
|
||||
}
|
||||
|
||||
bool button_is_down(button_t button) {
|
||||
button_driver_t *drv = &g_button_driver;
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (button) {
|
||||
#ifdef BTN_LEFT_PIN
|
||||
case BTN_LEFT:
|
||||
return drv->left_down;
|
||||
#endif
|
||||
#ifdef BTN_RIGHT_PIN
|
||||
case BTN_RIGHT:
|
||||
return drv->right_down;
|
||||
#endif
|
||||
#ifdef BTN_POWER_PIN
|
||||
case BTN_POWER:
|
||||
return drv->power_down;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return (button_read_state(drv) & (1 << button)) != 0;
|
||||
}
|
||||
|
||||
#ifdef BTN_EXTI_INTERRUPT_HANDLER
|
||||
@ -221,4 +190,40 @@ void BTN_EXTI_INTERRUPT_HANDLER(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static void on_task_created(void* context, systask_id_t task_id) {
|
||||
button_driver_t* drv = (button_driver_t*)context;
|
||||
button_fsm_t* fsm = &drv->tls[task_id];
|
||||
button_fsm_init(fsm);
|
||||
}
|
||||
|
||||
static void on_event_poll(void* context, bool read_awaited,
|
||||
bool write_awaited) {
|
||||
button_driver_t* drv = (button_driver_t*)context;
|
||||
|
||||
UNUSED(write_awaited);
|
||||
|
||||
if (read_awaited) {
|
||||
uint32_t state = button_read_state(drv);
|
||||
syshandle_signal_read_ready(SYSHANDLE_BUTTON, &state);
|
||||
}
|
||||
}
|
||||
|
||||
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
||||
void* param) {
|
||||
button_driver_t* drv = (button_driver_t*)context;
|
||||
button_fsm_t* fsm = &drv->tls[task_id];
|
||||
|
||||
uint32_t new_state = *(uint32_t*)param;
|
||||
|
||||
return button_fsm_event_ready(fsm, new_state);
|
||||
}
|
||||
|
||||
static const syshandle_vmt_t g_button_handle_vmt = {
|
||||
.task_created = on_task_created,
|
||||
.task_killed = NULL,
|
||||
.check_read_ready = on_check_read_ready,
|
||||
.check_write_ready = NULL,
|
||||
.poll = on_event_poll,
|
||||
};
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
|
@ -20,23 +20,19 @@
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <io/button.h>
|
||||
#include <sys/sysevent_source.h>
|
||||
#include <sys/unix/sdl_event.h>
|
||||
|
||||
#include "../button_fsm.h"
|
||||
|
||||
// Button driver state
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
|
||||
#ifdef BTN_LEFT_KEY
|
||||
bool left_down;
|
||||
#endif
|
||||
#ifdef BTN_RIGHT_KEY
|
||||
bool right_down;
|
||||
#endif
|
||||
#ifdef BTN_POWER_KEY
|
||||
bool power_down;
|
||||
#endif
|
||||
// Global state of buttons
|
||||
uint32_t state;
|
||||
// Each task has its own state machine
|
||||
button_fsm_t tls[SYSTASK_MAX_TASKS];
|
||||
} button_driver_t;
|
||||
|
||||
// Button driver instance
|
||||
@ -44,8 +40,12 @@ static button_driver_t g_button_driver = {
|
||||
.initialized = false,
|
||||
};
|
||||
|
||||
// Forward declarations
|
||||
static const syshandle_vmt_t g_button_handle_vmt;
|
||||
static void button_sdl_event_filter(void* context, SDL_Event* sdl_event);
|
||||
|
||||
bool button_init(void) {
|
||||
button_driver_t *drv = &g_button_driver;
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return true;
|
||||
@ -53,79 +53,128 @@ bool button_init(void) {
|
||||
|
||||
memset(drv, 0, sizeof(button_driver_t));
|
||||
|
||||
if (!syshandle_register(SYSHANDLE_BUTTON, &g_button_handle_vmt, drv)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!sdl_events_register(button_sdl_event_filter, drv)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
drv->initialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool button_get_event(button_event_t *event) {
|
||||
button_driver_t *drv = &g_button_driver;
|
||||
|
||||
memset(event, 0, sizeof(button_event_t));
|
||||
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Event sdl_event;
|
||||
|
||||
if (SDL_PollEvent(&sdl_event) > 0 &&
|
||||
(sdl_event.type == SDL_KEYDOWN || sdl_event.type == SDL_KEYUP) &&
|
||||
!sdl_event.key.repeat) {
|
||||
bool down = (sdl_event.type == SDL_KEYDOWN);
|
||||
uint32_t evt_type = down ? BTN_EVENT_DOWN : BTN_EVENT_UP;
|
||||
|
||||
switch (sdl_event.key.keysym.sym) {
|
||||
#ifdef BTN_LEFT_KEY
|
||||
case BTN_LEFT_KEY:
|
||||
drv->left_down = down;
|
||||
event->event_type = evt_type;
|
||||
event->button = BTN_LEFT;
|
||||
return true;
|
||||
#endif
|
||||
#ifdef BTN_RIGHT_KEY
|
||||
case BTN_RIGHT_KEY:
|
||||
drv->right_down = down;
|
||||
event->event_type = evt_type;
|
||||
event->button = BTN_RIGHT;
|
||||
return true;
|
||||
#endif
|
||||
#ifdef BTN_POWER_KEY
|
||||
case BTN_POWER_KEY:
|
||||
drv->power_down = down;
|
||||
event->event_type = evt_type;
|
||||
event->button = BTN_POWER;
|
||||
return true;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
button_deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool button_is_down(button_t button) {
|
||||
button_driver_t *drv = &g_button_driver;
|
||||
void button_deinit(void) {
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
|
||||
syshandle_unregister(SYSHANDLE_BUTTON);
|
||||
|
||||
sdl_events_unregister(button_sdl_event_filter, drv);
|
||||
|
||||
memset(drv, 0, sizeof(button_driver_t));
|
||||
}
|
||||
|
||||
// Called from global event loop to filter and process SDL events
|
||||
static void button_sdl_event_filter(void* context, SDL_Event* sdl_event) {
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
|
||||
if (sdl_event->type != SDL_KEYDOWN && sdl_event->type != SDL_KEYUP) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sdl_event->key.repeat) {
|
||||
return;
|
||||
}
|
||||
|
||||
button_t button;
|
||||
|
||||
switch (sdl_event->key.keysym.sym) {
|
||||
#ifdef BTN_LEFT_KEY
|
||||
case BTN_LEFT_KEY:
|
||||
button = BTN_LEFT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef BTN_RIGHT_KEY
|
||||
case BTN_RIGHT_KEY:
|
||||
button = BTN_RIGHT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef BTN_POWER_KEY
|
||||
case BTN_POWER_KEY:
|
||||
button = BTN_POWER;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (sdl_event->type == SDL_KEYDOWN) {
|
||||
drv->state |= (1 << button);
|
||||
} else {
|
||||
drv->state &= ~(1 << button);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t button_read_state(button_driver_t* drv) {
|
||||
sdl_events_poll();
|
||||
return drv->state;
|
||||
}
|
||||
|
||||
bool button_get_event(button_event_t* event) {
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
memset(event, 0, sizeof(*event));
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (button) {
|
||||
#ifdef BTN_LEFT_KEY
|
||||
case BTN_LEFT:
|
||||
return drv->left_down;
|
||||
#endif
|
||||
#ifdef BTN_RIGHT_KEY
|
||||
case BTN_RIGHT:
|
||||
return drv->right_down;
|
||||
#endif
|
||||
#ifdef BTN_POWER_KEY
|
||||
case BTN_POWER:
|
||||
return drv->power_down;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
uint32_t new_state = button_read_state(drv);
|
||||
|
||||
button_fsm_t* fsm = &drv->tls[systask_id(systask_active())];
|
||||
return button_fsm_get_event(fsm, new_state, event);
|
||||
}
|
||||
|
||||
bool button_is_down(button_t button) {
|
||||
button_driver_t* drv = &g_button_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (button_read_state(drv) & (1 << button)) != 0;
|
||||
}
|
||||
|
||||
static void on_event_poll(void* context, bool read_awaited,
|
||||
bool write_awaited) {
|
||||
button_driver_t* drv = (button_driver_t*)context;
|
||||
|
||||
UNUSED(write_awaited);
|
||||
|
||||
if (read_awaited) {
|
||||
uint32_t state = button_read_state(drv);
|
||||
syshandle_signal_read_ready(SYSHANDLE_BUTTON, &state);
|
||||
}
|
||||
}
|
||||
|
||||
static bool on_check_read_ready(void* context, systask_id_t task_id,
|
||||
void* param) {
|
||||
button_driver_t* drv = (button_driver_t*)context;
|
||||
button_fsm_t* fsm = &drv->tls[task_id];
|
||||
|
||||
uint32_t new_state = *(uint32_t*)param;
|
||||
|
||||
return button_fsm_event_ready(fsm, new_state);
|
||||
}
|
||||
|
||||
static const syshandle_vmt_t g_button_handle_vmt = {
|
||||
.task_created = NULL,
|
||||
.task_killed = NULL,
|
||||
.check_read_ready = on_check_read_ready,
|
||||
.check_write_ready = NULL,
|
||||
.poll = on_event_poll,
|
||||
};
|
||||
|
@ -70,15 +70,11 @@ void ui_click(void) {
|
||||
|
||||
void ui_click(void) {
|
||||
for (;;) {
|
||||
button_event_t event = {0};
|
||||
button_get_event(&event);
|
||||
if (button_is_down(BTN_LEFT) && button_is_down(BTN_RIGHT)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
button_event_t event = {0};
|
||||
button_get_event(&event);
|
||||
if (!button_is_down(BTN_LEFT) && !button_is_down(BTN_RIGHT)) {
|
||||
break;
|
||||
}
|
||||
|
@ -362,8 +362,6 @@ int bootloader_main(void) {
|
||||
}
|
||||
}
|
||||
#elif defined USE_BUTTON
|
||||
button_event_t btn_evt = {0};
|
||||
button_get_event(&btn_evt);
|
||||
if (button_is_down(BTN_LEFT)) {
|
||||
touched = 1;
|
||||
}
|
||||
|
@ -67,10 +67,6 @@ static void test_button_combination(cli_t* cli, uint32_t timeout, button_t btn1,
|
||||
cli_trace(cli, "Waiting for button combination to be pressed...");
|
||||
|
||||
while (true) {
|
||||
// Event must be read before calling `button_is_down()`
|
||||
button_event_t e = {0};
|
||||
button_get_event(&e);
|
||||
|
||||
if (button_is_down(btn1) && button_is_down(btn2)) {
|
||||
break;
|
||||
} else if (ticks_expired(expire_time)) {
|
||||
@ -84,10 +80,6 @@ static void test_button_combination(cli_t* cli, uint32_t timeout, button_t btn1,
|
||||
cli_trace(cli, "Waiting for buttons to be released...");
|
||||
|
||||
while (true) {
|
||||
// Event must be read before calling `button_is_down()`
|
||||
button_event_t e = {0};
|
||||
button_get_event(&e);
|
||||
|
||||
if (!button_is_down(btn1) && !button_is_down(btn2)) {
|
||||
break;
|
||||
} else if (ticks_expired(expire_time)) {
|
||||
|
@ -50,6 +50,7 @@ def configure(
|
||||
|
||||
if "input" in features_wanted:
|
||||
sources += ["embed/io/button/unix/button.c"]
|
||||
sources += ["embed/io/button/button_fsm.c"]
|
||||
paths += ["embed/io/button/inc"]
|
||||
features_available.append("button")
|
||||
defines += [("USE_BUTTON", "1")]
|
||||
|
@ -50,6 +50,7 @@ def configure(
|
||||
|
||||
if "input" in features_wanted:
|
||||
sources += ["embed/io/button/stm32/button.c"]
|
||||
sources += ["embed/io/button/button_fsm.c"]
|
||||
paths += ["embed/io/button/inc"]
|
||||
features_available.append("button")
|
||||
defines += [("USE_BUTTON", "1")]
|
||||
|
@ -50,6 +50,7 @@ def configure(
|
||||
|
||||
if "input" in features_wanted:
|
||||
sources += ["embed/io/button/unix/button.c"]
|
||||
sources += ["embed/io/button/button_fsm.c"]
|
||||
paths += ["embed/io/button/inc"]
|
||||
features_available.append("button")
|
||||
defines += [("USE_BUTTON", "1")]
|
||||
|
@ -49,6 +49,7 @@ def configure(
|
||||
|
||||
if "input" in features_wanted:
|
||||
sources += ["embed/io/button/stm32/button.c"]
|
||||
sources += ["embed/io/button/button_fsm.c"]
|
||||
paths += ["embed/io/button/inc"]
|
||||
features_available.append("button")
|
||||
defines += [("USE_BUTTON", "1")]
|
||||
|
@ -63,6 +63,7 @@ def configure(
|
||||
paths += ["embed/io/touch/inc"]
|
||||
features_available.append("touch")
|
||||
sources += ["embed/io/button/stm32/button.c"]
|
||||
sources += ["embed/io/button/button_fsm.c"]
|
||||
paths += ["embed/io/button/inc"]
|
||||
features_available.append("button")
|
||||
defines += [
|
||||
|
@ -63,6 +63,7 @@ def configure(
|
||||
paths += ["embed/io/touch/inc"]
|
||||
features_available.append("touch")
|
||||
sources += ["embed/io/button/stm32/button.c"]
|
||||
sources += ["embed/io/button/button_fsm.c"]
|
||||
paths += ["embed/io/button/inc"]
|
||||
features_available.append("button")
|
||||
defines += [
|
||||
|
@ -63,6 +63,7 @@ def configure(
|
||||
paths += ["embed/io/touch/inc"]
|
||||
features_available.append("touch")
|
||||
sources += ["embed/io/button/stm32/button.c"]
|
||||
sources += ["embed/io/button/button_fsm.c"]
|
||||
paths += ["embed/io/button/inc"]
|
||||
features_available.append("button")
|
||||
defines += [
|
||||
|
Loading…
Reference in New Issue
Block a user