Merge branch 'develop' into pinmap

main
hubmartin 2021-09-13 10:19:07 +07:00
commit 73d3e41cea
17 changed files with 71 additions and 86 deletions

@ -44,7 +44,7 @@ jobs:
- name: Install Embedded Arm Toolchain arm-none-eabi-gcc - name: Install Embedded Arm Toolchain arm-none-eabi-gcc
if: steps.cache-toolchain.outputs.cache-hit != 'true' # Install toolchain if not found in cache if: steps.cache-toolchain.outputs.cache-hit != 'true' # Install toolchain if not found in cache
uses: fiam/arm-none-eabi-gcc@v1.0.2 uses: fiam/arm-none-eabi-gcc@v1.0.4
with: with:
# GNU Embedded Toolchain for Arm release name, in the V-YYYY-qZ format (e.g. "9-2019-q4") # GNU Embedded Toolchain for Arm release name, in the V-YYYY-qZ format (e.g. "9-2019-q4")
release: 9-2020-q2 release: 9-2020-q2
@ -83,10 +83,11 @@ jobs:
if: steps.cache-mcuboot.outputs.cache-hit != 'true' # Install MCUBoot if not found in cache if: steps.cache-mcuboot.outputs.cache-hit != 'true' # Install MCUBoot if not found in cache
run: | run: |
cd ${{ runner.temp }} cd ${{ runner.temp }}
git clone --branch v1.5.0 https://github.com/JuulLabs-OSS/mcuboot git clone --branch v1.7.2 https://github.com/mcu-tools/mcuboot
- name: Install imgtool dependencies - name: Install imgtool dependencies
run: pip3 install --user -r ${{ runner.temp }}/mcuboot/scripts/requirements.txt run: |
pip3 install --user -r ${{ runner.temp }}/mcuboot/scripts/requirements.txt
- name: Install adafruit-nrfutil - name: Install adafruit-nrfutil
run: | run: |
@ -99,6 +100,8 @@ jobs:
- name: Checkout source files - name: Checkout source files
uses: actions/checkout@v2 uses: actions/checkout@v2
with:
submodules: recursive
- name: Show files - name: Show files
run: set ; pwd ; ls -l run: set ; pwd ; ls -l
@ -110,7 +113,7 @@ jobs:
run: | run: |
mkdir -p build mkdir -p build
cd build cd build
cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=${{ runner.temp }}/arm-none-eabi -DNRF5_SDK_PATH=${{ runner.temp }}/nrf5_sdk -DUSE_OPENOCD=1 ../ cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=${{ runner.temp }}/arm-none-eabi -DNRF5_SDK_PATH=${{ runner.temp }}/nrf5_sdk -DUSE_OPENOCD=1 -DBUILD_DFU=1 ../
######################################################################################### #########################################################################################
# Make and Upload DFU Package # Make and Upload DFU Package
@ -125,19 +128,10 @@ jobs:
cd build cd build
make pinetime-mcuboot-app make pinetime-mcuboot-app
- name: Create firmware image - name: Unzip DFU package
run: | run: |
# The generated firmware binary looks like "pinetime-mcuboot-app-0.8.2.bin"
ls -l build/src/pinetime-mcuboot-app*.bin
${{ runner.temp }}/mcuboot/scripts/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header build/src/pinetime-mcuboot-app*.bin build/src/pinetime-mcuboot-app-img.bin
${{ runner.temp }}/mcuboot/scripts/imgtool.py verify build/src/pinetime-mcuboot-app-img.bin
- name: Create DFU package
run: |
~/.local/bin/adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/src/pinetime-mcuboot-app-img.bin build/src/pinetime-mcuboot-app-dfu.zip
unzip -v build/src/pinetime-mcuboot-app-dfu.zip
# Unzip the package because Upload Artifact will zip up the files # Unzip the package because Upload Artifact will zip up the files
unzip build/src/pinetime-mcuboot-app-dfu.zip -d build/src/pinetime-mcuboot-app-dfu unzip build/src/pinetime-mcuboot-app-dfu*.zip -d build/src/pinetime-mcuboot-app-dfu
- name: Upload DFU package - name: Upload DFU package
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(pinetime VERSION 1.3.0 LANGUAGES C CXX ASM) project(pinetime VERSION 1.4.0 LANGUAGES C CXX ASM)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)

