Skip to content

Commit 27ca163

Browse files
committed
2 parents 1963e1f + 66b5977 commit 27ca163

File tree

7 files changed

+77
-13
lines changed

7 files changed

+77
-13
lines changed

src/components/motor/MotorController.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ void MotorController::StopRinging() {
3434
nrf_gpio_pin_set(PinMap::Motor);
3535
}
3636

37+
bool MotorController::IsRinging() {
38+
return (xTimerIsTimerActive(longVib) == pdTRUE);
39+
}
40+
3741
void MotorController::StopMotor(TimerHandle_t /*xTimer*/) {
3842
nrf_gpio_pin_set(PinMap::Motor);
3943
}

src/components/motor/MotorController.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace Pinetime {
1515
void RunForDuration(uint8_t motorDuration);
1616
void StartRinging();
1717
void StopRinging();
18+
bool IsRinging();
1819

1920
private:
2021
static void Ring(TimerHandle_t xTimer);

src/components/timer/Timer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ void Timer::StopTimer() {
4141
bool Timer::IsRunning() {
4242
return (xTimerIsTimerActive(timer) == pdTRUE);
4343
}
44+
45+
void Timer::ResetExpiredTime() {
46+
triggered = false;
47+
}

src/components/timer/Timer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace Pinetime {
2525

2626
bool IsRunning();
2727

28+
void ResetExpiredTime();
29+
2830
private:
2931
TimerHandle_t timer;
3032
TickType_t expiry;

src/displayapp/DisplayApp.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -370,19 +370,21 @@ void DisplayApp::Refresh() {
370370
case Messages::NewNotification:
371371
LoadNewScreen(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down);
372372
break;
373-
case Messages::TimerDone:
373+
case Messages::TimerDone: {
374374
if (state != States::Running) {
375375
PushMessageToSystemTask(System::Messages::GoToRunning);
376376
}
377-
if (currentApp == Apps::Timer) {
378-
lv_disp_trig_activity(nullptr);
379-
auto* timer = static_cast<Screens::Timer*>(currentScreen.get());
380-
timer->Reset();
381-
} else {
377+
lv_disp_trig_activity(nullptr);
378+
// Load timer app if not loaded
379+
if (currentApp != Apps::Timer) {
382380
LoadNewScreen(Apps::Timer, DisplayApp::FullRefreshDirections::Up);
381+
} else {
382+
// Set the timer to ringing mode if already loaded
383+
auto* timerScreen = static_cast<Screens::Timer*>(currentScreen.get());
384+
timerScreen->SetTimerRinging();
383385
}
384-
motorController.RunForDuration(35);
385386
break;
387+
}
386388
case Messages::AlarmTriggered:
387389
if (currentApp == Apps::Alarm) {
388390
auto* alarm = static_cast<Screens::Alarm*>(currentScreen.get());

src/displayapp/screens/Timer.cpp

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ static void btnEventHandler(lv_obj_t* obj, lv_event_t event) {
1717
}
1818
}
1919

20-
Timer::Timer(Controllers::Timer& timerController) : timer {timerController} {
20+
Timer::Timer(Controllers::Timer& timerController, Controllers::MotorController& motorController, System::SystemTask& systemTask)
21+
: timer {timerController}, motorController {motorController}, wakeLock(systemTask) {
2122

2223
lv_obj_t* colonLabel = lv_label_create(lv_scr_act(), nullptr);
2324
lv_obj_set_style_local_text_font(colonLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
@@ -62,7 +63,11 @@ Timer::Timer(Controllers::Timer& timerController) : timer {timerController} {
6263
// Create the label as a child of the button so it stays centered by default
6364
txtPlayPause = lv_label_create(btnPlayPause, nullptr);
6465

65-
if (timer.IsRunning()) {
66+
auto timerStatus = timer.GetTimerState();
67+
68+
if (timerStatus && timerStatus->expired) {
69+
SetTimerRinging();
70+
} else if (timer.IsRunning()) {
6671
SetTimerRunning();
6772
} else {
6873
SetTimerStopped();
@@ -73,6 +78,14 @@ Timer::Timer(Controllers::Timer& timerController) : timer {timerController} {
7378

7479
Timer::~Timer() {
7580
lv_task_del(taskRefresh);
81+
82+
// If timer has expired, reset it when leaving the screen
83+
auto timerStatus = timer.GetTimerState();
84+
if (timerStatus && timerStatus->expired) {
85+
motorController.StopRinging();
86+
timer.ResetExpiredTime();
87+
}
88+
7689
lv_obj_clean(lv_scr_act());
7790
}
7891

@@ -103,7 +116,23 @@ void Timer::UpdateMask() {
103116
}
104117

105118
void Timer::Refresh() {
106-
if (timer.IsRunning()) {
119+
auto timerStatus = timer.GetTimerState();
120+
121+
if (timerStatus && timerStatus->expired) {
122+
// Timer exists and has expired, so we're in ringing mode
123+
DisplayTime();
124+
125+
if (timerStatus->distanceToExpiry.count() > 10000 && motorController.IsRinging()) {
126+
// Stop buzzing after 10 seconds, but continue the counter
127+
motorController.StopRinging();
128+
wakeLock.Release();
129+
}
130+
131+
// Reset timer after 1 minute
132+
if (timerStatus->distanceToExpiry.count() > 60000) {
133+
Reset();
134+
}
135+
} else if (timer.IsRunning()) {
107136
DisplayTime();
108137
} else if (buttonPressing && xTaskGetTickCount() - pressTime > pdMS_TO_TICKS(150)) {
109138
lv_label_set_text_static(txtPlayPause, "Reset");
@@ -130,16 +159,31 @@ void Timer::SetTimerRunning() {
130159
minuteCounter.HideControls();
131160
secondCounter.HideControls();
132161
lv_label_set_text_static(txtPlayPause, "Pause");
162+
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
133163
}
134164

135165
void Timer::SetTimerStopped() {
136166
minuteCounter.ShowControls();
137167
secondCounter.ShowControls();
138168
lv_label_set_text_static(txtPlayPause, "Start");
169+
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
170+
}
171+
172+
void Timer::SetTimerRinging() {
173+
motorController.StartRinging();
174+
wakeLock.Lock();
175+
minuteCounter.HideControls();
176+
secondCounter.HideControls();
177+
lv_label_set_text_static(txtPlayPause, "Reset");
178+
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
139179
}
140180

141181
void Timer::ToggleRunning() {
142-
if (timer.IsRunning()) {
182+
auto timerStatus = timer.GetTimerState();
183+
if (timerStatus && timerStatus->expired) {
184+
motorController.StopRinging();
185+
Reset();
186+
} else if (timer.IsRunning()) {
143187
DisplayTime();
144188
timer.StopTimer();
145189
SetTimerStopped();
@@ -152,6 +196,7 @@ void Timer::ToggleRunning() {
152196
}
153197

154198
void Timer::Reset() {
199+
timer.ResetExpiredTime();
155200
DisplayTime();
156201
SetTimerStopped();
157202
}

src/displayapp/screens/Timer.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#pragma once
22

33
#include "displayapp/screens/Screen.h"
4+
#include "components/motor/MotorController.h"
45
#include "systemtask/SystemTask.h"
6+
#include "systemtask/WakeLock.h"
57
#include "displayapp/LittleVgl.h"
68
#include "displayapp/widgets/Counter.h"
79
#include "utility/DirtyValue.h"
@@ -14,20 +16,24 @@ namespace Pinetime::Applications {
1416
namespace Screens {
1517
class Timer : public Screen {
1618
public:
17-
Timer(Controllers::Timer& timerController);
19+
Timer(Controllers::Timer& timerController, Controllers::MotorController& motorController, System::SystemTask& systemTask);
1820
~Timer() override;
1921
void Refresh() override;
2022
void Reset();
2123
void ToggleRunning();
2224
void ButtonPressed();
2325
void MaskReset();
26+
void SetTimerRinging();
2427

2528
private:
2629
void SetTimerRunning();
2730
void SetTimerStopped();
2831
void UpdateMask();
2932
void DisplayTime();
3033
Pinetime::Controllers::Timer& timer;
34+
Pinetime::Controllers::MotorController& motorController;
35+
36+
Pinetime::System::WakeLock wakeLock;
3137

3238
lv_obj_t* btnPlayPause;
3339
lv_obj_t* txtPlayPause;
@@ -54,7 +60,7 @@ namespace Pinetime::Applications {
5460
static constexpr const char* icon = Screens::Symbols::hourGlass;
5561

5662
static Screens::Screen* Create(AppControllers& controllers) {
57-
return new Screens::Timer(controllers.timer);
63+
return new Screens::Timer(controllers.timer, controllers.motorController, *controllers.systemTask);
5864
};
5965

6066
static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {

0 commit comments

Comments
 (0)