Add button signals.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2026-05-31 20:09:28 +02:00
parent d711f33721
commit eb26a96d3b
6 changed files with 139 additions and 72 deletions

View File

@@ -330,6 +330,7 @@ list(APPEND PICOKEYS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/src/pico_time.c
${CMAKE_CURRENT_LIST_DIR}/src/button.c
${CMAKE_CURRENT_LIST_DIR}/src/led/led.c
${CMAKE_CURRENT_LIST_DIR}/src/signal.c
)
if(ESP_PLATFORM)

View File

@@ -27,6 +27,7 @@
#include "driver/gpio.h"
#endif
#include "usb.h"
#include "signal.h"
extern void execute_tasks(void);
@@ -104,6 +105,10 @@ bool button_wait(void) {
if (button_timeout == 0) {
return false;
}
signal_user_presence_request_data_t data = {
.timeout = button_timeout / 1000,
};
signal_emit_param(SIGNAL_USER_PRESENCE_REQUEST, &data);
uint32_t start_button = board_millis();
bool timeout = false;
cancel_button = false;
@@ -130,6 +135,15 @@ bool button_wait(void) {
}
led_set_mode(led_mode);
req_button_pending = false;
if (timeout) {
signal_emit(SIGNAL_USER_PRESENCE_TIMEOUT);
}
else if (cancel_button) {
signal_emit(SIGNAL_USER_PRESENCE_CANCELLED);
}
else {
signal_emit(SIGNAL_USER_PRESENCE_COMPLETED);
}
return timeout || cancel_button;
}
#endif

View File

@@ -50,9 +50,6 @@ app_t *current_app = NULL;
const uint8_t *ccid_atr = NULL;
signal_t signals[MAX_SIGNALS] = {0};
uint8_t num_signals = 0;
bool app_exists(const uint8_t *aid, size_t aid_len) {
for (int a = 0; a < num_apps; a++) {
if (aid_len >= apps[a].aid[0] && !memcmp(apps[a].aid + 1, aid, apps[a].aid[0])) {
@@ -118,6 +115,9 @@ void execute_tasks(void) {
#endif
usb_task();
led_blinking_task();
#ifdef ENABLE_LVGL_UI
platform_ui_task();
#endif
}
static void core0_loop(void *arg) {
@@ -218,43 +218,3 @@ int main(void) {
return 0;
}
int signal_add(signal_code_t code, signal_flag_t flags, signal_handler_t handler) {
if (num_signals >= MAX_SIGNALS) {
return -1;
}
signals[num_signals].code = code;
signals[num_signals].flags = flags;
signals[num_signals].handler = handler;
num_signals++;
return 0;
}
int signal_remove(signal_code_t code, signal_handler_t handler) {
for (int i = 0; i < num_signals; i++) {
if (signals[i].code == code && signals[i].handler == handler) {
for (int j = i; j < num_signals - 1; j++) {
signals[j] = signals[j + 1];
}
num_signals--;
return 0;
}
}
return -1;
}
int signal_emit_param(signal_code_t code, void *data) {
for (int i = 0; i < num_signals; i++) {
if (signals[i].code == code) {
int ret = signals[i].handler(code, data);
if (ret != 0 && (signals[i].flags & SIGNAL_FLAG_ERROR_CONTINUE) == 0) {
return ret;
}
}
}
return 0;
}
int signal_emit(signal_code_t code) {
return signal_emit_param(code, NULL);
}

View File

@@ -172,33 +172,4 @@ extern bool is_req_button_pending(void);
extern int set_atr(void);
#define MAX_SIGNALS 32
typedef enum {
SIGNAL_NONE = 0,
SIGNAL_BOOT = 1,
SIGNAL_USB_MOUNTED = 2,
SIGNAL_BUTTON_PRESS = 3,
SIGNAL_BUTTON_RELEASE = 4,
SIGNAL_USER_PRESENCE_REQUEST = 5,
} signal_code_t;
typedef enum {
SIGNAL_FLAG_NONE = 0x0,
SIGNAL_FLAG_ERROR_CONTINUE = 0x1,
} signal_flag_t;
typedef int (*signal_handler_t)(signal_code_t, void *);
typedef struct {
signal_code_t code;
signal_flag_t flags;
signal_handler_t handler;
} signal_t;
extern int signal_add(signal_code_t code, signal_flag_t flags, signal_handler_t handler);
extern int signal_remove(signal_code_t code, signal_handler_t handler);
extern int signal_emit_param(signal_code_t code, void *data);
extern int signal_emit(signal_code_t code);
#endif

65
src/signal.c Normal file
View File

@@ -0,0 +1,65 @@
/*
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3.
*
* 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
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "picokeys.h"
#include "signal.h"
static signal_t signals[MAX_SIGNALS] = {0};
static uint8_t num_signals = 0;
int signal_add(signal_code_t code, signal_flag_t flags, signal_handler_t handler) {
if (num_signals >= MAX_SIGNALS) {
return PICOKEYS_ERR_NO_MEMORY;
}
if (handler == NULL) {
return PICOKEYS_ERR_NULL_PARAM;
}
signals[num_signals].code = code;
signals[num_signals].flags = flags;
signals[num_signals].handler = handler;
num_signals++;
return PICOKEYS_OK;
}
int signal_remove(signal_code_t code, signal_handler_t handler) {
for (int i = 0; i < num_signals; i++) {
if (signals[i].code == code && signals[i].handler == handler) {
for (int j = i; j < num_signals - 1; j++) {
signals[j] = signals[j + 1];
}
num_signals--;
return PICOKEYS_OK;
}
}
return PICOKEYS_ERR_FILE_NOT_FOUND;
}
int signal_emit_param(signal_code_t code, void *data) {
for (int i = 0; i < num_signals; i++) {
if (signals[i].code == code) {
int ret = signals[i].handler(code, data);
if (ret != 0 && (signals[i].flags & SIGNAL_FLAG_ERROR_CONTINUE) == 0) {
return ret;
}
}
}
return PICOKEYS_ERR_FILE_NOT_FOUND;
}
int signal_emit(signal_code_t code) {
return signal_emit_param(code, NULL);
}

56
src/signal.h Normal file
View File

@@ -0,0 +1,56 @@
/*
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3.
*
* 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
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef _SIGNAL_H_
#define _SIGNAL_H_
#define MAX_SIGNALS 32
typedef enum {
SIGNAL_NONE = 0,
SIGNAL_BOOT = 1,
SIGNAL_USB_MOUNTED = 2,
SIGNAL_BUTTON_PRESS = 3,
SIGNAL_BUTTON_RELEASE = 4,
SIGNAL_USER_PRESENCE_REQUEST = 5,
SIGNAL_USER_PRESENCE_COMPLETED = 6,
SIGNAL_USER_PRESENCE_CANCELLED = 7,
SIGNAL_USER_PRESENCE_TIMEOUT = 8,
} signal_code_t;
typedef enum {
SIGNAL_FLAG_NONE = 0x0,
SIGNAL_FLAG_ERROR_CONTINUE = 0x1,
} signal_flag_t;
typedef int (*signal_handler_t)(signal_code_t, void *);
typedef struct {
uint32_t timeout;
} signal_user_presence_request_data_t;
typedef struct {
signal_code_t code;
signal_flag_t flags;
signal_handler_t handler;
} signal_t;
extern int signal_add(signal_code_t code, signal_flag_t flags, signal_handler_t handler);
extern int signal_remove(signal_code_t code, signal_handler_t handler);
extern int signal_emit_param(signal_code_t code, void *data);
extern int signal_emit(signal_code_t code);
#endif // _SIGNAL_H_