double tap wakeup error fix
battery nonblocking read
This commit is contained in:
parent
1d3742e14f
commit
bb7531e208
7 changed files with 89 additions and 68 deletions
|
@ -1,16 +1,38 @@
|
||||||
#include "BatteryController.h"
|
#include "BatteryController.h"
|
||||||
#include <hal/nrf_gpio.h>
|
#include <hal/nrf_gpio.h>
|
||||||
|
#include <nrfx_saadc.h>
|
||||||
#include <libraries/log/nrf_log.h>
|
#include <libraries/log/nrf_log.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
using namespace Pinetime::Controllers;
|
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() {
|
void Battery::Init() {
|
||||||
nrf_gpio_cfg_input(chargingPin, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup);
|
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);
|
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_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 = {
|
nrf_saadc_channel_config_t adcChannelConfig = {
|
||||||
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
|
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
|
||||||
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
|
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
|
||||||
|
@ -18,32 +40,50 @@ void Battery::Init() {
|
||||||
.reference = NRF_SAADC_REFERENCE_INTERNAL,
|
.reference = NRF_SAADC_REFERENCE_INTERNAL,
|
||||||
.acq_time = NRF_SAADC_ACQTIME_3US,
|
.acq_time = NRF_SAADC_ACQTIME_3US,
|
||||||
.mode = NRF_SAADC_MODE_SINGLE_ENDED,
|
.mode = NRF_SAADC_MODE_SINGLE_ENDED,
|
||||||
.burst = NRF_SAADC_BURST_DISABLED,
|
.burst = NRF_SAADC_BURST_ENABLED,
|
||||||
.pin_p = batteryVoltageAdcInput,
|
.pin_p = batteryVoltageAdcInput,
|
||||||
.pin_n = NRF_SAADC_INPUT_DISABLED
|
.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() {
|
void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) {
|
||||||
isCharging = !nrf_gpio_pin_read(chargingPin);
|
int avg_sample = 0;
|
||||||
isPowerPresent = !nrf_gpio_pin_read(powerPresentPin);
|
int i = 0;
|
||||||
|
|
||||||
nrf_saadc_value_t value = 0;
|
const float battery_max = 4.18; //maximum voltage of battery ( max charging voltage is 4.21 )
|
||||||
nrfx_saadc_sample_convert(0, &value);
|
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
|
||||||
|
|
||||||
|
voltage = (static_cast<float>(avg_sample) * 2.04f) / (1024 / 3.0f);
|
||||||
|
voltage = roundf(voltage * 100) / 100;
|
||||||
|
|
||||||
|
percentRemaining = static_cast<int>(((voltage - battery_min) / (battery_max - battery_min)) * 100);
|
||||||
|
|
||||||
// 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::max(percentRemaining, 0);
|
||||||
percentRemaining = std::min(percentRemaining, 100);
|
percentRemaining = std::min(percentRemaining, 100);
|
||||||
|
|
||||||
percentRemainingBuffer.insert(percentRemaining);
|
nrfx_saadc_uninit();
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * event) {
|
|
||||||
|
|
||||||
|
int Battery::PercentRemaining() {
|
||||||
|
return percentRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Battery::Voltage() {
|
||||||
|
return voltage;
|
||||||
}
|
}
|
|
@ -6,44 +6,16 @@
|
||||||
|
|
||||||
namespace Pinetime {
|
namespace Pinetime {
|
||||||
namespace Controllers {
|
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 <int N>
|
|
||||||
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<int, N> 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 {
|
class Battery {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Update();
|
void Update();
|
||||||
int PercentRemaining() const { return percentRemainingBuffer.GetAverage(); }
|
|
||||||
float Voltage() const { return voltage; }
|
int PercentRemaining();
|
||||||
|
float Voltage();
|
||||||
|
|
||||||
bool IsCharging() const { return isCharging; }
|
bool IsCharging() const { return isCharging; }
|
||||||
bool IsPowerPresent() const { return isPowerPresent; }
|
bool IsPowerPresent() const { return isPowerPresent; }
|
||||||
|
|
||||||
|
@ -51,12 +23,13 @@ namespace Pinetime {
|
||||||
static constexpr uint32_t chargingPin = 12;
|
static constexpr uint32_t chargingPin = 12;
|
||||||
static constexpr uint32_t powerPresentPin = 19;
|
static constexpr uint32_t powerPresentPin = 19;
|
||||||
static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7;
|
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<percentRemainingSamples> percentRemainingBuffer {};
|
|
||||||
float voltage = 0.0f;
|
|
||||||
bool isCharging = false;
|
bool isCharging = false;
|
||||||
bool isPowerPresent = false;
|
bool isPowerPresent = false;
|
||||||
|
|
||||||
|
static void SaadcEventHandler(nrfx_saadc_evt_t const * p_event);
|
||||||
|
void SaadcInit();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -56,6 +56,8 @@ bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||||
std::fill(b, b + bufferSize, selectColor);
|
std::fill(b, b + bufferSize, selectColor);
|
||||||
color++;
|
color++;
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case Pinetime::Applications::TouchEvents::LongTap: {
|
case Pinetime::Applications::TouchEvents::LongTap: {
|
||||||
notificationManager.ToggleVibrations();
|
//notificationManager.ToggleVibrations();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -214,6 +214,7 @@ namespace {
|
||||||
lv_obj_set_size(bt_accept, (LV_HOR_RES / 3) - 5, 80);
|
lv_obj_set_size(bt_accept, (LV_HOR_RES / 3) - 5, 80);
|
||||||
label_accept = lv_label_create(bt_accept, nullptr);
|
label_accept = lv_label_create(bt_accept, nullptr);
|
||||||
lv_label_set_text(label_accept, Symbols::phone);
|
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 = lv_btn_create(callBtnContainer, nullptr);
|
||||||
bt_reject->user_data = this;
|
bt_reject->user_data = this;
|
||||||
|
@ -221,6 +222,7 @@ namespace {
|
||||||
lv_obj_set_size(bt_reject, (LV_HOR_RES / 3) - 5, 80);
|
lv_obj_set_size(bt_reject, (LV_HOR_RES / 3) - 5, 80);
|
||||||
label_reject = lv_label_create(bt_reject, nullptr);
|
label_reject = lv_label_create(bt_reject, nullptr);
|
||||||
lv_label_set_text(label_reject, Symbols::phoneSlash);
|
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 = lv_btn_create(callBtnContainer, nullptr);
|
||||||
bt_mute->user_data = this;
|
bt_mute->user_data = this;
|
||||||
|
@ -228,6 +230,7 @@ namespace {
|
||||||
lv_obj_set_size(bt_mute, (LV_HOR_RES / 3) - 5, 80);
|
lv_obj_set_size(bt_mute, (LV_HOR_RES / 3) - 5, 80);
|
||||||
label_mute = lv_label_create(bt_mute, nullptr);
|
label_mute = lv_label_create(bt_mute, nullptr);
|
||||||
lv_label_set_text(label_mute, Symbols::volumMute);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using namespace Pinetime::Drivers;
|
||||||
|
|
||||||
TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module{module}, params{params} {
|
TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module{module}, params{params} {
|
||||||
mutex = xSemaphoreCreateBinary();
|
mutex = xSemaphoreCreateBinary();
|
||||||
|
ASSERT(mutex != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwiMaster::Init() {
|
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) {
|
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);
|
auto ret = ReadWithRetry(deviceAddress, registerAddress, data, size);
|
||||||
xSemaphoreGive(mutex);
|
//xSemaphoreGive(mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ typedef int16_t lv_coord_t;
|
||||||
#define LV_MEM_CUSTOM 0
|
#define LV_MEM_CUSTOM 0
|
||||||
#if LV_MEM_CUSTOM == 0
|
#if LV_MEM_CUSTOM == 0
|
||||||
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
/* 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 */
|
/* Complier prefix for a big array declaration */
|
||||||
#define LV_MEM_ATTR
|
#define LV_MEM_ATTR
|
||||||
|
|
|
@ -148,8 +148,12 @@ void SystemTask::Work() {
|
||||||
break;
|
break;
|
||||||
case Messages::GoToRunning:
|
case Messages::GoToRunning:
|
||||||
spi.Wakeup();
|
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();
|
nimbleController.StartAdvertising();
|
||||||
xTimerStart(idleTimer, 0);
|
xTimerStart(idleTimer, 0);
|
||||||
|
@ -212,12 +216,8 @@ void SystemTask::Work() {
|
||||||
|
|
||||||
// Double Tap needs the touch screen to be in normal mode
|
// Double Tap needs the touch screen to be in normal mode
|
||||||
if ( settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) {
|
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;
|
isSleeping = true;
|
||||||
|
@ -281,10 +281,10 @@ void SystemTask::OnTouchEvent() {
|
||||||
GoToRunning();
|
GoToRunning();
|
||||||
} else if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) {
|
} else if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) {
|
||||||
// error
|
// error
|
||||||
/*auto info = touchPanel.GetTouchInfo();
|
auto info = touchPanel.GetTouchInfo();
|
||||||
if( info.isTouch and info.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap ) {
|
if( info.isTouch and info.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap ) {
|
||||||
GoToRunning();
|
GoToRunning();
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue