diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-05-02 19:12:26 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-05-02 19:12:26 +1000 |
| commit | 1573a8c4cde1cd9528b422b2dcc598e37ffe94a7 (patch) | |
| tree | d162822b8fd7054f81bace0c7a65ab4d5e6f93ef /src/battery/battery.cpp | |
| parent | a231fd1c8afedbeb14b0bc77d76bad61db986059 (diff) | |
| download | tangara-fw-1573a8c4cde1cd9528b422b2dcc598e37ffe94a7.tar.gz | |
WIP merge cyclically dependent components into one big component
Diffstat (limited to 'src/battery/battery.cpp')
| -rw-r--r-- | src/battery/battery.cpp | 112 |
1 files changed, 0 insertions, 112 deletions
diff --git a/src/battery/battery.cpp b/src/battery/battery.cpp deleted file mode 100644 index debef9e6..00000000 --- a/src/battery/battery.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2023 jacqueline <me@jacqueline.id.au> - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#include "battery.hpp" - -#include <cstdint> - -#include "adc.hpp" -#include "event_queue.hpp" -#include "freertos/portmacro.h" -#include "samd.hpp" -#include "system_events.hpp" - -namespace battery { - -static const TickType_t kBatteryCheckPeriod = pdMS_TO_TICKS(60 * 1000); - -/* - * Battery voltage, in millivolts, at which the battery charger IC will stop - * charging. - */ -static const uint32_t kFullChargeMilliVolts = 4200; - -/* - * Battery voltage, in millivolts, at which *we* will consider the battery to - * be completely discharged. This is intentionally higher than the charger IC - * cut-off and the protection on the battery itself; we want to make sure we - * finish up and have everything unmounted and snoozing before the BMS cuts us - * off. - */ -static const uint32_t kEmptyChargeMilliVolts = 3200; // BMS limit is 3100. - -using ChargeStatus = drivers::Samd::ChargeStatus; - -static void check_voltage_cb(TimerHandle_t timer) { - Battery* instance = reinterpret_cast<Battery*>(pvTimerGetTimerID(timer)); - instance->Update(); -} - -Battery::Battery(drivers::Samd& samd, std::unique_ptr<drivers::AdcBattery> adc) - : samd_(samd), adc_(std::move(adc)) { - timer_ = xTimerCreate("BATTERY", kBatteryCheckPeriod, true, this, - check_voltage_cb); - xTimerStart(timer_, portMAX_DELAY); - Update(); -} - -Battery::~Battery() { - xTimerStop(timer_, portMAX_DELAY); - xTimerDelete(timer_, portMAX_DELAY); -} - -auto Battery::Update() -> void { - std::lock_guard<std::mutex> lock{state_mutex_}; - - auto charge_state = samd_.GetChargeStatus(); - - // FIXME: So what we *should* do here is measure the actual real-life - // time from full battery -> empty battery, store it in NVS, then rely on - // that. If someone could please do this, it would be lovely. Thanks! - uint32_t mV = std::max(adc_->Millivolts(), kEmptyChargeMilliVolts); - uint_fast8_t percent = static_cast<uint_fast8_t>(std::min<double>( - std::max<double>(0.0, mV - kEmptyChargeMilliVolts) / - (kFullChargeMilliVolts - kEmptyChargeMilliVolts) * 100.0, - 100.0)); - - bool is_charging; - if (!charge_state) { - is_charging = false; - } else { - is_charging = *charge_state == ChargeStatus::kChargingRegular || - *charge_state == ChargeStatus::kChargingFast || - *charge_state == ChargeStatus::kFullCharge || - // Treat 'no battery' as charging because, for UI purposes, - // we're *kind of* at full charge if u think about it. - *charge_state == ChargeStatus::kNoBattery; - } - - if (state_ && state_->is_charging == is_charging && - state_->percent == percent) { - return; - } - - state_ = BatteryState{ - .percent = percent, - .millivolts = mV, - .is_charging = is_charging, - }; - EmitEvent(); -} - -auto Battery::State() -> std::optional<BatteryState> { - std::lock_guard<std::mutex> lock{state_mutex_}; - return state_; -} - -auto Battery::EmitEvent() -> void { - auto state = state_; - if (!state) { - return; - } - system_fsm::BatteryStateChanged ev{ - .new_state = *state, - }; - events::System().Dispatch(ev); - events::Ui().Dispatch(ev); -} - -} // namespace battery |
