Merge branch 'develop' into update_touch_driver

This commit is contained in:
Riku Isokoski 2021-10-05 12:45:03 +03:00
commit f61e88b842
28 changed files with 110 additions and 107 deletions

View file

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(pinetime VERSION 1.4.0 LANGUAGES C CXX ASM) project(pinetime VERSION 1.6.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)

View file

@ -67,7 +67,7 @@ As of now, here is the list of achievements of this project:
* **[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) * **[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://www.mcuboot.com)
## Documentation ## Documentation

View file

@ -22,14 +22,14 @@ The Pinetime is a cool open source project that deserves to be known. Talk about
## TL;DR ## TL;DR
- Create a branch from develop; - Create a branch from develop
- Work on a single subject in this branch. Create multiple branches/pulls-requests if you want to work on multiple subjects (bugs, features,...); - Work on a single subject in this branch. Create multiple branches/pulls-requests if you want to work on multiple subjects (bugs, features,...)
- Test your modifications on the actual hardware; - Test your modifications on the actual hardware
- Check the code formatting against our coding conventions and [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy); - Check the code formatting against our coding conventions and [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy)
- Clean your code and remove files that are not needed; - Clean your code and remove files that are not needed
- Write documentation related to your new feature if applicable; - Write documentation related to your new feature if applicable
- Create a pull request and write a great description about it : what does your PR do, why, how,... Add pictures and video if possible; - Create a pull request and write a great description about it: what does your PR do, why, how,... Add pictures and video if possible
- Wait for someone to review your PR and take part in the review process; - Wait for someone to review your PR and take part in the review process
- Your PR will eventually be merged :) - Your PR will eventually be merged :)
Your contributions are more than welcome! Your contributions are more than welcome!

View file

@ -17,6 +17,12 @@ void Battery::Update() {
isCharging = !nrf_gpio_pin_read(PinMap::Charging); isCharging = !nrf_gpio_pin_read(PinMap::Charging);
isPowerPresent = !nrf_gpio_pin_read(PinMap::PowerPresent); isPowerPresent = !nrf_gpio_pin_read(PinMap::PowerPresent);
if (isPowerPresent && !isCharging) {
isFull = true;
} else if (!isPowerPresent) {
isFull = false;
}
if (isReading) { if (isReading) {
return; return;
} }
@ -63,12 +69,12 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) {
// p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024 // p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024
voltage = p_event->data.done.p_buffer[0] * (8 * 600) / 1024; voltage = p_event->data.done.p_buffer[0] * (8 * 600) / 1024;
if (voltage > battery_max) { if (isFull) {
percentRemaining = 100; percentRemaining = 100;
} else if (voltage < battery_min) { } else if (voltage < battery_min) {
percentRemaining = 0; percentRemaining = 0;
} else { } else {
percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min); percentRemaining = std::min((voltage - battery_min) * 100 / (battery_max - battery_min), isCharging ? 99 : 100);
} }
nrfx_saadc_uninit(); nrfx_saadc_uninit();

View file

