From 1d3742e14f09316a1d795527713eb8f9742f0ffb Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sun, 4 Apr 2021 03:08:51 +0100 Subject: Big UI and navigation Rewrite new navigation add some color to the apps redesign menus new settings menu new quick settings code clean up size reduction by converting navigation images to font and more... --- src/components/brightness/BrightnessController.cpp | 28 ++++++ src/components/brightness/BrightnessController.h | 4 + src/components/motor/MotorController.cpp | 7 +- src/components/motor/MotorController.h | 3 + src/components/settings/Settings.cpp | 110 +++++++++++++++++++-- src/components/settings/Settings.h | 87 ++++++++++++++-- 6 files changed, 226 insertions(+), 13 deletions(-) (limited to 'src/components') diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 78c461d7..0d8f366a 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -1,5 +1,6 @@ #include "BrightnessController.h" #include +#include "displayapp/screens/Symbols.h" using namespace Pinetime::Controllers; @@ -68,3 +69,30 @@ void BrightnessController::Restore() { Set(backupLevel); } +void BrightnessController::Step() { + switch(level) { + case Levels::Low: Set(Levels::Medium); break; + case Levels::Medium: Set(Levels::High); break; + case Levels::High: Set(Levels::Low); break; + default: break; + } +} + +const char* BrightnessController::GetIcon() { + switch(level) { + case Levels::Medium: return Applications::Screens::Symbols::brightnessMedium; + case Levels::High: return Applications::Screens::Symbols::brightnessHigh; + default: break; + } + return Applications::Screens::Symbols::brightnessLow; +} + +const char* BrightnessController::ToString() { + switch(level) { + case Levels::Off: return "Off"; + case Levels::Low: return "Low"; + case Levels::Medium: return "Medium"; + case Levels::High: return "High"; + default : return "???"; + } +} \ No newline at end of file diff --git a/src/components/brightness/BrightnessController.h b/src/components/brightness/BrightnessController.h index b8354ec0..efff7e81 100644 --- a/src/components/brightness/BrightnessController.h +++ b/src/components/brightness/BrightnessController.h @@ -13,10 +13,14 @@ namespace Pinetime { Levels Level() const; void Lower(); void Higher(); + void Step(); void Backup(); void Restore(); + const char* GetIcon(); + const char* ToString(); + private: static constexpr uint8_t pinLcdBacklight1 = 14; static constexpr uint8_t pinLcdBacklight2 = 22; diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 7f53fbf7..345234b3 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -7,6 +7,8 @@ APP_TIMER_DEF(vibTimer); using namespace Pinetime::Controllers; +MotorController::MotorController( Controllers::Settings &settingsController ) : settingsController{settingsController} {} + void MotorController::Init() { nrf_gpio_cfg_output(pinMotor); nrf_gpio_pin_set(pinMotor); @@ -14,7 +16,10 @@ void MotorController::Init() { app_timer_create(&vibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate); } -void MotorController::SetDuration(uint8_t motorDuration) { +void MotorController::SetDuration(uint8_t motorDuration) { + + if ( settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF ) return; + nrf_gpio_pin_clear(pinMotor); /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ app_timer_start(vibTimer, APP_TIMER_TICKS(motorDuration), NULL); diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index bdc20c0c..2f2e0343 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -2,6 +2,7 @@ #include #include "app_timer.h" +#include "components/settings/Settings.h" namespace Pinetime { namespace Controllers { @@ -9,10 +10,12 @@ namespace Pinetime { class MotorController { public: + MotorController( Controllers::Settings &settingsController ); void Init(); void SetDuration(uint8_t motorDuration); private: + Controllers::Settings& settingsController; static void vibrate(void * p_context); }; } diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index 0c6cf610..454df577 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -1,16 +1,114 @@ #include "Settings.h" +#include +#include using namespace Pinetime::Controllers; +struct SettingsHeader { + uint8_t isActive; // 0xF1 = Block is active, 0xF0 = Block is inactive + uint16_t version; // Current version, to verify if the saved data is for the current Version +}; + +#define HEADER_SIZE sizeof(SettingsHeader) + + +Settings::Settings( Pinetime::Drivers::SpiNorFlash &spiNorFlash ) : spiNorFlash{spiNorFlash} {} -// TODO (team): -// Read and write the settings to Flash -// void Settings::Init() { - // default Clock face - clockFace = 0; - clockType = ClockType::H24; + // Load default settings from Flash + LoadSettingsFromFlash(); + +} + +void Settings::SaveSettings() { + + // verify if is necessary to save + if ( settingsChanged ) { + SaveSettingsToFlash(); + } + settingsChanged = false; +} + + +bool Settings::FindHeader() { + SettingsHeader settingsHeader; + uint8_t bufferHead[sizeof(settingsHeader)]; + + for (uint8_t block = 0; block < 10; block++) { + + spiNorFlash.Read( settingsBaseAddr + (block * 0x1000), bufferHead, sizeof(settingsHeader) ); + std::memcpy(&settingsHeader, bufferHead, sizeof(settingsHeader)); + if ( settingsHeader.isActive == 0xF1 && settingsHeader.version == settingsVersion ) { + settingsFlashBlock = block; + return true; + } + } + return false; +} + +void Settings::ReadSettingsData() { + uint8_t bufferSettings[sizeof(settings)]; + spiNorFlash.Read( settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings) ); + std::memcpy(&settings, bufferSettings, sizeof(settings)); +} + +void Settings::EraseBlock() { + spiNorFlash.SectorErase(settingsBaseAddr + (settingsFlashBlock * 0x1000)); } +void Settings::SetHeader( bool state ) { + SettingsHeader settingsHeader; + uint8_t bufferHead[sizeof(settingsHeader)]; + settingsHeader.isActive = state ? 0xF1 : 0xF0; + settingsHeader.version = settingsVersion; + + std::memcpy(bufferHead, &settingsHeader, sizeof(settingsHeader)); + spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000), bufferHead, sizeof(settingsHeader)); + +} + +void Settings::SaveSettingsData() { + uint8_t bufferSettings[sizeof(settings)]; + std::memcpy(bufferSettings, &settings, sizeof(settings)); + spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings)); +} + +void Settings::LoadSettingsFromFlash() { + + if ( settingsFlashBlock == 99 ) { + // Find current Block, if can't find use default settings and set block to 0 ans save ! + if ( FindHeader() ) { + ReadSettingsData(); + } else { + SaveSettingsToFlash(); + } + } else { + // Read Settings from flash... + // never used :) + ReadSettingsData(); + } + +} + +void Settings::SaveSettingsToFlash() { + + // calculate where to save... + // mark current to inactive + // erase the new location and save + // set settingsFlashBlock + + // if first time hever, only saves to block 0 and set settingsFlashBlock + + if ( settingsFlashBlock != 99 ) { + SetHeader( false ); + } + + settingsFlashBlock++; + if ( settingsFlashBlock > 9 ) settingsFlashBlock = 0; + + EraseBlock(); + SetHeader( true ); + SaveSettingsData(); +} diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index fa67f35e..9cbbee62 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -1,29 +1,104 @@ #pragma once #include +#include "components/datetime/DateTimeController.h" +#include "components/brightness/BrightnessController.h" +#include "drivers/SpiNorFlash.h" +#include "drivers/Cst816s.h" namespace Pinetime { namespace Controllers { class Settings { public: enum class ClockType {H24, H12}; + enum class Vibration {ON, OFF}; + enum class WakeUpMode {None, SingleTap, DoubleTap, RaiseWrist}; + + Settings( Pinetime::Drivers::SpiNorFlash &spiNorFlash ); void Init(); + void SaveSettings(); - void SetClockFace( uint8_t face ) { clockFace = face; }; - uint8_t GetClockFace() { return clockFace; }; + void SetClockFace( uint8_t face ) { + if ( face != settings.clockFace ) settingsChanged = true; + settings.clockFace = face; + }; + uint8_t GetClockFace() const { return settings.clockFace; }; void SetAppMenu( uint8_t menu ) { appMenu = menu; }; uint8_t GetAppMenu() { return appMenu; }; - void SetClockType( ClockType clocktype ) { clockType = clocktype; }; - ClockType GetClockType() { return clockType; }; + void SetSettingsMenu( uint8_t menu ) { settingsMenu = menu; }; + uint8_t GetSettingsMenu() const { return settingsMenu; }; + + void SetClockType( ClockType clocktype ) { + if ( clocktype != settings.clockType ) settingsChanged = true; + settings.clockType = clocktype; + }; + ClockType GetClockType() const { return settings.clockType; }; + + void SetVibrationStatus( Vibration status ) { + if ( status != settings.vibrationStatus ) settingsChanged = true; + settings.vibrationStatus = status; + }; + Vibration GetVibrationStatus() const { return settings.vibrationStatus; }; + + void SetScreenTimeOut( uint32_t timeout ) { + if ( timeout != settings.screenTimeOut ) settingsChanged = true; + settings.screenTimeOut = timeout; + }; + uint32_t GetScreenTimeOut() const { return settings.screenTimeOut; }; + void setWakeUpMode( WakeUpMode wakeUp ) { + if ( wakeUp != settings.wakeUpMode ) settingsChanged = true; + settings.wakeUpMode = wakeUp; + }; + WakeUpMode getWakeUpMode() const { return settings.wakeUpMode; }; + + void SetBrightness( Controllers::BrightnessController::Levels level ) { + if ( level != settings.brightLevel ) settingsChanged = true; + settings.brightLevel = level; + }; + Controllers::BrightnessController::Levels GetBrightness() const { return settings.brightLevel; }; private: - uint8_t clockFace = 0; + + Pinetime::Drivers::SpiNorFlash& spiNorFlash; + struct SettingsData { + + ClockType clockType = ClockType::H24; + Vibration vibrationStatus = Vibration::ON; + + uint8_t clockFace = 0; + + uint32_t stepsGoal = 1000; + uint32_t screenTimeOut = 15000; + + WakeUpMode wakeUpMode = WakeUpMode::None; + + Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; + + }; + + SettingsData settings; + bool settingsChanged = false; + uint8_t appMenu = 0; + uint8_t settingsMenu = 0; + + // There are 10 blocks of reserved flash to save settings + // to minimize wear, the recording is done in a rotating way by the 10 blocks + uint8_t settingsFlashBlock = 99; // default to indicate it needs to find the active block + + static constexpr uint32_t settingsBaseAddr = 0x3F6000; // Flash Settings Location + static constexpr uint16_t settingsVersion = 0x0100; // Flash Settings Version - ClockType clockType = ClockType::H24; + bool FindHeader(); + void ReadSettingsData(); + void EraseBlock(); + void SetHeader( bool state ); + void SaveSettingsData(); + void LoadSettingsFromFlash(); + void SaveSettingsToFlash(); }; } -- cgit v1.2.3 From bb7531e2085cee056161c528d84884d5a75c5e6e Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sun, 4 Apr 2021 13:51:22 +0100 Subject: double tap wakeup error fix battery nonblocking read --- src/components/battery/BatteryController.cpp | 74 +++++++++++++++++++++------- src/components/battery/BatteryController.h | 47 ++++-------------- src/displayapp/screens/InfiniPaint.cpp | 2 + src/displayapp/screens/Notifications.cpp | 5 +- src/drivers/TwiMaster.cpp | 7 ++- src/libs/lv_conf.h | 2 +- src/systemtask/SystemTask.cpp | 20 ++++---- 7 files changed, 89 insertions(+), 68 deletions(-) (limited to 'src/components') diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index aaa245e4..50f95c99 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,16 +1,38 @@ #include "BatteryController.h" #include +#include #include #include +#include using namespace Pinetime::Controllers; +#define SAMPLES_IN_BUFFER 1 +static nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER]; + +static float voltage = 0.0f; +static int percentRemaining = -1; + void Battery::Init() { nrf_gpio_cfg_input(chargingPin, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup); nrf_gpio_cfg_input(powerPresentPin, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup); +} + +void Battery::Update() { + isCharging = !nrf_gpio_pin_read(chargingPin); + isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); + + // Non blocking read + SaadcInit(); + nrfx_saadc_sample(); + +} + +void Battery::SaadcInit() { nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG; - nrfx_saadc_init(&adcConfig, SaadcEventHandler); + APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, SaadcEventHandler)); + nrf_saadc_channel_config_t adcChannelConfig = { .resistor_p = NRF_SAADC_RESISTOR_DISABLED, .resistor_n = NRF_SAADC_RESISTOR_DISABLED, @@ -18,32 +40,50 @@ void Battery::Init() { .reference = NRF_SAADC_REFERENCE_INTERNAL, .acq_time = NRF_SAADC_ACQTIME_3US, .mode = NRF_SAADC_MODE_SINGLE_ENDED, - .burst = NRF_SAADC_BURST_DISABLED, + .burst = NRF_SAADC_BURST_ENABLED, .pin_p = batteryVoltageAdcInput, .pin_n = NRF_SAADC_INPUT_DISABLED }; - nrfx_saadc_channel_init(0, &adcChannelConfig); + APP_ERROR_CHECK(nrfx_saadc_channel_init(0, &adcChannelConfig)); + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(m_buffer_pool[0],SAMPLES_IN_BUFFER)); + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER)); + } -void Battery::Update() { - isCharging = !nrf_gpio_pin_read(chargingPin); - isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); +void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) { + int avg_sample = 0; + int i = 0; + + const float battery_max = 4.18; //maximum voltage of battery ( max charging voltage is 4.21 ) + const float battery_min = 3.20; //minimum voltage of battery before shutdown ( depends on the battery ) - nrf_saadc_value_t value = 0; - nrfx_saadc_sample_convert(0, &value); + if (p_event->type == NRFX_SAADC_EVT_DONE) { + + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER)); - // see https://forum.pine64.org/showthread.php?tid=8147 - voltage = (value * 2.0f) / (1024/3.0f); - int percentRemaining = ((voltage - 3.55f)*100.0f)*3.9f; - percentRemaining = std::max(percentRemaining, 0); - percentRemaining = std::min(percentRemaining, 100); + for (i = 0; i < SAMPLES_IN_BUFFER; i++) { + avg_sample += p_event->data.done.p_buffer[i]; // take N samples in a row + } + avg_sample /= i; // average all the samples out - percentRemainingBuffer.insert(percentRemaining); + voltage = (static_cast(avg_sample) * 2.04f) / (1024 / 3.0f); + voltage = roundf(voltage * 100) / 100; -// NRF_LOG_INFO("BATTERY " NRF_LOG_FLOAT_MARKER " %% - " NRF_LOG_FLOAT_MARKER " v", NRF_LOG_FLOAT(percentRemaining), NRF_LOG_FLOAT(voltage)); -// NRF_LOG_INFO("POWER Charging : %d - Power : %d", isCharging, isPowerPresent); + percentRemaining = static_cast(((voltage - battery_min) / (battery_max - battery_min)) * 100); + + percentRemaining = std::max(percentRemaining, 0); + percentRemaining = std::min(percentRemaining, 100); + + nrfx_saadc_uninit(); + + } } -void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * event) { +int Battery::PercentRemaining() { + return percentRemaining; +} + +float Battery::Voltage() { + return voltage; } \ No newline at end of file diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 86250a57..9bc942c9 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -6,44 +6,16 @@ namespace Pinetime { namespace Controllers { - /** A simple circular buffer that can be used to average - out the sensor values. The total capacity of the CircBuffer - is given as the template parameter N. - */ - template - class CircBuffer { - public: - CircBuffer() : arr{}, sz{}, cap{N}, head{} {} - /** - insert member function overwrites the next data to the current - HEAD and moves the HEAD to the newly inserted value. - */ - void insert(const int num) { - head %= cap; - arr[head++] = num; - if (sz != cap) { - sz++; - } - } - - int GetAverage() const { - int sum = std::accumulate(arr.begin(), arr.end(), 0); - return (sum / sz); - } - - private: - std::array arr; /**< internal array used to store the values*/ - uint8_t sz; /**< The current size of the array.*/ - uint8_t cap; /**< Total capacity of the CircBuffer.*/ - uint8_t head; /**< The current head of the CircBuffer*/ - }; class Battery { public: + void Init(); void Update(); - int PercentRemaining() const { return percentRemainingBuffer.GetAverage(); } - float Voltage() const { return voltage; } + + int PercentRemaining(); + float Voltage(); + bool IsCharging() const { return isCharging; } bool IsPowerPresent() const { return isPowerPresent; } @@ -51,12 +23,13 @@ namespace Pinetime { static constexpr uint32_t chargingPin = 12; static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; - static constexpr uint8_t percentRemainingSamples = 10; - static void SaadcEventHandler(nrfx_saadc_evt_t const * p_event); - CircBuffer percentRemainingBuffer {}; - float voltage = 0.0f; + bool isCharging = false; bool isPowerPresent = false; + + static void SaadcEventHandler(nrfx_saadc_evt_t const * p_event); + void SaadcInit(); + }; } } \ No newline at end of file diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index b2f0fdfe..b6a7e3e4 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -56,6 +56,8 @@ bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { std::fill(b, b + bufferSize, selectColor); color++; return true; + default: + return true; } return true; } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index ea6adc64..1a8fca9c 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -117,7 +117,7 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } return true; case Pinetime::Applications::TouchEvents::LongTap: { - notificationManager.ToggleVibrations(); + //notificationManager.ToggleVibrations(); return true; } default: @@ -214,6 +214,7 @@ namespace { lv_obj_set_size(bt_accept, (LV_HOR_RES / 3) - 5, 80); label_accept = lv_label_create(bt_accept, nullptr); lv_label_set_text(label_accept, Symbols::phone); + lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); bt_reject = lv_btn_create(callBtnContainer, nullptr); bt_reject->user_data = this; @@ -221,6 +222,7 @@ namespace { lv_obj_set_size(bt_reject, (LV_HOR_RES / 3) - 5, 80); label_reject = lv_label_create(bt_reject, nullptr); lv_label_set_text(label_reject, Symbols::phoneSlash); + lv_obj_set_style_local_bg_color(bt_reject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); bt_mute = lv_btn_create(callBtnContainer, nullptr); bt_mute->user_data = this; @@ -228,6 +230,7 @@ namespace { lv_obj_set_size(bt_mute, (LV_HOR_RES / 3) - 5, 80); label_mute = lv_label_create(bt_mute, nullptr); lv_label_set_text(label_mute, Symbols::volumMute); + lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); } break; } diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index 6a063ecf..d5898b5e 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -10,6 +10,7 @@ using namespace Pinetime::Drivers; TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module{module}, params{params} { mutex = xSemaphoreCreateBinary(); + ASSERT(mutex != NULL); } void TwiMaster::Init() { @@ -61,9 +62,11 @@ void TwiMaster::Init() { } TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) { - xSemaphoreTake(mutex, portMAX_DELAY); + // this is causing an error when came from sleep + //xSemaphoreTake(mutex, portMAX_DELAY); + auto ret = ReadWithRetry(deviceAddress, registerAddress, data, size); - xSemaphoreGive(mutex); + //xSemaphoreGive(mutex); return ret; } diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 0d1304a5..b2c45ab1 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -74,7 +74,7 @@ typedef int16_t lv_coord_t; #define LV_MEM_CUSTOM 0 #if LV_MEM_CUSTOM == 0 /* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ -#define LV_MEM_SIZE (12U * 1024U) +#define LV_MEM_SIZE (14U * 1024U) /* Complier prefix for a big array declaration */ #define LV_MEM_ATTR diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 236c313a..2aa071dc 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -148,8 +148,12 @@ void SystemTask::Work() { break; case Messages::GoToRunning: spi.Wakeup(); - //twiMaster.Wakeup(); - //touchPanel.Wakeup(); + + // Double Tap needs the touch screen to be in normal mode + if ( settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { + twiMaster.Wakeup(); + touchPanel.Wakeup(); + } nimbleController.StartAdvertising(); xTimerStart(idleTimer, 0); @@ -212,14 +216,10 @@ void SystemTask::Work() { // Double Tap needs the touch screen to be in normal mode if ( settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { - //touchPanel.Sleep(); + touchPanel.Sleep(); + twiMaster.Sleep(); } - // No Wake uo mode, we can put the twi to sleep - if ( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None ) { - //twiMaster.Sleep(); - } - isSleeping = true; isGoingToSleep = false; break; @@ -281,10 +281,10 @@ void SystemTask::OnTouchEvent() { GoToRunning(); } else if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { // error - /*auto info = touchPanel.GetTouchInfo(); + auto info = touchPanel.GetTouchInfo(); if( info.isTouch and info.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap ) { GoToRunning(); - }*/ + } } } } -- cgit v1.2.3 From 365e68e6cc3c9f893e7582d26a1805d6d51ef294 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Mon, 5 Apr 2021 15:22:10 +0100 Subject: Fix wake up lock in twi optimize battery code --- src/components/battery/BatteryController.cpp | 48 ++++++++++++---------------- src/components/battery/BatteryController.h | 12 +++++-- src/drivers/TwiMaster.cpp | 6 ++-- src/systemtask/SystemTask.cpp | 26 +++++++++------ src/systemtask/SystemTask.h | 2 +- 5 files changed, 50 insertions(+), 44 deletions(-) (limited to 'src/components') diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index 50f95c99..beca95c4 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -7,11 +7,11 @@ using namespace Pinetime::Controllers; -#define SAMPLES_IN_BUFFER 1 -static nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER]; +Battery *Battery::instance = nullptr; -static float voltage = 0.0f; -static int percentRemaining = -1; +Battery::Battery() { + instance = this; +} void Battery::Init() { nrf_gpio_cfg_input(chargingPin, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup); @@ -31,7 +31,7 @@ void Battery::Update() { void Battery::SaadcInit() { nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG; - APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, SaadcEventHandler)); + APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, adcCallbackStatic)); nrf_saadc_channel_config_t adcChannelConfig = { .resistor_p = NRF_SAADC_RESISTOR_DISABLED, @@ -45,40 +45,34 @@ void Battery::SaadcInit() { .pin_n = NRF_SAADC_INPUT_DISABLED }; APP_ERROR_CHECK(nrfx_saadc_channel_init(0, &adcChannelConfig)); - APP_ERROR_CHECK(nrfx_saadc_buffer_convert(m_buffer_pool[0],SAMPLES_IN_BUFFER)); - APP_ERROR_CHECK(nrfx_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER)); + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); } void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) { - int avg_sample = 0; - int i = 0; - - const float battery_max = 4.18; //maximum voltage of battery ( max charging voltage is 4.21 ) - const float battery_min = 3.20; //minimum voltage of battery before shutdown ( depends on the battery ) - if (p_event->type == NRFX_SAADC_EVT_DONE) { - - APP_ERROR_CHECK(nrfx_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER)); - - for (i = 0; i < SAMPLES_IN_BUFFER; i++) { - avg_sample += p_event->data.done.p_buffer[i]; // take N samples in a row - } - avg_sample /= i; // average all the samples out + const float battery_max = 4.18; // maximum voltage of battery ( max charging voltage is 4.21 ) + const float battery_min = 3.20; // minimum voltage of battery before shutdown ( depends on the battery ) - voltage = (static_cast(avg_sample) * 2.04f) / (1024 / 3.0f); - voltage = roundf(voltage * 100) / 100; + if (p_event->type == NRFX_SAADC_EVT_DONE) { + + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); - percentRemaining = static_cast(((voltage - battery_min) / (battery_max - battery_min)) * 100); + voltage = (static_cast(p_event->data.done.p_buffer[0]) * 2.04f) / (1024 / 3.0f); + voltage = roundf(voltage * 100) / 100; - percentRemaining = std::max(percentRemaining, 0); - percentRemaining = std::min(percentRemaining, 100); + percentRemaining = static_cast(((voltage - battery_min) / (battery_max - battery_min)) * 100); - nrfx_saadc_uninit(); + percentRemaining = std::max(percentRemaining, 0); + percentRemaining = std::min(percentRemaining, 100); + nrfx_saadc_uninit(); + } } -} +void Battery::adcCallbackStatic(nrfx_saadc_evt_t const *event) { + instance->SaadcEventHandler(event); +} int Battery::PercentRemaining() { return percentRemaining; diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 9bc942c9..6a0c7dff 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -10,6 +10,8 @@ namespace Pinetime { class Battery { public: + Battery(); + void Init(); void Update(); @@ -20,16 +22,22 @@ namespace Pinetime { bool IsPowerPresent() const { return isPowerPresent; } private: + static Battery *instance; + nrf_saadc_value_t saadc_value; + static constexpr uint32_t chargingPin = 12; static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; + float voltage = 0.0f; + int percentRemaining = -1; bool isCharging = false; bool isPowerPresent = false; - - static void SaadcEventHandler(nrfx_saadc_evt_t const * p_event); + void SaadcInit(); + void SaadcEventHandler(nrfx_saadc_evt_t const * p_event); + static void adcCallbackStatic(nrfx_saadc_evt_t const *event); }; } } \ No newline at end of file diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index 072dd5fc..021eac59 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -62,11 +62,9 @@ void TwiMaster::Init() { } TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) { - // this is causing an error when came from sleep - // - //xSemaphoreTake(mutex, portMAX_DELAY); + xSemaphoreTake(mutex, portMAX_DELAY); auto ret = ReadWithRetry(deviceAddress, registerAddress, data, size); - //xSemaphoreGive(mutex); + xSemaphoreGive(mutex); return ret; } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 43e6f082..57d7fb17 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -167,6 +167,21 @@ void SystemTask::Work() { isSleeping = false; isWakingUp = false; break; + case Messages::TouchWakeUp: { + auto touchInfo = touchPanel.GetTouchInfo(); + if( touchInfo.isTouch and + ( + ( touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and + settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap + ) or + ( touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and + settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap + ) + ) + ) { + GoToRunning(); + } + } break; case Messages::GoToSleep: isGoingToSleep = true; NRF_LOG_INFO("[systemtask] Going to sleep"); @@ -276,16 +291,7 @@ void SystemTask::OnTouchEvent() { } else if(!isWakingUp) { if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None or settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist ) return; - - if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap ) { - GoToRunning(); - } else if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { - - auto info = touchPanel.GetTouchInfo(); - if( info.isTouch and info.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap ) { - GoToRunning(); - } - } + PushMessage(Messages::TouchWakeUp); } } diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index fda951bd..9d0b41ad 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -37,7 +37,7 @@ namespace Pinetime { namespace System { class SystemTask { public: - enum class Messages {GoToSleep, GoToRunning, OnNewTime, OnNewNotification, OnNewCall, BleConnected, UpdateTimeOut, + enum class Messages {GoToSleep, GoToRunning, TouchWakeUp, OnNewTime, OnNewNotification, OnNewCall, BleConnected, UpdateTimeOut, BleFirmwareUpdateStarted, BleFirmwareUpdateFinished, OnTouchEvent, OnButtonEvent, OnDisplayTaskSleeping, EnableSleeping, DisableSleeping }; -- cgit v1.2.3 From 3cf4df905a20a51939141430e155c9d8e6623e30 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Thu, 8 Apr 2021 16:15:57 +0100 Subject: restore battery buffer --- src/components/battery/BatteryController.cpp | 10 ++----- src/components/battery/BatteryController.h | 40 ++++++++++++++++++++++++++-- src/displayapp/screens/Twos.cpp | 3 +-- 3 files changed, 41 insertions(+), 12 deletions(-) (limited to 'src/components') diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index beca95c4..4a7a2345 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -66,6 +66,8 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) { percentRemaining = std::max(percentRemaining, 0); percentRemaining = std::min(percentRemaining, 100); + percentRemainingBuffer.insert(percentRemaining); + nrfx_saadc_uninit(); } } @@ -73,11 +75,3 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) { void Battery::adcCallbackStatic(nrfx_saadc_evt_t const *event) { instance->SaadcEventHandler(event); } - -int Battery::PercentRemaining() { - return percentRemaining; -} - -float Battery::Voltage() { - return voltage; -} \ No newline at end of file diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 6a0c7dff..2776687b 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -7,6 +7,38 @@ namespace Pinetime { namespace Controllers { + /** A simple circular buffer that can be used to average + out the sensor values. The total capacity of the CircBuffer + is given as the template parameter N. + */ + template + class CircBuffer { + public: + CircBuffer() : arr{}, sz{}, cap{N}, head{} {} + /** + insert member function overwrites the next data to the current + HEAD and moves the HEAD to the newly inserted value. + */ + void insert(const int num) { + head %= cap; + arr[head++] = num; + if (sz != cap) { + sz++; + } + } + + int GetAverage() const { + int sum = std::accumulate(arr.begin(), arr.end(), 0); + return (sum / sz); + } + + private: + std::array arr; /**< internal array used to store the values*/ + uint8_t sz; /**< The current size of the array.*/ + uint8_t cap; /**< Total capacity of the CircBuffer.*/ + uint8_t head; /**< The current head of the CircBuffer*/ + }; + class Battery { public: @@ -15,8 +47,9 @@ namespace Pinetime { void Init(); void Update(); - int PercentRemaining(); - float Voltage(); + int PercentRemaining() const { return percentRemainingBuffer.GetAverage(); } + + float Voltage() const { return voltage; } bool IsCharging() const { return isCharging; } bool IsPowerPresent() const { return isPowerPresent; } @@ -24,6 +57,9 @@ namespace Pinetime { private: static Battery *instance; nrf_saadc_value_t saadc_value; + + static constexpr uint8_t percentRemainingSamples = 10; + CircBuffer percentRemainingBuffer {}; static constexpr uint32_t chargingPin = 12; static constexpr uint32_t powerPresentPin = 19; diff --git a/src/displayapp/screens/Twos.cpp b/src/displayapp/screens/Twos.cpp index 5210a4d6..7a3ed1e4 100644 --- a/src/displayapp/screens/Twos.cpp +++ b/src/displayapp/screens/Twos.cpp @@ -153,8 +153,7 @@ bool Twos::tryMove(Tile grid[][4], int newRow, int newCol, int oldRow, int oldCo } bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - bool validMove; - validMove = false; + bool validMove = false; for(int row = 0; row < 4; row++) { for(int col = 0; col < 4; col++) { grid[row][col].merged = false; // reinitialize merge state -- cgit v1.2.3