nrfcxx  0.1.0
C++-17 Framework for Nordic nRF5 Devices
lipomon.hpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0 */
2 /* Copyright 2018-2019 Peter A. Bigot */
3 
8 #ifndef NRFCXX_MISC_LIPOMON_HPP
9 #define NRFCXX_MISC_LIPOMON_HPP
10 #pragma once
11 
12 #include <nrfcxx/periph.hpp>
13 #include <nrfcxx/lpm.hpp>
14 #include <nrfcxx/sensor/adc.hpp>
15 
16 namespace nrfcxx {
17 namespace misc {
18 
50 {
51  using super = lpm::lpsm_capable;
52 
53 public:
54 
57  enum PowerSource_e : uint8_t
58  {
67  };
68 
69 private:
70  using flags_type = uint8_t;
71 
73  enum flags_enum : flags_type
74  {
77  FL_PWRSRCCAP_Pos = 0U,
78  FL_PWRSRCCAP_Msk = 0x03 << FL_PWRSRCCAP_Pos,
79 
82  FL_PWRSRCPRC_Pos = 2U,
83  FL_PWRSRCPRC_Msk = 0x03 << FL_PWRSRCPRC_Pos,
84 
87  FL_CALIBRATED = 0x10,
88 
91  FL_SAMPLING = 0x20,
92 
95  FL_SAMPLE_CORRUPTED = 0x40,
96  };
97 
98  /* Power source changes affecting #PF_LIPO, #PF_MAINS, #PF_CHARGING,
99  * #PF_CHARGED are decoupled from the battery sampling state.
100  *
101  * State transitions:
102  *
103  * * ENTRY_START enables change detection on VCHG_DETECT and
104  * CHGn_STATE, captures their initial state, and sets PF_STARTED.
105  * It falls through to ENTRY_CALIBRATE.
106  *
107  * * ENTRY_CALIBRATE queues an ADC calibration and falls into
108  * EXIT_CALIBRATE.
109  *
110  * * EXIT_CALIBRATE loops until calibration resolved, then records
111  * state of calibration and falls into ENTRY_VBATT.
112  *
113  * * ENTRY_VBATT if not calibrated jumps to ENTRY_CALIBRATE.
114  * Otherwise it invokes sample_setup() and transitions to VBATT
115  * (after a setup delay if necessary).
116  *
117  * * VBATT queues an ADC collection and transitions to EXIT_VBATT.
118  *
119  * * EXIT_VBATT is blocked until the ADC completes, then it invokes
120  * sample_teardown() and processes the sample, emitting
121  * #PF_OBSERVATION if the collection was valid. It then
122  * transitions to IDLE.
123  */
124  static constexpr auto MS_ENTRY_CALIBRATE = lpm::state_machine::MS_ENTRY_SAMPLE + 1;
125  static constexpr auto MS_EXIT_CALIBRATE = lpm::state_machine::MS_EXIT_SAMPLE + 1;
126  static constexpr auto MS_ENTRY_VBATT = lpm::state_machine::MS_ENTRY_SAMPLE;
127  static constexpr auto MS_VBATT = lpm::state_machine::MS_SAMPLE;
128  static constexpr auto MS_EXIT_VBATT = lpm::state_machine::MS_EXIT_SAMPLE;
129 
130 public:
131  static constexpr auto PF_STARTED = lpm::state_machine::PF_STARTED;
132 
136  static constexpr auto PF_LIPO = lpm::state_machine::PF_APP_BASE;
137 
144  static constexpr auto PF_MAINS = lpm::state_machine::PF_APP_BASE << 1;
145 
149  static constexpr auto PF_CHARGING = lpm::state_machine::PF_APP_BASE << 2;
150 
154  static constexpr auto PF_CHARGED = lpm::state_machine::PF_APP_BASE << 3;
155 
159  static constexpr auto PF_CALIBRATED = lpm::state_machine::PF_APP_BASE << 5;
160 
176  lipo_monitor (notifier_type notify,
177  const gpio::gpio_pin& vchg_detect,
178  const gpio::gpio_pin& chgn_state,
179  sensor::adc::voltage_divider& battmeas);
180 
183  {
184  return vchg_detect_.read();
185  }
186 
189  {
190  return vchg_detect_.read() && !chgn_state_.read();
191  }
192 
197  int calibrate ();
198 
205  int batt_mV () const
206  {
207  return batt_mV_;
208  }
209 
217  int power_source () const;
218 
219 private:
221  using adc_mutex_type = periph::ADCClient::mutex_type;
222 
223  void callback_bi_ (const periph::GPIOTE::sense_status_type* sp);
224 
225  int lpsm_process_ (int& delay,
226  process_flags_type& pf) override;
227 
229 
230  gpio::gpio_pin vchg_detect_;
231  gpio::gpio_pin chgn_state_;
232  sensor::adc::voltage_divider& battmeas_;
233  int16_t batt_mV_ = 0;
234 
235  // Protected by mutex_type
236  flags_type volatile flags_bi_ = 0;
237 
238  // These three protected by adc_mutex_type, if necessary.
239  bool volatile adc_pending_ = false;
240  int8_t volatile adc_calibrating_ = 0;
241  int8_t volatile adc_sampling_ = 0;
242 };
243 
244 } // ns misc
245 } // namespace
246 
247 #endif /* NRFCXX_MISC_LIPOMON_HPP */
nrfcxx::misc::lipo_monitor::lipo_monitor
lipo_monitor(notifier_type notify, const gpio::gpio_pin &vchg_detect, const gpio::gpio_pin &chgn_state, sensor::adc::voltage_divider &battmeas)
Construct an instance.
nrfcxx::misc::lipo_monitor::PF_MAINS
static constexpr auto PF_MAINS
Sensor-specific indication from lpm::lpsm_capable::lpsm_process() that a powered USB cable has been i...
Definition: lipomon.hpp:144
nrfcxx::misc::lipo_monitor::PS_Charging
V_BUS is non-zero and TCK106 charging active.
Definition: lipomon.hpp:64
nrfcxx::misc::lipo_monitor::calibrate
int calibrate()
Initiate a calibration of the ADC used to measure voltage.
lpm.hpp
Material supporting low-power-mode operations.
nrfcxx::periph::GPIOTE::sense_listener
Object used to manage sense callbacks.
Definition: periph.hpp:854
nrfcxx::gpio::gpio_pin
Extension of generic_pin using an owned pin_reference.
Definition: gpio.hpp:507
nrfcxx::periph::GPIOTE::sense_listener::mutex_type
GPIOTE::mutex_type mutex_type
Mutex used for blocked interrupts related to the listener.
Definition: periph.hpp:869
nrfcxx::lpm::state_machine::PF_STARTED
static constexpr process_flags_type PF_STARTED
lpsm_capable::lpsm_process() flag bit when the machine is ready to provide observations.
Definition: lpm.hpp:222
nrfcxx::misc::lipo_monitor::PF_CHARGING
static constexpr auto PF_CHARGING
Sensor-specific indication from lpm::lpsm_capable::lpsm_process() that the LiPo battery is being char...
Definition: lipomon.hpp:149
nrfcxx::misc::lipo_monitor::charging_live
bool charging_live()
Read the live charging signal.
Definition: lipomon.hpp:188
nrfcxx::lpm::state_machine::MS_SAMPLE
static constexpr state_type MS_SAMPLE
States available to implement a sample state.
Definition: lpm.hpp:192
nrfcxx::gpio::gpio_pin::read
bool read() const override
Return the input signal observed at the pin, or zero if the reference is invalid.
Definition: gpio.hpp:554
nrfcxx::misc::lipo_monitor::PF_CALIBRATED
static constexpr auto PF_CALIBRATED
Sensor-specific indication from lpm::lpsm_capable::lpsm_process() that the battery voltage sensor has...
Definition: lipomon.hpp:159
nrfcxx::misc::lipo_monitor::PF_LIPO
static constexpr auto PF_LIPO
Sensor-specific indication from lpm::lpsm_capable::lpsm_process() that a powered USB cable has been r...
Definition: lipomon.hpp:136
nrfcxx::misc::lipo_monitor::PS_OnBattery
V_BUS is zero.
Definition: lipomon.hpp:62
adc.hpp
Specializations of nrfcxx::periph::ADC for common ADC operations.
nrfcxx::periph::GPIOTE::sense_status_type
Structure used to convey information about pin levels to sense_listener callbacks.
Definition: periph.hpp:672
nrfcxx::misc::lipo_monitor::PS_Unknown
No information available.
Definition: lipomon.hpp:60
nrfcxx::misc::lipo_monitor::PF_CHARGED
static constexpr auto PF_CHARGED
Sensor-specific indication from lpm::lpsm_capable::lpsm_process() that the LiPo battery has completed...
Definition: lipomon.hpp:154
nrfcxx::notifier_type
std::function< void()> notifier_type
Type used to hold a notifier.
Definition: core.hpp:514
nrfcxx::misc::lipo_monitor::batt_mV
int batt_mV() const
The most recently collected LiPo output voltage.
Definition: lipomon.hpp:205
nrfcxx::misc::lipo_monitor::power_source
int power_source() const
Get the latest processed power source.
nrfcxx::lpm::state_machine::MS_EXIT_SAMPLE
static constexpr state_type MS_EXIT_SAMPLE
States available to guard exit from a sample state.
Definition: lpm.hpp:201
nrfcxx::lpm::lpsm_capable
Base (or mixin) class for anything that supports a state_machine.
Definition: lpm.hpp:426
nrfcxx::misc::lipo_monitor::PS_Charged
V_BUS is non-zero and TCK106 charging not active.
Definition: lipomon.hpp:66
nrfcxx::misc::lipo_monitor::vchg_detected_live
bool vchg_detected_live()
Read the live USB detection signal.
Definition: lipomon.hpp:182
nrfcxx::lpm::state_machine::MS_ENTRY_SAMPLE
static constexpr state_type MS_ENTRY_SAMPLE
States available to guard entry to a sample state.
Definition: lpm.hpp:183
nrfcxx::misc::lipo_monitor
A state machine to monitor a LiPo battery and charger.
Definition: lipomon.hpp:49
nrfcxx::lpm::state_machine::PF_APP_BASE
static constexpr process_flags_type PF_APP_BASE
First lpsm_capable::lpsm_process() flag bit available for application-specific result code bits.
Definition: lpm.hpp:255
nrfcxx::periph::ADCClient::mutex_type
peripheral::mutex_type mutex_type
Mutex required to inhibit ADC interrupts.
Definition: periph.hpp:2178
nrfcxx::sensor::adc::voltage_divider
ADC instance for voltage dividers.
Definition: adc.hpp:96
periph.hpp
Abstraction of Nordic device peripherals.
nrfcxx
Primary namespace for nrfcxx functionality.
Definition: clock.hpp:17
nrfcxx::misc::lipo_monitor::PowerSource_e
PowerSource_e
State of power source as inferred from VCHG_DETECT and BAT_CHG_STAT signals.
Definition: lipomon.hpp:57