mirror of
https://github.com/InfiniTimeOrg/InfiniTime.git
synced 2024-11-28 14:33:24 +03:00
double tap wakeup error fix
battery nonblocking read
This commit is contained in:
parent
1d3742e14f
commit
bb7531e208
@ -1,16 +1,38 @@
|
||||
#include "BatteryController.h"
|
||||
#include <hal/nrf_gpio.h>
|
||||
#include <nrfx_saadc.h>
|
||||
#include <libraries/log/nrf_log.h>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
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<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);
|
||||
|
||||
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;
|
||||
}
|
@ -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 <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 {
|
||||
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<percentRemainingSamples> percentRemainingBuffer {};
|
||||
float voltage = 0.0f;
|
||||
|
||||
bool isCharging = 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);
|
||||
color++;
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user