Skip to content

Commit

Permalink
Merge branch 'InfiniTimeOrg:main' into casio-weather
Browse files Browse the repository at this point in the history
  • Loading branch information
Ghoelian authored Nov 21, 2024
2 parents 6cc9662 + a77a3dc commit 1bade4b
Show file tree
Hide file tree
Showing 62 changed files with 656 additions and 441 deletions.
15 changes: 10 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,30 @@ jobs:
# Unzip the package because Upload Artifact will zip up the files
- name: Unzip DFU package
run: unzip ./build/output/pinetime-mcuboot-app-dfu-*.zip -d ./build/output/pinetime-mcuboot-app-dfu
- name: Set ref_name, but replace slashes with dashes.
shell: bash
env:
ref_name: ${{ github.head_ref || github.ref_name }}
run: echo "REF_NAME=${ref_name//\//-}" >> $GITHUB_ENV
- name: Upload DFU artifacts
uses: actions/upload-artifact@v3
with:
name: InfiniTime DFU ${{ github.head_ref }}
name: InfiniTime DFU ${{ env.REF_NAME }}
path: ./build/output/pinetime-mcuboot-app-dfu/*
- name: Upload MCUBoot image artifacts
uses: actions/upload-artifact@v3
with:
name: InfiniTime MCUBoot image ${{ github.head_ref }}
name: InfiniTime MCUBoot image ${{ env.REF_NAME }}
path: ./build/output/pinetime-mcuboot-app-image-*.bin
- name: Upload standalone ELF artifacts
uses: actions/upload-artifact@v3
with:
name: InfiniTime image ${{ github.head_ref }}
name: InfiniTime image ${{ env.REF_NAME }}
path: ./build/output/src/pinetime-app-*.out
- name: Upload resources artifacts
uses: actions/upload-artifact@v3
with:
name: InfiniTime resources ${{ github.head_ref }}
name: InfiniTime resources ${{ env.REF_NAME }}
path: ./build/output/infinitime-resources-*.zip

build-simulator:
Expand Down Expand Up @@ -105,7 +110,7 @@ jobs:
- name: Upload simulator executable
uses: actions/upload-artifact@v3
with:
name: infinisim-${{ github.head_ref }}
name: infinisim-${{ env.REF_NAME }}
path: build_lv_sim/infinisim

get-base-ref-size:
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
[submodule "src/libs/littlefs"]
path = src/libs/littlefs
url = https://github.com/littlefs-project/littlefs.git
[submodule "src/libs/QCBOR"]
path = src/libs/QCBOR
url = https://github.com/laurencelundblade/QCBOR.git
[submodule "src/libs/arduinoFFT"]
path = src/libs/arduinoFFT
url = https://github.com/kosme/arduinoFFT.git
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
# [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime)
<div align="center">

![InfiniTime logo](doc/logo/infinitime-logo-small.jpg "InfiniTime Logo")
![Header Image](doc/logo/watchface_collage.png)

Fast open-source firmware for the [PineTime smartwatch](https://pine64.org/devices/pinetime/) with many features, written in modern C++.
<br>

[![GitHub tag](https://img.shields.io/github/tag/InfiniTimeOrg/InfiniTime?include_prereleases=&sort=semver&color=blue)](https://github.com/InfiniTimeOrg/InfiniTime/releases)
[![GitHub License](https://img.shields.io/github/license/InfiniTimeOrg/InfiniTime)](https://github.com/InfiniTimeOrg/InfiniLink/blob/main/LICENSE)
[![Issues - InfiniTime](https://img.shields.io/github/issues/InfiniTimeOrg/InfiniTime)](https://github.com/InfiniTimeOrg/InfiniTime/issues)
[![Pull Requests - InfiniTime](https://img.shields.io/github/issues-pr/InfiniTimeOrg/InfiniTime)](https://github.com/InfiniTimeOrg/InfiniTime/pulls)
[![Downloads - InfiniTime](https://img.shields.io/github/downloads/InfiniTimeOrg/InfiniTime/total)](https://github.com/InfiniTimeOrg/InfiniTime)
[![Stars - InfiniTime](https://img.shields.io/github/stars/InfiniTimeOrg/InfiniTime?style=social)](https://github.com/InfiniTimeOrg/InfiniTime/stargazers)
[![Forks - InfiniTime](https://img.shields.io/github/forks/InfiniTimeOrg/InfiniTime?style=social)](https://github.com/InfiniTimeOrg/InfiniTime/network/members)

# InfiniTime

*Fast open-source firmware for the [PineTime smartwatch](https://pine64.org/devices/pinetime/) with many features, written in modern C++.*

<br>

</div>

## New to InfiniTime?

Expand All @@ -17,13 +33,18 @@ Fast open-source firmware for the [PineTime smartwatch](https://pine64.org/devic
### Companion apps

- [Gadgetbridge](https://gadgetbridge.org/) (Android)
- [AmazFish](https://openrepos.net/content/piggz/amazfish/) (SailfishOS)
- [Amazfish](https://github.com/piggz/harbour-amazfish/) ([SailfishOS](https://sailfishos-chum.github.io/apps/harbour-amazfish/), [Ubuntu Touch](https://open-store.io/app/uk.co.piggz.amazfish), [Flatpak](https://flathub.org/apps/uk.co.piggz.amazfish))
- [Siglo](https://github.com/alexr4535/siglo) (Linux)
- [InfiniLink](https://github.com/InfiniTimeOrg/InfiniLink) (iOS)
- [ITD](https://gitea.elara.ws/Elara6331/itd) (Linux)
- [WatchMate](https://github.com/azymohliad/watchmate) (Linux)
- [InfiniTimeExplorer](https://infinitimeexplorer.netlify.app) (Web)

<br>

***Note**: We removed mentions to NRFConnect as this app is closed source and recent versions do not work anymore with InfiniTime (the last version known to work is 4.24.3). If you used NRFConnect in the past, we recommend you switch to [Gadgetbridge](https://gadgetbridge.org/).*
> *InfiniTimeExplorer is only compatible with web browsers that support Web BLE. Current fully supported browsers include Chrome and Microsoft Edge.*
>
> *We removed mentions to NRFConnect as this app is closed source and recent versions do not work anymore with InfiniTime (the last version known to work is 4.24.3). If you used NRFConnect in the past, we recommend you switch to [Gadgetbridge](https://gadgetbridge.org/).*
## Development

Expand Down
Binary file added doc/logo/watchface_collage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ RUN bash -c "source /opt/build.sh; GetMcuBoot;"

# Add the infinitime user for connecting devcontainer
RUN adduser infinitime


# Configure Git to accept the /sources directory as safe
RUN git config --global --add safe.directory /sources

ENV SOURCES_DIR /sources
CMD ["/opt/build.sh"]
4 changes: 3 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ list(APPEND SOURCE_FILES

systemtask/SystemTask.cpp
systemtask/SystemMonitor.cpp
systemtask/WakeLock.cpp
drivers/TwiMaster.cpp

heartratetask/HeartRateTask.cpp
Expand Down Expand Up @@ -542,6 +543,7 @@ list(APPEND RECOVERY_SOURCE_FILES

systemtask/SystemTask.cpp
systemtask/SystemMonitor.cpp
systemtask/WakeLock.cpp
drivers/TwiMaster.cpp
components/rle/RleDecoder.cpp
components/heartrate/HeartRateController.cpp
Expand Down Expand Up @@ -660,6 +662,7 @@ set(INCLUDE_FILES
displayapp/InfiniTimeTheme.h
systemtask/SystemTask.h
systemtask/SystemMonitor.h
systemtask/WakeLock.h
displayapp/screens/Symbols.h
drivers/TwiMaster.h
heartratetask/HeartRateTask.h
Expand Down Expand Up @@ -860,7 +863,6 @@ target_compile_options(nrf-sdk PRIVATE
$<$<CONFIG:RELEASE>: ${RELEASE_FLAGS}>
$<$<COMPILE_LANGUAGE:CXX>: ${CXX_FLAGS}>
$<$<COMPILE_LANGUAGE:ASM>: ${ASM_FLAGS}>
-O3
)

# NimBLE
Expand Down
101 changes: 88 additions & 13 deletions src/components/alarm/AlarmController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
#include "systemtask/SystemTask.h"
#include "task.h"
#include <chrono>
#include <libraries/log/nrf_log.h>

using namespace Pinetime::Controllers;
using namespace std::chrono_literals;

AlarmController::AlarmController(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} {
AlarmController::AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs)
: dateTimeController {dateTimeController}, fs {fs} {
}

namespace {
Expand All @@ -36,11 +38,28 @@ namespace {
void AlarmController::Init(System::SystemTask* systemTask) {
this->systemTask = systemTask;
alarmTimer = xTimerCreate("Alarm", 1, pdFALSE, this, SetOffAlarm);
LoadSettingsFromFile();
if (alarm.isEnabled) {
NRF_LOG_INFO("[AlarmController] Loaded alarm was enabled, scheduling");
ScheduleAlarm();
}
}

void AlarmController::SaveAlarm() {
// verify if it is necessary to save
if (alarmChanged) {
SaveSettingsToFile();
}
alarmChanged = false;
}

void AlarmController::SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin) {
hours = alarmHr;
minutes = alarmMin;
if (alarm.hours == alarmHr && alarm.minutes == alarmMin) {
return;
}
alarm.hours = alarmHr;
alarm.minutes = alarmMin;
alarmChanged = true;
}

void AlarmController::ScheduleAlarm() {
Expand All @@ -53,18 +72,19 @@ void AlarmController::ScheduleAlarm() {
tm* tmAlarmTime = std::localtime(&ttAlarmTime);

// If the time being set has already passed today,the alarm should be set for tomorrow
if (hours < dateTimeController.Hours() || (hours == dateTimeController.Hours() && minutes <= dateTimeController.Minutes())) {
if (alarm.hours < dateTimeController.Hours() ||
(alarm.hours == dateTimeController.Hours() && alarm.minutes <= dateTimeController.Minutes())) {
tmAlarmTime->tm_mday += 1;
// tm_wday doesn't update automatically
tmAlarmTime->tm_wday = (tmAlarmTime->tm_wday + 1) % 7;
}

tmAlarmTime->tm_hour = hours;
tmAlarmTime->tm_min = minutes;
tmAlarmTime->tm_hour = alarm.hours;
tmAlarmTime->tm_min = alarm.minutes;
tmAlarmTime->tm_sec = 0;

// if alarm is in weekday-only mode, make sure it shifts to the next weekday
if (recurrence == RecurType::Weekdays) {
if (alarm.recurrence == RecurType::Weekdays) {
if (tmAlarmTime->tm_wday == 0) { // Sunday, shift 1 day
tmAlarmTime->tm_mday += 1;
} else if (tmAlarmTime->tm_wday == 6) { // Saturday, shift 2 days
Expand All @@ -79,7 +99,10 @@ void AlarmController::ScheduleAlarm() {
xTimerChangePeriod(alarmTimer, secondsToAlarm * configTICK_RATE_HZ, 0);
xTimerStart(alarmTimer, 0);

state = AlarmState::Set;
if (!alarm.isEnabled) {
alarm.isEnabled = true;
alarmChanged = true;
}
}

uint32_t AlarmController::SecondsToAlarm() const {
Expand All @@ -88,20 +111,72 @@ uint32_t AlarmController::SecondsToAlarm() const {

void AlarmController::DisableAlarm() {
xTimerStop(alarmTimer, 0);
state = AlarmState::Not_Set;
isAlerting = false;
if (alarm.isEnabled) {
alarm.isEnabled = false;
alarmChanged = true;
}
}

void AlarmController::SetOffAlarmNow() {
state = AlarmState::Alerting;
isAlerting = true;
systemTask->PushMessage(System::Messages::SetOffAlarm);
}

void AlarmController::StopAlerting() {
// Alarm state is off unless this is a recurring alarm
if (recurrence == RecurType::None) {
state = AlarmState::Not_Set;
isAlerting = false;
// Disable alarm unless it is recurring
if (alarm.recurrence == RecurType::None) {
alarm.isEnabled = false;
alarmChanged = true;
} else {
// set next instance
ScheduleAlarm();
}
}

void AlarmController::SetRecurrence(RecurType recurrence) {
if (alarm.recurrence != recurrence) {
alarm.recurrence = recurrence;
alarmChanged = true;
}
}

void AlarmController::LoadSettingsFromFile() {
lfs_file_t alarmFile;
AlarmSettings alarmBuffer;

if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_RDONLY) != LFS_ERR_OK) {
NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file");
return;
}

fs.FileRead(&alarmFile, reinterpret_cast<uint8_t*>(&alarmBuffer), sizeof(alarmBuffer));
fs.FileClose(&alarmFile);
if (alarmBuffer.version != alarmFormatVersion) {
NRF_LOG_WARNING("[AlarmController] Loaded alarm settings has version %u instead of %u, discarding",
alarmBuffer.version,
alarmFormatVersion);
return;
}

alarm = alarmBuffer;
NRF_LOG_INFO("[AlarmController] Loaded alarm settings from file");
}

void AlarmController::SaveSettingsToFile() const {
lfs_dir systemDir;
if (fs.DirOpen("/.system", &systemDir) != LFS_ERR_OK) {
fs.DirCreate("/.system");
}
fs.DirClose(&systemDir);
lfs_file_t alarmFile;
if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_WRONLY | LFS_O_CREAT) != LFS_ERR_OK) {
NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file for saving");
return;
}

fs.FileWrite(&alarmFile, reinterpret_cast<const uint8_t*>(&alarm), sizeof(alarm));
fs.FileClose(&alarmFile);
NRF_LOG_INFO("[AlarmController] Saved alarm settings with format version %u to file", alarm.version);
}
46 changes: 32 additions & 14 deletions src/components/alarm/AlarmController.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,47 +30,65 @@ namespace Pinetime {
namespace Controllers {
class AlarmController {
public:
AlarmController(Controllers::DateTime& dateTimeController);
AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs);

void Init(System::SystemTask* systemTask);
void SaveAlarm();
void SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin);
void ScheduleAlarm();
void DisableAlarm();
void SetOffAlarmNow();
uint32_t SecondsToAlarm() const;
void StopAlerting();
enum class AlarmState { Not_Set, Set, Alerting };
enum class RecurType { None, Daily, Weekdays };

uint8_t Hours() const {
return hours;
return alarm.hours;
}

uint8_t Minutes() const {
return minutes;
return alarm.minutes;
}

AlarmState State() const {
return state;
bool IsAlerting() const {
return isAlerting;
}

RecurType Recurrence() const {
return recurrence;
bool IsEnabled() const {
return alarm.isEnabled;
}

void SetRecurrence(RecurType recurType) {
recurrence = recurType;
RecurType Recurrence() const {
return alarm.recurrence;
}

void SetRecurrence(RecurType recurrence);

private:
// Versions 255 is reserved for now, so the version field can be made
// bigger, should it ever be needed.
static constexpr uint8_t alarmFormatVersion = 1;

struct AlarmSettings {
uint8_t version = alarmFormatVersion;
uint8_t hours = 7;
uint8_t minutes = 0;
RecurType recurrence = RecurType::None;
bool isEnabled = false;
};

bool isAlerting = false;
bool alarmChanged = false;

Controllers::DateTime& dateTimeController;
Controllers::FS& fs;
System::SystemTask* systemTask = nullptr;
TimerHandle_t alarmTimer;
uint8_t hours = 7;
uint8_t minutes = 0;
AlarmSettings alarm;
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> alarmTime;
AlarmState state = AlarmState::Not_Set;
RecurType recurrence = RecurType::None;

void LoadSettingsFromFile();
void SaveSettingsToFile() const;
};
}
}
Loading

0 comments on commit 1bade4b

Please sign in to comment.