summaryrefslogtreecommitdiff
path: root/src/buttonhandler/ButtonHandler.cpp
diff options
context:
space:
mode:
authorJean-François Milants <jf@codingfield.com>2021-11-11 09:08:20 (GMT)
committerJean-François Milants <jf@codingfield.com>2021-11-11 09:08:20 (GMT)
commitf6d0ec49e6f2669c64729b081eb3342f02151f4a (patch)
tree7e21c83726bd3e0d18ec4ebe871274b1dbe2eb38 /src/buttonhandler/ButtonHandler.cpp
parentf41aaad6836ae348d1b5b084b4533b636f516b93 (diff)
parenta57fda6ba4a29866083a1254ffdf92939d00e182 (diff)
Merge branch 'develop'
# Conflicts: # doc/buildAndProgram.md
Diffstat (limited to 'src/buttonhandler/ButtonHandler.cpp')
-rw-r--r--src/buttonhandler/ButtonHandler.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/buttonhandler/ButtonHandler.cpp b/src/buttonhandler/ButtonHandler.cpp
new file mode 100644
index 0000000..91e8bbd
--- /dev/null
+++ b/src/buttonhandler/ButtonHandler.cpp
@@ -0,0 +1,78 @@
+#include "ButtonHandler.h"
+
+using namespace Pinetime::Controllers;
+
+void ButtonTimerCallback(TimerHandle_t xTimer) {
+ auto* sysTask = static_cast<Pinetime::System::SystemTask*>(pvTimerGetTimerID(xTimer));
+ sysTask->PushMessage(Pinetime::System::Messages::HandleButtonTimerEvent);
+}
+
+void ButtonHandler::Init(Pinetime::System::SystemTask* systemTask) {
+ buttonTimer = xTimerCreate("buttonTimer", 0, pdFALSE, systemTask, ButtonTimerCallback);
+}
+
+ButtonActions ButtonHandler::HandleEvent(Events event) {
+ static constexpr TickType_t doubleClickTime = pdMS_TO_TICKS(200);
+ static constexpr TickType_t longPressTime = pdMS_TO_TICKS(400);
+ static constexpr TickType_t longerPressTime = pdMS_TO_TICKS(2000);
+
+ if (event == Events::Press) {
+ buttonPressed = true;
+ } else if (event == Events::Release) {
+ releaseTime = xTaskGetTickCount();
+ buttonPressed = false;
+ }
+
+ switch (state) {
+ case States::Idle:
+ if (event == Events::Press) {
+ xTimerChangePeriod(buttonTimer, doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ state = States::Pressed;
+ }
+ break;
+ case States::Pressed:
+ if (event == Events::Press) {
+ if (xTaskGetTickCount() - releaseTime < doubleClickTime) {
+ xTimerStop(buttonTimer, 0);
+ state = States::Idle;
+ return ButtonActions::DoubleClick;
+ }
+ } else if (event == Events::Release) {
+ xTimerChangePeriod(buttonTimer, doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ } else if (event == Events::Timer) {
+ if (buttonPressed) {
+ xTimerChangePeriod(buttonTimer, longPressTime - doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ state = States::Holding;
+ } else {
+ state = States::Idle;
+ return ButtonActions::Click;
+ }
+ }
+ break;
+ case States::Holding:
+ if (event == Events::Release) {
+ xTimerStop(buttonTimer, 0);
+ state = States::Idle;
+ return ButtonActions::Click;
+ } else if (event == Events::Timer) {
+ xTimerChangePeriod(buttonTimer, longerPressTime - longPressTime - doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ state = States::LongHeld;
+ return ButtonActions::LongPress;
+ }
+ break;
+ case States::LongHeld:
+ if (event == Events::Release) {
+ xTimerStop(buttonTimer, 0);
+ state = States::Idle;
+ } else if (event == Events::Timer) {
+ state = States::Idle;
+ return ButtonActions::LongerPress;
+ }
+ break;
+ }
+ return ButtonActions::None;
+}