summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--buttons.cpp4
-rw-r--r--buttons.hpp3
-rw-r--r--pico-watch.cpp18
3 files changed, 17 insertions, 8 deletions
diff --git a/buttons.cpp b/buttons.cpp
index c919562..15e0ff7 100644
--- a/buttons.cpp
+++ b/buttons.cpp
@@ -5,7 +5,7 @@
#include "api.hpp"
// From pico-watch.c:
extern int app_btnpressed(int app_id, uint gpio);
-extern void app_switch(int old_appid, int new_appid);
+extern void app_switch_request(int);
extern Api app_api;
//const uint BUTTON_PINS[] = {BUTTON_HOME, BUTTON_SELECT, BUTTON_MODE, BUTTON_UP, BUTTON_DOWN};
@@ -15,7 +15,7 @@ void gpio_interrupt_cb(uint gpio, uint32_t events) {
if (app_api.m_interpret_button_press) {
if (gpio == BUTTON_HOME && (g_s.current_app != 0)) // Home app
- app_switch(g_s.current_app, 0);
+ app_switch_request(0);
else
app_btnpressed(g_s.current_app, gpio);
}
diff --git a/buttons.hpp b/buttons.hpp
index b8ecbc3..fa05e4e 100644
--- a/buttons.hpp
+++ b/buttons.hpp
@@ -16,7 +16,8 @@ struct global_status {
int current_app = 0;
bool is_sleeping = false;
bool app_ready = true;
- bool app_rendering = false;
+ bool app_switch_requested = false;
+ int app_switch_to_app = 0;
// Debounce control
// See https://www.raspberrypi.org/forums/viewtopic.php?f=145&t=301522#p1812063
diff --git a/pico-watch.cpp b/pico-watch.cpp
index f3b8e4a..d593d45 100644
--- a/pico-watch.cpp
+++ b/pico-watch.cpp
@@ -98,11 +98,15 @@ bool repeating_callback(struct repeating_timer *t) {
return true;
}
+void app_switch_request(int to_appid) {
+ if (!g_s.app_switch_requested)
+ g_s.app_switch_to_app = to_appid;
+ g_s.app_switch_requested = true;
+ app_api.performance_render_interval_set(0); // This will be reset on new app init
+}
+
void app_switch(int old_appid, int new_appid) {
g_s.app_ready = false;
- // FIXME: race condition when pressing on HOME while app is rendering!
- // The system is blocked waiting for the app to finish rendering, which will never happen. To fix the problem, app switching has to be a flag (c.f struct) that is set, and checked before rendering app. "if (app_switching.requested) app_switch(...);" We will not need anymore the app_rendering flag, as the check is done while the app is not rendering.
- while (g_s.app_rendering); // Wait for the app to finish rendering cycle
if (APPS_DESTROY_ON_EXIT[old_appid])
app_destroy(old_appid);
g_s.current_app = app_init(new_appid);
@@ -120,12 +124,16 @@ int main() {
app_init(g_s.current_app);
while (1) {
+ if (g_s.app_switch_requested) {
+ app_switch(g_s.current_app, g_s.app_switch_to_app);
+ g_s.app_switch_requested = false;
+ }
+
if (g_s.app_ready && !g_s.is_sleeping) {
- g_s.app_rendering = true;
app_render(g_s.current_app);
app_api.display_write_backbuffer();
- g_s.app_rendering = false;
}
+
if (g_s.is_sleeping) __wfi();
else sleep_ms(app_api.performance_render_interval_get());
}