Compare commits

...

122 commits

Author SHA1 Message Date
Eve C de119b569e merged from main, fixed WatchFaceCasio after merge mess, fix my Infineat modifications according to new alarmcontroller 2024-10-16 18:08:41 +02:00
Eve C c71d64393b merge from main 2024-10-16 17:41:26 +02:00
Eve C 6f9df084d9 Merge branch 'main' of github.com:InfiniTimeOrg/InfiniTime 2024-10-16 17:38:14 +02:00
Eve C cdf86dab6a Merge branch 'alarm-status-on-infineat' of github.com:Eve1374/InfiniTime into alarm-status-on-infineat 2024-10-16 17:32:56 +02:00
Eve C e16c8f8bab correcitons 2024-10-16 17:01:53 +02:00
NeroBurner 8598142c27
Remove unused submodule QCBOR (#2138)
Some checks failed
CI / build-firmware (push) Successful in 5m57s
CI / build-simulator (push) Failing after 3s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
The submodule isn't used anymore. Remove the submodule reference
completely.
2024-10-09 20:26:08 +02:00
Eve C 39241889be corrections 2024-10-02 15:39:45 +02:00
Eve C e2ca5393a6 corrections 2024-10-02 15:35:10 +02:00
Eve C a18190e37f corrections 2024-10-02 15:09:19 +02:00
Eve C 9ff835bb89 corrections 2024-10-02 15:06:20 +02:00
Eve C b7b68f6362 merge ?? 2024-10-02 12:28:03 +02:00
NeroBurner a2356f2f4a
MusicService: add missing includes for TickType_t and xTaskGetTickCount (#2130)
Some checks failed
CI / build-firmware (push) Successful in 10m55s
CI / build-simulator (push) Failing after 3s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
Add `FreeRTOS.h` include for the directly used data type `TickType_t` in the header
and the function `xTaskGetTickCount` from FreeRTOS's `task.h`
2024-09-29 21:10:32 +02:00
NeroBurner 3db4e012ce
Remove unused pointer to DisplayApp member variables (#2125)
Some checks failed
CI / build-firmware (push) Successful in 10m10s
CI / build-simulator (push) Failing after 3s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
In the screens that use `DisplayApp *app` and pass it to a child item,
or use the reference just in the constructor. Afterwards the `app`
member is not used. So remove it from the private member variables.

Completely remove `app` parameter from `SettingDisplay` constructor as
it is unused.
2024-09-29 19:39:14 +02:00
NeroBurner a0cd439efc
Alarm persist to flash (#1367)
Some checks failed
CI / build-firmware (push) Successful in 13m37s
CI / build-simulator (push) Failing after 4s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
* AlarmController: Add saving alarm time to file

Save the set alarm time to the SPI NOR flash, so it does not reset to
the default value when the watch resets, e.g. due to watchdog timeout
or reflashing of a new version of InfiniTime.

Just like the `Settings.h` `LoadSettingsFromFile()` the previous alarm
at boot (if available) and `SaveSettingsToFile()` the current alarm when
the `Alarm.h` screen is closed (only if the settings have changed).

The alarm-settings file is stored in `.system/alarm.dat`. The `.system`
folder is created if it doesn't yet exist.

Fixes: https://github.com/InfiniTimeOrg/InfiniTime/issues/1330

* alarmController: close .system dir after usage

Close the `lfs_dir` object for the `.system` dir after usage. Otherwise
on the second changed alarm the system will lockup because the `.system`
dir is already open and was never closed.

---------

Co-authored-by: Galdor Takacs <g@ldor.de>
2024-09-28 08:14:08 +02:00
Reinhold Gschweicher 997e4cee8c Hrs3300: fix includes for std::begin/std::end
Some checks failed
CI / build-firmware (push) Successful in 5m35s
CI / build-simulator (push) Failing after 2s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
Fix for Hrs3300 PR about Atomic HRS reads:
https://github.com/InfiniTimeOrg/InfiniTime/pull/1845

We use `std::begin` and `std::end`, but we don't include one of the
headers that define those functions.
See https://en.cppreference.com/w/cpp/iterator/begin for a list of
headers that define `std::begin` and `std::end`.

Starting with GCC 14 this leads to a compilation error presumably
because they cleaned up their headers.

Fix code by inlcuding `<iterator>`
2024-09-22 16:15:48 +02:00
mark9064 ad3bf49c7b
Atomic HRS reads (#1845)
Some checks failed
CI / build-firmware (push) Successful in 5m25s
CI / build-simulator (push) Failing after 2s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
- Combine the reading of all `HRS3300` registers into one I2C read so data is not partial
- Downsizes both HRS and ALS to 16bit as the sensor does not generate larger than
  16bit values in its current configuration
  - Increasing the resolution by 1 bit doubles the sensor acquisition time,
    since we are already at 10Hz we are never going to use a higher resolution
  - The PPG algorithm buffers for ALS/HRS are already 16bit anyway
- Remove functions for setting gain / drive that are unused throughout the codebase
- Calculate constants with constexpr
2024-09-22 00:29:15 +02:00
mark9064 7ca0418c82 Refactor doNotGoToSleep to a wakelock counter
Some checks failed
CI / build-firmware (push) Successful in 6m20s
CI / build-simulator (push) Failing after 22s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
2024-09-21 22:45:57 +02:00
mark9064 c3d05901a0 Refactor SystemTask state handling for resilience
State transitions now happen immediately where possible
This simplifies state management in general,
and prevents bugs such as the chime issue from occurring in the first place
2024-09-21 21:08:07 +02:00
mark9064 b3756e45fa Remove unused method declarations 2024-09-21 21:08:07 +02:00
Eli Tan a266202831
notifications: Dismiss to watchface when empty (#1716)
Some checks failed
CI / build-firmware (push) Successful in 6m40s
CI / build-simulator (push) Failing after 24s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
Set `running` to false to flag end of watchface when there are no more
notifications left to display.

I found it slightly annoying that dismissing all notifications leaves me with
a "No notification to display" message. Instead of dismissing to a relatively
useless message, dismiss to watchface.
2024-09-18 22:31:15 +02:00
mark9064 c8236afbef Restrict debugging monitor to debug builds
Some checks failed
CI / build-firmware (push) Successful in 6m31s
CI / build-simulator (push) Failing after 22s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
2024-09-14 12:10:55 +02:00
mark9064 5040733a97 Clean unused DisplayApp messages 2024-09-14 12:10:14 +02:00
mark9064 fd019c7aad Use DirtyValue for timer 2024-09-14 11:20:47 +02:00
mark9064 975bfc5420 Size optimise NRF SDK build 2024-09-14 11:19:34 +02:00
Eve C e940593803 Merge branch 'main' of github.com:InfiniTimeOrg/InfiniTime
Your branch and 'github_orig/main' have diverged,
 and have 3 and 21 different commits each, respectively.
 Changes to be committed:
	modified:   README.md
2024-08-26 11:21:48 +02:00
Eve C b7263ed795 start to add timer info on WatchFaceMeow 2024-07-25 17:27:10 +02:00
Eve C 5e19e042c0 new file: doc/lvgl_align.png add ref for alignment names in lvgl
modified:   src/displayapp/apps/CMakeLists.txt uncomment wome watchfaces
	modified:   src/displayapp/screens/WatchFaceCasioStyleG7710.cpp add alarm, overlaps with heartbeat
	modified:   src/displayapp/screens/WatchFaceCasioStyleG7710.h
	new file:   todo.log
2024-07-16 08:36:01 +02:00
Eve C 6ce316dc06 hide alarm depending on option status 2024-07-15 16:39:17 +02:00
Eve C 59f9a5eaff Changes to be committed:
modified:   src/displayapp/screens/Calendar.cpp
	modified:   src/libs/lv_conf.h
week start on monday with LV_CALENDAR_WEEK_STARTS_MONDAY
 Changes not staged for commit:
	modified:   src/libs/lvgl (modified content)
2024-07-10 17:20:52 +02:00
Eve C 2a762f62ad On branch my-custom-infinitime
modified:   package-lock.json : ???
	modified:   package.json : ???
	modified:   src/displayapp/screens/AlarmIcon.cpp : put bell /
not bell in this file to keep infineat as in the PR I submit
	modified:   src/displayapp/screens/WatchFaceMeow.cpp : don't
refer to alarmIcon.cpp to change the icon, instead do it in this file
directly to have different icons
	modified:   src/libs/QCBOR  : reverted to match original repo's
version (git submodule status : compare commit id in this repo and a
freshly cloned repo)
	modified:   src/libs/arduinoFFT : reverted
	modified:   src/libs/littlefs : reverted
2024-07-10 11:48:09 +02:00
Eve C e4d6014d88 updated WatchFaceMeow to match alignment, settings, AMPM compatibility of Infineat. also files that seemed to have been modified by submodules update. 2024-07-10 10:34:37 +02:00
Eve C 164a21218f faire en sorte que watchfacemeow et watchface infineat soient compatibles, en cours 2024-07-09 12:05:06 +02:00
Eve C 8ed1d22a48 Merge branch 'main' into my-custom-infinitime
Conflicts:
	.gitignore
	README.md
somehow when I compile it adds a nodemodules folder, that is not in the
original (from Infinitime) .gitignore file. So I added it.
I also modified the readme to list the branches in this project and my
modifications.

These are the changes from main that I didn't have yet in this branch
 Changes to be committed:
	modified:   README.md
	new file:   doc/ui/infineat_settings.png
	modified:   src/components/ble/SimpleWeatherService.cpp
	modified:   src/components/ble/SimpleWeatherService.h
	modified:   src/components/datetime/DateTimeController.cpp
	modified:   src/components/datetime/DateTimeController.h
	new file:   src/components/datetime/TODO.md
	modified:   src/displayapp/DisplayApp.cpp
	modified:   src/displayapp/screens/WatchFaceAnalog.h
	modified:   src/drivers/Bma421.cpp
	modified:   src/drivers/St7789.cpp
	modified:   src/drivers/St7789.h
	modified:   src/systemtask/SystemTask.cpp
2024-07-08 17:12:29 +02:00
Eve C f42ef49a40 Merge branch 'testcalendar' into my-custom-infinitime
Conflicts:
	src/displayapp/apps/CMakeLists.txt
	src/displayapp/fonts/fonts.json
	src/displayapp/screens/Symbols.h

 On branch my-custom-infinitime
 All conflicts fixed but you are still merging.
 Changes to be committed:
	modified:   src/CMakeLists.txt
	modified:   src/displayapp/DisplayApp.cpp
	modified:   src/displayapp/InfiniTimeTheme.h
	modified:   src/displayapp/apps/Apps.h.in
	modified:   src/displayapp/apps/CMakeLists.txt
	modified:   src/displayapp/fonts/fonts.json
	new file:   src/displayapp/screens/Calendar.cpp
	new file:   src/displayapp/screens/Calendar.h
	modified:   src/displayapp/screens/Symbols.h
merge conflicts were mainly symbols, so I gathered the most complete
list of symbols from the merge conflict
2024-07-08 17:05:53 +02:00
Eve C d78e60329e sync with main from infinitime 2024-06-26 17:49:42 +02:00
Eve C 3133adaba9 remove apps and wf from cmake 2024-05-30 17:12:03 +02:00
Eve C 3f214a2f84 cleaned CMAKELISTS 2024-05-30 16:22:49 +02:00
Eve C 6602a1d7c0 update fonts with calendar symbols, rebase failed 2024-05-30 16:08:27 +02:00
Eve C acbcd531b5 cat as battery icon : modified the lines of infineat and position of picture 2024-05-30 15:54:40 +02:00
ecarlett e2056f6420 revert meow to pine icon, rework on cat later 2024-05-30 15:54:40 +02:00
ecarlett 5d261f579d modified the battery icon in Meow to be a cat face. add pictures accordingly. doesnt work on pt 2024-05-30 15:54:40 +02:00
ecarlett f7333c66bd copied a memo I made with files to modify when ADDING a watchface. may be incomplete.. 2024-05-30 15:54:40 +02:00
ecarlett 9437a8d125 now there is my watchface in pink and stuff adn the Infineat watchface with alarm status but the icons are not the same as on branch alarm-on-infineat 2024-05-30 15:54:40 +02:00
ecarlett 5dfdec4ee2 fixing mess again after merge mess 2024-05-30 15:54:40 +02:00
ecarlett 7bab4a66aa fix Apps.h.in and src/components/settings/Settings.h after merge mess 2024-05-30 15:54:40 +02:00
ecarlett 055b9a93c4 fix AlarmIcon.cpp and WatchFaceInfineat.cpp after merge mess 2024-05-30 15:54:40 +02:00
ecarlett e8b1b94507 fix src/displayapp/screens/settings/SettingWatchFace.h after merge mess 2024-05-30 15:54:40 +02:00
ecarlett dbc1dcfbdf fix src/displayapp/UserApps.h
after merge mess
2024-05-30 15:54:40 +02:00
Eve C d1c00370d1 combiner calendar et meow 2024-05-30 15:54:21 +02:00
ecarlett 99d223b4d1 fix src/CMakeLists.txt after merge mess 2024-05-30 15:53:52 +02:00
ecarlett ad19b9e798 fix src/displayapp/apps/CMakeLists.txt after merge mess 2024-05-30 15:53:52 +02:00
ecarlett bbbc9d9910 now I have the Meow Watchface AND the Infineat Watchface with alarm display
interactive rebase in progress; onto b7a353cf
 Last commands done (3 commands done):
    pick 9d04c32f recovering manually changes to original Infineat
    pick 70f9025f now I have the Meow Watchface AND the Infineat Watchface with alarm display
 No commands remaining.
 You are currently rebasing branch 'my-custom-infinitime' on 'b7a353cf'.

 Changes to be committed:
	modified:   src/components/settings/Settings.h
2024-05-30 15:53:52 +02:00
ecarlett 6cb3b6060e test combiner tout 2024-05-30 15:53:47 +02:00
ecarlett ee99e554f0 copy :( files from gitlab repo
interactive rebase in progress; onto b7a353cf
 Last command done (1 command done):
    pick 504f5774 copy :( files from gitlab repo
 Next commands to do (2 remaining commands):
    pick 9d04c32f recovering manually changes to original Infineat
    pick 70f9025f now I have the Meow Watchface AND the Infineat Watchface with alarm display
 You are currently rebasing branch 'my-custom-infinitime' on 'b7a353cf'.

 Changes to be committed:
	modified:   src/CMakeLists.txt
	modified:   src/displayapp/apps/Apps.h.in
	modified:   src/displayapp/apps/CMakeLists.txt
	modified:   src/displayapp/screens/Symbols.h
2024-05-30 15:53:04 +02:00
ecarlett ad5a472b4b modified: .gitignore 2024-05-30 15:51:20 +02:00
ecarlett 8929563950 test 2024-05-30 15:51:20 +02:00
ecarlett d6a6bda6ba start cat icon 2024-05-30 15:51:20 +02:00
ecarlett ecea195533 Add pictures in readme 2024-05-30 15:51:20 +02:00
ecarlett 55866d4470 InfiniTime firmware for pinetime with a new watchface. Note that some other watchfaces are disabled from compilation to save memory space, in case. The WatchFaceMeow, named Meow in the interface, displays the status of the alarm on the screen 2024-05-30 15:51:20 +02:00
ecarlett 91fb716ea3 c'est mieux aligné 2024-05-30 15:51:20 +02:00
Eve C 6494faa249 try to rebase scottcalendar into this testbranch 2024-05-30 15:50:41 +02:00
ecarlett 5cd1bcf460 add WatchFaceInfineatColors that has different color sets than infineat 2024-05-30 15:48:38 +02:00
ecarlett b588241207 compile sans avoir modifié de code ok 2024-05-30 15:48:38 +02:00
ecarlett e8a1b12e17 fixed that label ampm stays shown when alarm status is hidden 2024-05-30 15:48:38 +02:00
ecarlett 194b061e19 update settings of watchfaceInifineat with alarm settings so it looks better 2024-05-30 15:48:38 +02:00
ecarlett 8ca3888540 AMPM for alarm seems to work - but overloads the screen, of course. check tomorrow all cases 2024-05-30 15:48:38 +02:00
ecarlett f366354e28 fixed alarm status reappearing when alarm changed, even if not set to be displayed. TODO : clean comments related to this, and add am/pm format for alarm 2024-05-30 15:48:38 +02:00
ecarlett feb7631f45 added option to show or hide alarm status 2024-05-30 15:48:38 +02:00
ecarlett b55c9d256c initial commit, with already alarm added. TODO : add possibility to disable alarm status, and make it work on 12hrs format
pick 0dcfb2ed Fix erratum 58 workaround
    pick 1162fdbf initial commit, with already alarm added. TODO : add possibility to disable alarm status, and make it work on 12hrs format
 Next commands to do (30 remaining commands):
    pick ab901b89 added option to show or hide alarm status
    pick 1af813a2 fixed alarm status reappearing when alarm changed, even if not set to be displayed. TODO : clean comments related to this, and add am/pm format for alarm
 You are currently rebasing branch 'testcalendar' on '577dfd5b'.
2024-05-30 15:47:49 +02:00
mark9064 1246d77781 Fix erratum 58 workaround 2024-05-30 15:45:33 +02:00
mark9064 5c93cbd552 Include task header (Fixes sim) 2024-05-30 15:45:33 +02:00
mark9064 b8fe20b71a Move includes back 2024-05-30 15:45:33 +02:00
mark9064 32dfaa82d6 Apply display driver datasheet delays 2024-05-30 15:45:33 +02:00
mark9064 cad3de46b0 Use FreeRTOS delay instead of spinning the CPU 2024-05-30 15:45:33 +02:00
mark9064 7c8e5c2144 Rename to pre-transaction hook 2024-05-30 15:45:33 +02:00
mark9064 7e8a4d32ee Avoid storing lambda 2024-05-30 15:45:33 +02:00
mark9064 1a379c80bf Refactor lambdas 2024-05-30 15:45:33 +02:00
mark9064 0d77cf9189 Use functional abstraction for hooks 2024-05-30 15:45:33 +02:00
mark9064 7739ecf900 Refactor display WriteToRam 2024-05-30 15:45:33 +02:00
mark9064 e579b83201 Remove task to notify 2024-05-30 15:45:33 +02:00
mark9064 2c9444d67a SPI transaction hooks 2024-05-30 15:45:33 +02:00
John Crawford 80b4da8197 fix: heartrate app displays --- instead of 000 (#1887) 2024-05-30 15:45:33 +02:00
BloodStainedCrow c7a74adb13 Unify docker devcontainer with dockerfile used for CI (#1587)
* Only use one Dockerfile and build.sh script for both docker and devcontainer
* Remove all now unneccessary tasks and scripts
* Update to clang-format-14
* Move devcontainer.json into root folder
* Fix conditional statements in Dockerfile
* Move .devcontainer/README into doc/usingDevcontainers
* Remove obsolete VSCode Task
* Change standard compiler path to the correct compiler
* Set GDB Path for debugging
* Hide broken buttons from CMake Extension
* Refactor .devcontainer
* Remove unneccessary postBuildCommand
* Add devcontainer dependencies to all docker images
* Add Devcontainer Debug launch config
* Add an additional c_cpp_properties config as a fallback for devcontainer
* Remove obsolete Docker Argument
* Fix wrong C/Cpp versions
* Fix silent fail of gdb, add libncurses5
2024-05-30 15:45:33 +02:00
Victor Kareh db947fa97c WatchFaceDigital: Remove unused variables 2024-05-30 15:45:33 +02:00
JF cbc16cd683 Emit the message BleRadioEnableToggle to DisplayApp only if the enable state of the radio has actually changed. (#2037)
This fixes an issue where the BLE connected logo would disappear when opening and closing the BLE setting (without changing it) while InfiniTime was already connected to a companion app.

Co-authored-by: JustScott <development@justscott.me>
2024-05-30 15:45:33 +02:00
Eve C a0c9b4d5fc cat as battery icon : modified the lines of infineat and position of picture 2024-05-30 13:23:25 +02:00
ecarlett d81356c8f7 revert meow to pine icon, rework on cat later 2024-05-29 17:42:59 +02:00
ecarlett 13773a9b25 modified the battery icon in Meow to be a cat face. add pictures accordingly. doesnt work on pt 2024-05-29 17:38:21 +02:00
ecarlett 961c51083e copied a memo I made with files to modify when ADDING a watchface. may be incomplete.. 2024-05-29 16:27:58 +02:00
ecarlett 48f182c25f update README with link to original repo 2024-05-29 16:21:07 +02:00
ecarlett 10c470ef71 update doc of main branch 2024-05-29 16:19:59 +02:00
ecarlett 25e81b159b now there is my watchface in pink and stuff adn the Infineat watchface with alarm status but the icons are not the same as on branch alarm-on-infineat 2024-05-29 15:54:56 +02:00
ecarlett 896f2011b2 fixing mess again after merge mess 2024-05-29 15:48:35 +02:00
ecarlett 3cfe46ec8f fix Apps.h.in and src/components/settings/Settings.h after merge mess 2024-05-29 15:43:30 +02:00
ecarlett a6b932e608 fix AlarmIcon.cpp and WatchFaceInfineat.cpp after merge mess 2024-05-29 15:40:21 +02:00
ecarlett a250fa45ec fix src/displayapp/screens/settings/SettingWatchFace.h after merge mess 2024-05-29 15:37:19 +02:00
ecarlett 6475d6e624 fix src/displayapp/UserApps.h
after merge mess
2024-05-29 15:35:21 +02:00
ecarlett ce13c721be fix fonts after merge mess 2024-05-29 15:33:21 +02:00
ecarlett 5ac1e90040 fix src/CMakeLists.txt after merge mess 2024-05-29 15:26:59 +02:00
ecarlett 9a377f6baf fix src/displayapp/apps/CMakeLists.txt after merge mess 2024-05-29 15:25:05 +02:00
ecarlett 0ecfbee4b7 now I have the Meow Watchface AND the Infineat Watchface with alarm display
interactive rebase in progress; onto b7a353cf
 Last commands done (3 commands done):
    pick 9d04c32f recovering manually changes to original Infineat
    pick 70f9025f now I have the Meow Watchface AND the Infineat Watchface with alarm display
 No commands remaining.
 You are currently rebasing branch 'my-custom-infinitime' on 'b7a353cf'.

 Changes to be committed:
	modified:   src/components/settings/Settings.h
2024-05-29 15:22:55 +02:00
ecarlett 055b75d55d test combiner tout 2024-05-29 15:22:16 +02:00
ecarlett b8f7b65d84 copy :( files from gitlab repo
interactive rebase in progress; onto b7a353cf
 Last command done (1 command done):
    pick 504f5774 copy :( files from gitlab repo
 Next commands to do (2 remaining commands):
    pick 9d04c32f recovering manually changes to original Infineat
    pick 70f9025f now I have the Meow Watchface AND the Infineat Watchface with alarm display
 You are currently rebasing branch 'my-custom-infinitime' on 'b7a353cf'.

 Changes to be committed:
	modified:   src/CMakeLists.txt
	modified:   src/displayapp/apps/Apps.h.in
	modified:   src/displayapp/apps/CMakeLists.txt
	modified:   src/displayapp/screens/Symbols.h
2024-05-29 15:21:12 +02:00
ecarlett b7a353cfb6 modified: .gitignore 2024-05-29 13:00:23 +02:00
ecarlett a4389f63fa test 2024-05-29 13:00:23 +02:00
ecarlett ef59bed954 start cat icon 2024-05-29 13:00:23 +02:00
ecarlett d2fab8d99a Add pictures in readme 2024-05-29 13:00:23 +02:00
ecarlett 82e96cf8d7 InfiniTime firmware for pinetime with a new watchface. Note that some other watchfaces are disabled from compilation to save memory space, in case. The WatchFaceMeow, named Meow in the interface, displays the status of the alarm on the screen 2024-05-29 13:00:23 +02:00
ecarlett 1ec43e27de c'est mieux aligné 2024-05-29 13:00:23 +02:00
ecarlett d7de641b8d added symbols for alarm states, added alarm state and hour to watchface meow, changed steps to paw. Need to align everythign nicely and find where to change release number
modified:   make_pine_mcu.sh
	modified:   src/CMakeLists.txt
	modified:   src/components/settings/Settings.h
	modified:   src/displayapp/UserApps.h
	modified:   src/displayapp/apps/Apps.h.in
	modified:   src/displayapp/apps/CMakeLists.txt
	modified:   src/displayapp/fonts/fonts.json
	modified:   src/displayapp/screens/AlarmIcon.cpp
	new file:   src/displayapp/screens/README.md
	modified:   src/displayapp/screens/Symbols.h
	modified:   src/displayapp/screens/WatchFaceInfineatColors.cpp
	modified:   src/displayapp/screens/WatchFaceInfineatColors.h
	new file:   src/displayapp/screens/WatchFaceMeow.cpp
	new file:   src/displayapp/screens/WatchFaceMeow.h
	modified:   src/displayapp/screens/settings/SettingWatchFace.h
2024-05-29 13:00:07 +02:00
ecarlett b16e13f471 add WatchFaceInfineatColors that has different color sets than infineat 2024-05-29 12:58:46 +02:00
ecarlett a5246941b0 compile sans avoir modifié de code ok 2024-05-29 12:58:46 +02:00
ecarlett edb61e7658 fixed that label ampm stays shown when alarm status is hidden 2024-05-29 12:08:25 +02:00
ecarlett 48cfd48e39 update settings of watchfaceInifineat with alarm settings so it looks better 2024-05-29 11:18:10 +02:00
ecarlett 735083a042 AMPM for alarm seems to work - but overloads the screen, of course. check tomorrow all cases 2024-05-28 17:45:31 +02:00
ecarlett 1af813a2ef fixed alarm status reappearing when alarm changed, even if not set to be displayed. TODO : clean comments related to this, and add am/pm format for alarm 2024-05-28 16:44:33 +02:00
ecarlett ab901b890b added option to show or hide alarm status 2024-05-28 13:40:16 +02:00
ecarlett 1162fdbf14 initial commit, with already alarm added. TODO : add possibility to disable alarm status, and make it work on 12hrs format 2024-05-28 10:39:51 +02:00
JustScott 577dfd5b87 Updated the calendar to use colors from the InfiniTimeTheme.h's Colors namespace 2024-03-15 01:16:39 -05:00
JustScott 0535e93848 Reformatted the code to comply with clang-format. 2024-03-15 01:16:39 -05:00
JustScott 780e68f456 Removed unused variables, some of the commented out code, and added a
license copyright notice to the source and header calendar files.
2024-03-15 01:16:39 -05:00
JustScott d0f776b44c Add a new Calendar App
A basic calendar app that shows all the days dates in the current month along
with the correlating week days, highlights the current day, and allows swiping
left and right to increase and decrease the current month by one.

Co-authored-by: thnikk <thnikk@users.noreply.github.com>
Co-authored-by: Boteium <boteium@users.noreply.github.com>
2024-03-15 01:16:39 -05:00
75 changed files with 531 additions and 486 deletions

View file

@ -3,3 +3,16 @@
autocrlf = input
[apply]
whitespace = fix
[diff]
tool = meld
[difftool]
prompt = false
[difftool "meld"]
cmd = meld "$LOCAL" "$REMOTE"
[merge]
tool = meld
[mergetool "meld"]
# Choose one of these two lines (not both!) explained below.
cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"

2
.gitignore vendored
View file

@ -11,7 +11,7 @@ cmake_install.cmake
Makefile
build
tools
node_modules
# Resulting binary files
*.a

3
.gitmodules vendored
View file

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

View file

@ -1,9 +1,41 @@
# [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime)
# [InfiniTime](https://github.com/Eve1374/InfiniTime)
![InfiniTime logo](doc/logo/infinitime-logo-small.jpg "InfiniTime Logo")
Fast open-source firmware for the [PineTime smartwatch](https://pine64.org/devices/pinetime/) with many features, written in modern C++.
## Quick notes on this InfiniTime version
- I copied the source code from this git repo : [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime)
- I added a watch face "WatchFaceMeow" whose main features are to be pink and have info about the alarm status
- I stored the compile commands in scripts compile.sh to run from InfiniTime/ folder, and make_pine_mcu.sh to build the image must be run from InfiniTime/build/ (compile.sh copies make_pine_mcu.sh to build/
- The file to flash to the pinetime is InfiniTime/build/pinetime-mcuboot-app-dfu-1.14.0.zip : I didn't change the version compared to the one I downloaded from [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime) so make sure not to keep keep a copy of it
Here are pictures with and without alarm set :
Original repo : [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime)
- [Getting started with InfiniTime](doc/gettingStarted/gettingStarted-1.0.md)
- [Updating the software](doc/gettingStarted/updating-software.md)
- [About the firmware and bootloader](doc/gettingStarted/about-software.md)
- [Available apps](doc/gettingStarted/Applications.md)
- [Available watch faces](/doc/gettingStarted/Watchfaces.md)
- [PineTimeStyle Watch face](https://pine64.org/documentation/PineTime/Watchfaces/PineTimeStyle)
- [Weather integration](https://pine64.org/documentation/PineTime/Software/InfiniTime_weather/)
## Welcome to my InfiniTime fork ?!
Branches :
- main : shows this doc
- alarm-status-on-infineat : shows the alarm status on infineat, can be enabled or disabled from the settigns menu that is updated accordingly :
![Infineat settings](doc/ui/infineat_settings.png "Infineat settings")
- my-custom-infinitime : branch were I put things that I want for myself, like a watchface with paw instead of shoe icon for steps counter :
## New to InfiniTime?
- [Getting started with InfiniTime](doc/gettingStarted/gettingStarted-1.0.md)
@ -88,3 +120,4 @@ Here are some people I would like to highlight:
- [Atc1441](https://github.com/atc1441/): He works on an Arduino based firmware for the Pinetime and many other smartwatches based on similar hardware. He was of great help when I was implementing support for the BMA421 motion sensor and I²C driver.
- [Koen](https://github.com/bosmoment): Hes working on a firmware based on RiotOS. He integrated similar libs as me: NimBLE, LittleVGL,… His help was invaluable too!
- [Lup Yuen Lee](https://github.com/lupyuen): He is everywhere: he works on a Rust firmware, builds a MCUBoot based bootloader for the Pinetime, designs a Flutter based companion app for smartphones and writes a lot of articles about the Pinetime!
>>>>>>>>> Temporary merge branch 2

8
compile.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/bash
rm -r build
cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=/home/eve/Work/gcc-arm-none-eabi-10.3-2021.10 -DNRF5_SDK_PATH=/home/eve/Work/nRF5_SDK_17.1.0_ddde560 -DTARGET_DEVICE=PINETIME -DBUILD_DFU=1 -DBUILD_RESOURCES=1 -B build -DCMAKE_BUILD_TYPE=Release
cp make_pine_mcu.sh build/

BIN
doc/lvgl_align.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
doc/palettes.xcf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
doc/ui/meow_alarmnotset.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
doc/ui/meow_alarmset.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

BIN
draft_pictures/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

BIN
draft_pictures/cat.xcf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

6
make_pine.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
#cp ./displayapp/apps/Apps.h ../src/displayapp/apps/Apps.h
make -j4 pinetime-app

6
make_pine_mcu.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
#cp ./displayapp/apps/Apps.h ../src/displayapp/apps/Apps.h
make clean -j4 pinetime-mcuboot-app

183
package-lock.json generated
View file

@ -1,183 +0,0 @@
{
"name": "InfiniTime",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"lv_font_conv": "^1.5.2"
}
},
"node_modules/lv_font_conv": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/lv_font_conv/-/lv_font_conv-1.5.2.tgz",
"integrity": "sha512-0UapRSTkVP/pnB8Z4r2HDHx5p2dJx/xUG1+14u/WXo59mwuC7BahR+Bnx/66jKoDrG1wFQwn9ZzoyMxRHOD9bg==",
"bundleDependencies": [
"argparse",
"bit-buffer",
"debug",
"make-error",
"mkdirp",
"opentype.js",
"pngjs"
],
"dependencies": {
"argparse": "^2.0.0",
"bit-buffer": "^0.2.5",
"debug": "^4.1.1",
"make-error": "^1.3.5",
"mkdirp": "^1.0.4",
"opentype.js": "^1.1.0",
"pngjs": "^6.0.0"
},
"bin": {
"lv_font_conv": "lv_font_conv.js"
}
},
"node_modules/lv_font_conv/node_modules/argparse": {
"version": "2.0.1",
"inBundle": true,
"license": "Python-2.0"
},
"node_modules/lv_font_conv/node_modules/bit-buffer": {
"version": "0.2.5",
"inBundle": true,
"license": "MIT"
},
"node_modules/lv_font_conv/node_modules/debug": {
"version": "4.3.1",
"inBundle": true,
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/lv_font_conv/node_modules/make-error": {
"version": "1.3.6",
"inBundle": true,
"license": "ISC"
},
"node_modules/lv_font_conv/node_modules/mkdirp": {
"version": "1.0.4",
"inBundle": true,
"license": "MIT",
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/lv_font_conv/node_modules/ms": {
"version": "2.1.2",
"inBundle": true,
"license": "MIT"
},
"node_modules/lv_font_conv/node_modules/opentype.js": {
"version": "1.3.3",
"inBundle": true,
"license": "MIT",
"dependencies": {
"string.prototype.codepointat": "^0.2.1",
"tiny-inflate": "^1.0.3"
},
"bin": {
"ot": "bin/ot"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/lv_font_conv/node_modules/pngjs": {
"version": "6.0.0",
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">=12.13.0"
}
},
"node_modules/lv_font_conv/node_modules/string.prototype.codepointat": {
"version": "0.2.1",
"inBundle": true,
"license": "MIT"
},
"node_modules/lv_font_conv/node_modules/tiny-inflate": {
"version": "1.0.3",
"inBundle": true,
"license": "MIT"
}
},
"dependencies": {
"lv_font_conv": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/lv_font_conv/-/lv_font_conv-1.5.2.tgz",
"integrity": "sha512-0UapRSTkVP/pnB8Z4r2HDHx5p2dJx/xUG1+14u/WXo59mwuC7BahR+Bnx/66jKoDrG1wFQwn9ZzoyMxRHOD9bg==",
"requires": {
"argparse": "^2.0.0",
"bit-buffer": "^0.2.5",
"debug": "^4.1.1",
"make-error": "^1.3.5",
"mkdirp": "^1.0.4",
"opentype.js": "^1.1.0",
"pngjs": "^6.0.0"
},
"dependencies": {
"argparse": {
"version": "2.0.1",
"bundled": true
},
"bit-buffer": {
"version": "0.2.5",
"bundled": true
},
"debug": {
"version": "4.3.1",
"bundled": true,
"requires": {
"ms": "2.1.2"
}
},
"make-error": {
"version": "1.3.6",
"bundled": true
},
"mkdirp": {
"version": "1.0.4",
"bundled": true
},
"ms": {
"version": "2.1.2",
"bundled": true
},
"opentype.js": {
"version": "1.3.3",
"bundled": true,
"requires": {
"string.prototype.codepointat": "^0.2.1",
"tiny-inflate": "^1.0.3"
}
},
"pngjs": {
"version": "6.0.0",
"bundled": true
},
"string.prototype.codepointat": {
"version": "0.2.1",
"bundled": true
},
"tiny-inflate": {
"version": "1.0.3",
"bundled": true
}
}
}
}
}

View file

@ -1,5 +0,0 @@
{
"dependencies": {
"lv_font_conv": "^1.5.2"
}
}

View file

@ -371,7 +371,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/StopWatch.cpp
displayapp/screens/BatteryIcon.cpp
displayapp/screens/BleIcon.cpp
displayapp/screens/AlarmIcon.cpp
displayapp/screens/AlarmIcon.cpp
displayapp/screens/NotificationIcon.cpp
displayapp/screens/SystemInfo.cpp
displayapp/screens/Label.cpp
@ -479,6 +479,7 @@ list(APPEND SOURCE_FILES
systemtask/SystemTask.cpp
systemtask/SystemMonitor.cpp
systemtask/WakeLock.cpp
drivers/TwiMaster.cpp
heartratetask/HeartRateTask.cpp
@ -543,6 +544,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
@ -661,6 +663,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
@ -861,7 +864,6 @@ target_compile_options(nrf-sdk PRIVATE
$<$<CONFIG:RELEASE>: ${RELEASE_FLAGS}>
$<$<COMPILE_LANGUAGE:CXX>: ${CXX_FLAGS}>
$<$<COMPILE_LANGUAGE:ASM>: ${ASM_FLAGS}>
-O3
)
# NimBLE

View file

@ -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 {
@ -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() {
@ -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
@ -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 {
@ -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);
}

View file

@ -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;
}
bool IsEnabled() const {
return alarm.isEnabled;
}
RecurType Recurrence() const {
return recurrence;
return alarm.recurrence;
}
void SetRecurrence(RecurType recurType) {
recurrence = recurType;
}
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;
};
}
}

View file

@ -124,9 +124,11 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf* om) {
bootloaderSize,
applicationSize);
// wait until SystemTask has finished waking up all devices
while (systemTask.IsSleeping()) {
vTaskDelay(50); // 50ms
// Wait until SystemTask has disabled sleeping
// This isn't quite correct, as we don't actually know
// if BleFirmwareUpdateStarted has been received yet
while (!systemTask.IsSleepDisabled()) {
vTaskDelay(pdMS_TO_TICKS(5));
}
dfuImage.Erase();

View file

@ -18,6 +18,8 @@
#include "components/ble/MusicService.h"
#include "components/ble/NimbleController.h"
#include <cstring>
#include <FreeRTOS.h>
#include <task.h>
namespace {
// 0000yyxx-78fc-48fe-8e23-433b3a1942d0

View file

@ -25,6 +25,7 @@
#include <host/ble_uuid.h>
#undef max
#undef min
#include <FreeRTOS.h>
namespace Pinetime {
namespace Controllers {

View file

@ -454,9 +454,15 @@ void NimbleController::PersistBond(struct ble_gap_conn_desc& desc) {
/* Wakeup Spi and SpiNorFlash before accessing the file system
* This should be fixed in the FS driver
*/
systemTask.PushMessage(Pinetime::System::Messages::GoToRunning);
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
vTaskDelay(10);
// This isn't quite correct
// SystemTask could receive EnableSleeping right after passing this check
// We need some guarantee that the SystemTask has processed the above message
// before we can continue
while (!systemTask.IsSleepDisabled()) {
vTaskDelay(pdMS_TO_TICKS(5));
}
lfs_file_t file_p;

View file

@ -142,7 +142,7 @@ Ppg::Ppg() {
spectrum.fill(0.0f);
}
int8_t Ppg::Preprocess(uint32_t hrs, uint32_t als) {
int8_t Ppg::Preprocess(uint16_t hrs, uint16_t als) {
if (dataIndex < dataLength) {
dataHRS[dataIndex++] = hrs;
}

View file

@ -14,7 +14,7 @@ namespace Pinetime {
class Ppg {
public:
Ppg();
int8_t Preprocess(uint32_t hrs, uint32_t als);
int8_t Preprocess(uint16_t hrs, uint16_t als);
int HeartRate();
void Reset(bool resetDaqBuffer);
static constexpr int deltaTms = 100;

View file

@ -135,6 +135,7 @@ namespace Pinetime {
return settings.watchFaceInfineat.showAlarmStatus;
};
void SetInfineatColorIndex(int index) {
if (index != settings.watchFaceInfineat.colorIndex) {
settings.watchFaceInfineat.colorIndex = index;

View file

@ -209,21 +209,6 @@ void DisplayApp::Refresh() {
LoadScreen(returnAppStack.Pop(), returnDirection);
};
auto DimScreen = [this]() {
if (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) {
isDimmed = true;
brightnessController.Set(Controllers::BrightnessController::Levels::Low);
}
};
auto RestoreBrightness = [this]() {
if (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) {
isDimmed = false;
lv_disp_trig_activity(nullptr);
ApplyBrightness();
}
};
auto IsPastDimTime = [this]() -> bool {
return lv_disp_get_inactive_time(nullptr) >= pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000);
};
@ -267,14 +252,27 @@ void DisplayApp::Refresh() {
if (!systemTask->IsSleepDisabled() && IsPastDimTime()) {
if (!isDimmed) {
DimScreen();
isDimmed = true;
brightnessController.Set(Controllers::BrightnessController::Levels::Low);
}
if (IsPastSleepTime()) {
systemTask->PushMessage(System::Messages::GoToSleep);
state = States::Idle;
if (IsPastSleepTime() && uxQueueMessagesWaiting(msgQueue) == 0) {
PushMessageToSystemTask(System::Messages::GoToSleep);
// Can't set state to Idle here, something may send
// DisableSleeping before this GoToSleep arrives
// Instead we check we have no messages queued before sending GoToSleep
// This works as the SystemTask is higher priority than DisplayApp
// As soon as we send GoToSleep, SystemTask pre-empts DisplayApp
// Whenever DisplayApp is running again, it is guaranteed that
// SystemTask has handled the message
// If it responded, we will have a GoToSleep waiting in the queue
// By checking that there are no messages in the queue, we avoid
// resending GoToSleep when we already have a response
// SystemTask is resilient to duplicate messages, this is an
// optimisation to reduce pressure on the message queues
}
} else if (isDimmed) {
RestoreBrightness();
isDimmed = false;
ApplyBrightness();
}
break;
default:
@ -285,10 +283,10 @@ void DisplayApp::Refresh() {
Messages msg;
if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) {
switch (msg) {
case Messages::DimScreen:
DimScreen();
break;
case Messages::GoToSleep:
if (state != States::Running) {
break;
}
while (brightnessController.Level() != Controllers::BrightnessController::Levels::Low) {
brightnessController.Lower();
vTaskDelay(100);
@ -323,6 +321,9 @@ void DisplayApp::Refresh() {
lv_disp_trig_activity(nullptr);
break;
case Messages::GoToRunning:
if (state == States::Running) {
break;
}
if (settingsController.GetAlwaysOnDisplay()) {
lcd.LowPowerOff();
} else {
@ -333,8 +334,7 @@ void DisplayApp::Refresh() {
state = States::Running;
break;
case Messages::UpdateBleConnection:
// clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected :
// Screens::Clock::BleConnectionStates::NotConnected);
// Only used for recovery firmware
break;
case Messages::NewNotification:
LoadNewScreen(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down);
@ -449,16 +449,11 @@ void DisplayApp::Refresh() {
case Messages::BleRadioEnableToggle:
PushMessageToSystemTask(System::Messages::BleRadioEnableToggle);
break;
case Messages::UpdateDateTime:
// Added to remove warning
// What should happen here?
break;
case Messages::Chime:
LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::None);
motorController.RunForDuration(35);
break;
case Messages::OnChargingEvent:
RestoreBrightness();
motorController.RunForDuration(15);
break;
}
@ -587,7 +582,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
currentScreen = std::make_unique<Screens::SettingWakeUp>(settingsController);
break;
case Apps::SettingDisplay:
currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController);
currentScreen = std::make_unique<Screens::SettingDisplay>(settingsController);
break;
case Apps::SettingSteps:
currentScreen = std::make_unique<Screens::SettingSteps>(settingsController);

View file

@ -8,6 +8,7 @@ namespace Colors {
static constexpr lv_color_t green = LV_COLOR_MAKE(0x0, 0xb0, 0x0);
static constexpr lv_color_t blue = LV_COLOR_MAKE(0x0, 0x50, 0xff);
static constexpr lv_color_t lightGray = LV_COLOR_MAKE(0xb0, 0xb0, 0xb0);
static constexpr lv_color_t gray = LV_COLOR_MAKE(0x50, 0x50, 0x50);
static constexpr lv_color_t bg = LV_COLOR_MAKE(0x5d, 0x69, 0x7e);
static constexpr lv_color_t bgAlt = LV_COLOR_MAKE(0x38, 0x38, 0x38);

View file

@ -7,7 +7,6 @@ namespace Pinetime {
enum class Messages : uint8_t {
GoToSleep,
GoToRunning,
UpdateDateTime,
UpdateBleConnection,
TouchEvent,
ButtonPushed,
@ -17,7 +16,8 @@ namespace Pinetime {
NewNotification,
TimerDone,
BleFirmwareUpdateStarted,
DimScreen,
// Resets the screen timeout timer when awake
// Does nothing when asleep
NotifyDeviceActivity,
ShowPairingKey,
AlarmTriggered,

View file

@ -23,6 +23,7 @@ namespace Pinetime {
Twos,
HeartRate,
Navigation,
Calendar,
StopWatch,
Metronome,
Motion,
@ -51,6 +52,7 @@ namespace Pinetime {
PineTimeStyle,
Terminal,
Infineat,
Meow,
CasioStyleG7710,
};

View file

@ -48,7 +48,7 @@ Alarm::Alarm(Controllers::AlarmController& alarmController,
Controllers::Settings::ClockType clockType,
System::SystemTask& systemTask,
Controllers::MotorController& motorController)
: alarmController {alarmController}, systemTask {systemTask}, motorController {motorController} {
: alarmController {alarmController}, wakeLock(systemTask), motorController {motorController} {
hourCounter.Create();
lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
@ -117,7 +117,7 @@ Alarm::Alarm(Controllers::AlarmController& alarmController,
UpdateAlarmTime();
if (alarmController.State() == Controllers::AlarmController::AlarmState::Alerting) {
if (alarmController.IsAlerting()) {
SetAlerting();
} else {
SetSwitchState(LV_ANIM_OFF);
@ -125,14 +125,15 @@ Alarm::Alarm(Controllers::AlarmController& alarmController,
}
Alarm::~Alarm() {
if (alarmController.State() == AlarmController::AlarmState::Alerting) {
if (alarmController.IsAlerting()) {
StopAlerting();
}
lv_obj_clean(lv_scr_act());
alarmController.SaveAlarm();
}
void Alarm::DisableAlarm() {
if (alarmController.State() == AlarmController::AlarmState::Set) {
if (alarmController.IsEnabled()) {
alarmController.DisableAlarm();
lv_switch_off(enableSwitch, LV_ANIM_ON);
}
@ -172,7 +173,7 @@ bool Alarm::OnButtonPushed() {
HideInfo();
return true;
}
if (alarmController.State() == AlarmController::AlarmState::Alerting) {
if (alarmController.IsAlerting()) {
StopAlerting();
return true;
}
@ -181,7 +182,7 @@ bool Alarm::OnButtonPushed() {
bool Alarm::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
// Don't allow closing the screen by swiping while the alarm is alerting
return alarmController.State() == AlarmController::AlarmState::Alerting && event == TouchEvents::SwipeDown;
return alarmController.IsAlerting() && event == TouchEvents::SwipeDown;
}
void Alarm::OnValueChanged() {
@ -205,7 +206,7 @@ void Alarm::SetAlerting() {
lv_obj_set_hidden(btnStop, false);
taskStopAlarm = lv_task_create(StopAlarmTaskCallback, pdMS_TO_TICKS(60 * 1000), LV_TASK_PRIO_MID, this);
motorController.StartRinging();
systemTask.PushMessage(System::Messages::DisableSleeping);
wakeLock.Lock();
}
void Alarm::StopAlerting() {
@ -216,21 +217,16 @@ void Alarm::StopAlerting() {
lv_task_del(taskStopAlarm);
taskStopAlarm = nullptr;
}
systemTask.PushMessage(System::Messages::EnableSleeping);
wakeLock.Release();
lv_obj_set_hidden(enableSwitch, false);
lv_obj_set_hidden(btnStop, true);
}
void Alarm::SetSwitchState(lv_anim_enable_t anim) {
switch (alarmController.State()) {
case AlarmController::AlarmState::Set:
lv_switch_on(enableSwitch, anim);
break;
case AlarmController::AlarmState::Not_Set:
lv_switch_off(enableSwitch, anim);
break;
default:
break;
if (alarmController.IsEnabled()) {
lv_switch_on(enableSwitch, anim);
} else {
lv_switch_off(enableSwitch, anim);
}
}
@ -247,7 +243,7 @@ void Alarm::ShowInfo() {
txtMessage = lv_label_create(btnMessage, nullptr);
lv_obj_set_style_local_bg_color(btnMessage, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_NAVY);
if (alarmController.State() == AlarmController::AlarmState::Set) {
if (alarmController.IsEnabled()) {
auto timeToAlarm = alarmController.SecondsToAlarm();
auto daysToAlarm = timeToAlarm / 86400;

View file

@ -22,6 +22,7 @@
#include "displayapp/screens/Screen.h"
#include "displayapp/widgets/Counter.h"
#include "displayapp/Controllers.h"
#include "systemtask/WakeLock.h"
#include "Symbols.h"
namespace Pinetime {
@ -43,7 +44,7 @@ namespace Pinetime {
private:
Controllers::AlarmController& alarmController;
System::SystemTask& systemTask;
System::WakeLock wakeLock;
Controllers::MotorController& motorController;
lv_obj_t *btnStop, *txtStop, *btnRecur, *txtRecur, *btnInfo, *enableSwitch;

View file

@ -15,7 +15,7 @@ namespace {
}
FlashLight::FlashLight(System::SystemTask& systemTask, Controllers::BrightnessController& brightnessController)
: systemTask {systemTask}, brightnessController {brightnessController} {
: wakeLock(systemTask), brightnessController {brightnessController} {
previousBrightnessLevel = brightnessController.Level();
brightnessController.Set(Controllers::BrightnessController::Levels::Low);
@ -47,14 +47,13 @@ FlashLight::FlashLight(System::SystemTask& systemTask, Controllers::BrightnessCo
backgroundAction->user_data = this;
lv_obj_set_event_cb(backgroundAction, EventHandler);
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
wakeLock.Lock();
}
FlashLight::~FlashLight() {
lv_obj_clean(lv_scr_act());
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
brightnessController.Set(previousBrightnessLevel);
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
}
void FlashLight::SetColors() {

View file

@ -3,6 +3,7 @@
#include "displayapp/screens/Screen.h"
#include "components/brightness/BrightnessController.h"
#include "systemtask/SystemTask.h"
#include "systemtask/WakeLock.h"
#include <cstdint>
#include <lvgl/lvgl.h>
@ -23,7 +24,7 @@ namespace Pinetime {
void SetIndicators();
void SetColors();
Pinetime::System::SystemTask& systemTask;
Pinetime::System::WakeLock wakeLock;
Controllers::BrightnessController& brightnessController;
Controllers::BrightnessController::Levels brightnessLevel = Controllers::BrightnessController::Levels::High;

View file

@ -29,7 +29,7 @@ namespace {
}
HeartRate::HeartRate(Controllers::HeartRateController& heartRateController, System::SystemTask& systemTask)
: heartRateController {heartRateController}, systemTask {systemTask} {
: heartRateController {heartRateController}, wakeLock(systemTask) {
bool isHrRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
label_hr = lv_label_create(lv_scr_act(), nullptr);
@ -63,7 +63,7 @@ HeartRate::HeartRate(Controllers::HeartRateController& heartRateController, Syst
label_startStop = lv_label_create(btn_startStop, nullptr);
UpdateStartStopButton(isHrRunning);
if (isHrRunning) {
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
wakeLock.Lock();
}
taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this);
@ -72,7 +72,6 @@ HeartRate::HeartRate(Controllers::HeartRateController& heartRateController, Syst
HeartRate::~HeartRate() {
lv_task_del(taskRefresh);
lv_obj_clean(lv_scr_act());
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
}
void HeartRate::Refresh() {
@ -101,12 +100,12 @@ void HeartRate::OnStartStopEvent(lv_event_t event) {
if (heartRateController.State() == Controllers::HeartRateController::States::Stopped) {
heartRateController.Start();
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
wakeLock.Lock();
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
} else {
heartRateController.Stop();
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
wakeLock.Release();
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
}
}

View file

@ -4,6 +4,7 @@
#include <chrono>
#include "displayapp/screens/Screen.h"
#include "systemtask/SystemTask.h"
#include "systemtask/WakeLock.h"
#include "Symbols.h"
#include <lvgl/src/lv_core/lv_style.h>
#include <lvgl/src/lv_core/lv_obj.h>
@ -27,7 +28,7 @@ namespace Pinetime {
private:
Controllers::HeartRateController& heartRateController;
Pinetime::System::SystemTask& systemTask;
Pinetime::System::WakeLock wakeLock;
void UpdateStartStopButton(bool isRunning);
lv_obj_t* label_hr;
lv_obj_t* label_bpm;

View file

@ -22,7 +22,7 @@ namespace {
}
Metronome::Metronome(Controllers::MotorController& motorController, System::SystemTask& systemTask)
: motorController {motorController}, systemTask {systemTask} {
: motorController {motorController}, wakeLock(systemTask) {
bpmArc = lv_arc_create(lv_scr_act(), nullptr);
bpmArc->user_data = this;
@ -72,7 +72,6 @@ Metronome::Metronome(Controllers::MotorController& motorController, System::Syst
Metronome::~Metronome() {
lv_task_del(taskRefresh);
systemTask.PushMessage(System::Messages::EnableSleeping);
lv_obj_clean(lv_scr_act());
}
@ -128,12 +127,12 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) {
metronomeStarted = !metronomeStarted;
if (metronomeStarted) {
lv_label_set_text_static(lblPlayPause, Symbols::pause);
systemTask.PushMessage(System::Messages::DisableSleeping);
wakeLock.Lock();
startTime = xTaskGetTickCount();
counter = 1;
} else {
lv_label_set_text_static(lblPlayPause, Symbols::play);
systemTask.PushMessage(System::Messages::EnableSleeping);
wakeLock.Release();
}
}
break;

View file

@ -1,6 +1,7 @@
#pragma once
#include "systemtask/SystemTask.h"
#include "systemtask/WakeLock.h"
#include "components/motor/MotorController.h"
#include "displayapp/screens/Screen.h"
#include "Symbols.h"
@ -21,7 +22,7 @@ namespace Pinetime {
TickType_t startTime = 0;
TickType_t tappedTime = 0;
Controllers::MotorController& motorController;
System::SystemTask& systemTask;
System::WakeLock wakeLock;
int16_t bpm = 120;
uint8_t bpb = 4;
uint8_t counter = 1;

View file

@ -20,7 +20,7 @@ Notifications::Notifications(DisplayApp* app,
notificationManager {notificationManager},
alertNotificationService {alertNotificationService},
motorController {motorController},
systemTask {systemTask},
wakeLock(systemTask),
mode {mode} {
notificationManager.ClearNewNotificationFlag();
@ -40,7 +40,7 @@ Notifications::Notifications(DisplayApp* app,
validDisplay = false;
}
if (mode == Modes::Preview) {
systemTask.PushMessage(System::Messages::DisableSleeping);
wakeLock.Lock();
if (notification.category == Controllers::NotificationManager::Categories::IncomingCall) {
motorController.StartRinging();
} else {
@ -65,7 +65,6 @@ Notifications::~Notifications() {
lv_task_del(taskRefresh);
// make sure we stop any vibrations before exiting
motorController.StopRinging();
systemTask.PushMessage(System::Messages::EnableSleeping);
lv_obj_clean(lv_scr_act());
}
@ -82,7 +81,6 @@ void Notifications::Refresh() {
} else if (mode == Modes::Preview && dismissingNotification) {
running = false;
currentItem = std::make_unique<NotificationItem>(alertNotificationService, motorController);
} else if (dismissingNotification) {
dismissingNotification = false;
@ -113,15 +111,15 @@ void Notifications::Refresh() {
alertNotificationService,
motorController);
} else {
currentItem = std::make_unique<NotificationItem>(alertNotificationService, motorController);
running = false;
}
}
running = currentItem->IsRunning() && running;
running = running && currentItem->IsRunning();
}
void Notifications::OnPreviewInteraction() {
systemTask.PushMessage(System::Messages::EnableSleeping);
wakeLock.Release();
motorController.StopRinging();
if (timeoutLine != nullptr) {
lv_obj_del(timeoutLine);
@ -173,7 +171,9 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
} else if (nextMessage.valid) {
currentId = nextMessage.id;
} else {
// don't update id, won't be found be refresh and try to load latest message or no message box
// don't update id, notification manager will try to fetch
// but not find it. Refresh will try to load latest message
// or dismiss to watchface
}
DismissToBlack();
return true;

View file

@ -8,6 +8,7 @@
#include "components/ble/NotificationManager.h"
#include "components/motor/MotorController.h"
#include "systemtask/SystemTask.h"
#include "systemtask/WakeLock.h"
namespace Pinetime {
namespace Controllers {
@ -73,7 +74,7 @@ namespace Pinetime {
Pinetime::Controllers::NotificationManager& notificationManager;
Pinetime::Controllers::AlertNotificationService& alertNotificationService;
Pinetime::Controllers::MotorController& motorController;
System::SystemTask& systemTask;
System::WakeLock wakeLock;
Modes mode = Modes::Normal;
std::unique_ptr<NotificationItem> currentItem;
Pinetime::Controllers::NotificationManager::Notification::Id currentId;

View file

@ -0,0 +1,10 @@
# Add a new watchface :
## Modify the following files with the names of your source files :
- /src/displayapp/apps/Apps.h.in
- /src/components/settings/Settings.h
- /src/displayapp/UserApps.h
- /src/displayapp/apps/CMakeLists.txt
- CMakelists.txt

View file

@ -34,7 +34,7 @@ namespace {
constexpr TickType_t blinkInterval = pdMS_TO_TICKS(1000);
}
StopWatch::StopWatch(System::SystemTask& systemTask) : systemTask {systemTask} {
StopWatch::StopWatch(System::SystemTask& systemTask) : wakeLock(systemTask) {
static constexpr uint8_t btnWidth = 115;
static constexpr uint8_t btnHeight = 80;
btnPlayPause = lv_btn_create(lv_scr_act(), nullptr);
@ -79,7 +79,6 @@ StopWatch::StopWatch(System::SystemTask& systemTask) : systemTask {systemTask} {
StopWatch::~StopWatch() {
lv_task_del(taskRefresh);
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
lv_obj_clean(lv_scr_act());
}
@ -135,7 +134,7 @@ void StopWatch::Start() {
SetInterfaceRunning();
startTime = xTaskGetTickCount();
currentState = States::Running;
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
wakeLock.Lock();
}
void StopWatch::Pause() {
@ -145,7 +144,7 @@ void StopWatch::Pause() {
oldTimeElapsed = laps[lapsDone];
blinkTime = xTaskGetTickCount() + blinkInterval;
currentState = States::Halted;
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
wakeLock.Release();
}
void StopWatch::Refresh() {

View file

@ -7,6 +7,7 @@
#include "portmacro_cmsis.h"
#include "systemtask/SystemTask.h"
#include "systemtask/WakeLock.h"
#include "displayapp/apps/Apps.h"
#include "displayapp/Controllers.h"
#include "Symbols.h"
@ -43,7 +44,7 @@ namespace Pinetime {
void Start();
void Pause();
Pinetime::System::SystemTask& systemTask;
Pinetime::System::WakeLock wakeLock;
States currentState = States::Init;
TickType_t startTime;
TickType_t oldTimeElapsed = 0;

View file

@ -40,8 +40,7 @@ SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp* app,
Pinetime::Controllers::MotionController& motionController,
const Pinetime::Drivers::Cst816S& touchPanel,
const Pinetime::Drivers::SpiNorFlash& spiNorFlash)
: app {app},
dateTimeController {dateTimeController},
: dateTimeController {dateTimeController},
batteryController {batteryController},
brightnessController {brightnessController},
bleController {bleController},

View file

@ -35,7 +35,6 @@ namespace Pinetime {
bool OnTouchEvent(TouchEvents event) override;
private:
DisplayApp* app;
Pinetime::Controllers::DateTime& dateTimeController;
const Pinetime::Controllers::Battery& batteryController;
Pinetime::Controllers::BrightnessController& brightnessController;

View file

@ -104,9 +104,7 @@ void Timer::UpdateMask() {
void Timer::Refresh() {
if (timer.IsRunning()) {
auto secondsRemaining = std::chrono::duration_cast<std::chrono::seconds>(timer.GetTimeRemaining());
minuteCounter.SetValue(secondsRemaining.count() / 60);
secondCounter.SetValue(secondsRemaining.count() % 60);
DisplayTime();
} else if (buttonPressing && xTaskGetTickCount() > pressTime + pdMS_TO_TICKS(150)) {
lv_label_set_text_static(txtPlayPause, "Reset");
maskPosition += 15;
@ -119,6 +117,14 @@ void Timer::Refresh() {
}
}
void Timer::DisplayTime() {
displaySeconds = std::chrono::duration_cast<std::chrono::seconds>(timer.GetTimeRemaining());
if (displaySeconds.IsUpdated()) {
minuteCounter.SetValue(displaySeconds.Get().count() / 60);
secondCounter.SetValue(displaySeconds.Get().count() % 60);
}
}
void Timer::SetTimerRunning() {
minuteCounter.HideControls();
secondCounter.HideControls();
@ -133,9 +139,7 @@ void Timer::SetTimerStopped() {
void Timer::ToggleRunning() {
if (timer.IsRunning()) {
auto secondsRemaining = std::chrono::duration_cast<std::chrono::seconds>(timer.GetTimeRemaining());
minuteCounter.SetValue(secondsRemaining.count() / 60);
secondCounter.SetValue(secondsRemaining.count() % 60);
DisplayTime();
timer.StopTimer();
SetTimerStopped();
} else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) {
@ -147,7 +151,6 @@ void Timer::ToggleRunning() {
}
void Timer::Reset() {
minuteCounter.SetValue(0);
secondCounter.SetValue(0);
DisplayTime();
SetTimerStopped();
}

View file

@ -5,6 +5,7 @@
#include "systemtask/SystemTask.h"
#include "displayapp/LittleVgl.h"
#include "displayapp/widgets/Counter.h"
#include "utility/DirtyValue.h"
#include <lvgl/lvgl.h>
#include "components/timer/Timer.h"
@ -26,6 +27,7 @@ namespace Pinetime::Applications {
void SetTimerRunning();
void SetTimerStopped();
void UpdateMask();
void DisplayTime();
Pinetime::Controllers::Timer& timer;
lv_obj_t* btnPlayPause;
@ -43,6 +45,7 @@ namespace Pinetime::Applications {
bool buttonPressing = false;
lv_coord_t maskPosition = 0;
TickType_t pressTime = 0;
Utility::DirtyValue<std::chrono::seconds> displaySeconds;
};
}

View file

@ -4,10 +4,12 @@
#include <cstdio>
#include "displayapp/screens/BatteryIcon.h"
#include "displayapp/screens/BleIcon.h"
#include "displayapp/screens/AlarmIcon.h"
#include "displayapp/screens/NotificationIcon.h"
#include "displayapp/screens/Symbols.h"
#include "components/battery/BatteryController.h"
#include "components/ble/BleController.h"
#include "components/alarm/AlarmController.h"
#include "components/ble/NotificationManager.h"
#include "components/heartrate/HeartRateController.h"
#include "components/motion/MotionController.h"
@ -17,6 +19,7 @@ using namespace Pinetime::Applications::Screens;
WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTimeController,
const Controllers::Battery& batteryController,
const Controllers::Ble& bleController,
Controllers::AlarmController& alarmController,
Controllers::NotificationManager& notificatioManager,
Controllers::Settings& settingsController,
Controllers::HeartRateController& heartRateController,
@ -27,6 +30,7 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi
dateTimeController {dateTimeController},
batteryController {batteryController},
bleController {bleController},
alarmController {alarmController},
notificatioManager {notificatioManager},
settingsController {settingsController},
heartRateController {heartRateController},
@ -168,6 +172,23 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(Controllers::DateTime& dateTi
lv_label_set_text_static(stepIcon, Symbols::shoe);
lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0);
alarmIcon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(alarmIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
lv_label_set_text_static(alarmIcon, Symbols::notbell);
lv_obj_align(alarmIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2);
labelAlarm = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(labelAlarm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
// lv_obj_set_style_local_text_font(labelAlarm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko);
lv_obj_align(labelAlarm, alarmIcon, LV_ALIGN_OUT_RIGHT_MID, 3, 0);
lv_label_set_text_static(labelAlarm, "00:00");
labelTimeAmPmAlarm = lv_label_create(lv_scr_act(), nullptr);
// lv_obj_set_style_local_text_font(labelTimeAmPmAlarm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko);
lv_label_set_text_static(labelTimeAmPmAlarm, "");
lv_obj_set_style_local_text_color(labelTimeAmPmAlarm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text);
lv_obj_align(labelTimeAmPmAlarm, labelAlarm, LV_ALIGN_OUT_RIGHT_MID, 3, 0);
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
Refresh();
}
@ -310,8 +331,6 @@ void WatchFaceCasioStyleG7710::Refresh() {
lv_obj_realign(stepValue);
lv_obj_realign(stepIcon);
}
}
bool WatchFaceCasioStyleG7710::IsAvailable(Pinetime::Controllers::FS& filesystem) {
lfs_file file = {};

View file

@ -253,7 +253,7 @@ WatchFaceInfineat::WatchFaceInfineat(Controllers::DateTime& dateTimeController,
lv_label_set_text_static(alarmIcon, Symbols::notbell);
lv_obj_align(alarmIcon, labelAlarm, LV_ALIGN_OUT_LEFT_MID, -3, 0);
// don't show the icons jsut set if we don't show alarm status
// don't show the icons just set if we don't show alarm status
if (!settingsController.GetInfineatShowAlarmStatus()) {
lv_obj_set_hidden(labelAlarm, true);
lv_obj_set_hidden(alarmIcon, true);
@ -509,11 +509,11 @@ void WatchFaceInfineat::Refresh() {
}
if (settingsController.GetInfineatShowAlarmStatus()) {
alarmState = alarmController.State()==Pinetime::Controllers::AlarmController::AlarmState::Set;
isAlarmSet = alarmController.IsEnabled()==true;
// sets the icon as bell or barred bell
lv_label_set_text_static(alarmIcon, AlarmIcon::GetIcon(alarmState));
lv_label_set_text_static(alarmIcon, AlarmIcon::GetIcon(isAlarmSet.Get()));
//displays the time of the alarm or nothing if the alarm is not set
if (alarmState) {
if (isAlarmSet.Get()) {
uint8_t alarmHours = alarmController.Hours();
uint8_t alarmMinutes = alarmController.Minutes();
//handles the am pm format.

View file

@ -53,7 +53,7 @@ namespace Pinetime {
Utility::DirtyValue<bool> isCharging {};
Utility::DirtyValue<bool> bleState {};
Utility::DirtyValue<bool> bleRadioEnabled {};
bool alarmState {};
Utility::DirtyValue<bool> isAlarmSet{};
Utility::DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>> currentDateTime {};
Utility::DirtyValue<uint32_t> stepCount {};
Utility::DirtyValue<bool> notificationState {};
@ -102,8 +102,6 @@ namespace Pinetime {
void SetBatteryLevel(uint8_t batteryPercent);
void ToggleBatteryIndicatorColor(bool showSideCover);
void ToggleShowAlarmStatus(bool showAlarmStatus);
lv_task_t* taskRefresh;
lv_font_t* font_teko = nullptr;
lv_font_t* font_bebas = nullptr;

View file

@ -0,0 +1,11 @@
# Add a new watchface :
## Modify the following files with the names of your source files :
- /src/displayapp/apps/Apps.h.in
- /src/components/settings/Settings.h
- /src/displayapp/screens/settings/SettingWatchFace.h
- /src/displayapp/UserApps.h
- /src/displayapp/apps/CMakeLists.txt
- CMakelists.txt

View file

@ -24,8 +24,7 @@ namespace {
constexpr std::array<uint16_t, 6> SettingDisplay::options;
SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
: app {app}, settingsController {settingsController} {
SettingDisplay::SettingDisplay(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} {
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);

View file

@ -14,14 +14,13 @@ namespace Pinetime {
class SettingDisplay : public Screen {
public:
SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController);
SettingDisplay(Pinetime::Controllers::Settings& settingsController);
~SettingDisplay() override;
void UpdateSelected(lv_obj_t* object, lv_event_t event);
void ToggleAlwaysOn();
private:
DisplayApp* app;
static constexpr std::array<uint16_t, 6> options = {5000, 7000, 10000, 15000, 20000, 30000};
Controllers::Settings& settingsController;

View file

@ -15,8 +15,7 @@ bool SettingSetDateTime::OnTouchEvent(Pinetime::Applications::TouchEvents event)
SettingSetDateTime::SettingSetDateTime(Pinetime::Applications::DisplayApp* app,
Pinetime::Controllers::DateTime& dateTimeController,
Pinetime::Controllers::Settings& settingsController)
: app {app},
dateTimeController {dateTimeController},
: dateTimeController {dateTimeController},
settingsController {settingsController},
screens {app,
0,

View file

@ -20,7 +20,6 @@ namespace Pinetime {
void Quit();
private:
DisplayApp* app;
Controllers::DateTime& dateTimeController;
Controllers::Settings& settingsController;

View file

@ -54,8 +54,7 @@ SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app,
std::array<Screens::SettingWatchFace::Item, UserWatchFaceTypes::Count>&& watchfaceItems,
Pinetime::Controllers::Settings& settingsController,
Pinetime::Controllers::FS& filesystem)
: app {app},
watchfaceItems {std::move(watchfaceItems)},
: watchfaceItems {std::move(watchfaceItems)},
settingsController {settingsController},
filesystem {filesystem},
screens {app, 0, CreateScreenList(), Screens::ScreenListModes::UpDown} {

View file

@ -12,6 +12,8 @@
#include "displayapp/screens/WatchFaceInfineat.h"
#include "displayapp/screens/WatchFaceCasioStyleG7710.h"
namespace Pinetime {
namespace Applications {
@ -34,7 +36,6 @@ namespace Pinetime {
bool OnTouchEvent(TouchEvents event) override;
private:
DisplayApp* app;
auto CreateScreenList() const;
std::unique_ptr<Screen> CreateScreen(unsigned int screenNum) const;

View file

@ -6,6 +6,7 @@
#include "drivers/Hrs3300.h"
#include <algorithm>
#include <iterator>
#include <nrf_gpio.h>
#include <FreeRTOS.h>
@ -67,40 +68,37 @@ void Hrs3300::Disable() {
WriteRegister(static_cast<uint8_t>(Registers::PDriver), 0);
}
uint32_t Hrs3300::ReadHrs() {
auto m = ReadRegister(static_cast<uint8_t>(Registers::C0DataM));
auto h = ReadRegister(static_cast<uint8_t>(Registers::C0DataH));
auto l = ReadRegister(static_cast<uint8_t>(Registers::C0dataL));
return ((l & 0x30) << 12) | (m << 8) | ((h & 0x0f) << 4) | (l & 0x0f);
}
Hrs3300::PackedHrsAls Hrs3300::ReadHrsAls() {
constexpr Registers dataRegisters[] =
{Registers::C1dataM, Registers::C0DataM, Registers::C0DataH, Registers::C1dataH, Registers::C1dataL, Registers::C0dataL};
// Calculate smallest register address
constexpr uint8_t baseOffset = static_cast<uint8_t>(*std::min_element(std::begin(dataRegisters), std::end(dataRegisters)));
// Calculate largest address to determine length of read needed
// Add one to largest relative index to find the length
constexpr uint8_t length = static_cast<uint8_t>(*std::max_element(std::begin(dataRegisters), std::end(dataRegisters))) - baseOffset + 1;
uint32_t Hrs3300::ReadAls() {
auto m = ReadRegister(static_cast<uint8_t>(Registers::C1dataM));
auto h = ReadRegister(static_cast<uint8_t>(Registers::C1dataH));
auto l = ReadRegister(static_cast<uint8_t>(Registers::C1dataL));
return ((h & 0x3f) << 11) | (m << 3) | (l & 0x07);
}
void Hrs3300::SetGain(uint8_t gain) {
constexpr uint8_t maxGain = 64U;
gain = std::min(gain, maxGain);
uint8_t hgain = 0;
while ((1 << hgain) < gain) {
++hgain;
Hrs3300::PackedHrsAls res;
uint8_t buf[length];
auto ret = twiMaster.Read(twiAddress, baseOffset, buf, length);
if (ret != TwiMaster::ErrorCodes::NoError) {
NRF_LOG_INFO("READ ERROR");
}
// hrs
uint8_t m = static_cast<uint8_t>(Registers::C0DataM) - baseOffset;
uint8_t h = static_cast<uint8_t>(Registers::C0DataH) - baseOffset;
uint8_t l = static_cast<uint8_t>(Registers::C0dataL) - baseOffset;
// There are two extra bits (17 and 18) but they are not read here
// as resolutions >16bit aren't practically useful (too slow) and
// all hrs values throughout InfiniTime are 16bit
res.hrs = (buf[m] << 8) | ((buf[h] & 0x0f) << 4) | (buf[l] & 0x0f);
WriteRegister(static_cast<uint8_t>(Registers::Hgain), hgain << 2);
}
// als
m = static_cast<uint8_t>(Registers::C1dataM) - baseOffset;
h = static_cast<uint8_t>(Registers::C1dataH) - baseOffset;
l = static_cast<uint8_t>(Registers::C1dataL) - baseOffset;
res.als = ((buf[h] & 0x3f) << 11) | (buf[m] << 3) | (buf[l] & 0x07);
void Hrs3300::SetDrive(uint8_t drive) {
auto en = ReadRegister(static_cast<uint8_t>(Registers::Enable));
auto pd = ReadRegister(static_cast<uint8_t>(Registers::PDriver));
en = (en & 0xf7) | ((drive & 2) << 2);
pd = (pd & 0xbf) | ((drive & 1) << 6);
WriteRegister(static_cast<uint8_t>(Registers::Enable), en);
WriteRegister(static_cast<uint8_t>(Registers::PDriver), pd);
return res;
}
void Hrs3300::WriteRegister(uint8_t reg, uint8_t data) {

View file

@ -21,6 +21,11 @@ namespace Pinetime {
Hgain = 0x17
};
struct PackedHrsAls {
uint16_t hrs;
uint16_t als;
};
Hrs3300(TwiMaster& twiMaster, uint8_t twiAddress);
Hrs3300(const Hrs3300&) = delete;
Hrs3300& operator=(const Hrs3300&) = delete;
@ -30,10 +35,7 @@ namespace Pinetime {
void Init();
void Enable();
void Disable();
uint32_t ReadHrs();
uint32_t ReadAls();
void SetGain(uint8_t gain);
void SetDrive(uint8_t drive);
PackedHrsAls ReadHrsAls();
private:
TwiMaster& twiMaster;

View file

@ -70,7 +70,8 @@ void HeartRateTask::Work() {
}
if (measurementStarted) {
int8_t ambient = ppg.Preprocess(heartRateSensor.ReadHrs(), heartRateSensor.ReadAls());
auto sensorData = heartRateSensor.ReadHrsAls();
int8_t ambient = ppg.Preprocess(sensorData.hrs, sensorData.als);
int bpm = ppg.HeartRate();
// If ambient light detected or a reset requested (bpm < 0)

@ -1 +0,0 @@
Subproject commit 56b17bf9f74096774944bcac0829adcd887d391e

View file

@ -589,7 +589,7 @@ typedef void* lv_obj_user_data_t;
/*Calendar (dependencies: -)*/
#define LV_USE_CALENDAR 1
#if LV_USE_CALENDAR
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
#define LV_CALENDAR_WEEK_STARTS_MONDAY 1
#endif
/*Canvas (dependencies: lv_img)*/

View file

@ -104,7 +104,7 @@ Pinetime::Controllers::DateTime dateTimeController {settingsController};
Pinetime::Drivers::Watchdog watchdog;
Pinetime::Controllers::NotificationManager notificationManager;
Pinetime::Controllers::MotionController motionController;
Pinetime::Controllers::AlarmController alarmController {dateTimeController};
Pinetime::Controllers::AlarmController alarmController {dateTimeController, fs};
Pinetime::Controllers::TouchHandler touchHandler;
Pinetime::Controllers::ButtonHandler buttonHandler;
Pinetime::Controllers::BrightnessController brightnessController {};

View file

@ -1,11 +1,18 @@
{
"pine_small" : {
"pine_small" : {
"sources": "images/pine_logo.png",
"color_format": "CF_TRUE_COLOR_ALPHA",
"output_format": "bin",
"binary_format": "ARGB8565_RBSWAP",
"target_path": "/images/"
},
"cat_small" : {
"sources": "images/cat_clean.png",
"color_format": "CF_TRUE_COLOR_ALPHA",
"output_format": "bin",
"binary_format": "ARGB8565_RBSWAP",
"target_path": "/images/"
},
"navigation0" : {
"sources": "images/navigation0.png",
"color_format": "CF_INDEXED_1_BIT",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -1,5 +1,5 @@
#include "systemtask/SystemTask.h"
#if configUSE_TRACE_FACILITY == 1
#if NRF_LOG_ENABLED
// FreeRtosMonitor
#include <FreeRTOS.h>
#include <task.h>

View file

@ -189,37 +189,14 @@ void SystemTask::Work() {
if (xQueueReceive(systemTasksMsgQueue, &msg, 100) == pdTRUE) {
switch (msg) {
case Messages::EnableSleeping:
// Make sure that exiting an app doesn't enable sleeping,
// if the exiting was caused by a firmware update
if (!bleController.IsFirmwareUpdating()) {
doNotGoToSleep = false;
}
displayApp.PushMessage(Pinetime::Applications::Display::Messages::NotifyDeviceActivity);
wakeLocksHeld--;
break;
case Messages::DisableSleeping:
doNotGoToSleep = true;
GoToRunning();
wakeLocksHeld++;
break;
case Messages::GoToRunning:
// SPI doesn't go to sleep for always on mode
if (!settingsController.GetAlwaysOnDisplay()) {
spi.Wakeup();
}
// Double Tap needs the touch screen to be in normal mode
if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
touchPanel.Wakeup();
}
spiNorFlash.Wakeup();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning);
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
if (bleController.IsRadioEnabled() && !bleController.IsConnected()) {
nimbleController.RestartFastAdv();
}
state = SystemTaskState::Running;
GoToRunning();
break;
case Messages::TouchWakeUp: {
if (touchHandler.ProcessTouchInfo(touchPanel.GetTouchInfo())) {
@ -236,35 +213,23 @@ void SystemTask::Work() {
break;
}
case Messages::GoToSleep:
if (doNotGoToSleep) {
break;
}
state = SystemTaskState::GoingToSleep; // Already set in PushMessage()
NRF_LOG_INFO("[systemtask] Going to sleep");
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
GoToSleep();
break;
case Messages::OnNewTime:
displayApp.PushMessage(Pinetime::Applications::Display::Messages::NotifyDeviceActivity);
displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime);
if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) {
if (alarmController.IsEnabled()) {
alarmController.ScheduleAlarm();
}
break;
case Messages::OnNewNotification:
if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::On) {
if (state == SystemTaskState::Sleeping) {
if (IsSleeping()) {
GoToRunning();
} else {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::NotifyDeviceActivity);
}
displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification);
}
break;
case Messages::SetOffAlarm:
if (state == SystemTaskState::Sleeping) {
GoToRunning();
}
GoToRunning();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::AlarmTriggered);
break;
case Messages::BleConnected:
@ -273,29 +238,25 @@ void SystemTask::Work() {
bleDiscoveryTimer = 5;
break;
case Messages::BleFirmwareUpdateStarted:
doNotGoToSleep = true;
if (state == SystemTaskState::Sleeping) {
GoToRunning();
}
GoToRunning();
wakeLocksHeld++;
displayApp.PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted);
break;
case Messages::BleFirmwareUpdateFinished:
if (bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) {
NVIC_SystemReset();
}
doNotGoToSleep = false;
wakeLocksHeld--;
break;
case Messages::StartFileTransfer:
NRF_LOG_INFO("[systemtask] FS Started");
doNotGoToSleep = true;
if (state == SystemTaskState::Sleeping) {
GoToRunning();
}
GoToRunning();
wakeLocksHeld++;
// TODO add intent of fs access icon or something
break;
case Messages::StopFileTransfer:
NRF_LOG_INFO("[systemtask] FS Stopped");
doNotGoToSleep = false;
wakeLocksHeld--;
// TODO add intent of fs access icon or something
break;
case Messages::OnTouchEvent:
@ -323,6 +284,13 @@ void SystemTask::Work() {
HandleButtonAction(action);
} break;
case Messages::OnDisplayTaskSleeping:
// The state was set to GoingToSleep when GoToSleep() was called
// If the state is no longer GoingToSleep, we have since transitioned back to Running
// In this case absorb the OnDisplayTaskSleeping
// as DisplayApp is about to receive GoToRunning
if (state != SystemTaskState::GoingToSleep) {
break;
}
if (BootloaderVersion::IsValid()) {
// First versions of the bootloader do not expose their version and cannot initialize the SPI NOR FLASH
// if it's in sleep mode. Avoid bricked device by disabling sleep mode on these versions.
@ -349,39 +317,23 @@ void SystemTask::Work() {
case Messages::OnNewHour:
using Pinetime::Controllers::AlarmController;
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours &&
alarmController.State() != AlarmController::AlarmState::Alerting) {
// if sleeping, we can't send a chime to displayApp yet (SPI flash switched off)
// request running first and repush the chime message
if (state == SystemTaskState::Sleeping) {
GoToRunning();
PushMessage(msg);
} else {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
}
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && !alarmController.IsAlerting()) {
GoToRunning();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
}
break;
case Messages::OnNewHalfHour:
using Pinetime::Controllers::AlarmController;
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours &&
alarmController.State() != AlarmController::AlarmState::Alerting) {
// if sleeping, we can't send a chime to displayApp yet (SPI flash switched off)
// request running first and repush the chime message
if (state == SystemTaskState::Sleeping) {
GoToRunning();
PushMessage(msg);
} else {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
}
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && !alarmController.IsAlerting()) {
GoToRunning();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
}
break;
case Messages::OnChargingEvent:
batteryController.ReadPowerState();
GoToRunning();
displayApp.PushMessage(Applications::Display::Messages::OnChargingEvent);
if (state == SystemTaskState::Sleeping) {
GoToRunning();
}
break;
case Messages::MeasureBatteryTimerExpired:
batteryController.MeasureVoltage();
@ -390,9 +342,7 @@ void SystemTask::Work() {
nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining());
break;
case Messages::OnPairing:
if (state == SystemTaskState::Sleeping) {
GoToRunning();
}
GoToRunning();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::ShowPairingKey);
break;
case Messages::BleRadioEnableToggle:
@ -427,14 +377,50 @@ void SystemTask::Work() {
#pragma clang diagnostic pop
}
void SystemTask::UpdateMotion() {
if (state == SystemTaskState::GoingToSleep || state == SystemTaskState::WakingUp) {
void SystemTask::GoToRunning() {
if (state == SystemTaskState::Running) {
return;
}
// SPI doesn't go to sleep for always on mode
if (!settingsController.GetAlwaysOnDisplay()) {
spi.Wakeup();
}
if (state == SystemTaskState::Sleeping && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) ||
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) ||
motionController.GetService()->IsMotionNotificationSubscribed())) {
// Double Tap needs the touch screen to be in normal mode
if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
touchPanel.Wakeup();
}
spiNorFlash.Wakeup();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning);
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
if (bleController.IsRadioEnabled() && !bleController.IsConnected()) {
nimbleController.RestartFastAdv();
}
state = SystemTaskState::Running;
};
void SystemTask::GoToSleep() {
if (IsSleeping()) {
return;
}
if (IsSleepDisabled()) {
return;
}
NRF_LOG_INFO("[systemtask] Going to sleep");
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
state = SystemTaskState::GoingToSleep;
};
void SystemTask::UpdateMotion() {
if (IsSleeping() && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) ||
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) ||
motionController.GetService()->IsMotionNotificationSubscribed())) {
return;
}
@ -457,7 +443,7 @@ void SystemTask::UpdateMotion() {
}
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::LowerWrist) && state == SystemTaskState::Running &&
motionController.ShouldLowerSleep()) {
PushMessage(Messages::GoToSleep);
GoToSleep();
}
}
@ -473,7 +459,7 @@ void SystemTask::HandleButtonAction(Controllers::ButtonActions action) {
switch (action) {
case Actions::Click:
// If the first action after fast wakeup is a click, it should be ignored.
if (!fastWakeUpDone && state != SystemTaskState::GoingToSleep) {
if (!fastWakeUpDone) {
displayApp.PushMessage(Applications::Display::Messages::ButtonPushed);
}
break;
@ -493,17 +479,10 @@ void SystemTask::HandleButtonAction(Controllers::ButtonActions action) {
fastWakeUpDone = false;
}
void SystemTask::GoToRunning() {
if (state == SystemTaskState::Sleeping) {
state = SystemTaskState::WakingUp;
PushMessage(Messages::GoToRunning);
}
}
void SystemTask::OnTouchEvent() {
if (state == SystemTaskState::Running) {
PushMessage(Messages::OnTouchEvent);
} else if (state == SystemTaskState::Sleeping) {
} else {
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap) or
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
PushMessage(Messages::TouchWakeUp);
@ -512,10 +491,6 @@ void SystemTask::OnTouchEvent() {
}
void SystemTask::PushMessage(System::Messages msg) {
if (msg == Messages::GoToSleep && !doNotGoToSleep) {
state = SystemTaskState::GoingToSleep;
}
if (in_isr()) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(systemTasksMsgQueue, &msg, &xHigherPriorityTaskWoken);

View file

@ -52,7 +52,7 @@ namespace Pinetime {
namespace System {
class SystemTask {
public:
enum class SystemTaskState { Sleeping, Running, GoingToSleep, WakingUp };
enum class SystemTaskState { Sleeping, Running, GoingToSleep };
SystemTask(Drivers::SpiMaster& spi,
Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Drivers::TwiMaster& twiMaster,
@ -79,11 +79,8 @@ namespace Pinetime {
void OnTouchEvent();
void OnIdle();
void OnDim();
bool IsSleepDisabled() {
return doNotGoToSleep;
return wakeLocksHeld > 0;
}
Pinetime::Controllers::NimbleController& nimble() {
@ -91,7 +88,7 @@ namespace Pinetime {
};
bool IsSleeping() const {
return state == SystemTaskState::Sleeping || state == SystemTaskState::WakingUp;
return state != SystemTaskState::Running;
}
private:
@ -127,13 +124,14 @@ namespace Pinetime {
bool isBleDiscoveryTimerRunning = false;
uint8_t bleDiscoveryTimer = 0;
TimerHandle_t measureBatteryTimer;
bool doNotGoToSleep = false;
uint8_t wakeLocksHeld = 0;
SystemTaskState state = SystemTaskState::Running;
void HandleButtonAction(Controllers::ButtonActions action);
bool fastWakeUpDone = false;
void GoToRunning();
void GoToSleep();
void UpdateMotion();
bool stepCounterMustBeReset = false;
static constexpr TickType_t batteryMeasurementPeriod = pdMS_TO_TICKS(10 * 60 * 1000);

View file

@ -0,0 +1,27 @@
#include "systemtask/WakeLock.h"
using namespace Pinetime::System;
WakeLock::WakeLock(SystemTask& systemTask) : systemTask {systemTask} {
lockHeld = false;
}
WakeLock::~WakeLock() {
Release();
}
void WakeLock::Lock() {
if (lockHeld) {
return;
}
systemTask.PushMessage(Messages::DisableSleeping);
lockHeld = true;
}
void WakeLock::Release() {
if (!lockHeld) {
return;
}
systemTask.PushMessage(Messages::EnableSleeping);
lockHeld = false;
}

19
src/systemtask/WakeLock.h Normal file
View file

@ -0,0 +1,19 @@
#pragma once
#include "systemtask/SystemTask.h"
namespace Pinetime {
namespace System {
class WakeLock {
public:
WakeLock(SystemTask& systemTask);
~WakeLock();
void Lock();
void Release();
private:
bool lockHeld;
SystemTask& systemTask;
};
}
}

3
todo.log Normal file
View file

@ -0,0 +1,3 @@
replace alarm info by timer info when timer is ongoing
add a shortcut for a 1min timer on the right