Skip to content

Commit 1fb5757

Browse files
committed
Created basic alarm app
1 parent 6f9f0e8 commit 1fb5757

16 files changed

Lines changed: 480 additions & 3 deletions

src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ list(APPEND SOURCE_FILES
418418
displayapp/screens/BatteryInfo.cpp
419419
displayapp/screens/Steps.cpp
420420
displayapp/screens/Timer.cpp
421+
displayapp/screens/Alarm.cpp
421422
displayapp/Colors.cpp
422423

423424
## Settings
@@ -474,6 +475,7 @@ list(APPEND SOURCE_FILES
474475
components/motor/MotorController.cpp
475476
components/settings/Settings.cpp
476477
components/timer/TimerController.cpp
478+
components/alarm/AlarmController.cpp
477479
components/fs/FS.cpp
478480
drivers/Cst816s.cpp
479481
FreeRTOS/port.c
@@ -540,6 +542,7 @@ list(APPEND RECOVERY_SOURCE_FILES
540542
components/firmwarevalidator/FirmwareValidator.cpp
541543
components/settings/Settings.cpp
542544
components/timer/TimerController.cpp
545+
components/alarm/AlarmController.cpp
543546
drivers/Cst816s.cpp
544547
FreeRTOS/port.c
545548
FreeRTOS/port_cmsis_systick.c
@@ -612,6 +615,7 @@ set(INCLUDE_FILES
612615
displayapp/screens/Metronome.h
613616
displayapp/screens/Motion.h
614617
displayapp/screens/Timer.h
618+
displayapp/screens/Alarm.h
615619
displayapp/Colors.h
616620
drivers/St7789.h
617621
drivers/SpiNorFlash.h
@@ -643,6 +647,7 @@ set(INCLUDE_FILES
643647
components/ble/HeartRateService.h
644648
components/settings/Settings.h
645649
components/timer/TimerController.h
650+
components/alarm/AlarmController.h
646651
drivers/Cst816s.h
647652
FreeRTOS/portmacro.h
648653
FreeRTOS/portmacro_cmsis.h
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
//
2+
// Created by mrussell on 30.08.21.
3+
//
4+
// Copied from Florian's Timer app
5+
6+
#include "AlarmController.h"
7+
#include "systemtask/SystemTask.h"
8+
#include "app_timer.h"
9+
#include "task.h"
10+
#include <chrono>
11+
12+
using namespace Pinetime::Controllers;
13+
using namespace std::chrono_literals;
14+
15+
AlarmController::AlarmController(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} {
16+
}
17+
18+
APP_TIMER_DEF(alarmAppTimer);
19+
20+
namespace {
21+
void SetOffAlarm(void* p_context) {
22+
auto* controller = static_cast<Pinetime::Controllers::AlarmController*>(p_context);
23+
if (controller != nullptr)
24+
controller->SetOffAlarmNow();
25+
}
26+
}
27+
28+
void AlarmController::Init() {
29+
app_timer_create(&alarmAppTimer, APP_TIMER_MODE_SINGLE_SHOT, SetOffAlarm);
30+
}
31+
32+
void AlarmController::SetAlarm(uint8_t alarmHr, uint8_t alarmMin) {
33+
hours = alarmHr;
34+
minutes = alarmMin;
35+
state = AlarmState::Set;
36+
scheduleAlarm();
37+
}
38+
39+
void AlarmController::scheduleAlarm() {
40+
// Determine the next time the alarm needs to go off and set the app_timer
41+
app_timer_stop(alarmAppTimer);
42+
43+
auto now = dateTimeController.CurrentDateTime();
44+
alarmTime = now;
45+
time_t ttAlarmTime = std::chrono::system_clock::to_time_t(alarmTime);
46+
tm* tmAlarmTime = std::localtime(&ttAlarmTime);
47+
48+
// If the time being set has already passed today,the alarm should be set for tomorrow
49+
if (hours < dateTimeController.Hours() || (hours == dateTimeController.Hours() && minutes <= dateTimeController.Minutes())) {
50+
tmAlarmTime->tm_mday += 1;
51+
// tm_wday doesn't update automatically
52+
tmAlarmTime->tm_wday = (tmAlarmTime->tm_wday + 1) % 7;
53+
}
54+
55+
tmAlarmTime->tm_hour = hours;
56+
tmAlarmTime->tm_min = minutes;
57+
tmAlarmTime->tm_sec = 0;
58+
59+
// if alarm is in weekday-only mode, make sure it shifts to the next weekday
60+
if (recurrence == RecurType::Weekdays) {
61+
if (tmAlarmTime->tm_wday == 0) { // Sunday, shift 1 day
62+
tmAlarmTime->tm_mday += 1;
63+
} else if (tmAlarmTime->tm_wday == 6) { // Saturday, shift 2 days
64+
tmAlarmTime->tm_mday += 2;
65+
}
66+
}
67+
tmAlarmTime->tm_isdst = -1; // use system timezone setting to determine DST
68+
69+
// now can convert back to a time_point
70+
alarmTime = std::chrono::system_clock::from_time_t(std::mktime(tmAlarmTime));
71+
auto mSecToAlarm = std::chrono::duration_cast<std::chrono::milliseconds>(alarmTime - now).count();
72+
app_timer_start(alarmAppTimer, APP_TIMER_TICKS(mSecToAlarm), this);
73+
}
74+
75+
uint32_t AlarmController::SecondsToAlarm() {
76+
return std::chrono::duration_cast<std::chrono::seconds>(alarmTime - dateTimeController.CurrentDateTime()).count();
77+
}
78+
79+
void AlarmController::DisableAlarm() {
80+
app_timer_stop(alarmAppTimer);
81+
state = AlarmState::Not_Set;
82+
}
83+
84+
void AlarmController::SetOffAlarmNow() {
85+
state = AlarmState::Alerting;
86+
if (systemTask != nullptr) {
87+
systemTask->PushMessage(System::Messages::SetOffAlarm);
88+
}
89+
}
90+
91+
void AlarmController::StopAlerting() {
92+
if (systemTask != nullptr) {
93+
systemTask->PushMessage(System::Messages::StopRinging);
94+
}
95+
96+
// Alarm state is off unless this is a recurring alarm
97+
if (recurrence == RecurType::None) {
98+
state = AlarmState::Not_Set;
99+
} else {
100+
state = AlarmState::Set;
101+
// set next instance
102+
scheduleAlarm();
103+
}
104+
}
105+
106+
void AlarmController::ToggleRecurrence() {
107+
if (recurrence == AlarmController::RecurType::None) {
108+
recurrence = AlarmController::RecurType::Daily;
109+
} else if (recurrence == AlarmController::RecurType::Daily) {
110+
recurrence = AlarmController::RecurType::Weekdays;
111+
} else {
112+
recurrence = AlarmController::RecurType::None;
113+
}
114+
}
115+
116+
void AlarmController::Register(Pinetime::System::SystemTask* systemTask) {
117+
this->systemTask = systemTask;
118+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include "app_timer.h"
5+
#include "components/datetime/DateTimeController.h"
6+
7+
namespace Pinetime {
8+
namespace System {
9+
class SystemTask;
10+
}
11+
namespace Controllers {
12+
class AlarmController {
13+
public:
14+
AlarmController(Controllers::DateTime& dateTimeController);
15+
16+
void Init();
17+
void SetAlarm(uint8_t alarmHr, uint8_t alarmMin);
18+
void DisableAlarm();
19+
void SetOffAlarmNow();
20+
uint32_t SecondsToAlarm();
21+
void StopAlerting();
22+
void Register(System::SystemTask* systemTask);
23+
enum class AlarmState { Not_Set, Set, Alerting };
24+
enum class RecurType { None, Daily, Weekdays };
25+
void ToggleRecurrence();
26+
uint8_t Hours() const {
27+
return hours;
28+
}
29+
uint8_t Minutes() const {
30+
return minutes;
31+
}
32+
AlarmState State() const {
33+
return state;
34+
}
35+
RecurType Recurrence() const {
36+
return recurrence;
37+
}
38+
39+
private:
40+
Controllers::DateTime& dateTimeController;
41+
System::SystemTask* systemTask = nullptr;
42+
uint8_t hours;
43+
uint8_t minutes;
44+
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> alarmTime;
45+
AlarmState state = AlarmState::Not_Set;
46+
RecurType recurrence = RecurType::None;
47+
void scheduleAlarm();
48+
};
49+
}
50+
}

src/components/motor/MotorController.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ void MotorController::StartRinging() {
4242
app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this);
4343
}
4444

45+
// This function is the same as StartRinging(), but will ring even if notifications are turned off in Settings
46+
void MotorController::StartRingingDisregardSettings() {
47+
Ring(this);
48+
app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this);
49+
}
50+
4551
void MotorController::StopRinging() {
4652
app_timer_stop(longVibTimer);
4753
nrf_gpio_pin_set(pinMotor);

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
static void StopRinging();
18+
void StartRingingDisregardSettings();
1819

1920
private:
2021
static void Ring(void* p_context);

src/displayapp/Apps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace Pinetime {
1212
NotificationsPreview,
1313
Notifications,
1414
Timer,
15+
Alarm,
1516
FlashLight,
1617
BatteryInfo,
1718
Music,

src/displayapp/DisplayApp.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <displayapp/screens/HeartRate.h>
44
#include <displayapp/screens/Motion.h>
55
#include <displayapp/screens/Timer.h>
6+
#include <displayapp/screens/Alarm.h>
67
#include "components/battery/BatteryController.h"
78
#include "components/ble/BleController.h"
89
#include "components/datetime/DateTimeController.h"
@@ -90,6 +91,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
9091
Pinetime::Controllers::MotorController& motorController,
9192
Pinetime::Controllers::MotionController& motionController,
9293
Pinetime::Controllers::TimerController& timerController,
94+
Pinetime::Controllers::AlarmController& alarmController,
9395
Pinetime::Controllers::TouchHandler& touchHandler)
9496
: lcd {lcd},
9597
lvgl {lvgl},
@@ -104,6 +106,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
104106
motorController {motorController},
105107
motionController {motionController},
106108
timerController {timerController},
109+
alarmController {alarmController},
107110
touchHandler {touchHandler} {
108111
}
109112

@@ -208,6 +211,13 @@ void DisplayApp::Refresh() {
208211
LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down);
209212
}
210213
break;
214+
case Messages::AlarmTriggered:
215+
if (currentApp == Apps::Alarm) {
216+
auto* alarm = static_cast<Screens::Alarm*>(currentScreen.get());
217+
alarm->SetAlerting();
218+
} else {
219+
LoadApp(Apps::Alarm, DisplayApp::FullRefreshDirections::None);
220+
}
211221
case Messages::TouchEvent: {
212222
if (state != States::Running) {
213223
break;
@@ -340,6 +350,9 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
340350
case Apps::Timer:
341351
currentScreen = std::make_unique<Screens::Timer>(this, timerController);
342352
break;
353+
case Apps::Alarm:
354+
currentScreen = std::make_unique<Screens::Alarm>(this, alarmController);
355+
break;
343356

344357
// Settings
345358
case Apps::QuickSettings:

src/displayapp/DisplayApp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
#include "components/settings/Settings.h"
1515
#include "displayapp/screens/Screen.h"
1616
#include "components/timer/TimerController.h"
17+
#include "components/alarm/AlarmController.h"
1718
#include "touchhandler/TouchHandler.h"
19+
1820
#include "Messages.h"
1921

2022
namespace Pinetime {
@@ -57,6 +59,7 @@ namespace Pinetime {
5759
Pinetime::Controllers::MotorController& motorController,
5860
Pinetime::Controllers::MotionController& motionController,
5961
Pinetime::Controllers::TimerController& timerController,
62+
Pinetime::Controllers::AlarmController& alarmController,
6063
Pinetime::Controllers::TouchHandler& touchHandler);
6164
void Start();
6265
void PushMessage(Display::Messages msg);
@@ -82,6 +85,7 @@ namespace Pinetime {
8285
Pinetime::Controllers::MotorController& motorController;
8386
Pinetime::Controllers::MotionController& motionController;
8487
Pinetime::Controllers::TimerController& timerController;
88+
Pinetime::Controllers::AlarmController& alarmController;
8589
Pinetime::Controllers::TouchHandler& touchHandler;
8690

8791
Pinetime::Controllers::FirmwareValidator validator;

src/displayapp/Messages.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ namespace Pinetime {
1515
BleFirmwareUpdateStarted,
1616
UpdateTimeOut,
1717
DimScreen,
18-
RestoreBrightness
18+
RestoreBrightness,
19+
AlarmTriggered
1920
};
2021
}
2122
}

0 commit comments

Comments
 (0)