From bb7531e2085cee056161c528d84884d5a75c5e6e Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sun, 4 Apr 2021 13:51:22 +0100 Subject: [PATCH] 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(-) 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; - nrf_saadc_value_t value = 0; - nrfx_saadc_sample_convert(0, &value); + 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 ) - // 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); + if (p_event->type == NRFX_SAADC_EVT_DONE) { + + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER)); - percentRemainingBuffer.insert(percentRemaining); + 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 -// 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); + voltage = (static_cast(avg_sample) * 2.04f) / (1024 / 3.0f); + voltage = roundf(voltage * 100) / 100; + + 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(); - }*/ + } } } }