summaryrefslogtreecommitdiff
path: root/src/components/battery/BatteryController.h
blob: e5c734d21d3c161fb4cc24a93a311e66d2b63c70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#pragma once
#include <cstdint>
#include <drivers/include/nrfx_saadc.h>
#include <array>
#include <numeric>

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:
      Battery();

      void Init();
      void Update();

      int PercentRemaining() const {
        return percentRemainingBuffer.GetAverage();
      }

      float Voltage() const {
        return voltage;
      }

      bool IsCharging() const {
        return isCharging;
      }
      bool IsPowerPresent() const {
        return isPowerPresent;
      }

        private:
      static Battery* instance;
      nrf_saadc_value_t saadc_value;

      static constexpr uint8_t percentRemainingSamples = 5;
      CircBuffer<percentRemainingSamples> percentRemainingBuffer {};

      static constexpr uint32_t chargingPin = 12;
      static constexpr uint32_t powerPresentPin = 19;
      static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7;
      float voltage = 0.0f;
      int percentRemaining = -1;

      bool isCharging = false;
      bool isPowerPresent = false;

      void SaadcInit();

      void SaadcEventHandler(nrfx_saadc_evt_t const* p_event);
      static void adcCallbackStatic(nrfx_saadc_evt_t const* event);

      bool isReading = false;
      uint8_t samples = 0;
    };
  }
}