@ -1,20 +1,10 @@
# PineTime # InfiniTime
[![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions) [![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions)
> The PineTime is a free and open source smartwatch capable of running custom-built open operating systems. Some of the notable features include a heart rate monitor, a week-long battery as well as a capacitive touch IPS display that is legible in direct sunlight. It is a fully community driven side-project, which means that it will ultimately be up to the developers and end-users to determine when they deem the PineTime ready to ship.
> We envision the PineTime as a companion for not only your PinePhone but also for your favorite devices — any phone, tablet, or even PC.
*https://www.pine64.org/pinetime/*
The **Pinetime** smartwatch is built around the NRF52832 MCU (512KB Flash, 64KB RAM), a 240*240 LCD display driven by the ST7789 controller, an accelerometer, a heart rate sensor, and a vibration motor.
# InfiniTime
![InfiniTime logo](images/infinitime-logo.jpg "InfiniTime Logo") ![InfiniTime logo](images/infinitime-logo.jpg "InfiniTime Logo")
The goal of this project is to design an open-source firmware for the Pinetime smartwatch : The goal of this project is to design an open-source firmware for the [Pinetime smartwatch](https://www.pine64.org/pinetime/) :
- Code written in **modern C++**; - Code written in **modern C++**;
- Build system based on **CMake**; - Build system based on **CMake**;
@ -22,6 +12,11 @@ The goal of this project is to design an open-source firmware for the Pinetime s
- Using **[LittleVGL/LVGL 7](https://lvgl.io/)** as UI library... - Using **[LittleVGL/LVGL 7](https://lvgl.io/)** as UI library...
- ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack. - ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack.
## New to InfiniTime?
- [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md)
- [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md)
## Overview ## Overview
![Pinetime screens](images/1.0.0/collage.png "PinetimeScreens") ![Pinetime screens](images/1.0.0/collage.png "PinetimeScreens")
@ -70,16 +65,12 @@ As of now, here is the list of achievements of this project:
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux) * [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux)
* [Siglo](https://github.com/alexr4535/siglo) (on Linux) * [Siglo](https://github.com/alexr4535/siglo) (on Linux)
* **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY) * **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY)
* **[Experimental]** [Infini-iOS](https://github.com/xan-m/Infini-iOS) (on iOS)
- OTA (Over-the-air) update via BLE - OTA (Over-the-air) update via BLE
- [Bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader) based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/) - [Bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader) based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/)
## Documentation ## Documentation
### Getting started
- [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md)
- [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md)
### Develop ### Develop
- [Generate the fonts and symbols](src/displayapp/fonts/README.md) - [Generate the fonts and symbols](src/displayapp/fonts/README.md)

@ -47,6 +47,8 @@ Read carefully the warning and tap **Install**:
Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime! Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime!
Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used.
![Gadgetbridge 5](gadgetbridge5.jpg) ![Gadgetbridge 5](gadgetbridge5.jpg)
### Using NRFConnect ### Using NRFConnect
@ -64,6 +66,8 @@ Select **Distribution packet (ZIP)**:
Browse to the DFU file you downloaded previously, the DFU transfer will start automatically. When the transfer is finished, your PineTime will reset and restart on the new version of InfiniTime! Browse to the DFU file you downloaded previously, the DFU transfer will start automatically. When the transfer is finished, your PineTime will reset and restart on the new version of InfiniTime!
Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used.
![NRFConnect 3](nrfconnect3.jpg) ![NRFConnect 3](nrfconnect3.jpg)
## How to flash InfiniTime using the SWD interface ## How to flash InfiniTime using the SWD interface
@ -88,6 +92,10 @@ If you are using OpenOCD with a STLinkV2, you can find more info [on this page](
### Using Gadgetbridge ### Using Gadgetbridge
Good news! Gadgetbridge **automatically** synchronizes the time when connecting to your PineTime! Good news! Gadgetbridge **automatically** synchronizes the time when connecting to your PineTime!
### Using any Chromium-based web browser
You can use it from your PC, Mac, Android. Browsers now have BLE support.
https://hubmartin.github.io/WebBLEWatch/
### Using NRFConnect ### Using NRFConnect
You must enable the **CTS** *GATT server* into NRFConnect so that InfiniTime can synchronize the time with your smartphone. You must enable the **CTS** *GATT server* into NRFConnect so that InfiniTime can synchronize the time with your smartphone.

@ -10,10 +10,7 @@ Battery* Battery::instance = nullptr;
Battery::Battery() { Battery::Battery() {
instance = this; instance = this;
} nrf_gpio_cfg_input(PinMap::Charging, static_cast<nrf_gpio_pin_pull_t> GPIO_PIN_CNF_PULL_Disabled);
void Battery::Init() {
nrf_gpio_cfg_input(PinMap::Charging, static_cast<nrf_gpio_pin_pull_t> GPIO_PIN_CNF_PULL_Pullup);
} }
void Battery::Update() { void Battery::Update() {
@ -76,5 +73,11 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) {
nrfx_saadc_uninit(); nrfx_saadc_uninit();
isReading = false; isReading = false;
systemTask->PushMessage(System::Messages::BatteryMeasurementDone);
} }
} }
void Battery::Register(Pinetime::System::SystemTask* systemTask) {
this->systemTask = systemTask;
}

