diff --git a/applications/app-loader/app-loader.c b/applications/app-loader/app-loader.c
index c1b31339c..df49b3e0a 100644
--- a/applications/app-loader/app-loader.c
+++ b/applications/app-loader/app-loader.c
@@ -36,7 +36,7 @@ static void render_callback(Canvas* canvas, void* _ctx) {
static void input_callback(InputEvent* input_event, void* _ctx) {
AppLoaderState* ctx = (AppLoaderState*)_ctx;
- if(input_event->state && input_event->input == InputBack) {
+ if(input_event->type == InputTypeShort && input_event->key == InputKeyBack) {
osThreadTerminate(ctx->app_thread_id);
view_port_enabled_set(ctx->view_port, false);
api_hal_timebase_insomnia_exit();
diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp
index 30e90507e..2dfe86ff8 100644
--- a/applications/cc1101-workaround/cc1101-workaround.cpp
+++ b/applications/cc1101-workaround/cc1101-workaround.cpp
@@ -237,8 +237,11 @@ const FreqConfig FREQ_LIST[] = {
{&bands[10], 0},
};
-extern "C" void cc1101_isr() {
- gpio_write((GpioPin*)&debug_0, gpio_read(&cc1101_g0_gpio));
+extern "C" void cc1101_isr(void* _pin, void* _ctx) {
+ uint32_t pin = (uint32_t)_pin;
+ if(pin == CC1101_G0_Pin) {
+ gpio_write((GpioPin*)&debug_0, gpio_read(&cc1101_g0_gpio));
+ }
}
typedef enum {
@@ -343,7 +346,7 @@ static void input_callback(InputEvent* input_event, void* ctx) {
}
extern "C" void cc1101_workaround(void* p) {
- osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(AppEvent), NULL);
+ osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(AppEvent), NULL);
furi_check(event_queue);
State _state;
@@ -383,7 +386,7 @@ extern "C" void cc1101_workaround(void* p) {
GpioPin cs_pin = {CC1101_CS_GPIO_Port, CC1101_CS_Pin};
gpio_init(&cc1101_g0_gpio, GpioModeInput);
-
+ api_interrupt_add(cc1101_isr, InterruptTypeExternalInterrupt, NULL);
// TODO open record
GpioPin* cs_pin_record = &cs_pin;
CC1101 cc1101(cs_pin_record);
@@ -425,7 +428,8 @@ extern "C" void cc1101_workaround(void* p) {
if(event_status == osOK) {
if(event.type == EventTypeKey) {
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyBack) {
printf("[cc1101] bye!\r\n");
cc1101.SpiStrobe(CC1101_SIDLE);
@@ -438,7 +442,8 @@ extern "C" void cc1101_workaround(void* p) {
furiac_exit(NULL);
}
- if(event.value.input.state && event.value.input.input == InputDown) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyDown) {
if(state->active_freq_idx > 0) {
state->active_freq_idx--;
}
@@ -448,7 +453,8 @@ extern "C" void cc1101_workaround(void* p) {
state->need_cc1101_conf = true;
}
- if(event.value.input.state && event.value.input.input == InputUp) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyUp) {
if(state->active_freq_idx < (sizeof(FREQ_LIST) / sizeof(FREQ_LIST[0]) - 1)) {
state->active_freq_idx++;
}
@@ -458,7 +464,8 @@ extern "C" void cc1101_workaround(void* p) {
state->need_cc1101_conf = true;
}
- if(event.value.input.state && event.value.input.input == InputRight) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyRight) {
/*
if(state->tx_level < (sizeof(TX_LEVELS) / sizeof(TX_LEVELS[0]) - 1)) {
state->tx_level++;
@@ -471,7 +478,8 @@ extern "C" void cc1101_workaround(void* p) {
state->need_cc1101_conf = true;
}
- if(event.value.input.state && event.value.input.input == InputLeft) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyLeft) {
/*
if(state->tx_level < (sizeof(TX_LEVELS) / sizeof(TX_LEVELS[0]) - 1)) {
state->tx_level++;
@@ -484,9 +492,14 @@ extern "C" void cc1101_workaround(void* p) {
state->need_cc1101_conf = true;
}
- if(event.value.input.input == InputOk) {
- state->mode = event.value.input.state ? ModeTx : ModeRx;
- state->need_cc1101_conf = true;
+ if(event.value.input.key == InputKeyOk) {
+ if(event.value.input.type == InputTypePress) {
+ state->mode = ModeTx;
+ state->need_cc1101_conf = true;
+ } else if(event.value.input.type == InputTypeRelease) {
+ state->mode = ModeRx;
+ state->need_cc1101_conf = true;
+ }
}
}
} else {
diff --git a/applications/dolphin/dolphin.c b/applications/dolphin/dolphin.c
index 33e08ebf9..ec52f9315 100644
--- a/applications/dolphin/dolphin.c
+++ b/applications/dolphin/dolphin.c
@@ -4,13 +4,13 @@ bool dolphin_view_first_start_input(InputEvent* event, void* context) {
furi_assert(event);
furi_assert(context);
Dolphin* dolphin = context;
- if(event->state) {
- if(event->input == InputLeft) {
+ if(event->type == InputTypeShort) {
+ if(event->key == InputKeyLeft) {
with_view_model(
dolphin->idle_view_first_start, (DolphinViewFirstStartModel * model) {
if(model->page > 0) model->page--;
});
- } else if(event->input == InputRight) {
+ } else if(event->key == InputKeyRight) {
uint32_t page;
with_view_model(
dolphin->idle_view_first_start,
@@ -30,13 +30,13 @@ bool dolphin_view_idle_main_input(InputEvent* event, void* context) {
furi_assert(context);
Dolphin* dolphin = context;
- if(event->state) {
- if(event->input == InputOk) {
+ if(event->type == InputTypeShort) {
+ if(event->key == InputKeyOk) {
with_value_mutex(
dolphin->menu_vm, (Menu * menu) { menu_ok(menu); });
- } else if(event->input == InputUp) {
+ } else if(event->key == InputKeyUp) {
view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleStats);
- } else if(event->input == InputDown) {
+ } else if(event->key == InputKeyDown) {
view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleDebug);
}
}
@@ -49,13 +49,13 @@ bool dolphin_view_idle_stats_input(InputEvent* event, void* context) {
furi_assert(context);
Dolphin* dolphin = context;
- if(!event->state) return false;
+ if(event->type != InputTypeShort) return false;
- if(event->input == InputLeft) {
+ if(event->key == InputKeyLeft) {
dolphin_deed(dolphin, DolphinDeedWrong);
- } else if(event->input == InputRight) {
+ } else if(event->key == InputKeyRight) {
dolphin_deed(dolphin, DolphinDeedIButtonRead);
- } else if(event->input == InputOk) {
+ } else if(event->key == InputKeyOk) {
dolphin_save(dolphin);
} else {
return false;
diff --git a/applications/examples/input_dump.c b/applications/examples/input_dump.c
index 806451719..2284e90eb 100644
--- a/applications/examples/input_dump.c
+++ b/applications/examples/input_dump.c
@@ -4,27 +4,17 @@
typedef union {
unsigned int packed;
- InputState state;
+ InputType state;
} InputDump;
-static void state_cb(const void* value, void* ctx) {
- InputDump dump = {.packed = 0};
- dump.state = *(InputState*)value;
-
- printf("state: %02x\r\n", dump.packed);
-}
-
static void event_cb(const void* value, void* ctx) {
const InputEvent* event = value;
- printf("event: %02x %s\r\n", event->input, event->state ? "pressed" : "released");
+ printf("event: %02x %s\r\n", event->key, event->type ? "pressed" : "released");
}
void application_input_dump(void* p) {
// open record
- ValueManager* state_record = furi_record_open("input_state");
- subscribe_pubsub(&state_record->pubsub, state_cb, NULL);
-
PubSub* event_record = furi_record_open("input_events");
subscribe_pubsub(event_record, event_cb, NULL);
diff --git a/applications/examples/strobe.c b/applications/examples/strobe.c
index ea922196a..8e8379483 100644
--- a/applications/examples/strobe.c
+++ b/applications/examples/strobe.c
@@ -7,11 +7,11 @@ static void event_cb(const void* value, void* ctx) {
uint32_t* delay_time = acquire_mutex(ctx, 0);
if(delay_time == NULL) return;
- if(event->input == InputUp && *delay_time < 1000) {
+ if(event->key == InputKeyUp && *delay_time < 1000) {
*delay_time += 5;
}
- if(event->input == InputDown && *delay_time > 10) {
+ if(event->key == InputKeyDown && *delay_time > 10) {
*delay_time -= 5;
}
release_mutex(ctx, delay_time);
diff --git a/applications/examples/vibro.c b/applications/examples/vibro.c
index 4189910db..fa4fdc2e6 100644
--- a/applications/examples/vibro.c
+++ b/applications/examples/vibro.c
@@ -10,9 +10,14 @@ static void button_handler(const void* value, void* _ctx) {
const InputEvent* event = value;
Ctx* ctx = (Ctx*)_ctx;
- if(event->input == InputOk) {
- gpio_write(ctx->vibro, event->state);
- gpio_write(ctx->led, !event->state);
+ if(event->key != InputKeyOk) return;
+
+ if(event->type == InputTypePress) {
+ gpio_write(ctx->led, false);
+ gpio_write(ctx->vibro, true);
+ } else if(event->type == InputTypeRelease) {
+ gpio_write(ctx->led, true);
+ gpio_write(ctx->vibro, false);
}
}
diff --git a/applications/floopper-bloopper b/applications/floopper-bloopper
index 318b5f6c4..598edd541 160000
--- a/applications/floopper-bloopper
+++ b/applications/floopper-bloopper
@@ -1 +1 @@
-Subproject commit 318b5f6c43b0219ec490a088ef51421fc8b94ac5
+Subproject commit 598edd54197d58b35d8cc2513549ddda3938fa38
diff --git a/applications/gpio-tester/gpio-tester.c b/applications/gpio-tester/gpio-tester.c
index 92b6bd915..765758681 100644
--- a/applications/gpio-tester/gpio-tester.c
+++ b/applications/gpio-tester/gpio-tester.c
@@ -58,7 +58,7 @@ static void input_callback(InputEvent* input_event, void* ctx) {
}
void app_gpio_test(void* p) {
- osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(AppEvent), NULL);
+ osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(AppEvent), NULL);
furi_check(event_queue);
State _state;
@@ -88,34 +88,41 @@ void app_gpio_test(void* p) {
AppEvent event;
while(1) {
- osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 150);
+ osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever);
State* state = (State*)acquire_mutex_block(&state_mutex);
if(event_status == osOK) {
if(event.type == EventTypeKey) {
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyBack) {
printf("[gpio-tester] bye!\r\n");
// TODO remove all view_ports create by app
view_port_enabled_set(view_port, false);
furiac_exit(NULL);
}
- if(event.value.input.state && event.value.input.input == InputRight) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyRight) {
if(state->gpio_index < (sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]) - 1)) {
state->gpio_index++;
}
}
- if(event.value.input.state && event.value.input.input == InputLeft) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyLeft) {
if(state->gpio_index > 0) {
state->gpio_index--;
}
}
- if(event.value.input.input == InputOk) {
- gpio_write(
- (GpioPin*)&GPIO_PINS[state->gpio_index].pin, event.value.input.state);
- gpio_write((GpioPin*)&led_gpio[1], !event.value.input.state);
+ if(event.value.input.key == InputKeyOk) {
+ if(event.value.input.type == InputTypePress) {
+ gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, true);
+ gpio_write((GpioPin*)&led_gpio[1], false);
+ } else if(event.value.input.type == InputTypeRelease) {
+ gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, false);
+ gpio_write((GpioPin*)&led_gpio[1], true);
+ }
}
}
}
diff --git a/applications/gui/modules/dialog.c b/applications/gui/modules/dialog.c
index 74298e95c..df20ad9a2 100644
--- a/applications/gui/modules/dialog.c
+++ b/applications/gui/modules/dialog.c
@@ -43,11 +43,11 @@ static bool dialog_view_input_callback(InputEvent* event, void* context) {
bool consumed = false;
// Process key presses only
- if(event->state && dialog->callback) {
- if(event->input == InputLeft) {
+ if(event->type == InputTypeShort && dialog->callback) {
+ if(event->key == InputKeyLeft) {
dialog->callback(DialogResultLeft, dialog->context);
consumed = true;
- } else if(event->input == InputRight) {
+ } else if(event->key == InputKeyRight) {
dialog->callback(DialogResultRight, dialog->context);
consumed = true;
}
diff --git a/applications/gui/modules/dialog_ex.c b/applications/gui/modules/dialog_ex.c
index 23534b4f2..4fbbc4f41 100644
--- a/applications/gui/modules/dialog_ex.c
+++ b/applications/gui/modules/dialog_ex.c
@@ -97,14 +97,14 @@ static bool dialog_ex_view_input_callback(InputEvent* event, void* context) {
});
// Process key presses only
- if(event->state && dialog_ex->callback) {
- if(event->input == InputLeft && left_text != NULL) {
+ if(event->type == InputTypeShort && dialog_ex->callback) {
+ if(event->key == InputKeyLeft && left_text != NULL) {
dialog_ex->callback(DialogExResultLeft, dialog_ex->context);
consumed = true;
- } else if(event->input == InputOk && center_text != NULL) {
+ } else if(event->key == InputKeyOk && center_text != NULL) {
dialog_ex->callback(DialogExResultCenter, dialog_ex->context);
consumed = true;
- } else if(event->input == InputRight && right_text != NULL) {
+ } else if(event->key == InputKeyRight && right_text != NULL) {
dialog_ex->callback(DialogExResultRight, dialog_ex->context);
consumed = true;
}
diff --git a/applications/gui/modules/popup.c b/applications/gui/modules/popup.c
index 73a855d28..8f79850cf 100644
--- a/applications/gui/modules/popup.c
+++ b/applications/gui/modules/popup.c
@@ -83,7 +83,7 @@ static bool popup_view_input_callback(InputEvent* event, void* context) {
bool consumed = false;
// Process key presses only
- if(event->state && popup->callback) {
+ if(event->type == InputTypeShort && popup->callback) {
popup->callback(popup->context);
consumed = true;
}
diff --git a/applications/gui/modules/submenu.c b/applications/gui/modules/submenu.c
index 02887fa1f..d2873c8c1 100644
--- a/applications/gui/modules/submenu.c
+++ b/applications/gui/modules/submenu.c
@@ -74,17 +74,17 @@ static bool submenu_view_input_callback(InputEvent* event, void* context) {
furi_assert(submenu);
bool consumed = false;
- if(event->state) {
- switch(event->input) {
- case InputUp:
+ if(event->type == InputTypeShort) {
+ switch(event->key) {
+ case InputKeyUp:
consumed = true;
submenu_process_up(submenu);
break;
- case InputDown:
+ case InputKeyDown:
consumed = true;
submenu_process_down(submenu);
break;
- case InputOk:
+ case InputKeyOk:
consumed = true;
submenu_process_ok(submenu);
break;
diff --git a/applications/gui/modules/text_input.c b/applications/gui/modules/text_input.c
index 80a7fe6bf..88441b843 100644
--- a/applications/gui/modules/text_input.c
+++ b/applications/gui/modules/text_input.c
@@ -289,25 +289,25 @@ static bool text_input_view_input_callback(InputEvent* event, void* context) {
furi_assert(text_input);
bool consumed = false;
- if(event->state) {
- switch(event->input) {
- case InputUp:
+ if(event->type == InputTypeShort) {
+ switch(event->key) {
+ case InputKeyUp:
text_input_handle_up(text_input);
consumed = true;
break;
- case InputDown:
+ case InputKeyDown:
text_input_handle_down(text_input);
consumed = true;
break;
- case InputLeft:
+ case InputKeyLeft:
text_input_handle_left(text_input);
consumed = true;
break;
- case InputRight:
+ case InputKeyRight:
text_input_handle_right(text_input);
consumed = true;
break;
- case InputOk:
+ case InputKeyOk:
text_input_handle_ok(text_input);
consumed = true;
break;
diff --git a/applications/gui/view_dispatcher.c b/applications/gui/view_dispatcher.c
index 1ec57a4f9..7cf9e422b 100644
--- a/applications/gui/view_dispatcher.c
+++ b/applications/gui/view_dispatcher.c
@@ -89,11 +89,11 @@ void view_dispatcher_input_callback(InputEvent* event, void* context) {
if(view_dispatcher->current_view) {
is_consumed = view_input(view_dispatcher->current_view, event);
}
- if(!is_consumed && event->state) {
+ if(!is_consumed && event->type == InputTypeShort) {
uint32_t view_id = VIEW_IGNORE;
- if(event->input == InputBack) {
+ if(event->key == InputKeyBack) {
view_id = view_previous(view_dispatcher->current_view);
- } else if(event->input == InputOk) {
+ } else if(event->key == InputKeyOk) {
view_id = view_next(view_dispatcher->current_view);
}
view_dispatcher_switch_to_view(view_dispatcher, view_id);
diff --git a/applications/ibutton/ibutton.cpp b/applications/ibutton/ibutton.cpp
index 06f76a385..8557d2d6c 100644
--- a/applications/ibutton/ibutton.cpp
+++ b/applications/ibutton/ibutton.cpp
@@ -28,10 +28,11 @@ void AppiButton::run() {
AppiButtonEvent event;
while(1) {
- if(get_event(&event, 20)) {
+ if(get_event(&event, 1024 / 8)) {
if(event.type == AppiButtonEvent::EventTypeKey) {
// press events
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyBack) {
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
api_hal_timebase_insomnia_exit();
@@ -39,11 +40,13 @@ void AppiButton::run() {
osThreadExit();
}
- if(event.value.input.state && event.value.input.input == InputLeft) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyLeft) {
decrease_mode();
}
- if(event.value.input.state && event.value.input.input == InputRight) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyRight) {
increase_mode();
}
}
diff --git a/applications/ibutton/ibutton_mode_cyfral_emulate.h b/applications/ibutton/ibutton_mode_cyfral_emulate.h
index 157e15ca2..e0b2cb609 100644
--- a/applications/ibutton/ibutton_mode_cyfral_emulate.h
+++ b/applications/ibutton/ibutton_mode_cyfral_emulate.h
@@ -29,11 +29,11 @@ void AppiButtonModeCyfralEmulate::event(AppiButtonEvent* event, AppiButtonState*
app->blink_green();
} else if(event->type == AppiButtonEvent::EventTypeKey) {
- if(event->value.input.state && event->value.input.input == InputUp) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyUp) {
app->decrease_cyfral_address();
}
- if(event->value.input.state && event->value.input.input == InputDown) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyDown) {
app->increase_cyfral_address();
}
}
diff --git a/applications/ibutton/ibutton_mode_cyfral_read.h b/applications/ibutton/ibutton_mode_cyfral_read.h
index a887289cf..236c8e22c 100644
--- a/applications/ibutton/ibutton_mode_cyfral_read.h
+++ b/applications/ibutton/ibutton_mode_cyfral_read.h
@@ -59,11 +59,11 @@ void AppiButtonModeCyfralRead::event(AppiButtonEvent* event, AppiButtonState* st
}
}
} else if(event->type == AppiButtonEvent::EventTypeKey) {
- if(event->value.input.state && event->value.input.input == InputUp) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyUp) {
app->decrease_cyfral_address();
}
- if(event->value.input.state && event->value.input.input == InputDown) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyDown) {
app->increase_cyfral_address();
}
}
diff --git a/applications/ibutton/ibutton_mode_dallas_emulate.h b/applications/ibutton/ibutton_mode_dallas_emulate.h
index 02a0f4dd4..d502a5789 100644
--- a/applications/ibutton/ibutton_mode_dallas_emulate.h
+++ b/applications/ibutton/ibutton_mode_dallas_emulate.h
@@ -48,11 +48,11 @@ void AppiButtonModeDallasEmulate::event(AppiButtonEvent* event, AppiButtonState*
app->blink_green();
}
} else if(event->type == AppiButtonEvent::EventTypeKey) {
- if(event->value.input.state && event->value.input.input == InputUp) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyUp) {
app->decrease_dallas_address();
}
- if(event->value.input.state && event->value.input.input == InputDown) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyDown) {
app->increase_dallas_address();
}
}
diff --git a/applications/ibutton/ibutton_mode_dallas_read.h b/applications/ibutton/ibutton_mode_dallas_read.h
index 2e23b38a4..0f3303421 100644
--- a/applications/ibutton/ibutton_mode_dallas_read.h
+++ b/applications/ibutton/ibutton_mode_dallas_read.h
@@ -46,11 +46,11 @@ void AppiButtonModeDallasRead::event(AppiButtonEvent* event, AppiButtonState* st
}
}
} else if(event->type == AppiButtonEvent::EventTypeKey) {
- if(event->value.input.state && event->value.input.input == InputUp) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyUp) {
app->decrease_dallas_address();
}
- if(event->value.input.state && event->value.input.input == InputDown) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyDown) {
app->increase_dallas_address();
}
}
diff --git a/applications/ibutton/ibutton_mode_dallas_write.h b/applications/ibutton/ibutton_mode_dallas_write.h
index 6f0f72c8b..135511aa7 100644
--- a/applications/ibutton/ibutton_mode_dallas_write.h
+++ b/applications/ibutton/ibutton_mode_dallas_write.h
@@ -39,11 +39,11 @@ void AppiButtonModeDallasWrite::event(AppiButtonEvent* event, AppiButtonState* s
}
} else if(event->type == AppiButtonEvent::EventTypeKey) {
- if(event->value.input.state && event->value.input.input == InputUp) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyUp) {
app->decrease_dallas_address();
}
- if(event->value.input.state && event->value.input.input == InputDown) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyDown) {
app->increase_dallas_address();
}
}
diff --git a/applications/input/input.c b/applications/input/input.c
index 658412ccf..92e8a0f4b 100644
--- a/applications/input/input.c
+++ b/applications/input/input.c
@@ -1,131 +1,72 @@
-#include
-#include
-#include
+#include "input_i.h"
-#ifdef APP_NFC
-void nfc_isr(void);
-#endif
+#define GPIO_Read(input_pin) \
+ (HAL_GPIO_ReadPin((GPIO_TypeDef*)input_pin.pin->port, input_pin.pin->pin) ^ \
+ input_pin.pin->inverted)
-#ifdef BUILD_CC1101
-void cc1101_isr();
-#endif
+static Input* input = NULL;
-static volatile bool initialized = false;
-static ValueManager input_state_record;
-static PubSub input_events_record;
-static Event event;
-static InputState input_state = {
- false,
-};
+void input_press_timer_callback(void* arg) {
+ InputPin* input_pin = arg;
+ InputEvent event;
+ event.key = input_pin->key;
+ event.type = InputTypeLong;
+ notify_pubsub(&input->event_pubsub, &event);
+}
-static void exti_input_callback(void* _pin, void* _ctx);
+void input_isr(void* _pin, void* _ctx) {
+ osThreadFlagsSet(input->thread, INPUT_THREAD_FLAG_ISR);
+}
-void input_task(void* p) {
- uint32_t state_bits = 0;
- uint8_t debounce_counters[INPUT_COUNT];
+void input_task() {
+ input = furi_alloc(sizeof(Input));
+ input->thread = osThreadGetId();
+ init_pubsub(&input->event_pubsub);
+ furi_record_create("input_events", &input->event_pubsub);
- if(!init_managed(&input_state_record, &input_state, sizeof(input_state))) {
- printf("[input_task] cannot initialize ValueManager for input_state\r\n");
- furiac_exit(NULL);
- }
- if(!init_pubsub(&input_events_record)) {
- printf("[input_task] cannot initialize PubSub for input_events\r\n");
- furiac_exit(NULL);
- }
- if(!init_event(&event)) {
- printf("[input_task] cannot initialize Event\r\n");
- furiac_exit(NULL);
+ const size_t pin_count = input_pins_count;
+ input->pin_states = furi_alloc(pin_count * sizeof(InputPinState));
+
+ api_interrupt_add(input_isr, InterruptTypeExternalInterrupt, NULL);
+
+ for(size_t i = 0; i < pin_count; i++) {
+ input->pin_states[i].pin = &input_pins[i];
+ input->pin_states[i].state = GPIO_Read(input->pin_states[i]);
+ input->pin_states[i].debounce = INPUT_DEBOUNCE_TICKS_HALF;
+ input->pin_states[i].press_timer =
+ osTimerNew(input_press_timer_callback, osTimerOnce, &input->pin_states[i], NULL);
}
- furi_record_create("input_state", &input_state_record);
- furi_record_create("input_events", &input_events_record);
-
- api_interrupt_add(exti_input_callback, InterruptTypeExternalInterrupt, NULL);
-
- // we ready to work
- initialized = true;
-
- // Force state update
- for(uint32_t i = 0; i < INPUT_COUNT; i++) {
- debounce_counters[i] = DEBOUNCE_TICKS / 2;
- }
-
- for(;;) {
- bool changed = false;
- for(uint32_t i = 0; i < INPUT_COUNT; i++) {
- bool input_state = false;
-
- // dirty hack, f3 has no CHARGING pin
- // TODO rewrite this
- if(i < GPIO_INPUT_PINS_COUNT) {
- input_state = gpio_read(&input_gpio[i]) ^ input_invert[i];
- }
-
- if(input_state) {
- if(debounce_counters[i] < DEBOUNCE_TICKS) {
- debounce_counters[i] += 1;
- changed = true;
- }
- } else {
- if(debounce_counters[i] > 0) {
- debounce_counters[i] -= 1;
- changed = true;
+ while(1) {
+ bool is_changing = false;
+ for(size_t i = 0; i < pin_count; i++) {
+ bool state = GPIO_Read(input->pin_states[i]);
+ if(input->pin_states[i].debounce > 0 &&
+ input->pin_states[i].debounce < INPUT_DEBOUNCE_TICKS) {
+ is_changing = true;
+ input->pin_states[i].debounce += (state ? 1 : -1);
+ } else if(input->pin_states[i].state != state) {
+ input->pin_states[i].state = state;
+ // Common state info
+ InputEvent event;
+ event.type = input->pin_states[i].state ? InputTypePress : InputTypeRelease;
+ event.key = input->pin_states[i].pin->key;
+ // Send Press/Release event
+ notify_pubsub(&input->event_pubsub, &event);
+ // Short/Long press logic
+ if(state) {
+ osTimerStart(input->pin_states[i].press_timer, INPUT_LONG_PRESS_TICKS);
+ } else if(osTimerStop(input->pin_states[i].press_timer) == osOK) {
+ event.type = InputTypeShort;
+ notify_pubsub(&input->event_pubsub, &event);
}
}
}
- if(!changed) {
- uint32_t new_state_bits = 0;
- for(uint32_t i = 0; i < INPUT_COUNT; i++) {
- if(debounce_counters[i] == DEBOUNCE_TICKS) {
- new_state_bits |= (1 << i);
- }
- }
- uint32_t changed_bits = new_state_bits ^ state_bits;
-
- if(changed_bits != 0) {
- // printf("[input] %02x -> %02x\n", state_bits, new_state_bits);
- InputState new_state = _BITS2STATE(new_state_bits);
- write_managed(&input_state_record, &new_state, sizeof(new_state), osWaitForever);
-
- state_bits = new_state_bits;
-
- for(uint32_t i = 0; i < INPUT_COUNT; i++) {
- if((changed_bits & (1 << i)) != 0) {
- bool state = (new_state_bits & (1 << i)) != 0;
- InputEvent event = {i, state};
- notify_pubsub(&input_events_record, &event);
- }
- }
- }
-
- // Sleep: wait for event
- wait_event(&event);
- } else {
+ if(is_changing) {
osDelay(1);
+ } else {
+ osThreadFlagsWait(INPUT_THREAD_FLAG_ISR, osFlagsWaitAny, osWaitForever);
}
}
}
-
-static void exti_input_callback(void* _pin, void* _ctx) {
- // interrupt manager get us pin constant, so...
- uint32_t pin = (uint32_t)_pin;
-
-#ifdef APP_NFC
- if(pin == NFC_IRQ_Pin) {
- nfc_isr();
- return;
- }
-#endif
-
-#ifdef BUILD_CC1101
- if(pin == CC1101_G0_Pin) {
- cc1101_isr();
- return;
- }
-#endif
-
- if(!initialized) return;
-
- signal_event(&event);
-}
\ No newline at end of file
diff --git a/applications/input/input.h b/applications/input/input.h
index 8e555c41a..a3500acbd 100644
--- a/applications/input/input.h
+++ b/applications/input/input.h
@@ -1,40 +1,19 @@
-#ifndef __INPUT_H
-#define __INPUT_H
+#pragma once
-#include
-
-#define INPUT_COUNT 7
+#include
+/* Input Types
+ * Some of them are physical events and some logical
+ */
typedef enum {
- InputUp = 0,
- InputDown,
- InputRight,
- InputLeft,
- InputOk,
- InputBack,
- InputCharging,
-} Input;
+ InputTypePress, /* Press event, emitted after debounce */
+ InputTypeRelease, /* Release event, emitted after debounce */
+ InputTypeShort, /* Short event, emitted after InputTypeRelease done withing INPUT_LONG_PRESS interval */
+ InputTypeLong, /* Long event, emmited after INPUT_LONG_PRESS interval, asynchronouse to InputTypeRelease */
+} InputType;
+/* Input Event, dispatches with PubSub */
typedef struct {
- Input input;
- bool state;
+ InputKey key;
+ InputType type;
} InputEvent;
-
-typedef struct {
- bool up : 1;
- bool down : 1;
- bool right : 1;
- bool left : 1;
- bool ok : 1;
- bool back : 1;
- bool charging : 1;
-} __attribute__((packed)) InputState;
-
-#define _BITS2STATE(bits) \
- { \
- .up = (((bits)&0x01) != 0), .down = (((bits)&0x02) != 0), .right = (((bits)&0x04) != 0), \
- .left = (((bits)&0x08) != 0), .ok = (((bits)&0x10) != 0), .back = (((bits)&0x20) != 0), \
- .charging = (((bits)&0x40) != 0) \
- }
-
-#endif /* __INPUT_H */
diff --git a/applications/input/input_i.h b/applications/input/input_i.h
new file mode 100644
index 000000000..2f0c883dd
--- /dev/null
+++ b/applications/input/input_i.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "input.h"
+
+#include
+#include
+#include
+#include
+
+#define INPUT_DEBOUNCE_TICKS_HALF (INPUT_DEBOUNCE_TICKS / 2)
+#define INPUT_LONG_PRESS_TICKS 2048
+#define INPUT_THREAD_FLAG_ISR 0x00000001
+
+/* Input pin state */
+typedef struct {
+ const InputPin* pin;
+ // State
+ volatile bool state;
+ volatile uint8_t debounce;
+ volatile osTimerId_t press_timer;
+} InputPinState;
+
+/* Input state */
+typedef struct {
+ osThreadId_t thread;
+ PubSub event_pubsub;
+ InputPinState* pin_states;
+} Input;
+
+/* Input press timer callback */
+void input_press_timer_callback(void* arg);
+
+/* Input interrupt handler */
+void input_isr(void* _pin, void* _ctx);
diff --git a/applications/irda/irda.c b/applications/irda/irda.c
index e43112cdd..6da6f0885 100644
--- a/applications/irda/irda.c
+++ b/applications/irda/irda.c
@@ -78,15 +78,15 @@ void render_carrier(Canvas* canvas, State* state) {
}
void input_carrier(AppEvent* event, State* state) {
- if(event->value.input.input == InputOk) {
- if(event->value.input.state) {
+ if(event->value.input.key == InputKeyOk) {
+ if(event->value.input.type == InputTypePress) {
irda_pwm_set(duty_cycles[state->carrier_duty_cycle_id], state->carrier_freq);
- } else {
+ } else if(event->value.input.type == InputTypeRelease) {
irda_pwm_stop();
}
}
- if(event->value.input.state && event->value.input.input == InputUp) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyUp) {
if(state->carrier_freq < 45000) {
state->carrier_freq += 1000;
} else {
@@ -94,7 +94,7 @@ void input_carrier(AppEvent* event, State* state) {
}
}
- if(event->value.input.state && event->value.input.input == InputDown) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyDown) {
uint8_t duty_cycles_count = sizeof(duty_cycles) / sizeof(duty_cycles[0]);
if(state->carrier_duty_cycle_id < (duty_cycles_count - 1)) {
state->carrier_duty_cycle_id++;
@@ -137,8 +137,8 @@ void render_packet(Canvas* canvas, State* state) {
}
void input_packet(AppEvent* event, State* state) {
- if(event->value.input.input == InputOk) {
- if(event->value.input.state) {
+ if(event->value.input.key == InputKeyOk) {
+ if(event->value.input.type == InputTypeShort) {
switch(state->packets[state->packet_id].protocol) {
case IRDA_NEC:
ir_nec_send(
@@ -156,13 +156,13 @@ void input_packet(AppEvent* event, State* state) {
}
}
- if(event->value.input.state && event->value.input.input == InputDown) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyDown) {
if(state->packet_id < (IRDA_PACKET_COUNT - 1)) {
state->packet_id++;
};
}
- if(event->value.input.state && event->value.input.input == InputUp) {
+ if(event->value.input.type == InputTypeShort && event->value.input.key == InputKeyUp) {
if(state->packet_id > 0) {
state->packet_id--;
};
@@ -299,7 +299,8 @@ void irda(void* p) {
if(event_status == osOK) {
if(event.type == EventTypeKey) {
// press events
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyBack) {
// remove all view_ports create by app
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
@@ -311,13 +312,15 @@ void irda(void* p) {
furiac_exit(NULL);
}
- if(event.value.input.state && event.value.input.input == InputLeft) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyLeft) {
if(state->mode_id > 0) {
state->mode_id--;
}
}
- if(event.value.input.state && event.value.input.input == InputRight) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyRight) {
if(state->mode_id < (mode_count - 1)) {
state->mode_id++;
}
diff --git a/applications/lf-rfid/lf-rfid.c b/applications/lf-rfid/lf-rfid.c
index b1bb1691a..382d5895f 100644
--- a/applications/lf-rfid/lf-rfid.c
+++ b/applications/lf-rfid/lf-rfid.c
@@ -161,7 +161,7 @@ static void extract_data(uint8_t* buf, uint8_t* customer, uint32_t* em_data) {
}
void lf_rfid_workaround(void* p) {
- osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(AppEvent), NULL);
+ osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(AppEvent), NULL);
// create pin
GpioPin pull_pin = {.pin = RFID_PULL_Pin, .port = RFID_PULL_GPIO_Port};
@@ -222,7 +222,7 @@ void lf_rfid_workaround(void* p) {
}
while(1) {
- osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100);
+ osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 1024 / 8);
if(event.type == EventTypeRx && event_status == osOK) {
uint32_t dt = (event.value.rx.dwt_value - prev_dwt) / (SystemCoreClock / 1000000.0f);
@@ -285,7 +285,8 @@ void lf_rfid_workaround(void* p) {
if(event_status == osOK) {
if(event.type == EventTypeKey) {
// press events
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyBack) {
hal_pwmn_stop(&TIM_C, TIM_CHANNEL_1); // TODO: move to furiac_onexit
gpio_init(pull_pin_record, GpioModeInput);
gpio_init((GpioPin*)&ibutton_gpio, GpioModeInput);
@@ -295,23 +296,28 @@ void lf_rfid_workaround(void* p) {
furiac_exit(NULL);
}
- if(event.value.input.state && event.value.input.input == InputUp) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyUp) {
state->dirty = true;
state->freq_khz += 10;
}
- if(event.value.input.state && event.value.input.input == InputDown) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyDown) {
state->dirty = true;
state->freq_khz -= 10;
}
- if(event.value.input.state && event.value.input.input == InputLeft) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyLeft) {
}
- if(event.value.input.state && event.value.input.input == InputRight) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyRight) {
}
- if(event.value.input.state && event.value.input.input == InputOk) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyOk) {
state->dirty = true;
state->on = !state->on;
}
diff --git a/applications/menu/menu_event.c b/applications/menu/menu_event.c
index eea029053..805127986 100644
--- a/applications/menu/menu_event.c
+++ b/applications/menu/menu_event.c
@@ -55,19 +55,19 @@ void menu_event_input_callback(InputEvent* input_event, void* context) {
MenuEvent* menu_event = context;
MenuMessage message;
- if(!input_event->state) return;
+ if(input_event->type != InputTypeShort) return;
- if(input_event->input == InputUp) {
+ if(input_event->key == InputKeyUp) {
message.type = MenuMessageTypeUp;
- } else if(input_event->input == InputDown) {
+ } else if(input_event->key == InputKeyDown) {
message.type = MenuMessageTypeDown;
- } else if(input_event->input == InputRight) {
+ } else if(input_event->key == InputKeyRight) {
message.type = MenuMessageTypeRight;
- } else if(input_event->input == InputLeft) {
+ } else if(input_event->key == InputKeyLeft) {
message.type = MenuMessageTypeLeft;
- } else if(input_event->input == InputOk) {
+ } else if(input_event->key == InputKeyOk) {
message.type = MenuMessageTypeOk;
- } else if(input_event->input == InputBack) {
+ } else if(input_event->key == InputKeyBack) {
message.type = MenuMessageTypeBack;
} else {
message.type = MenuMessageTypeUnknown;
diff --git a/applications/music-player/music-player.c b/applications/music-player/music-player.c
index c12408f0e..453724b3c 100644
--- a/applications/music-player/music-player.c
+++ b/applications/music-player/music-player.c
@@ -357,7 +357,7 @@ void music_player_thread(void* p) {
}
void music_player(void* p) {
- osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(MusicDemoEvent), NULL);
+ osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(MusicDemoEvent), NULL);
State _state;
_state.note_record = NULL;
@@ -384,7 +384,7 @@ void music_player(void* p) {
// open input record
PubSub* input_events_record = furi_record_open("input_events");
// prepare "do nothing" event
- InputEvent input_event = {InputRight, true};
+ InputEvent input_event = {InputKeyRight, true};
// start player thread
// TODO change to fuirac_start
@@ -406,24 +406,29 @@ void music_player(void* p) {
if(event_status == osOK) {
if(event.type == EventTypeKey) {
// press events
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyBack) {
}
- if(event.value.input.state && event.value.input.input == InputUp) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyUp) {
if(state->volume_id < state->volume_id_max - 1) state->volume_id++;
}
- if(event.value.input.state && event.value.input.input == InputDown) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyDown) {
if(state->volume_id > 0) state->volume_id--;
}
- if(event.value.input.state && event.value.input.input == InputLeft) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyLeft) {
}
- if(event.value.input.state && event.value.input.input == InputRight) {
+ if(event.value.input.type == InputTypePress &&
+ event.value.input.key == InputKeyRight) {
}
- if(event.value.input.input == InputOk) {
+ if(event.value.input.key == InputKeyOk) {
}
} else if(event.type == EventTypeNote) {
diff --git a/applications/sd-card-test/sd-card-test.cpp b/applications/sd-card-test/sd-card-test.cpp
index e2e736680..495cc28ed 100644
--- a/applications/sd-card-test/sd-card-test.cpp
+++ b/applications/sd-card-test/sd-card-test.cpp
@@ -57,8 +57,8 @@ public:
void render(Canvas* canvas);
template void set_text(std::initializer_list list);
template void set_error(std::initializer_list list);
- void wait_for_button(Input input_button);
- bool ask(Input input_button_cancel, Input input_button_ok);
+ void wait_for_button(InputKey input_button);
+ bool ask(InputKey input_button_cancel, InputKey input_button_ok);
void blink_red();
void set_red();
void blink_green();
@@ -145,7 +145,7 @@ void SdTest::run() {
"",
"press BACK to exit",
});
- wait_for_button(InputBack);
+ wait_for_button(InputKeyBack);
exit();
}
@@ -184,9 +184,9 @@ void SdTest::show_warning() {
"",
"press UP DOWN OK to continue"});
- wait_for_button(InputUp);
- wait_for_button(InputDown);
- wait_for_button(InputOk);
+ wait_for_button(InputKeyUp);
+ wait_for_button(InputKeyDown);
+ wait_for_button(InputKeyOk);
}
// get info about sd card, label, sn
@@ -216,7 +216,7 @@ void SdTest::get_sd_card_info() {
blink_green();
- wait_for_button(InputOk);
+ wait_for_button(InputKeyOk);
}
// prepare benchmark data (allocate data in ram)
@@ -296,7 +296,7 @@ void SdTest::write_benchmark() {
blink_green();
- wait_for_button(InputOk);
+ wait_for_button(InputKeyOk);
}
uint32_t SdTest::write_benchmark_internal(const uint32_t size, const uint32_t count, bool silent) {
@@ -436,7 +436,7 @@ void SdTest::read_benchmark() {
blink_green();
- wait_for_button(InputOk);
+ wait_for_button(InputKeyOk);
}
uint32_t SdTest::read_benchmark_internal(
@@ -590,7 +590,7 @@ void SdTest::hash_benchmark() {
blink_green();
- wait_for_button(InputOk);
+ wait_for_button(InputKeyOk);
}
void SdTest::cli_read_benchmark(string_t args, void* _ctx) {
@@ -786,18 +786,18 @@ void SdTest::cli_write_benchmark(string_t args, void* _ctx) {
}
// wait for button press
-void SdTest::wait_for_button(Input input_button) {
+void SdTest::wait_for_button(InputKey input_button) {
SdTestEvent event;
osMessageQueueReset(event_queue);
while(1) {
osStatus_t result = osMessageQueueGet(event_queue, &event, NULL, osWaitForever);
if(result == osOK && event.type == SdTestEvent::EventTypeKey) {
- if(event.value.input.state == true) {
- if(event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort) {
+ if(event.value.input.key == InputKeyBack) {
exit();
} else {
- if(event.value.input.input == input_button) {
+ if(event.value.input.key == input_button) {
blink_green();
break;
} else {
@@ -811,7 +811,7 @@ void SdTest::wait_for_button(Input input_button) {
}
// ask user to proceed or cancel
-bool SdTest::ask(Input input_button_cancel, Input input_button_ok) {
+bool SdTest::ask(InputKey input_button_cancel, InputKey input_button_ok) {
bool return_result;
SdTestEvent event;
osMessageQueueReset(event_queue);
@@ -819,15 +819,15 @@ bool SdTest::ask(Input input_button_cancel, Input input_button_ok) {
osStatus_t result = osMessageQueueGet(event_queue, &event, NULL, osWaitForever);
if(result == osOK && event.type == SdTestEvent::EventTypeKey) {
- if(event.value.input.state == true) {
- if(event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort) {
+ if(event.value.input.key == InputKeyBack) {
exit();
} else {
- if(event.value.input.input == input_button_ok) {
+ if(event.value.input.key == input_button_ok) {
blink_green();
return_result = true;
break;
- } else if(event.value.input.input == input_button_cancel) {
+ } else if(event.value.input.key == input_button_cancel) {
blink_green();
return_result = false;
break;
@@ -865,7 +865,7 @@ void SdTest::blink_green() {
template void SdTest::set_error(std::initializer_list list) {
set_text(list);
set_red();
- wait_for_button(InputBack);
+ wait_for_button(InputKeyBack);
exit();
}
diff --git a/applications/sd-filesystem/sd-filesystem.c b/applications/sd-filesystem/sd-filesystem.c
index 4afa1165a..3f4b18183 100644
--- a/applications/sd-filesystem/sd-filesystem.c
+++ b/applications/sd-filesystem/sd-filesystem.c
@@ -105,7 +105,7 @@ SdApp* sd_app_alloc() {
furiac_exit(NULL);
}
- sd_app->event_queue = osMessageQueueNew(1, sizeof(InputEvent), NULL);
+ sd_app->event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL);
// init view_port
sd_app->view_port = view_port_alloc();
@@ -127,7 +127,7 @@ SdApp* sd_app_alloc() {
return sd_app;
}
-bool app_sd_ask(SdApp* sd_app, Input input_true, Input input_false) {
+bool app_sd_ask(SdApp* sd_app, InputKey input_true, InputKey input_false) {
bool result;
InputEvent event;
@@ -136,11 +136,11 @@ bool app_sd_ask(SdApp* sd_app, Input input_true, Input input_false) {
osMessageQueueGet(sd_app->event_queue, &event, NULL, osWaitForever);
if(event_status == osOK) {
- if(event.state && event.input == input_true) {
+ if(event.type == InputTypeShort && event.key == input_true) {
result = true;
break;
}
- if(event.state && event.input == InputBack) {
+ if(event.type == InputTypeShort && event.key == InputKeyBack) {
result = false;
break;
}
@@ -254,7 +254,7 @@ void app_sd_info_callback(void* context) {
str_buffer[5]);
}
- app_sd_ask(sd_app, InputBack, InputBack);
+ app_sd_ask(sd_app, InputKeyBack, InputKeyBack);
sd_set_lines(sd_app, 0);
view_port_enabled_set(sd_app->view_port, false);
@@ -294,7 +294,7 @@ void app_sd_format_callback(void* context) {
view_port_enabled_set(sd_app->view_port, true);
// wait for input
- if(!app_sd_ask(sd_app, InputUp, InputBack)) {
+ if(!app_sd_ask(sd_app, InputKeyUp, InputKeyBack)) {
view_port_enabled_set(sd_app->view_port, false);
return;
}
@@ -313,7 +313,7 @@ void app_sd_format_callback(void* context) {
}
// wait for BACK
- app_sd_ask(sd_app, InputBack, InputBack);
+ app_sd_ask(sd_app, InputKeyBack, InputKeyBack);
view_port_enabled_set(sd_app->view_port, false);
}
@@ -357,7 +357,7 @@ void app_sd_eject_callback(void* context) {
sd_set_lines(sd_app, 1, "SD card can be pulled out");
// wait for BACK
- app_sd_ask(sd_app, InputBack, InputBack);
+ app_sd_ask(sd_app, InputKeyBack, InputKeyBack);
view_port_enabled_set(sd_app->view_port, false);
}
diff --git a/applications/sd-nfc/sdnfc.cpp b/applications/sd-nfc/sdnfc.cpp
index 1a63715a2..032afa1bf 100644
--- a/applications/sd-nfc/sdnfc.cpp
+++ b/applications/sd-nfc/sdnfc.cpp
@@ -105,7 +105,8 @@ void AppSdNFC::run() {
if(get_event(&event, 1000)) {
if(event.type == AppSdNFCEvent::EventTypeKey) {
// press events
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort &&
+ event.value.input.key == InputKeyBack) {
exit();
}
}
diff --git a/applications/template/template.c.example b/applications/template/template.c.example
index d86805c9d..7cd7975b3 100644
--- a/applications/template/template.c.example
+++ b/applications/template/template.c.example
@@ -38,7 +38,7 @@ static void input_callback(InputEvent* input_event, void* ctx) {
}
void template_app(void* p) {
- osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(Event), NULL);
+ osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(Event), NULL);
State _state;
/* init state here */
@@ -72,22 +72,22 @@ void template_app(void* p) {
if(event_status == osOK) {
if(event.type == EventTypeKey) {
// press events
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyBack) {
}
- if(event.value.input.state && event.value.input.input == InputUp) {
+ if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyUp) {
}
- if(event.value.input.state && event.value.input.input == InputDown) {
+ if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyDown) {
}
- if(event.value.input.state && event.value.input.input == InputLeft) {
+ if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyLeft) {
}
- if(event.value.input.state && event.value.input.input == InputRight) {
+ if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyRight) {
}
- if(event.value.input.input == InputOk) {
+ if(event.value.input.key == InputKeyOk) {
}
}
} else {
diff --git a/firmware/targets/f4/Src/target-resources.c b/firmware/targets/f4/Src/target-resources.c
deleted file mode 100644
index e14619e67..000000000
--- a/firmware/targets/f4/Src/target-resources.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "main.h"
-#include
-
-const bool input_invert[GPIO_INPUT_PINS_COUNT] = {
- true, // {BUTTON_UP_GPIO_Port, BUTTON_UP_Pin},
- true, // {BUTTON_DOWN_GPIO_Port, BUTTON_DOWN_Pin},
- true, // {BUTTON_RIGHT_GPIO_Port, BUTTON_RIGHT_Pin},
- true, // {BUTTON_LEFT_GPIO_Port, BUTTON_LEFT_Pin},
- false, // {BUTTON_OK_GPIO_Port, BUTTON_OK_Pin},
- true, // {BUTTON_BACK_GPIO_Port, BUTTON_BACK_Pin},
-};
diff --git a/firmware/targets/f4/api-hal/api-hal-resources.c b/firmware/targets/f4/api-hal/api-hal-resources.c
index d65d0fb63..369e9f4b5 100644
--- a/firmware/targets/f4/api-hal/api-hal-resources.c
+++ b/firmware/targets/f4/api-hal/api-hal-resources.c
@@ -1,15 +1,30 @@
+#include
#include "main.h"
#include
-const GpioPin input_gpio[GPIO_INPUT_PINS_COUNT] = {
- {BUTTON_UP_GPIO_Port, BUTTON_UP_Pin},
- {BUTTON_DOWN_GPIO_Port, BUTTON_DOWN_Pin},
- {BUTTON_RIGHT_GPIO_Port, BUTTON_RIGHT_Pin},
- {BUTTON_LEFT_GPIO_Port, BUTTON_LEFT_Pin},
- {BUTTON_OK_GPIO_Port, BUTTON_OK_Pin},
- {BUTTON_BACK_GPIO_Port, BUTTON_BACK_Pin},
+const InputPin input_pins[] = {
+ {.port = BUTTON_UP_GPIO_Port, .pin = BUTTON_UP_Pin, .key = InputKeyUp, .inverted = true},
+ {.port = BUTTON_DOWN_GPIO_Port,
+ .pin = BUTTON_DOWN_Pin,
+ .key = InputKeyDown,
+ .inverted = true},
+ {.port = BUTTON_RIGHT_GPIO_Port,
+ .pin = BUTTON_RIGHT_Pin,
+ .key = InputKeyRight,
+ .inverted = true},
+ {.port = BUTTON_LEFT_GPIO_Port,
+ .pin = BUTTON_LEFT_Pin,
+ .key = InputKeyLeft,
+ .inverted = true},
+ {.port = BUTTON_OK_GPIO_Port, .pin = BUTTON_OK_Pin, .key = InputKeyOk, .inverted = false},
+ {.port = BUTTON_BACK_GPIO_Port,
+ .pin = BUTTON_BACK_Pin,
+ .key = InputKeyBack,
+ .inverted = true},
};
+const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);
+
const GpioPin led_gpio[3] = {
{LED_RED_GPIO_Port, LED_RED_Pin},
{LED_GREEN_GPIO_Port, LED_GREEN_Pin},
diff --git a/firmware/targets/f4/api-hal/api-hal-resources.h b/firmware/targets/f4/api-hal/api-hal-resources.h
index eaedc85b3..53b3f7e5b 100644
--- a/firmware/targets/f4/api-hal/api-hal-resources.h
+++ b/firmware/targets/f4/api-hal/api-hal-resources.h
@@ -2,11 +2,28 @@
#include "main.h"
#include
-#define DEBOUNCE_TICKS 10
-#define GPIO_INPUT_PINS_COUNT 6
+/* Input Related Constants */
+#define INPUT_DEBOUNCE_TICKS 20
-extern const GpioPin input_gpio[GPIO_INPUT_PINS_COUNT];
-extern const bool input_invert[GPIO_INPUT_PINS_COUNT];
+/* Input Keys */
+typedef enum {
+ InputKeyUp,
+ InputKeyDown,
+ InputKeyRight,
+ InputKeyLeft,
+ InputKeyOk,
+ InputKeyBack,
+} InputKey;
+
+typedef struct {
+ const GPIO_TypeDef* port;
+ const uint16_t pin;
+ const InputKey key;
+ const bool inverted;
+} InputPin;
+
+extern const InputPin input_pins[];
+extern const size_t input_pins_count;
extern const GpioPin led_gpio[3];
extern const GpioPin backlight_gpio;
diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c
index 00ffb0b6e..8c51e7dcd 100644
--- a/lib/ST25RFAL002/platform.c
+++ b/lib/ST25RFAL002/platform.c
@@ -1,14 +1,18 @@
#include "platform.h"
#include
#include
+#include
#include
static osThreadAttr_t platform_irq_thread_attr;
static volatile osThreadId_t platform_irq_thread_id = NULL;
static volatile PlatformIrqCallback platform_irq_callback = NULL;
-void nfc_isr() {
- if(platform_irq_callback && platformGpioIsHigh( ST25R_INT_PORT, ST25R_INT_PIN )) {
+void nfc_isr(void* _pin, void* _ctx) {
+ uint32_t pin = (uint32_t)_pin;
+ if(pin == NFC_IRQ_Pin
+ && platform_irq_callback
+ && platformGpioIsHigh(ST25R_INT_PORT, ST25R_INT_PIN)) {
osThreadFlagsSet(platform_irq_thread_id, 0x1);
}
}
@@ -28,6 +32,7 @@ void platformSetIrqCallback(PlatformIrqCallback callback) {
platform_irq_thread_attr.stack_size = 512;
platform_irq_thread_attr.priority = osPriorityISR;
platform_irq_thread_id = osThreadNew(platformIrqWorker, NULL, &platform_irq_thread_attr);
+ api_interrupt_add(nfc_isr, InterruptTypeExternalInterrupt, NULL);
}
HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t len) {
diff --git a/lib/app-template/app-template.cpp b/lib/app-template/app-template.cpp
index b04210f14..d085f0c55 100644
--- a/lib/app-template/app-template.cpp
+++ b/lib/app-template/app-template.cpp
@@ -65,12 +65,12 @@ void AppExample::run() {
if(get_event(&event, 1000)) {
if(event.type == AppExampleEvent::EventTypeKey) {
// press events
- if(event.value.input.state && event.value.input.input == InputBack) {
+ if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyBack) {
printf("bye!\n");
exit();
}
- if(event.value.input.state && event.value.input.input == InputUp) {
+ if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyUp) {
// to read or write state you need to execute
// acquire modify release state
acquire_state();