aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConfuSomu2021-08-23 01:00:18 +0200
committerConfuSomu2021-08-23 01:00:18 +0200
commitf2c4de8739bd8c5bd121c823a1f54eae294e2515 (patch)
tree2f1da69380f111e81a147bcb409811da153a40c5
parent7c4ed9a4261b3c4ebb6bf5f1047507170f7c7e16 (diff)
downloadpico-watch-f2c4de8739bd8c5bd121c823a1f54eae294e2515.tar
pico-watch-f2c4de8739bd8c5bd121c823a1f54eae294e2515.tar.gz
pico-watch-f2c4de8739bd8c5bd121c823a1f54eae294e2515.zip
Implement BaseApp method called when btn released
I have done some basic testing using breakpoints. I plan to build a app used for testing the API and the feature set in the future.
-rw-r--r--app/app_manager.cpp4
-rw-r--r--app/app_manager.hpp3
-rw-r--r--app/base_app.hpp5
-rw-r--r--buttons.cpp33
4 files changed, 35 insertions, 10 deletions
diff --git a/app/app_manager.cpp b/app/app_manager.cpp
index 01bf3fd..b05b258 100644
--- a/app/app_manager.cpp
+++ b/app/app_manager.cpp
@@ -93,6 +93,10 @@ void app_mgr::app_btnpressed(BaseApp* app, uint gpio, unsigned long delta) {
app_act_on_return_value(app, app->btnpressed(&app_api, gpio, delta));
}
+void app_mgr::app_btnreleased(BaseApp* app, uint gpio, unsigned long delta) {
+ app_act_on_return_value(app, app->btnreleased(&app_api, gpio, delta));
+}
+
void app_mgr::app_destroy(BaseApp* to_erase) {
auto erase_it = std::find(open_apps.begin(), open_apps.end(), to_erase); // "it" meaning iterator
if (erase_it != open_apps.end()) {
diff --git a/app/app_manager.hpp b/app/app_manager.hpp
index b7783ea..e094ffb 100644
--- a/app/app_manager.hpp
+++ b/app/app_manager.hpp
@@ -16,6 +16,9 @@ namespace app_mgr {
// Delta is in ms, from time_since_button_press()
void app_btnpressed(BaseApp* app, uint gpio, unsigned long delta);
+ // Call when a button is released
+ void app_btnreleased(BaseApp* app, uint gpio, unsigned long delta);
+
// This should only be called by pico-watch.cpp before app rendering, to chage the current app.
void app_switch(BaseApp* app, int new_appid);
diff --git a/app/base_app.hpp b/app/base_app.hpp
index c9367de..1f0c319 100644
--- a/app/base_app.hpp
+++ b/app/base_app.hpp
@@ -22,6 +22,11 @@ class BaseApp {
// where app_attribues is an instance of AppAttributes
virtual AppReturnValues render(Api *app_api) = 0; // Has to be implemented
+ // Called when a button is released.
+ // \param delta The time since the button has been last released. Delta is in ms, from time_since_button_press().
virtual AppReturnValues btnpressed(Api *app_api, uint gpio, unsigned long delta) {return AppReturnValues::OK;};
+ // Called when a button is released.
+ // \param delta The time since the button has been pressed. Delta is in ms, from time_since_button_press().
+ virtual AppReturnValues btnreleased(Api *app_api, uint gpio, unsigned long delta) {return AppReturnValues::OK;};
virtual AppReturnValues bgrefresh(Api *app_api, bool in_foreground) {return AppReturnValues::OK;};
};
diff --git a/buttons.cpp b/buttons.cpp
index 1b92aa6..bc0ba74 100644
--- a/buttons.cpp
+++ b/buttons.cpp
@@ -10,19 +10,32 @@ extern Api app_api;
//const uint BUTTON_PINS[] = {BUTTON_HOME, BUTTON_SELECT, BUTTON_MODE, BUTTON_UP, BUTTON_DOWN};
+// Rising edge and falling edge are "inverted" as every button is set to be pulled up. This means that the falling edge is done when the button is pressed and the rising edge when the button is released.
+
void gpio_interrupt_cb(uint gpio, uint32_t events) {
auto delta_since_press = time_since_button_press();
if (delta_since_press > g_s.button_delay_time) {
if (app_api.m_interpret_button_press) {
- if (gpio == BUTTON_HOME && (g_s.foreground_app->app_get_attributes().id != 0)) // Home app
- app_mgr::app_switch_request(0);
- else
- app_mgr::app_btnpressed(g_s.foreground_app, gpio, delta_since_press);
+ switch (events) {
+ case GPIO_IRQ_EDGE_FALL:
+ if (gpio == BUTTON_HOME && (g_s.foreground_app->app_get_attributes().id != 0)) // Home app
+ app_mgr::app_switch_request(0);
+ else
+ app_mgr::app_btnpressed(g_s.foreground_app, gpio, delta_since_press);
+ break;
+
+ case GPIO_IRQ_EDGE_RISE:
+ if (gpio != BUTTON_HOME) // For simplicity's sake
+ app_mgr::app_btnreleased(g_s.foreground_app, gpio, delta_since_press);
+ break;
+ }
+
}
- app_api.button_last_set(gpio);
+ if (events == GPIO_IRQ_EDGE_FALL)
+ app_api.button_last_set(gpio);
g_s.button_last_pressed_time = to_ms_since_boot(get_absolute_time());
}
}
@@ -35,19 +48,19 @@ unsigned long time_since_button_press() {
void init_buttons() {
gpio_init(BUTTON_HOME);
gpio_pull_up(BUTTON_HOME);
- gpio_set_irq_enabled_with_callback(BUTTON_HOME, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb);
+ gpio_set_irq_enabled_with_callback(BUTTON_HOME, GPIO_IRQ_EDGE_FALL|GPIO_IRQ_EDGE_RISE, true, &gpio_interrupt_cb);
gpio_init(BUTTON_SELECT);
gpio_pull_up(BUTTON_SELECT);
- gpio_set_irq_enabled_with_callback(BUTTON_SELECT, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb);
+ gpio_set_irq_enabled_with_callback(BUTTON_SELECT, GPIO_IRQ_EDGE_FALL|GPIO_IRQ_EDGE_RISE, true, &gpio_interrupt_cb);
gpio_init(BUTTON_MODE);
gpio_pull_up(BUTTON_MODE);
- gpio_set_irq_enabled_with_callback(BUTTON_MODE, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb);
+ gpio_set_irq_enabled_with_callback(BUTTON_MODE, GPIO_IRQ_EDGE_FALL|GPIO_IRQ_EDGE_RISE, true, &gpio_interrupt_cb);
gpio_init(BUTTON_DOWN);
gpio_pull_up(BUTTON_DOWN);
- gpio_set_irq_enabled_with_callback(BUTTON_DOWN, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb);
+ gpio_set_irq_enabled_with_callback(BUTTON_DOWN, GPIO_IRQ_EDGE_FALL|GPIO_IRQ_EDGE_RISE, true, &gpio_interrupt_cb);
gpio_init(BUTTON_UP);
gpio_pull_up(BUTTON_UP);
- gpio_set_irq_enabled_with_callback(BUTTON_UP, GPIO_IRQ_EDGE_FALL , true, &gpio_interrupt_cb);
+ gpio_set_irq_enabled_with_callback(BUTTON_UP, GPIO_IRQ_EDGE_FALL|GPIO_IRQ_EDGE_RISE, true, &gpio_interrupt_cb);
/* For some reason for loop does not work… TODO
for (int i=0; i < NUMBER_OF_BUTTONS; i++) {