@ -22,7 +22,9 @@ namespace Pinetime {
} }
bool IsCharging() const { bool IsCharging() const {
return isCharging; // isCharging will go up and down when fully charged
// isFull makes sure this returns false while fully charged.
return isCharging && !isFull;
} }
bool IsPowerPresent() const { bool IsPowerPresent() const {
@ -37,6 +39,7 @@ namespace Pinetime {
uint16_t voltage = 0; uint16_t voltage = 0;
uint8_t percentRemaining = 0; uint8_t percentRemaining = 0;
bool isFull = false;
bool isCharging = false; bool isCharging = false;
bool isPowerPresent = false; bool isPowerPresent = false;

View file

@ -43,7 +43,7 @@ int BatteryInformationService::OnBatteryServiceRequested(uint16_t connectionHand
ble_gatt_access_ctxt* context) { ble_gatt_access_ctxt* context) {
if (attributeHandle == batteryLevelHandle) { if (attributeHandle == batteryLevelHandle) {
NRF_LOG_INFO("BATTERY : handle = %d", batteryLevelHandle); NRF_LOG_INFO("BATTERY : handle = %d", batteryLevelHandle);
static uint8_t batteryValue = batteryController.PercentRemaining(); uint8_t batteryValue = batteryController.PercentRemaining();
int res = os_mbuf_append(context->om, &batteryValue, 1); int res = os_mbuf_append(context->om, &batteryValue, 1);
return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
} }

View file

@ -79,14 +79,6 @@ bool NotificationManager::AreNewNotificationsAvailable() {
return newNotification; return newNotification;
} }
bool NotificationManager::IsVibrationEnabled() {
return vibrationEnabled;
}
void NotificationManager::ToggleVibrations() {
vibrationEnabled = !vibrationEnabled;
}
bool NotificationManager::ClearNewNotificationFlag() { bool NotificationManager::ClearNewNotificationFlag() {
return newNotification.exchange(false); return newNotification.exchange(false);
} }

View file

@ -44,8 +44,6 @@ namespace Pinetime {
Notification GetPrevious(Notification::Id id); Notification GetPrevious(Notification::Id id);
bool ClearNewNotificationFlag(); bool ClearNewNotificationFlag();
bool AreNewNotificationsAvailable(); bool AreNewNotificationsAvailable();
bool IsVibrationEnabled();
void ToggleVibrations();
static constexpr size_t MaximumMessageSize() { static constexpr size_t MaximumMessageSize() {
return MessageSize; return MessageSize;
@ -60,7 +58,6 @@ namespace Pinetime {
uint8_t writeIndex = 0; uint8_t writeIndex = 0;
bool empty = true; bool empty = true;
std::atomic<bool> newNotification {false}; std::atomic<bool> newNotification {false};
bool vibrationEnabled = true;
}; };
} }
} }

View file

@ -7,6 +7,7 @@ using namespace Pinetime::Controllers;
void DateTime::SetCurrentTime(std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> t) { void DateTime::SetCurrentTime(std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> t) {
this->currentDateTime = t; this->currentDateTime = t;
UpdateTime(previousSystickCounter); // Update internal state without updating the time
} }
void DateTime::SetTime( void DateTime::SetTime(

View file

@ -53,7 +53,7 @@ namespace Pinetime {
* *
*/ */
static constexpr size_t startAddress = 0x0B4000; static constexpr size_t startAddress = 0x0B4000;
static constexpr size_t size = 0x3C0000; static constexpr size_t size = 0x34C000;
static constexpr size_t blockSize = 4096; static constexpr size_t blockSize = 4096;
bool resourcesValid = false; bool resourcesValid = false;

View file

@ -9,9 +9,6 @@ APP_TIMER_DEF(longVibTimer);
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
MotorController::MotorController(Controllers::Settings& settingsController) : settingsController {settingsController} {
}
void MotorController::Init() { void MotorController::Init() {
nrf_gpio_cfg_output(PinMap::Motor); nrf_gpio_cfg_output(PinMap::Motor);
nrf_gpio_pin_set(PinMap::Motor); nrf_gpio_pin_set(PinMap::Motor);
@ -27,18 +24,11 @@ void MotorController::Ring(void* p_context) {
} }
void MotorController::RunForDuration(uint8_t motorDuration) { void MotorController::RunForDuration(uint8_t motorDuration) {
if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) {
return;
}
nrf_gpio_pin_clear(PinMap::Motor); nrf_gpio_pin_clear(PinMap::Motor);
app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr);
} }
void MotorController::StartRinging() { void MotorController::StartRinging() {
if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) {
return;
}
Ring(this); Ring(this);
app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this);
} }

View file

@ -1,14 +1,14 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include "components/settings/Settings.h"
namespace Pinetime { namespace Pinetime {
namespace Controllers { namespace Controllers {
class MotorController { class MotorController {
public: public:
MotorController(Controllers::Settings& settingsController); MotorController() = default;
void Init(); void Init();
void RunForDuration(uint8_t motorDuration); void RunForDuration(uint8_t motorDuration);
void StartRinging(); void StartRinging();
@ -16,7 +16,6 @@ namespace Pinetime {
private: private:
static void Ring(void* p_context); static void Ring(void* p_context);
Controllers::Settings& settingsController;
static void StopMotor(void* p_context); static void StopMotor(void* p_context);
}; };
} }

View file

@ -11,7 +11,7 @@ namespace Pinetime {
class Settings { class Settings {
public: public:
enum class ClockType : uint8_t { H24, H12 }; enum class ClockType : uint8_t { H24, H12 };
enum class Vibration : uint8_t { ON, OFF }; enum class Notification : uint8_t { ON, OFF };
enum class WakeUpMode : uint8_t { enum class WakeUpMode : uint8_t {
SingleTap = 0, SingleTap = 0,
DoubleTap = 1, DoubleTap = 1,
@ -93,14 +93,14 @@ namespace Pinetime {
return settings.clockType; return settings.clockType;
}; };
void SetVibrationStatus(Vibration status) { void SetNotificationStatus(Notification status) {
if (status != settings.vibrationStatus) { if (status != settings.notificationStatus) {
settingsChanged = true; settingsChanged = true;
} }
settings.vibrationStatus = status; settings.notificationStatus = status;
}; };
Vibration GetVibrationStatus() const { Notification GetNotificationStatus() const {
return settings.vibrationStatus; return settings.notificationStatus;
}; };
void SetScreenTimeOut(uint32_t timeout) { void SetScreenTimeOut(uint32_t timeout) {
@ -170,7 +170,7 @@ namespace Pinetime {
uint32_t screenTimeOut = 15000; uint32_t screenTimeOut = 15000;
ClockType clockType = ClockType::H24; ClockType clockType = ClockType::H24;
Vibration vibrationStatus = Vibration::ON; Notification notificationStatus = Notification::ON;
uint8_t clockFace = 0; uint8_t clockFace = 0;

View file

@ -147,19 +147,15 @@ void DisplayApp::InitHw() {
void DisplayApp::Refresh() { void DisplayApp::Refresh() {
TickType_t queueTimeout; TickType_t queueTimeout;
TickType_t delta;
switch (state) { switch (state) {
case States::Idle: case States::Idle:
IdleState();
queueTimeout = portMAX_DELAY; queueTimeout = portMAX_DELAY;
break; break;
case States::Running: case States::Running:
RunningState(); if (!currentScreen->IsRunning()) {
delta = xTaskGetTickCount() - lastWakeTime; LoadApp(returnToApp, returnDirection);
if (delta > LV_DISP_DEF_REFR_PERIOD) {
delta = LV_DISP_DEF_REFR_PERIOD;
} }
queueTimeout = LV_DISP_DEF_REFR_PERIOD - delta; queueTimeout = lv_task_handler();
break; break;
default: default:
queueTimeout = portMAX_DELAY; queueTimeout = portMAX_DELAY;
@ -167,9 +163,7 @@ void DisplayApp::Refresh() {
} }
Messages msg; Messages msg;
bool messageReceived = xQueueReceive(msgQueue, &msg, queueTimeout); if (xQueueReceive(msgQueue, &msg, queueTimeout)) {
lastWakeTime = xTaskGetTickCount();
if (messageReceived) {
switch (msg) { switch (msg) {
case Messages::DimScreen: case Messages::DimScreen:
// Backup brightness is the brightness to return to after dimming or sleeping // Backup brightness is the brightness to return to after dimming or sleeping
@ -285,13 +279,6 @@ void DisplayApp::Refresh() {
} }
} }
void DisplayApp::RunningState() {
if (!currentScreen->IsRunning()) {
LoadApp(returnToApp, returnDirection);
}
lv_task_handler();
}
void DisplayApp::StartApp(Apps app, DisplayApp::FullRefreshDirections direction) { void DisplayApp::StartApp(Apps app, DisplayApp::FullRefreshDirections direction) {
nextApp = app; nextApp = app;
nextDirection = direction; nextDirection = direction;
@ -441,9 +428,6 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
currentApp = app; currentApp = app;
} }
void DisplayApp::IdleState() {
}
void DisplayApp::PushMessage(Messages msg) { void DisplayApp::PushMessage(Messages msg) {
if (in_isr()) { if (in_isr()) {
BaseType_t xHigherPriorityTaskWoken; BaseType_t xHigherPriorityTaskWoken;

View file

@ -108,8 +108,6 @@ namespace Pinetime {
TouchEvents returnTouchEvent = TouchEvents::None; TouchEvents returnTouchEvent = TouchEvents::None;
TouchEvents GetGesture(); TouchEvents GetGesture();
void RunningState();
void IdleState();
static void Process(void* instance); static void Process(void* instance);
void InitHw(); void InitHw();
void Refresh(); void Refresh();
@ -119,8 +117,6 @@ namespace Pinetime {
Apps nextApp = Apps::None; Apps nextApp = Apps::None;
DisplayApp::FullRefreshDirections nextDirection; DisplayApp::FullRefreshDirections nextDirection;
TickType_t lastWakeTime;
System::BootErrors bootError; System::BootErrors bootError;
}; };
} }

View file

@ -58,7 +58,7 @@ void BatteryInfo::Refresh() {
batteryPercent = batteryController.PercentRemaining(); batteryPercent = batteryController.PercentRemaining();
batteryVoltage = batteryController.Voltage(); batteryVoltage = batteryController.Voltage();
if (batteryController.IsCharging() and batteryPercent < 100) { if (batteryController.IsCharging()) {
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_label_set_text_static(status, "Charging"); lv_label_set_text_static(status, "Charging");
} else if (batteryPercent == 100) { } else if (batteryPercent == 100) {

View file

@ -78,7 +78,7 @@ Metronome::~Metronome() {
void Metronome::Refresh() { void Metronome::Refresh() {
if (metronomeStarted) { if (metronomeStarted) {
if (xTaskGetTickCount() - startTime > 60 * configTICK_RATE_HZ / bpm) { if (xTaskGetTickCount() - startTime > 60u * configTICK_RATE_HZ / static_cast<uint16_t>(bpm)) {
startTime += 60 * configTICK_RATE_HZ / bpm; startTime += 60 * configTICK_RATE_HZ / bpm;
counter--; counter--;
if (counter == 0) { if (counter == 0) {

View file

@ -129,10 +129,6 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
alertNotificationService); alertNotificationService);
} }
return true; return true;
case Pinetime::Applications::TouchEvents::LongTap: {
// notificationManager.ToggleVibrations();
return true;
}
default: default:
return false; return false;
} }

View file

@ -100,10 +100,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000));
lv_label_set_text(batteryIcon, Symbols::batteryFull); lv_label_set_text(batteryIcon, Symbols::batteryFull);
lv_obj_align(batteryIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2); lv_obj_align(batteryIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2);
lv_obj_set_auto_realign(batteryIcon, true);
batteryPlug = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000));
lv_obj_align(batteryPlug, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2);
bleIcon = lv_label_create(lv_scr_act(), nullptr); bleIcon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000));
@ -205,18 +202,24 @@ PineTimeStyle::~PineTimeStyle() {
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
} }
void PineTimeStyle::SetBatteryIcon() {
auto batteryPercent = batteryPercentRemaining.Get();
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
}
void PineTimeStyle::Refresh() { void PineTimeStyle::Refresh() {
isCharging = batteryController.IsCharging();
if (isCharging.IsUpdated()) {
if (isCharging.Get()) {
lv_label_set_text(batteryIcon, Symbols::plug);
} else {
SetBatteryIcon();
}
}
if (!isCharging.Get()) {
batteryPercentRemaining = batteryController.PercentRemaining(); batteryPercentRemaining = batteryController.PercentRemaining();
if (batteryPercentRemaining.IsUpdated()) { if (batteryPercentRemaining.IsUpdated()) {
auto batteryPercent = batteryPercentRemaining.Get(); SetBatteryIcon();
if (batteryController.IsCharging()) {
auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent();
lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging));
lv_obj_realign(batteryPlug);
lv_label_set_text(batteryIcon, "");
} else {
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
lv_label_set_text(batteryPlug, "");
} }
} }

View file

@ -41,6 +41,7 @@ namespace Pinetime {
uint8_t currentDay = 0; uint8_t currentDay = 0;
DirtyValue<uint8_t> batteryPercentRemaining {}; DirtyValue<uint8_t> batteryPercentRemaining {};
DirtyValue<bool> isCharging {};
DirtyValue<bool> bleState {}; DirtyValue<bool> bleState {};
DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {}; DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
DirtyValue<bool> motionSensorOk {}; DirtyValue<bool> motionSensorOk {};
@ -58,7 +59,6 @@ namespace Pinetime {
lv_obj_t* backgroundLabel; lv_obj_t* backgroundLabel;
lv_obj_t* batteryIcon; lv_obj_t* batteryIcon;
lv_obj_t* bleIcon; lv_obj_t* bleIcon;
lv_obj_t* batteryPlug;
lv_obj_t* calendarOuter; lv_obj_t* calendarOuter;
lv_obj_t* calendarInner; lv_obj_t* calendarInner;
lv_obj_t* calendarBar1; lv_obj_t* calendarBar1;
@ -76,6 +76,8 @@ namespace Pinetime {
Controllers::Settings& settingsController; Controllers::Settings& settingsController;
Controllers::MotionController& motionController; Controllers::MotionController& motionController;
void SetBatteryIcon();
lv_task_t* taskRefresh; lv_task_t* taskRefresh;
}; };
} }

View file

@ -68,6 +68,7 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
batteryIcon = lv_label_create(lv_scr_act(), nullptr); batteryIcon = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text(batteryIcon, Symbols::batteryHalf); lv_label_set_text(batteryIcon, Symbols::batteryHalf);
lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 0); lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
lv_obj_set_auto_realign(batteryIcon, true);
notificationIcon = lv_label_create(lv_scr_act(), NULL); notificationIcon = lv_label_create(lv_scr_act(), NULL);
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00));
@ -176,11 +177,31 @@ void WatchFaceAnalog::UpdateClock() {
} }
} }
void WatchFaceAnalog::SetBatteryIcon() {
auto batteryPercent = batteryPercentRemaining.Get();
if (batteryPercent == 100) {
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
} else {
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
}
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
}
void WatchFaceAnalog::Refresh() { void WatchFaceAnalog::Refresh() {
isCharging = batteryController.IsCharging();
if (isCharging.IsUpdated()) {
if (isCharging.Get()) {
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_label_set_text(batteryIcon, Symbols::plug);
} else {
SetBatteryIcon();
}
}
if (!isCharging.Get()) {
batteryPercentRemaining = batteryController.PercentRemaining(); batteryPercentRemaining = batteryController.PercentRemaining();
if (batteryPercentRemaining.IsUpdated()) { if (batteryPercentRemaining.IsUpdated()) {
auto batteryPercent = batteryPercentRemaining.Get(); SetBatteryIcon();
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); }
} }
notificationState = notificationManager.AreNewNotificationsAvailable(); notificationState = notificationManager.AreNewNotificationsAvailable();

View file

@ -49,6 +49,7 @@ namespace Pinetime {
uint8_t currentDay = 0; uint8_t currentDay = 0;
DirtyValue<uint8_t> batteryPercentRemaining {0}; DirtyValue<uint8_t> batteryPercentRemaining {0};
DirtyValue<bool> isCharging {};
DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime; DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime;
DirtyValue<bool> notificationState {false}; DirtyValue<bool> notificationState {false};
@ -81,6 +82,7 @@ namespace Pinetime {
Controllers::Settings& settingsController; Controllers::Settings& settingsController;
void UpdateClock(); void UpdateClock();
void SetBatteryIcon();
lv_task_t* taskRefresh; lv_task_t* taskRefresh;
}; };

View file

@ -102,12 +102,20 @@ WatchFaceDigital::~WatchFaceDigital() {
} }
void WatchFaceDigital::Refresh() { void WatchFaceDigital::Refresh() {
powerPresent = batteryController.IsPowerPresent();
if (powerPresent.IsUpdated()) {
lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get()));
}
batteryPercentRemaining = batteryController.PercentRemaining(); batteryPercentRemaining = batteryController.PercentRemaining();
if (batteryPercentRemaining.IsUpdated()) { if (batteryPercentRemaining.IsUpdated()) {
auto batteryPercent = batteryPercentRemaining.Get(); auto batteryPercent = batteryPercentRemaining.Get();
if (batteryPercent == 100) {
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
} else {
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
}
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
auto isCharging = batteryController.IsCharging() or batteryController.IsPowerPresent();
lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging));
} }
bleState = bleController.IsConnected(); bleState = bleController.IsConnected();

View file

@ -44,6 +44,7 @@ namespace Pinetime {
uint8_t currentDay = 0; uint8_t currentDay = 0;
DirtyValue<uint8_t> batteryPercentRemaining {}; DirtyValue<uint8_t> batteryPercentRemaining {};
DirtyValue<bool> powerPresent {};
DirtyValue<bool> bleState {}; DirtyValue<bool> bleState {};
DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {}; DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
DirtyValue<bool> motionSensorOk {}; DirtyValue<bool> motionSensorOk {};

View file

@ -88,7 +88,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app,
btn3_lvl = lv_label_create(btn3, nullptr); btn3_lvl = lv_label_create(btn3, nullptr);
lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48);
if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::ON) { if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::ON) {
lv_obj_add_state(btn3, LV_STATE_CHECKED); lv_obj_add_state(btn3, LV_STATE_CHECKED);
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn);
} else { } else {
@ -142,11 +142,11 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) {
} else if (object == btn3 && event == LV_EVENT_VALUE_CHANGED) { } else if (object == btn3 && event == LV_EVENT_VALUE_CHANGED) {
if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) {
settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON); settingsController.SetNotificationStatus(Controllers::Settings::Notification::ON);
motorController.RunForDuration(35); motorController.RunForDuration(35);
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn);
} else { } else {
settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); settingsController.SetNotificationStatus(Controllers::Settings::Notification::OFF);
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff);
} }

View file

@ -51,7 +51,7 @@ static inline void ble_ll_rfmgmt_reset(void) { }
static inline void ble_ll_rfmgmt_scan_changed(bool e, uint32_t n) { } static inline void ble_ll_rfmgmt_scan_changed(bool e, uint32_t n) { }
static inline void ble_ll_rfmgmt_sched_changed(struct ble_ll_sched_item *f) { } static inline void ble_ll_rfmgmt_sched_changed(struct ble_ll_sched_item *f) { }
static inline void ble_ll_rfmgmt_release(void) { } static inline void ble_ll_rfmgmt_release(void) { }
static inline uint32_t ble_ll_rfmgmt_enable_now(void) { return 0; } static inline uint32_t ble_ll_rfmgmt_enable_now(void) { return os_cputime_get32(); }
static inline bool ble_ll_rfmgmt_is_enabled(void) { return true; } static inline bool ble_ll_rfmgmt_is_enabled(void) { return true; }
#endif #endif

View file

@ -113,7 +113,7 @@ Pinetime::Controllers::TouchHandler touchHandler(touchPanel, lvgl);
Pinetime::Controllers::FS fs {spiNorFlash}; Pinetime::Controllers::FS fs {spiNorFlash};
Pinetime::Controllers::Settings settingsController {fs}; Pinetime::Controllers::Settings settingsController {fs};
Pinetime::Controllers::MotorController motorController {settingsController}; Pinetime::Controllers::MotorController motorController {};
Pinetime::Applications::DisplayApp displayApp(lcd, Pinetime::Applications::DisplayApp displayApp(lcd,
lvgl, lvgl,

View file

@ -274,10 +274,12 @@ void SystemTask::Work() {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime); displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime);
break; break;
case Messages::OnNewNotification: case Messages::OnNewNotification:
if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::ON) {
if (isSleeping && !isWakingUp) { if (isSleeping && !isWakingUp) {
GoToRunning(); GoToRunning();
} }
displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification); displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification);
}
break; break;
case Messages::OnTimerDone: case Messages::OnTimerDone:
if (isSleeping && !isWakingUp) { if (isSleeping && !isWakingUp) {