@ -1,8 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <drivers/include/nrfx_saadc.h> #include <drivers/include/nrfx_saadc.h>
#include <array> #include <systemtask/SystemTask.h>
#include <numeric>
namespace Pinetime { namespace Pinetime {
namespace Controllers { namespace Controllers {
@ -11,8 +10,8 @@ namespace Pinetime {
public: public:
Battery(); Battery();
void Init();
void Update(); void Update();
void Register(System::SystemTask* systemTask);
uint8_t PercentRemaining() const { uint8_t PercentRemaining() const {
return percentRemaining; return percentRemaining;
@ -47,6 +46,8 @@ namespace Pinetime {
static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); static void AdcCallbackStatic(nrfx_saadc_evt_t const* event);
bool isReading = false; bool isReading = false;
Pinetime::System::SystemTask* systemTask = nullptr;
}; };
} }
} }

@ -114,7 +114,7 @@ namespace Pinetime {
}; };
void setWakeUpMode(WakeUpMode wakeUp, bool enabled) { void setWakeUpMode(WakeUpMode wakeUp, bool enabled) {
if (!isWakeUpModeOn(wakeUp)) { if (enabled != isWakeUpModeOn(wakeUp)) {
settingsChanged = true; settingsChanged = true;
} }
settings.wakeUpMode.set(static_cast<size_t>(wakeUp), enabled); settings.wakeUpMode.set(static_cast<size_t>(wakeUp), enabled);

@ -136,9 +136,6 @@ void DisplayApp::InitHw() {
brightnessController.Set(settingsController.GetBrightness()); brightnessController.Set(settingsController.GetBrightness());
} }
uint32_t acc = 0;
uint32_t count = 0;
bool toggle = true;
void DisplayApp::Refresh() { void DisplayApp::Refresh() {
TickType_t queueTimeout; TickType_t queueTimeout;
TickType_t delta; TickType_t delta;
@ -194,9 +191,6 @@ void DisplayApp::Refresh() {
// clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected :
// Screens::Clock::BleConnectionStates::NotConnected); // Screens::Clock::BleConnectionStates::NotConnected);
break; break;
case Messages::UpdateBatteryLevel:
batteryController.Update();
break;
case Messages::NewNotification: case Messages::NewNotification:
LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down);
break; break;

@ -7,7 +7,6 @@ namespace Pinetime {
GoToRunning, GoToRunning,
UpdateDateTime, UpdateDateTime,
UpdateBleConnection, UpdateBleConnection,
UpdateBatteryLevel,
TouchEvent, TouchEvent,
ButtonPushed, ButtonPushed,
NewNotification, NewNotification,

@ -55,8 +55,6 @@ BatteryInfo::~BatteryInfo() {
void BatteryInfo::Refresh() { void BatteryInfo::Refresh() {
batteryController.Update();
batteryPercent = batteryController.PercentRemaining(); batteryPercent = batteryController.PercentRemaining();
batteryVoltage = batteryController.Voltage(); batteryVoltage = batteryController.Voltage();

@ -73,7 +73,6 @@ void Notifications::Refresh() {
timeoutLinePoints[1].x = pos; timeoutLinePoints[1].x = pos;
lv_line_set_points(timeoutLine, timeoutLinePoints, 2); lv_line_set_points(timeoutLine, timeoutLinePoints, 2);
} }
running = currentItem->IsRunning();
} }
bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
@ -153,7 +152,7 @@ Notifications::NotificationItem::NotificationItem(const char* title,
uint8_t notifNb, uint8_t notifNb,
Modes mode, Modes mode,
Pinetime::Controllers::AlertNotificationService& alertNotificationService) Pinetime::Controllers::AlertNotificationService& alertNotificationService)
: notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { : mode {mode}, alertNotificationService {alertNotificationService} {
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL);
lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222));

@ -43,21 +43,13 @@ namespace Pinetime {
void OnCallButtonEvent(lv_obj_t*, lv_event_t event); void OnCallButtonEvent(lv_obj_t*, lv_event_t event);
private: private:
uint8_t notifNr = 0;
uint8_t notifNb = 0;
char pageText[4];
lv_obj_t* container1; lv_obj_t* container1;
lv_obj_t* t1;
lv_obj_t* l1;
lv_obj_t* l2;
lv_obj_t* bt_accept; lv_obj_t* bt_accept;
lv_obj_t* bt_mute; lv_obj_t* bt_mute;
lv_obj_t* bt_reject; lv_obj_t* bt_reject;
lv_obj_t* label_accept; lv_obj_t* label_accept;
lv_obj_t* label_mute; lv_obj_t* label_mute;
lv_obj_t* label_reject; lv_obj_t* label_reject;
lv_obj_t* bottomPlaceholder;
Modes mode; Modes mode;
Pinetime::Controllers::AlertNotificationService& alertNotificationService; Pinetime::Controllers::AlertNotificationService& alertNotificationService;
bool running = true; bool running = true;

@ -50,8 +50,8 @@ std::unique_ptr<Screen> Settings::CreateScreen2() {
std::array<Screens::List::Applications, 4> applications {{ std::array<Screens::List::Applications, 4> applications {{
{Symbols::shoe, "Steps", Apps::SettingSteps}, {Symbols::shoe, "Steps", Apps::SettingSteps},
{Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo},
{Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle},
{Symbols::check, "Firmware", Apps::FirmwareValidation}, {Symbols::check, "Firmware", Apps::FirmwareValidation},
{Symbols::list, "About", Apps::SysInfo},
}}; }};
return std::make_unique<Screens::List>(1, 3, app, settingsController, applications); return std::make_unique<Screens::List>(1, 3, app, settingsController, applications);
@ -60,7 +60,7 @@ std::unique_ptr<Screen> Settings::CreateScreen2() {
std::unique_ptr<Screen> Settings::CreateScreen3() { std::unique_ptr<Screen> Settings::CreateScreen3() {
std::array<Screens::List::Applications, 4> applications {{ std::array<Screens::List::Applications, 4> applications {{
{Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, {Symbols::list, "About", Apps::SysInfo},
{Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None},
{Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None},
{Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None},

@ -81,16 +81,13 @@ static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000};
Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl}; Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl};
Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress};
#ifdef PINETIME_IS_RECOVERY #ifdef PINETIME_IS_RECOVERY
static constexpr bool isFactory = true;
#include "displayapp/DummyLittleVgl.h" #include "displayapp/DummyLittleVgl.h"
#include "displayapp/DisplayAppRecovery.h" #include "displayapp/DisplayAppRecovery.h"
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
#else #else
static constexpr bool isFactory = false;
#include "displayapp/LittleVgl.h" #include "displayapp/LittleVgl.h"
#include "displayapp/DisplayApp.h" #include "displayapp/DisplayApp.h"
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
#endif #endif
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress}; Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress};
Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress}; Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress};
@ -99,8 +96,8 @@ TimerHandle_t debounceTimer;
TimerHandle_t debounceChargeTimer; TimerHandle_t debounceChargeTimer;
Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Battery batteryController;
Pinetime::Controllers::Ble bleController; Pinetime::Controllers::Ble bleController;
void ble_manager_set_ble_connection_callback(void (*connection)()); static constexpr uint8_t pinTouchIrq = Pinetime::PinMap::Cst816sIrq;
void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinPowerPresentIrq = Pinetime::PinMap::PowerPresent;
Pinetime::Controllers::HeartRateController heartRateController; Pinetime::Controllers::HeartRateController heartRateController;
Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController);

@ -20,7 +20,9 @@ namespace Pinetime {
EnableSleeping, EnableSleeping,
DisableSleeping, DisableSleeping,
OnNewDay, OnNewDay,
OnChargingEvent OnChargingEvent,
MeasureBatteryTimerExpired,
BatteryMeasurementDone,
}; };
} }
} }

