summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/buttonhandler/ButtonHandler.cpp85
-rw-r--r--src/buttonhandler/ButtonHandler.h24
-rw-r--r--src/displayapp/DisplayApp.cpp14
-rw-r--r--src/displayapp/Messages.h3
-rw-r--r--src/main.cpp24
-rw-r--r--src/systemtask/Messages.h7
-rw-r--r--src/systemtask/SystemTask.cpp63
-rw-r--r--src/systemtask/SystemTask.h7
9 files changed, 194 insertions, 36 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a839e080..e727b2b0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -507,6 +507,7 @@ list(APPEND SOURCE_FILES
components/heartrate/Ptagc.cpp
components/heartrate/HeartRateController.cpp
+ buttonhandler/ButtonHandler.cpp
touchhandler/TouchHandler.cpp
)
@@ -567,6 +568,7 @@ list(APPEND RECOVERY_SOURCE_FILES
components/heartrate/Ptagc.cpp
components/motor/MotorController.cpp
components/fs/FS.cpp
+ buttonhandler/ButtonHandler.cpp
touchhandler/TouchHandler.cpp
)
@@ -681,6 +683,7 @@ set(INCLUDE_FILES
components/heartrate/Ptagc.h
components/heartrate/HeartRateController.h
components/motor/MotorController.h
+ buttonhandler/ButtonHandler.h
touchhandler/TouchHandler.h
)
diff --git a/src/buttonhandler/ButtonHandler.cpp b/src/buttonhandler/ButtonHandler.cpp
new file mode 100644
index 00000000..997409e5
--- /dev/null
+++ b/src/buttonhandler/ButtonHandler.cpp
@@ -0,0 +1,85 @@
+#include "ButtonHandler.h"
+
+using namespace Pinetime::Controllers;
+
+void ButtonTimerCallback(TimerHandle_t xTimer) {
+ auto* buttonHandler = static_cast<ButtonHandler*>(pvTimerGetTimerID(xTimer));
+ buttonHandler->HandleEvent(ButtonHandler::Timer);
+}
+
+void ButtonHandler::Init(Pinetime::System::SystemTask* systemTask) {
+ this->systemTask = systemTask;
+ buttonTimer = xTimerCreate("buttonTimer", 0, pdFALSE, this, ButtonTimerCallback);
+}
+
+void 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 (systemTask->IsSleeping()) {
+ // This is for faster wakeup, sacrificing special longpress and doubleclick handling while sleeping
+ systemTask->PushMessage(System::Messages::GoToRunning);
+ } else {
+ systemTask->PushMessage(System::Messages::ReloadIdleTimer);
+ }
+
+ if (event == Press) {
+ buttonPressed = true;
+ } else if (event == Release) {
+ releaseTime = xTaskGetTickCount();
+ buttonPressed = false;
+ }
+
+ switch (state) {
+ case Idle:
+ if (event == Press) {
+ xTimerChangePeriod(buttonTimer, doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ state = Pressed;
+ }
+ break;
+ case Pressed:
+ if (event == Press) {
+ if (xTaskGetTickCount() - releaseTime < doubleClickTime) {
+ systemTask->PushMessage(System::Messages::OnButtonDoubleClicked);
+ xTimerStop(buttonTimer, 0);
+ state = Idle;
+ }
+ } else if (event == Release) {
+ xTimerChangePeriod(buttonTimer, doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ } else if (event == Timer) {
+ if (buttonPressed) {
+ xTimerChangePeriod(buttonTimer, longPressTime - doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ state = Holding;
+ } else {
+ systemTask->PushMessage(System::Messages::OnButtonPushed);
+ state = Idle;
+ }
+ }
+ break;
+ case Holding:
+ if (event == Release) {
+ systemTask->PushMessage(System::Messages::OnButtonPushed);
+ xTimerStop(buttonTimer, 0);
+ state = Idle;
+ } else if (event == Timer) {
+ xTimerChangePeriod(buttonTimer, longerPressTime - longPressTime - doubleClickTime, 0);
+ xTimerStart(buttonTimer, 0);
+ systemTask->PushMessage(System::Messages::OnButtonLongPressed);
+ state = LongHeld;
+ }
+ break;
+ case LongHeld:
+ if (event == Release) {
+ xTimerStop(buttonTimer, 0);
+ state = Idle;
+ } else if (event == Timer) {
+ systemTask->PushMessage(System::Messages::OnButtonLongerPressed);
+ state = Idle;
+ }
+ break;
+ }
+}
diff --git a/src/buttonhandler/ButtonHandler.h b/src/buttonhandler/ButtonHandler.h
new file mode 100644
index 00000000..5d5b57e9
--- /dev/null
+++ b/src/buttonhandler/ButtonHandler.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "systemtask/SystemTask.h"
+#include <FreeRTOS.h>
+#include <timers.h>
+
+namespace Pinetime {
+ namespace Controllers {
+ class ButtonHandler {
+ public:
+ enum events { Press, Release, Timer };
+ void Init(Pinetime::System::SystemTask* systemTask);
+ void HandleEvent(events event);
+
+ private:
+ Pinetime::System::SystemTask* systemTask = nullptr;
+ TickType_t releaseTime = 0;
+ TimerHandle_t buttonTimer;
+ bool buttonPressed = false;
+ enum states { Idle, Pressed, Holding, LongHeld };
+ states state = Idle;
+ };
+ }
+}
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index abe5851e..13ee0045 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -260,6 +260,20 @@ void DisplayApp::Refresh() {
}
}
break;
+ case Messages::ButtonLongPressed:
+ if (currentApp != Apps::Clock) {
+ LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::Down);
+ }
+ break;
+ case Messages::ButtonLongerPressed:
+ // Create reboot app and open it instead
+ LoadApp(Apps::SysInfo, DisplayApp::FullRefreshDirections::Up);
+ break;
+ case Messages::ButtonDoubleClicked:
+ if (currentApp != Apps::Notifications && currentApp != Apps::NotificationsPreview) {
+ LoadApp(Apps::Notifications, DisplayApp::FullRefreshDirections::Down);
+ }
+ break;
case Messages::BleFirmwareUpdateStarted:
LoadApp(Apps::FirmwareUpdate, DisplayApp::FullRefreshDirections::Down);
diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h
index d48b646f..ab0a0608 100644
--- a/src/displayapp/Messages.h
+++ b/src/displayapp/Messages.h
@@ -9,6 +9,9 @@ namespace Pinetime {
UpdateBleConnection,
TouchEvent,
ButtonPushed,
+ ButtonLongPressed,
+ ButtonLongerPressed,
+ ButtonDoubleClicked,
NewNotification,
TimerDone,
BleFirmwareUpdateStarted,
diff --git a/src/main.cpp b/src/main.cpp
index fc772355..b942fd41 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -47,6 +47,7 @@
#include "systemtask/SystemTask.h"
#include "drivers/PinMap.h"
#include "touchhandler/TouchHandler.h"
+#include "buttonhandler/ButtonHandler.h"
#if NRF_LOG_ENABLED
#include "logging/NrfLogger.h"
@@ -96,8 +97,6 @@ TimerHandle_t debounceTimer;
TimerHandle_t debounceChargeTimer;
Pinetime::Controllers::Battery batteryController;
Pinetime::Controllers::Ble bleController;
-static constexpr uint8_t pinTouchIrq = Pinetime::PinMap::Cst816sIrq;
-static constexpr uint8_t pinPowerPresentIrq = Pinetime::PinMap::PowerPresent;
Pinetime::Controllers::HeartRateController heartRateController;
Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController);
@@ -110,6 +109,7 @@ Pinetime::Controllers::MotionController motionController;
Pinetime::Controllers::TimerController timerController;
Pinetime::Controllers::AlarmController alarmController {dateTimeController};
Pinetime::Controllers::TouchHandler touchHandler(touchPanel, lvgl);
+Pinetime::Controllers::ButtonHandler buttonHandler;
Pinetime::Controllers::FS fs {spiNorFlash};
Pinetime::Controllers::Settings settingsController {fs};
@@ -153,7 +153,8 @@ Pinetime::System::SystemTask systemTask(spi,
displayApp,
heartRateApp,
fs,
- touchHandler);
+ touchHandler,
+ buttonHandler);
/* Variable Declarations for variables in noinit SRAM
Increment NoInit_MagicValue upon adding variables to this area
@@ -176,11 +177,11 @@ void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action
if (pin == Pinetime::PinMap::PowerPresent and action == NRF_GPIOTE_POLARITY_TOGGLE) {
xTimerStartFromISR(debounceChargeTimer, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
- return;
+ } else if (pin == Pinetime::PinMap::Button) {
+ // This activates on button release as well due to bouncing
+ xTimerStartFromISR(debounceTimer, &xHigherPriorityTaskWoken);
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
-
- xTimerStartFromISR(debounceTimer, &xHigherPriorityTaskWoken);
- portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void DebounceTimerChargeCallback(TimerHandle_t xTimer) {
@@ -188,9 +189,8 @@ void DebounceTimerChargeCallback(TimerHandle_t xTimer) {
systemTask.PushMessage(Pinetime::System::Messages::OnChargingEvent);
}
-void DebounceTimerCallback(TimerHandle_t xTimer) {
- xTimerStop(xTimer, 0);
- systemTask.OnButtonPushed();
+void DebounceTimerCallback(TimerHandle_t /*unused*/) {
+ systemTask.PushMessage(Pinetime::System::Messages::HandleButtonEvent);
}
void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) {
@@ -319,8 +319,8 @@ int main(void) {
}
nrf_gpio_cfg_default(Pinetime::PinMap::TwiScl);
- debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback);
- debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback);
+ debounceTimer = xTimerCreate("debounceTimer", 10, pdFALSE, nullptr, DebounceTimerCallback);
+ debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, nullptr, DebounceTimerChargeCallback);
// retrieve version stored by bootloader
Pinetime::BootloaderVersion::SetVersion(NRF_TIMER2->CC[0]);
diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h
index 5aa218d2..b0bdbf31 100644
--- a/src/systemtask/Messages.h
+++ b/src/systemtask/Messages.h
@@ -15,12 +15,17 @@ namespace Pinetime {
BleFirmwareUpdateStarted,
BleFirmwareUpdateFinished,
OnTouchEvent,
- OnButtonEvent,
+ OnButtonPushed,
+ OnButtonLongPressed,
+ OnButtonLongerPressed,
+ OnButtonDoubleClicked,
+ HandleButtonEvent,
OnDisplayTaskSleeping,
EnableSleeping,
DisableSleeping,
OnNewDay,
OnChargingEvent,
+ ReloadIdleTimer,
SetOffAlarm,
StopRinging,
MeasureBatteryTimerExpired,
diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp
index e0a5907a..b7db0b9d 100644
--- a/src/systemtask/SystemTask.cpp
+++ b/src/systemtask/SystemTask.cpp
@@ -25,7 +25,6 @@
#include "main.h"
#include "BootErrors.h"
-
#include <memory>
using namespace Pinetime::System;
@@ -77,7 +76,8 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
Pinetime::Applications::DisplayApp& displayApp,
Pinetime::Applications::HeartRateTask& heartRateApp,
Pinetime::Controllers::FS& fs,
- Pinetime::Controllers::TouchHandler& touchHandler)
+ Pinetime::Controllers::TouchHandler& touchHandler,
+ Pinetime::Controllers::ButtonHandler& buttonHandler)
: spi {spi},
lcd {lcd},
spiNorFlash {spiNorFlash},
@@ -101,8 +101,15 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
heartRateApp(heartRateApp),
fs {fs},
touchHandler {touchHandler},
- nimbleController(*this, bleController, dateTimeController, notificationManager,
- batteryController, spiNorFlash, heartRateController, motionController) {
+ buttonHandler {buttonHandler},
+ nimbleController(*this,
+ bleController,
+ dateTimeController,
+ notificationManager,
+ batteryController,
+ spiNorFlash,
+ heartRateController,
+ motionController) {
}
void SystemTask::Start() {
@@ -163,6 +170,8 @@ void SystemTask::Work() {
heartRateSensor.Disable();
heartRateApp.Start();
+ buttonHandler.Init(this);
+
// Button
nrf_gpio_cfg_output(15);
nrf_gpio_pin_set(15);
@@ -326,9 +335,32 @@ void SystemTask::Work() {
ReloadIdleTimer();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent);
break;
- case Messages::OnButtonEvent:
- ReloadIdleTimer();
- displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed);
+ case Messages::OnButtonPushed:
+ if (!isSleeping && !isGoingToSleep) {
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed);
+ }
+ break;
+ case Messages::OnButtonLongPressed:
+ if (!isSleeping) {
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonLongPressed);
+ }
+ break;
+ case Messages::OnButtonLongerPressed:
+ if (!isSleeping) {
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonLongerPressed);
+ }
+ break;
+ case Messages::OnButtonDoubleClicked:
+ if (!isSleeping) {
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonDoubleClicked);
+ }
+ break;
+ case Messages::HandleButtonEvent:
+ if (nrf_gpio_pin_read(Pinetime::PinMap::Button) == 0) {
+ buttonHandler.HandleEvent(Pinetime::Controllers::ButtonHandler::Release);
+ } else {
+ buttonHandler.HandleEvent(Pinetime::Controllers::ButtonHandler::Press);
+ }
break;
case Messages::OnDisplayTaskSleeping:
if (BootloaderVersion::IsValid()) {
@@ -366,6 +398,9 @@ void SystemTask::Work() {
case Messages::BatteryPercentageUpdated:
nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining());
break;
+ case Messages::ReloadIdleTimer:
+ ReloadIdleTimer();
+ break;
default:
break;
@@ -414,20 +449,6 @@ void SystemTask::UpdateMotion() {
}
}
-void SystemTask::OnButtonPushed() {
- if (isGoingToSleep)
- return;
- if (!isSleeping) {
- NRF_LOG_INFO("[systemtask] Button pushed");
- PushMessage(Messages::OnButtonEvent);
- } else {
- if (!isWakingUp) {
- NRF_LOG_INFO("[systemtask] Button pushed, waking up");
- GoToRunning();
- }
- }
-}
-
void SystemTask::GoToRunning() {
if (isGoingToSleep or (not isSleeping) or isWakingUp)
return;
diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h
index 879c1be8..9967f75c 100644
--- a/src/systemtask/SystemTask.h
+++ b/src/systemtask/SystemTask.h
@@ -20,6 +20,7 @@
#include "components/alarm/AlarmController.h"
#include "components/fs/FS.h"
#include "touchhandler/TouchHandler.h"
+#include "buttonhandler/ButtonHandler.h"
#ifdef PINETIME_IS_RECOVERY
#include "displayapp/DisplayAppRecovery.h"
@@ -45,6 +46,7 @@ namespace Pinetime {
}
namespace Controllers {
class TouchHandler;
+ class ButtonHandler;
}
namespace System {
class SystemTask {
@@ -71,12 +73,12 @@ namespace Pinetime {
Pinetime::Applications::DisplayApp& displayApp,
Pinetime::Applications::HeartRateTask& heartRateApp,
Pinetime::Controllers::FS& fs,
- Pinetime::Controllers::TouchHandler& touchHandler);
+ Pinetime::Controllers::TouchHandler& touchHandler,
+ Pinetime::Controllers::ButtonHandler& buttonHandler);
void Start();
void PushMessage(Messages msg);
- void OnButtonPushed();
void OnTouchEvent();
void OnIdle();
@@ -123,6 +125,7 @@ namespace Pinetime {
Pinetime::Applications::HeartRateTask& heartRateApp;
Pinetime::Controllers::FS& fs;
Pinetime::Controllers::TouchHandler& touchHandler;
+ Pinetime::Controllers::ButtonHandler& buttonHandler;
Pinetime::Controllers::NimbleController nimbleController;
static void Process(void* instance);