diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5f57ebf..b845fedd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,6 +38,7 @@ list(APPEND SOURCE_FILES drivers/SpiMaster.cpp Components/Gfx/Gfx.cpp BLE/BleManager.c + Components/Battery/BatteryController.cpp ) set(INCLUDE_FILES @@ -51,6 +52,7 @@ set(INCLUDE_FILES drivers/SpiMaster.h Components/Gfx/Gfx.h BLE/BleManager.h + Components/Battery/BatteryController.h ) nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}") \ No newline at end of file diff --git a/src/Components/Battery/BatteryController.cpp b/src/Components/Battery/BatteryController.cpp new file mode 100644 index 00000000..2d0ad520 --- /dev/null +++ b/src/Components/Battery/BatteryController.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#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) { + +} \ No newline at end of file diff --git a/src/Components/Battery/BatteryController.h b/src/Components/Battery/BatteryController.h new file mode 100644 index 00000000..5c631dc2 --- /dev/null +++ b/src/Components/Battery/BatteryController.h @@ -0,0 +1,24 @@ +#pragma once +#include + + +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; + }; + } +} \ No newline at end of file diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 496a204f..10153930 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -10,6 +10,10 @@ using namespace Pinetime::Applications; +DisplayApp::DisplayApp(Pinetime::Controllers::Battery &batteryController) : batteryController{batteryController} { + msgQueue = xQueueCreate(queueSize, itemSize); +} + void DisplayApp::Start() { if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 256, this, 0, &taskHandle)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); @@ -61,6 +65,9 @@ void DisplayApp::InitHw() { x = 181; 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() { @@ -116,9 +123,15 @@ void DisplayApp::SetTime(uint8_t minutes, uint8_t hours) { void DisplayApp::RunningState() { uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); - gfx->DrawString(10, 0, 0xffff, "BLE", &smallFont, false); - gfx->DrawString((240-96), 0, 0xffff, "BAT: 58%", &smallFont, false); - gfx->DrawString(20, 160, 0xffff, "FRIDAY 27 DEC 2019", &smallFont, false); + char batteryChar[11]; + uint16_t newBatteryValue = batteryController.PercentRemaining(); + 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 currentDeltaSeconds = raw - deltaSeconds; @@ -175,10 +188,6 @@ void DisplayApp::IdleState() { } -DisplayApp::DisplayApp() { - msgQueue = xQueueCreate(queueSize, itemSize); -} - void DisplayApp::PushMessage(DisplayApp::Messages msg) { BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index 19fe7ff1..4605cf1c 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "lcdfont14.h" extern const FONT_INFO lCD_70ptFontInfo; @@ -16,7 +17,7 @@ namespace Pinetime { public: enum class States {Idle, Running}; enum class Messages : uint8_t {GoToSleep, GoToRunning} ; - DisplayApp(); + DisplayApp(Pinetime::Controllers::Battery& batteryController); void Start(); void Minutes(uint8_t m); @@ -51,6 +52,9 @@ namespace Pinetime { static constexpr uint8_t queueSize = 10; static constexpr uint8_t itemSize = 1; + Pinetime::Controllers::Battery &batteryController; + uint16_t battery = 0; + }; } } diff --git a/src/main.cpp b/src/main.cpp index 533d5f5b..b883ce02 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,14 +6,12 @@ #include #include #include - #include #include #include #include -#include - #include "BLE/BleManager.h" +#include "Components/Battery/BatteryController.h" #if NRF_LOG_ENABLED #include "Logging/NrfLogger.h" @@ -23,10 +21,11 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif -Pinetime::Applications::DisplayApp displayApp; +std::unique_ptr displayApp; TaskHandle_t systemThread; bool isSleeping = false; TimerHandle_t debounceTimer; +Pinetime::Controllers::Battery batteryController; extern "C" { 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) { xTimerStop(xTimer, 0); if(isSleeping) { - displayApp.PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); isSleeping = false; + batteryController.Update(); } else { - displayApp.PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); isSleeping = true; } } -void nrfx_saadc_event_handler(nrfx_saadc_evt_t const * p_event) { - -} - - void SystemTask(void *) { APP_GPIOTE_INIT(2); bool erase_bonds=false; 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); @@ -82,69 +80,16 @@ void SystemTask(void *) { 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); } void OnNewTime(uint8_t minutes, uint8_t hours) { - displayApp.SetTime(minutes, hours); + displayApp->SetTime(minutes, hours); } int main(void) { + displayApp.reset(new Pinetime::Applications::DisplayApp(batteryController)); logger.Init(); nrf_drv_clock_init();