@ -49,6 +49,11 @@ void IdleTimerCallback(TimerHandle_t xTimer) {
sysTask->OnIdle(); sysTask->OnIdle();
} }
void MeasureBatteryTimerCallback(TimerHandle_t xTimer) {
auto* sysTask = static_cast<SystemTask*>(pvTimerGetTimerID(xTimer));
sysTask->PushMessage(Pinetime::System::Messages::MeasureBatteryTimerExpired);
}
SystemTask::SystemTask(Drivers::SpiMaster& spi, SystemTask::SystemTask(Drivers::SpiMaster& spi,
Drivers::St7789& lcd, Drivers::St7789& lcd,
Pinetime::Drivers::SpiNorFlash& spiNorFlash, Pinetime::Drivers::SpiNorFlash& spiNorFlash,
@ -129,7 +134,8 @@ void SystemTask::Work() {
twiMaster.Init(); twiMaster.Init();
touchPanel.Init(); touchPanel.Init();
dateTimeController.Register(this); dateTimeController.Register(this);
batteryController.Init(); batteryController.Register(this);
batteryController.Update();
motorController.Init(); motorController.Init();
motionSensor.SoftReset(); motionSensor.SoftReset();
timerController.Register(this); timerController.Register(this);
@ -146,8 +152,6 @@ void SystemTask::Work() {
displayApp.Register(this); displayApp.Register(this);
displayApp.Start(); displayApp.Start();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel);
heartRateSensor.Init(); heartRateSensor.Init();
heartRateSensor.Disable(); heartRateSensor.Disable();
heartRateApp.Start(); heartRateApp.Start();
@ -190,7 +194,9 @@ void SystemTask::Work() {
idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback);
dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback); dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback);
measureBatteryTimer = xTimerCreate("measureBattery", batteryMeasurementPeriod, pdTRUE, this, MeasureBatteryTimerCallback);
xTimerStart(dimTimer, 0); xTimerStart(dimTimer, 0);
xTimerStart(measureBatteryTimer, portMAX_DELAY);
// Suppress endless loop diagnostic // Suppress endless loop diagnostic
#pragma clang diagnostic push #pragma clang diagnostic push
@ -200,11 +206,6 @@ void SystemTask::Work() {
uint8_t msg; uint8_t msg;
if (xQueueReceive(systemTasksMsgQueue, &msg, 100)) { if (xQueueReceive(systemTasksMsgQueue, &msg, 100)) {
batteryController.Update();
// the battery does not emit events when changing charge levels, so we piggyback
// on any system event to read and update the current values
Messages message = static_cast<Messages>(msg); Messages message = static_cast<Messages>(msg);
switch (message) { switch (message) {
case Messages::EnableSleeping: case Messages::EnableSleeping:
@ -234,7 +235,6 @@ void SystemTask::Work() {
lcd.Wakeup(); lcd.Wakeup();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning);
displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel);
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
isSleeping = false; isSleeping = false;
@ -329,8 +329,18 @@ void SystemTask::Work() {
stepCounterMustBeReset = true; stepCounterMustBeReset = true;
break; break;
case Messages::OnChargingEvent: case Messages::OnChargingEvent:
batteryController.Update();
motorController.RunForDuration(15); motorController.RunForDuration(15);
// Battery level is updated on every message - there's no need to do anything break;
case Messages::MeasureBatteryTimerExpired:
sendBatteryNotification = true;
batteryController.Update();
break;
case Messages::BatteryMeasurementDone:
if (sendBatteryNotification) {
sendBatteryNotification = false;
nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining());
}
break; break;
default: default:
@ -349,11 +359,6 @@ void SystemTask::Work() {
} }
} }
if (xTaskGetTickCount() - batteryNotificationTick > batteryNotificationPeriod) {
nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining());
batteryNotificationTick = xTaskGetTickCount();
}
monitor.Process(); monitor.Process();
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
dateTimeController.UpdateTime(systick_counter); dateTimeController.UpdateTime(systick_counter);

@ -128,13 +128,15 @@ namespace Pinetime {
uint8_t bleDiscoveryTimer = 0; uint8_t bleDiscoveryTimer = 0;
TimerHandle_t dimTimer; TimerHandle_t dimTimer;
TimerHandle_t idleTimer; TimerHandle_t idleTimer;
TimerHandle_t measureBatteryTimer;
bool sendBatteryNotification = false;
bool doNotGoToSleep = false; bool doNotGoToSleep = false;
void GoToRunning(); void GoToRunning();
void UpdateMotion(); void UpdateMotion();
bool stepCounterMustBeReset = false; bool stepCounterMustBeReset = false;
static constexpr TickType_t batteryNotificationPeriod = 1000 * 60 * 10; // 1 tick ~= 1ms. 1ms * 60 * 10 = 10 minutes static constexpr TickType_t batteryMeasurementPeriod = pdMS_TO_TICKS(10 * 60 * 1000);
TickType_t batteryNotificationTick = 0; TickType_t lastBatteryNotificationTime = 0;
#if configUSE_TRACE_FACILITY == 1 #if configUSE_TRACE_FACILITY == 1
SystemMonitor<FreeRtosMonitor> monitor; SystemMonitor<FreeRtosMonitor> monitor;