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

@ -18,18 +18,18 @@ You want to fix a bug, add a cool new functionality or improve the code? See *Ho
The Pinetime is a cool open source project that deserves to be known. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open source firmware for a smartwatch! The Pinetime is a cool open source project that deserves to be known. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open source firmware for a smartwatch!
# How to submit a pull request ? # How to submit a pull request?
## 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() {
batteryPercentRemaining = batteryController.PercentRemaining(); isCharging = batteryController.IsCharging();
if (batteryPercentRemaining.IsUpdated()) { if (isCharging.IsUpdated()) {
auto batteryPercent = batteryPercentRemaining.Get(); if (isCharging.Get()) {
if (batteryController.IsCharging()) { lv_label_set_text(batteryIcon, Symbols::plug);
auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent();
lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging));
lv_obj_realign(batteryPlug);
lv_label_set_text(batteryIcon, "");
} else { } else {
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); SetBatteryIcon();
lv_label_set_text(batteryPlug, ""); }
}
if (!isCharging.Get()) {
batteryPercentRemaining = batteryController.PercentRemaining();
if (batteryPercentRemaining.IsUpdated()) {
SetBatteryIcon();
} }
} }

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() {
batteryPercentRemaining = batteryController.PercentRemaining(); isCharging = batteryController.IsCharging();
if (batteryPercentRemaining.IsUpdated()) { if (isCharging.IsUpdated()) {
auto batteryPercent = batteryPercentRemaining.Get(); if (isCharging.Get()) {
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); 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();
if (batteryPercentRemaining.IsUpdated()) {
SetBatteryIcon();
}
} }
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 (isSleeping && !isWakingUp) { if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::ON) {
GoToRunning(); if (isSleeping && !isWakingUp) {
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) {