aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Hustak <coding@journey.sk>2024-10-20 12:01:36 +0200
committerJF <JF002@users.noreply.github.com>2025-11-04 21:25:31 +0100
commitdb5d4704cc4a7361c80d1eab199af268364545c7 (patch)
tree060efe2965b0984637fc8054353c1dcea5ffb622
parent74cf69bb6716657575f52e0e207ff123c6e01575 (diff)
StopWatch: add persistence
# Conflicts: # src/displayapp/screens/StopWatch.h
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/components/stopwatch/StopWatchController.cpp101
-rw-r--r--src/components/stopwatch/StopWatchController.h66
-rw-r--r--src/displayapp/Controllers.h2
-rw-r--r--src/displayapp/DisplayApp.cpp3
-rw-r--r--src/displayapp/DisplayApp.h3
-rw-r--r--src/displayapp/DisplayAppRecovery.cpp1
-rw-r--r--src/displayapp/DisplayAppRecovery.h2
-rw-r--r--src/displayapp/screens/StopWatch.cpp178
-rw-r--r--src/displayapp/screens/StopWatch.h106
-rw-r--r--src/main.cpp4
-rw-r--r--src/systemtask/SystemTask.cpp2
-rw-r--r--src/systemtask/SystemTask.h3
13 files changed, 332 insertions, 142 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 78ff2d6a..43aa1d15 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -469,6 +469,7 @@ list(APPEND SOURCE_FILES
components/motor/MotorController.cpp
components/settings/Settings.cpp
components/timer/Timer.cpp
+ components/stopwatch/StopWatchController.cpp
components/alarm/AlarmController.cpp
components/fs/FS.cpp
drivers/Cst816s.cpp
@@ -538,6 +539,7 @@ list(APPEND RECOVERY_SOURCE_FILES
components/firmwarevalidator/FirmwareValidator.cpp
components/settings/Settings.cpp
components/timer/Timer.cpp
+ components/stopwatch/StopWatchController.cpp
components/alarm/AlarmController.cpp
drivers/Cst816s.cpp
FreeRTOS/port.c
@@ -657,6 +659,7 @@ set(INCLUDE_FILES
components/ble/SimpleWeatherService.h
components/settings/Settings.h
components/timer/Timer.h
+ components/stopwatch/StopWatchController.h
components/alarm/AlarmController.h
drivers/Cst816s.h
FreeRTOS/portmacro.h
diff --git a/src/components/stopwatch/StopWatchController.cpp b/src/components/stopwatch/StopWatchController.cpp
new file mode 100644
index 00000000..200919f4
--- /dev/null
+++ b/src/components/stopwatch/StopWatchController.cpp
@@ -0,0 +1,101 @@
+#include "components/stopwatch/StopWatchController.h"
+
+using namespace Pinetime::Controllers;
+
+namespace {
+ TickType_t CalculateDelta(const TickType_t startTime, const TickType_t currentTime) {
+ TickType_t delta = 0;
+ // Take care of overflow
+ if (startTime > currentTime) {
+ delta = 0xffffffff - startTime;
+ delta += (currentTime + 1);
+ } else {
+ delta = currentTime - startTime;
+ }
+ return delta;
+ }
+}
+
+StopWatchController::StopWatchController() {
+ Clear();
+}
+
+// State Change
+
+void StopWatchController::Start() {
+ currentState = StopWatchStates::Running;
+ startTime = xTaskGetTickCount();
+}
+
+void StopWatchController::Pause() {
+ currentState = StopWatchStates::Paused;
+ timeElapsedPreviously += CalculateDelta(startTime, xTaskGetTickCount());
+}
+
+void StopWatchController::Clear() {
+ currentState = StopWatchStates::Cleared;
+ timeElapsedPreviously = 0;
+
+ for (int i = 0; i < LAP_CAPACITY; i++) {
+ laps[i].count = 0;
+ laps[i].time = 0;
+ }
+ lapCount = 0;
+ lapHead = 0;
+}
+
+// Lap
+
+void StopWatchController::PushLap() {
+ TickType_t lapEnd = GetElapsedTime();
+ laps[lapHead].time = lapEnd;
+ laps[lapHead].count = lapCount + 1;
+ lapCount += 1;
+ lapHead = lapCount % LAP_CAPACITY;
+}
+
+int StopWatchController::GetLapNum() {
+ if (lapCount < LAP_CAPACITY)
+ return lapCount;
+ else
+ return LAP_CAPACITY;
+}
+
+int StopWatchController::GetLapCount() {
+ return lapCount;
+}
+
+int Wrap(int index) {
+ return ((index % LAP_CAPACITY) + LAP_CAPACITY) % LAP_CAPACITY;
+}
+
+LapInfo* StopWatchController::LastLap(int lap) {
+ if (lap >= LAP_CAPACITY || lap > lapCount || lapCount == 0) {
+ // Return "empty" LapInfo_t
+ return &emptyLapInfo;
+ }
+ // Index backwards
+ int index = Wrap(lapHead - lap);
+ return &laps[index];
+}
+
+// Data / State acess
+
+TickType_t StopWatchController::GetElapsedTime() {
+ if (!IsRunning()) {
+ return timeElapsedPreviously;
+ }
+ return timeElapsedPreviously + CalculateDelta(startTime, xTaskGetTickCount());
+}
+
+bool StopWatchController::IsRunning() {
+ return currentState == StopWatchStates::Running;
+}
+
+bool StopWatchController::IsCleared() {
+ return currentState == StopWatchStates::Cleared;
+}
+
+bool StopWatchController::IsPaused() {
+ return currentState == StopWatchStates::Paused;
+}
diff --git a/src/components/stopwatch/StopWatchController.h b/src/components/stopwatch/StopWatchController.h
new file mode 100644
index 00000000..0aaeb5ca
--- /dev/null
+++ b/src/components/stopwatch/StopWatchController.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <FreeRTOS.h>
+#include <timers.h>
+
+#define LAP_CAPACITY 2
+
+namespace Pinetime {
+ namespace System {
+ class SystemTask;
+ }
+ namespace Controllers {
+
+ enum class StopWatchStates { Cleared, Running, Paused };
+
+ struct LapInfo {
+ int count = 0; // Used to label the lap
+ TickType_t time = 0; // Delta time from beginning of stopwatch
+ };
+
+ class StopWatchController {
+ public:
+ StopWatchController();
+
+ // StopWatch functionality and data
+ void Start();
+ void Pause();
+ void Clear();
+
+ TickType_t GetElapsedTime();
+
+ // Lap functionality
+
+ /// Only the latest laps are stored, the lap count is saved until reset
+ void PushLap();
+
+ /// Returns actual count of stored laps
+ int GetLapNum();
+
+ /// Returns lapCount
+ int GetLapCount();
+
+ /// Indexes into lap history, with 0 being the latest lap.
+ /// If the lap is unavailable, count and time will be 0. If there is a
+ /// real value, count should be above 0
+ LapInfo* LastLap(int lap = 0);
+
+ bool IsRunning();
+ bool IsCleared();
+ bool IsPaused();
+
+ private:
+ // Current state of stopwatch
+ StopWatchStates currentState = StopWatchStates::Cleared;
+ // Start time of current duration
+ TickType_t startTime = 0;
+ // How much time was elapsed before current duration
+ TickType_t timeElapsedPreviously = 0;
+ // Stores lap times
+ LapInfo laps[LAP_CAPACITY];
+ LapInfo emptyLapInfo = {.count = 0, .time = 0};
+ int lapCount = 0;
+ int lapHead = 0;
+ };
+ }
+}
diff --git a/src/displayapp/Controllers.h b/src/displayapp/Controllers.h
index 9992426c..223c7c69 100644
--- a/src/displayapp/Controllers.h
+++ b/src/displayapp/Controllers.h
@@ -18,6 +18,7 @@ namespace Pinetime {
class Settings;
class MotorController;
class MotionController;
+ class StopWatchController;
class AlarmController;
class BrightnessController;
class SimpleWeatherService;
@@ -41,6 +42,7 @@ namespace Pinetime {
Pinetime::Controllers::Settings& settingsController;
Pinetime::Controllers::MotorController& motorController;
Pinetime::Controllers::MotionController& motionController;
+ Pinetime::Controllers::StopWatchController& stopWatchController;
Pinetime::Controllers::AlarmController& alarmController;
Pinetime::Controllers::BrightnessController& brightnessController;
Pinetime::Controllers::SimpleWeatherService* weatherController;
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index 5c50e85f..7585c55d 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -82,6 +82,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
Controllers::Settings& settingsController,
Pinetime::Controllers::MotorController& motorController,
Pinetime::Controllers::MotionController& motionController,
+ Pinetime::Controllers::StopWatchController& stopWatchController,
Pinetime::Controllers::AlarmController& alarmController,
Pinetime::Controllers::BrightnessController& brightnessController,
Pinetime::Controllers::TouchHandler& touchHandler,
@@ -98,6 +99,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
settingsController {settingsController},
motorController {motorController},
motionController {motionController},
+ stopWatchController {stopWatchController},
alarmController {alarmController},
brightnessController {brightnessController},
touchHandler {touchHandler},
@@ -113,6 +115,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
settingsController,
motorController,
motionController,
+ stopWatchController,
alarmController,
brightnessController,
nullptr,
diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h
index dabed99e..016f91d3 100644
--- a/src/displayapp/DisplayApp.h
+++ b/src/displayapp/DisplayApp.h
@@ -13,6 +13,7 @@
#include "components/settings/Settings.h"
#include "displayapp/screens/Screen.h"
#include "components/timer/Timer.h"
+#include "components/stopwatch/StopWatchController.h"
#include "components/alarm/AlarmController.h"
#include "touchhandler/TouchHandler.h"
@@ -63,6 +64,7 @@ namespace Pinetime {
Controllers::Settings& settingsController,
Pinetime::Controllers::MotorController& motorController,
Pinetime::Controllers::MotionController& motionController,
+ Pinetime::Controllers::StopWatchController& stopWatchController,
Pinetime::Controllers::AlarmController& alarmController,
Pinetime::Controllers::BrightnessController& brightnessController,
Pinetime::Controllers::TouchHandler& touchHandler,
@@ -93,6 +95,7 @@ namespace Pinetime {
Pinetime::Controllers::Settings& settingsController;
Pinetime::Controllers::MotorController& motorController;
Pinetime::Controllers::MotionController& motionController;
+ Pinetime::Controllers::StopWatchController& stopWatchController;
Pinetime::Controllers::AlarmController& alarmController;
Pinetime::Controllers::BrightnessController& brightnessController;
Pinetime::Controllers::TouchHandler& touchHandler;
diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp
index bcb8db0e..cb358d60 100644
--- a/src/displayapp/DisplayAppRecovery.cpp
+++ b/src/displayapp/DisplayAppRecovery.cpp
@@ -21,6 +21,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
Controllers::Settings& /*settingsController*/,
Pinetime::Controllers::MotorController& /*motorController*/,
Pinetime::Controllers::MotionController& /*motionController*/,
+ Pinetime::Controllers::StopWatchController& /*stopWatchController*/,
Pinetime::Controllers::AlarmController& /*alarmController*/,
Pinetime::Controllers::BrightnessController& /*brightnessController*/,
Pinetime::Controllers::TouchHandler& /*touchHandler*/,
diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h
index 162ff257..ed387a8b 100644
--- a/src/displayapp/DisplayAppRecovery.h
+++ b/src/displayapp/DisplayAppRecovery.h
@@ -31,6 +31,7 @@ namespace Pinetime {
class MotionController;
class TouchHandler;
class MotorController;
+ class StopWatchController;
class AlarmController;
class BrightnessController;
class FS;
@@ -57,6 +58,7 @@ namespace Pinetime {
Controllers::Settings& settingsController,
Pinetime::Controllers::MotorController& motorController,
Pinetime::Controllers::MotionController& motionController,
+ Pinetime::Controllers::StopWatchController& stopWatchController,
Pinetime::Controllers::AlarmController& alarmController,
Pinetime::Controllers::BrightnessController& brightnessController,
Pinetime::Controllers::TouchHandler& touchHandler,
diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp
index ff852beb..397cd365 100644
--- a/src/displayapp/screens/StopWatch.cpp
+++ b/src/displayapp/screens/StopWatch.cpp
@@ -4,9 +4,10 @@
#include "displayapp/InfiniTimeTheme.h"
using namespace Pinetime::Applications::Screens;
+using namespace Pinetime::Controllers;
namespace {
- TimeSeparated_t convertTicksToTimeSegments(const TickType_t timeElapsed) {
+ TimeSeparated convertTicksToTimeSegments(const TickType_t timeElapsed) {
// Centiseconds
const int timeElapsedCentis = timeElapsed * 100 / configTICK_RATE_HZ;
@@ -14,27 +15,29 @@ namespace {
const int secs = (timeElapsedCentis / 100) % 60;
const int mins = ((timeElapsedCentis / 100) / 60) % 60;
const int hours = ((timeElapsedCentis / 100) / 60) / 60;
- return TimeSeparated_t {hours, mins, secs, hundredths};
+ return TimeSeparated {hours, mins, secs, hundredths};
}
void play_pause_event_handler(lv_obj_t* obj, lv_event_t event) {
auto* stopWatch = static_cast<StopWatch*>(obj->user_data);
if (event == LV_EVENT_CLICKED) {
- stopWatch->playPauseBtnEventHandler();
+ stopWatch->PlayPauseBtnEventHandler();
}
}
void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) {
auto* stopWatch = static_cast<StopWatch*>(obj->user_data);
if (event == LV_EVENT_CLICKED) {
- stopWatch->stopLapBtnEventHandler();
+ stopWatch->StopLapBtnEventHandler();
}
}
constexpr TickType_t blinkInterval = pdMS_TO_TICKS(1000);
}
-StopWatch::StopWatch(System::SystemTask& systemTask) : wakeLock(systemTask) {
+StopWatch::StopWatch(System::SystemTask& systemTask,
+ StopWatchController& stopWatchController)
+ : wakeLock(systemTask), stopWatchController {stopWatchController} {
static constexpr uint8_t btnWidth = 115;
static constexpr uint8_t btnHeight = 80;
btnPlayPause = lv_btn_create(lv_scr_act(), nullptr);
@@ -72,9 +75,28 @@ StopWatch::StopWatch(System::SystemTask& systemTask) : wakeLock(systemTask) {
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DISABLED, Colors::lightGray);
lv_obj_align(time, msecTime, LV_ALIGN_OUT_TOP_MID, 0, 0);
- SetInterfaceStopped();
-
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
+
+ // Figure out what the current state of the stopwatch is and select the correct display
+ if (stopWatchController.IsCleared()) {
+ DisplayCleared();
+ } else {
+ if (stopWatchController.GetLapCount() > 0) {
+ RenderLaps();
+ }
+ RenderTime();
+
+ if (stopWatchController.IsRunning()) {
+ lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
+ lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
+ DisplayStarted();
+ wakeLock.Lock();
+ } else if (stopWatchController.IsPaused()) {
+ lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
+ lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
+ DisplayPaused();
+ }
+ }
}
StopWatch::~StopWatch() {
@@ -82,14 +104,14 @@ StopWatch::~StopWatch() {
lv_obj_clean(lv_scr_act());
}
-void StopWatch::SetInterfacePaused() {
+void StopWatch::DisplayPaused() {
lv_obj_set_style_local_bg_color(btnStopLap, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
lv_label_set_text_static(txtPlayPause, Symbols::play);
lv_label_set_text_static(txtStopLap, Symbols::stop);
}
-void StopWatch::SetInterfaceRunning() {
+void StopWatch::DisplayStarted() {
lv_obj_set_state(time, LV_STATE_DEFAULT);
lv_obj_set_state(msecTime, LV_STATE_DEFAULT);
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
@@ -102,7 +124,7 @@ void StopWatch::SetInterfaceRunning() {
lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
}
-void StopWatch::SetInterfaceStopped() {
+void StopWatch::DisplayCleared() {
lv_obj_set_state(time, LV_STATE_DISABLED);
lv_obj_set_state(msecTime, LV_STATE_DISABLED);
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
@@ -123,96 +145,86 @@ void StopWatch::SetInterfaceStopped() {
lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
}
-void StopWatch::Reset() {
- SetInterfaceStopped();
- currentState = States::Init;
- oldTimeElapsed = 0;
- lapsDone = 0;
+void StopWatch::RenderTime() {
+ TimeSeparated currentTimeSeparated = convertTicksToTimeSegments(stopWatchController.GetElapsedTime());
+ if (currentTimeSeparated.hours == 0) {
+ lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
+ } else {
+ lv_label_set_text_fmt(time, "%02d:%02d:%02d", currentTimeSeparated.hours, currentTimeSeparated.mins, currentTimeSeparated.secs);
+ if (!isHoursLabelUpdated) {
+ lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
+ lv_obj_realign(time);
+ isHoursLabelUpdated = true;
+ }
+ }
+ lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
}
-void StopWatch::Start() {
- SetInterfaceRunning();
- startTime = xTaskGetTickCount();
- currentState = States::Running;
- wakeLock.Lock();
+void StopWatch::RenderPause() {
+ const TickType_t currentTime = xTaskGetTickCount();
+ if (currentTime > blinkTime) {
+ blinkTime = currentTime + blinkInterval;
+ if (lv_obj_get_state(time, LV_LABEL_PART_MAIN) == LV_STATE_DEFAULT) {
+ lv_obj_set_state(time, LV_STATE_DISABLED);
+ lv_obj_set_state(msecTime, LV_STATE_DISABLED);
+ } else {
+ lv_obj_set_state(time, LV_STATE_DEFAULT);
+ lv_obj_set_state(msecTime, LV_STATE_DEFAULT);
+ }
+ }
}
-void StopWatch::Pause() {
- SetInterfacePaused();
- startTime = 0;
- // Store the current time elapsed in cache
- oldTimeElapsed = laps[lapsDone];
- blinkTime = xTaskGetTickCount() + blinkInterval;
- currentState = States::Halted;
- wakeLock.Release();
+void StopWatch::RenderLaps() {
+ lv_label_set_text(lapText, "");
+ for (int i = 0; i < displayedLaps; i++) {
+ LapInfo* lap = stopWatchController.LastLap(i);
+
+ if (lap->count != 0) {
+ TimeSeparated laptime = convertTicksToTimeSegments(lap->time);
+ char buffer[16];
+ sprintf(buffer, "#%2d %2d:%02d.%02d\n", lap->count, laptime.mins, laptime.secs, laptime.hundredths);
+ lv_label_ins_text(lapText, LV_LABEL_POS_LAST, buffer);
+ }
+ }
}
void StopWatch::Refresh() {
- if (currentState == States::Running) {
- laps[lapsDone] = oldTimeElapsed + xTaskGetTickCount() - startTime;
-
- TimeSeparated_t currentTimeSeparated = convertTicksToTimeSegments(laps[lapsDone]);
- if (currentTimeSeparated.hours == 0) {
- lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
- } else {
- lv_label_set_text_fmt(time, "%02d:%02d:%02d", currentTimeSeparated.hours, currentTimeSeparated.mins, currentTimeSeparated.secs);
- if (!isHoursLabelUpdated) {
- lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
- lv_obj_realign(time);
- isHoursLabelUpdated = true;
- }
- }
- lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
- } else if (currentState == States::Halted) {
- const TickType_t currentTime = xTaskGetTickCount();
- if (currentTime > blinkTime) {
- blinkTime = currentTime + blinkInterval;
- if (lv_obj_get_state(time, LV_LABEL_PART_MAIN) == LV_STATE_DEFAULT) {
- lv_obj_set_state(time, LV_STATE_DISABLED);
- lv_obj_set_state(msecTime, LV_STATE_DISABLED);
- } else {
- lv_obj_set_state(time, LV_STATE_DEFAULT);
- lv_obj_set_state(msecTime, LV_STATE_DEFAULT);
- }
- }
+ if (stopWatchController.IsRunning()) {
+ RenderTime();
+ } else if (stopWatchController.IsPaused()) {
+ RenderPause();
}
}
-void StopWatch::playPauseBtnEventHandler() {
- if (currentState == States::Init || currentState == States::Halted) {
- Start();
- } else if (currentState == States::Running) {
- Pause();
+void StopWatch::PlayPauseBtnEventHandler() {
+ if (stopWatchController.IsCleared() || stopWatchController.IsPaused()) {
+ stopWatchController.Start();
+ DisplayStarted();
+ wakeLock.Lock();
+ } else if (stopWatchController.IsRunning()) {
+ stopWatchController.Pause();
+ blinkTime = xTaskGetTickCount() + blinkInterval;
+ DisplayPaused();
+ wakeLock.Release();
}
}
-void StopWatch::stopLapBtnEventHandler() {
- // If running, then this button is used to save laps
- if (currentState == States::Running) {
- lv_label_set_text(lapText, "");
- lapsDone = std::min(lapsDone + 1, maxLapCount);
- for (int i = lapsDone - displayedLaps; i < lapsDone; i++) {
- if (i < 0) {
- lv_label_ins_text(lapText, LV_LABEL_POS_LAST, "\n");
- continue;
- }
- TimeSeparated_t times = convertTicksToTimeSegments(laps[i]);
- char buffer[17];
- if (times.hours == 0) {
- snprintf(buffer, sizeof(buffer), "#%2d %2d:%02d.%02d\n", i + 1, times.mins, times.secs, times.hundredths);
- } else {
- snprintf(buffer, sizeof(buffer), "#%2d %2d:%02d:%02d.%02d\n", i + 1, times.hours, times.mins, times.secs, times.hundredths);
- }
- lv_label_ins_text(lapText, LV_LABEL_POS_LAST, buffer);
- }
- } else if (currentState == States::Halted) {
- Reset();
+void StopWatch::StopLapBtnEventHandler() {
+ if (stopWatchController.IsRunning()) {
+ stopWatchController.PushLap();
+ RenderLaps();
+ } else if (stopWatchController.IsPaused()) {
+ stopWatchController.Clear();
+ DisplayCleared();
+ wakeLock.Release();
}
}
bool StopWatch::OnButtonPushed() {
- if (currentState == States::Running) {
- Pause();
+ if (stopWatchController.IsRunning()) {
+ stopWatchController.Pause();
+ DisplayPaused();
+ wakeLock.Release();
return true;
}
return false;
diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h
index 7256dd5b..b2e85b7a 100644
--- a/src/displayapp/screens/StopWatch.h
+++ b/src/displayapp/screens/StopWatch.h
@@ -3,76 +3,64 @@
#include "displayapp/screens/Screen.h"
#include <lvgl/lvgl.h>
-#include <FreeRTOS.h>
-#include "portmacro_cmsis.h"
-
+#include "components/stopwatch/StopWatchController.h"
#include "systemtask/SystemTask.h"
#include "systemtask/WakeLock.h"
-#include "displayapp/apps/Apps.h"
-#include "displayapp/Controllers.h"
#include "Symbols.h"
-namespace Pinetime {
- namespace Applications {
- namespace Screens {
-
- enum class States { Init, Running, Halted };
-
- struct TimeSeparated_t {
- int hours;
- int mins;
- int secs;
- int hundredths;
- };
+namespace Pinetime::Applications {
+ namespace Screens {
- class StopWatch : public Screen {
- public:
- explicit StopWatch(System::SystemTask& systemTask);
- ~StopWatch() override;
- void Refresh() override;
-
- void playPauseBtnEventHandler();
- void stopLapBtnEventHandler();
- bool OnButtonPushed() override;
+ struct TimeSeparated {
+ int hours;
+ int mins;
+ int secs;
+ int hundredths;
+ };
- private:
- void SetInterfacePaused();
- void SetInterfaceRunning();
- void SetInterfaceStopped();
+ class StopWatch : public Screen {
+ public:
+ explicit StopWatch(System::SystemTask& systemTask,
+ Controllers::StopWatchController& stopWatchController);
+ ~StopWatch() override;
+ void Refresh() override;
- void Reset();
- void Start();
- void Pause();
+ void PlayPauseBtnEventHandler();
+ void StopLapBtnEventHandler();
+ bool OnButtonPushed() override;
- Pinetime::System::WakeLock wakeLock;
- States currentState = States::Init;
- TickType_t startTime;
- TickType_t oldTimeElapsed = 0;
- TickType_t blinkTime = 0;
- static constexpr int maxLapCount = 20;
- TickType_t laps[maxLapCount + 1];
- static constexpr int displayedLaps = 2;
- int lapsDone = 0;
- lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap;
- lv_obj_t* lapText;
- bool isHoursLabelUpdated = false;
+ private:
+ void DisplayPaused();
+ void DisplayStarted();
+ void DisplayCleared();
- lv_task_t* taskRefresh;
- };
- }
+ void RenderTime();
+ void RenderPause();
+ void RenderLaps();
- template <>
- struct AppTraits<Apps::StopWatch> {
- static constexpr Apps app = Apps::StopWatch;
- static constexpr const char* icon = Screens::Symbols::stopWatch;
+ Pinetime::System::WakeLock wakeLock;
+ Controllers::StopWatchController& stopWatchController;
+ TickType_t blinkTime = 0;
+ static constexpr int displayedLaps = 2;
+ lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap;
+ lv_obj_t* lapText;
+ bool isHoursLabelUpdated = false;
- static Screens::Screen* Create(AppControllers& controllers) {
- return new Screens::StopWatch(*controllers.systemTask);
- };
-
- static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {
- return true;
- };
+ lv_task_t* taskRefresh;
};
}
+
+ template <>
+ struct AppTraits<Apps::StopWatch> {
+ static constexpr Apps app = Apps::StopWatch;
+ static constexpr const char* icon = Screens::Symbols::stopWatch;
+
+ static Screens::Screen* Create(AppControllers& controllers) {
+ return new Screens::StopWatch(*controllers.systemTask,
+ controllers.stopWatchController);
+ }
+ static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {
+ return true;
+ }
+ };
}
diff --git a/src/main.cpp b/src/main.cpp
index 24f13cad..c573b482 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -35,6 +35,7 @@
#include "components/motor/MotorController.h"
#include "components/datetime/DateTimeController.h"
#include "components/heartrate/HeartRateController.h"
+#include "components/stopwatch/StopWatchController.h"
#include "components/fs/FS.h"
#include "drivers/Spi.h"
#include "drivers/SpiMaster.h"
@@ -104,6 +105,7 @@ Pinetime::Controllers::DateTime dateTimeController {settingsController};
Pinetime::Drivers::Watchdog watchdog;
Pinetime::Controllers::NotificationManager notificationManager;
Pinetime::Controllers::MotionController motionController;
+Pinetime::Controllers::StopWatchController stopWatchController;
Pinetime::Controllers::AlarmController alarmController {dateTimeController, fs};
Pinetime::Controllers::TouchHandler touchHandler;
Pinetime::Controllers::ButtonHandler buttonHandler;
@@ -120,6 +122,7 @@ Pinetime::Applications::DisplayApp displayApp(lcd,
settingsController,
motorController,
motionController,
+ stopWatchController,
alarmController,
brightnessController,
touchHandler,
@@ -133,6 +136,7 @@ Pinetime::System::SystemTask systemTask(spi,
batteryController,
bleController,
dateTimeController,
+ stopWatchController,
alarmController,
watchdog,
notificationManager,
diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp
index 8c979f39..21a4c1ea 100644
--- a/src/systemtask/SystemTask.cpp
+++ b/src/systemtask/SystemTask.cpp
@@ -39,6 +39,7 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::DateTime& dateTimeController,
+ Controllers::StopWatchController& stopWatchController,
Controllers::AlarmController& alarmController,
Drivers::Watchdog& watchdog,
Pinetime::Controllers::NotificationManager& notificationManager,
@@ -59,6 +60,7 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
batteryController {batteryController},
bleController {bleController},
dateTimeController {dateTimeController},
+ stopWatchController {stopWatchController},
alarmController {alarmController},
watchdog {watchdog},
notificationManager {notificationManager},
diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h
index 9d99124e..606ddd34 100644
--- a/src/systemtask/SystemTask.h
+++ b/src/systemtask/SystemTask.h
@@ -15,6 +15,7 @@
#include "systemtask/SystemMonitor.h"
#include "components/ble/NimbleController.h"
#include "components/ble/NotificationManager.h"
+#include "components/stopwatch/StopWatchController.h"
#include "components/alarm/AlarmController.h"
#include "components/fs/FS.h"
#include "touchhandler/TouchHandler.h"
@@ -60,6 +61,7 @@ namespace Pinetime {
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::DateTime& dateTimeController,
+ Controllers::StopWatchController& stopWatchController,
Controllers::AlarmController& alarmController,
Drivers::Watchdog& watchdog,
Pinetime::Controllers::NotificationManager& notificationManager,
@@ -108,6 +110,7 @@ namespace Pinetime {
Pinetime::Controllers::Ble& bleController;
Pinetime::Controllers::DateTime& dateTimeController;
+ Pinetime::Controllers::StopWatchController& stopWatchController;
Pinetime::Controllers::AlarmController& alarmController;
QueueHandle_t systemTasksMsgQueue;
Pinetime::Drivers::Watchdog& watchdog;