Newer buttonhandler

This commit is contained in:
Riku Isokoski
2021-10-25 12:53:14 +03:00
parent 82ca526ec2
commit d5dfa80876
9 changed files with 194 additions and 36 deletions

View File

@@ -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;
}
}

View File

@@ -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;
};
}
}