Implement battery measurement in BatteryController.

Update battery info on wake up (with button)
This commit is contained in:
JF 2019-12-27 16:05:35 +01:00
parent 11d5403558
commit fcbd341c1c
6 changed files with 103 additions and 75 deletions

View file

@ -38,6 +38,7 @@ list(APPEND SOURCE_FILES
drivers/SpiMaster.cpp drivers/SpiMaster.cpp
Components/Gfx/Gfx.cpp Components/Gfx/Gfx.cpp
BLE/BleManager.c BLE/BleManager.c
Components/Battery/BatteryController.cpp
) )
set(INCLUDE_FILES set(INCLUDE_FILES
@ -51,6 +52,7 @@ set(INCLUDE_FILES
drivers/SpiMaster.h drivers/SpiMaster.h
Components/Gfx/Gfx.h Components/Gfx/Gfx.h
BLE/BleManager.h BLE/BleManager.h
Components/Battery/BatteryController.h
) )
nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}") nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}")

View file

@ -0,0 +1,44 @@
#include <drivers/include/nrfx_saadc.h>
#include <hal/nrf_gpio.h>
#include <libraries/log/nrf_log.h>
#include "BatteryController.h"
using namespace Pinetime::Controllers;
void Battery::Init() {
nrf_gpio_cfg_input(12, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup);
nrf_gpio_cfg_input(19, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup);
nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG;
nrfx_saadc_init(&adcConfig, SaadcEventHandler);
nrf_saadc_channel_config_t adcChannelConfig = {
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
.gain = NRF_SAADC_GAIN1_5,
.reference = NRF_SAADC_REFERENCE_INTERNAL,
.acq_time = NRF_SAADC_ACQTIME_3US,
.mode = NRF_SAADC_MODE_SINGLE_ENDED,
.burst = NRF_SAADC_BURST_DISABLED,
.pin_p = (nrf_saadc_input_t)(SAADC_CH_PSELP_PSELP_AnalogInput7),
.pin_n = NRF_SAADC_INPUT_DISABLED
};
nrfx_saadc_channel_init(0, &adcChannelConfig);
}
void Battery::Update() {
isCharging = !nrf_gpio_pin_read(12);
isPowerPresent = !nrf_gpio_pin_read(19);
nrf_saadc_value_t value = 0;
nrfx_saadc_sample_convert(0, &value);
voltage = (value * 2.0f) / (1024/3.0f);
percentRemaining = ((voltage - 3.55)*100)*3.9;
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) {
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <drivers/include/nrfx_saadc.h>
namespace Pinetime {
namespace Controllers {
class Battery {
public:
void Init();
void Update();
float PercentRemaining() const { return percentRemaining; }
float Voltage() const { return voltage; }
bool IsCharging() const { return isCharging; }
bool IsPowerPresent() const { return isPowerPresent; }
private:
static void SaadcEventHandler(nrfx_saadc_evt_t const * p_event);
float percentRemaining = 0.0f;
float voltage = 0.0f;
bool isCharging = false;
bool isPowerPresent = false;
};
}
}

View file

@ -10,6 +10,10 @@
using namespace Pinetime::Applications; using namespace Pinetime::Applications;
DisplayApp::DisplayApp(Pinetime::Controllers::Battery &batteryController) : batteryController{batteryController} {
msgQueue = xQueueCreate(queueSize, itemSize);
}
void DisplayApp::Start() { void DisplayApp::Start() {
if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 256, this, 0, &taskHandle)) if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 256, this, 0, &taskHandle))
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
@ -61,6 +65,9 @@ void DisplayApp::InitHw() {
x = 181; x = 181;
gfx->DrawChar(&largeFont, '0', &x, 78, 0xffff); gfx->DrawChar(&largeFont, '0', &x, 78, 0xffff);
gfx->DrawString(10, 0, 0xffff, "BLE", &smallFont, false);
gfx->DrawString(20, 160, 0xffff, "FRIDAY 27 DEC 2019", &smallFont, false);
} }
void DisplayApp::Refresh() { void DisplayApp::Refresh() {
@ -116,9 +123,15 @@ void DisplayApp::SetTime(uint8_t minutes, uint8_t hours) {
void DisplayApp::RunningState() { void DisplayApp::RunningState() {
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
gfx->DrawString(10, 0, 0xffff, "BLE", &smallFont, false); char batteryChar[11];
gfx->DrawString((240-96), 0, 0xffff, "BAT: 58%", &smallFont, false); uint16_t newBatteryValue = batteryController.PercentRemaining();
gfx->DrawString(20, 160, 0xffff, "FRIDAY 27 DEC 2019", &smallFont, false); newBatteryValue = (newBatteryValue>100) ? 100 : newBatteryValue;
newBatteryValue = (newBatteryValue<0) ? 0 : newBatteryValue;
if(newBatteryValue != battery) {
battery = newBatteryValue;
sprintf(batteryChar, "BAT: %d%%", battery);
gfx->DrawString((240-108), 0, 0xffff, batteryChar, &smallFont, false);
}
auto raw = systick_counter / 1000; auto raw = systick_counter / 1000;
auto currentDeltaSeconds = raw - deltaSeconds; auto currentDeltaSeconds = raw - deltaSeconds;
@ -175,10 +188,6 @@ void DisplayApp::IdleState() {
} }
DisplayApp::DisplayApp() {
msgQueue = xQueueCreate(queueSize, itemSize);
}
void DisplayApp::PushMessage(DisplayApp::Messages msg) { void DisplayApp::PushMessage(DisplayApp::Messages msg) {
BaseType_t xHigherPriorityTaskWoken; BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE; xHigherPriorityTaskWoken = pdFALSE;

View file

@ -6,6 +6,7 @@
#include <Components/Gfx/Gfx.h> #include <Components/Gfx/Gfx.h>
#include <bits/unique_ptr.h> #include <bits/unique_ptr.h>
#include <queue.h> #include <queue.h>
#include <Components/Battery/BatteryController.h>
#include "lcdfont14.h" #include "lcdfont14.h"
extern const FONT_INFO lCD_70ptFontInfo; extern const FONT_INFO lCD_70ptFontInfo;
@ -16,7 +17,7 @@ namespace Pinetime {
public: public:
enum class States {Idle, Running}; enum class States {Idle, Running};
enum class Messages : uint8_t {GoToSleep, GoToRunning} ; enum class Messages : uint8_t {GoToSleep, GoToRunning} ;
DisplayApp(); DisplayApp(Pinetime::Controllers::Battery& batteryController);
void Start(); void Start();
void Minutes(uint8_t m); void Minutes(uint8_t m);
@ -51,6 +52,9 @@ namespace Pinetime {
static constexpr uint8_t queueSize = 10; static constexpr uint8_t queueSize = 10;
static constexpr uint8_t itemSize = 1; static constexpr uint8_t itemSize = 1;
Pinetime::Controllers::Battery &batteryController;
uint16_t battery = 0;
}; };
} }
} }

View file

@ -6,14 +6,12 @@
#include <libraries/gpiote/app_gpiote.h> #include <libraries/gpiote/app_gpiote.h>
#include <DisplayApp/DisplayApp.h> #include <DisplayApp/DisplayApp.h>
#include <softdevice/common/nrf_sdh.h> #include <softdevice/common/nrf_sdh.h>
#include <softdevice/common/nrf_sdh_freertos.h> #include <softdevice/common/nrf_sdh_freertos.h>
#include <hal/nrf_rtc.h> #include <hal/nrf_rtc.h>
#include <timers.h> #include <timers.h>
#include <libraries/log/nrf_log.h> #include <libraries/log/nrf_log.h>
#include <drivers/include/nrfx_saadc.h>
#include "BLE/BleManager.h" #include "BLE/BleManager.h"
#include "Components/Battery/BatteryController.h"
#if NRF_LOG_ENABLED #if NRF_LOG_ENABLED
#include "Logging/NrfLogger.h" #include "Logging/NrfLogger.h"
@ -23,10 +21,11 @@ Pinetime::Logging::NrfLogger logger;
Pinetime::Logging::DummyLogger logger; Pinetime::Logging::DummyLogger logger;
#endif #endif
Pinetime::Applications::DisplayApp displayApp; std::unique_ptr<Pinetime::Applications::DisplayApp> displayApp;
TaskHandle_t systemThread; TaskHandle_t systemThread;
bool isSleeping = false; bool isSleeping = false;
TimerHandle_t debounceTimer; TimerHandle_t debounceTimer;
Pinetime::Controllers::Battery batteryController;
extern "C" { extern "C" {
void vApplicationIdleHook() { void vApplicationIdleHook() {
@ -47,25 +46,24 @@ void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action
void DebounceTimerCallback(TimerHandle_t xTimer) { void DebounceTimerCallback(TimerHandle_t xTimer) {
xTimerStop(xTimer, 0); xTimerStop(xTimer, 0);
if(isSleeping) { if(isSleeping) {
displayApp.PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning);
isSleeping = false; isSleeping = false;
batteryController.Update();
} }
else { else {
displayApp.PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
isSleeping = true; isSleeping = true;
} }
} }
void nrfx_saadc_event_handler(nrfx_saadc_evt_t const * p_event) {
}
void SystemTask(void *) { void SystemTask(void *) {
APP_GPIOTE_INIT(2); APP_GPIOTE_INIT(2);
bool erase_bonds=false; bool erase_bonds=false;
nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds);
displayApp.Start(); displayApp->Start();
batteryController.Init();
batteryController.Update();
debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback); debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback);
@ -82,69 +80,16 @@ void SystemTask(void *) {
nrfx_gpiote_in_init(13, &pinConfig, nrfx_gpiote_evt_handler); nrfx_gpiote_in_init(13, &pinConfig, nrfx_gpiote_evt_handler);
nrf_gpio_cfg_input(12, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup);
nrf_gpio_cfg_input(19, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup);
nrf_gpio_cfg_output(27);
nrf_gpio_pin_set(27);
nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG;
nrfx_saadc_init(&adcConfig, nrfx_saadc_event_handler);
nrfx_err_t nrfx_saadc_calibrate_offset(void);
vTaskDelay(1000);
nrf_saadc_channel_config_t adcChannelConfig = {
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
.gain = NRF_SAADC_GAIN1_5,
.reference = NRF_SAADC_REFERENCE_INTERNAL,
.acq_time = NRF_SAADC_ACQTIME_3US,
.mode = NRF_SAADC_MODE_SINGLE_ENDED,
.burst = NRF_SAADC_BURST_DISABLED,
.pin_p = (nrf_saadc_input_t)(SAADC_CH_PSELP_PSELP_AnalogInput7),
.pin_n = NRF_SAADC_INPUT_DISABLED
};
nrfx_saadc_channel_init(0, &adcChannelConfig);
nrf_saadc_value_t value = 0;
nrfx_saadc_sample_convert(0, &value);
while(true) {
bool charge = nrf_gpio_pin_read(12);
bool power = nrf_gpio_pin_read(19);
if(!charge) {
NRF_LOG_INFO("CHARGE ON");
} else {
NRF_LOG_INFO("CHARGE OFF");
}
if(!power) {
NRF_LOG_INFO("POWER ON");
} else {
NRF_LOG_INFO("POWER OFF");
}
nrf_saadc_value_t value = 0;
nrfx_saadc_sample_convert(0, &value);
float v = (value * 2.0f) / (1024/3.0f);
float percent = ((v - 3.55)*100)*3.9;
NRF_LOG_INFO(NRF_LOG_FLOAT_MARKER "v - " NRF_LOG_FLOAT_MARKER "%%", NRF_LOG_FLOAT(v), NRF_LOG_FLOAT(percent));
nrf_gpio_pin_toggle(27);
vTaskDelay(1000);
}
vTaskSuspend(nullptr); vTaskSuspend(nullptr);
} }
void OnNewTime(uint8_t minutes, uint8_t hours) { void OnNewTime(uint8_t minutes, uint8_t hours) {
displayApp.SetTime(minutes, hours); displayApp->SetTime(minutes, hours);
} }
int main(void) { int main(void) {
displayApp.reset(new Pinetime::Applications::DisplayApp(batteryController));
logger.Init(); logger.Init();
nrf_drv_clock_init(); nrf_drv_clock_init();