summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-07-24 15:29:45 +1000
committerjacqueline <me@jacqueline.id.au>2024-07-24 15:29:45 +1000
commit0cc75366848e9205ac88884afcc128925024ccec (patch)
tree82fcd90d7f427c5f40112b8d8aa6293535372702 /src/drivers
parenteb5d0d50cd5a8d807897c08438e932083e5197c2 (diff)
downloadtangara-fw-0cc75366848e9205ac88884afcc128925024ccec.tar.gz
Add a settings screen with power+battery info
Mostly for debugging, but also u can toggle fast charging off and on now
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/include/drivers/nvs.hpp4
-rw-r--r--src/drivers/include/drivers/samd.hpp13
-rw-r--r--src/drivers/nvs.cpp12
-rw-r--r--src/drivers/samd.cpp74
4 files changed, 89 insertions, 14 deletions
diff --git a/src/drivers/include/drivers/nvs.hpp b/src/drivers/include/drivers/nvs.hpp
index 8eb28cc9..e298ffc3 100644
--- a/src/drivers/include/drivers/nvs.hpp
+++ b/src/drivers/include/drivers/nvs.hpp
@@ -90,6 +90,9 @@ class NvsStorage {
auto LraCalibration() -> std::optional<LraData>;
auto LraCalibration(const LraData&) -> void;
+ auto FastCharge() -> bool;
+ auto FastCharge(bool) -> void;
+
auto PreferredBluetoothDevice() -> std::optional<bluetooth::MacAndName>;
auto PreferredBluetoothDevice(std::optional<bluetooth::MacAndName>) -> void;
@@ -150,6 +153,7 @@ class NvsStorage {
Setting<uint16_t> display_rows_;
Setting<uint8_t> haptic_motor_type_;
Setting<LraData> lra_calibration_;
+ Setting<uint8_t> fast_charge_;
Setting<uint8_t> brightness_;
Setting<uint8_t> sensitivity_;
diff --git a/src/drivers/include/drivers/samd.hpp b/src/drivers/include/drivers/samd.hpp
index 897e78d6..ff479225 100644
--- a/src/drivers/include/drivers/samd.hpp
+++ b/src/drivers/include/drivers/samd.hpp
@@ -10,6 +10,7 @@
#include <optional>
#include <string>
+#include "drivers/nvs.hpp"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
@@ -17,9 +18,7 @@ namespace drivers {
class Samd {
public:
- static auto Create() -> Samd* { return new Samd(); }
-
- Samd();
+ Samd(NvsStorage& nvs);
~Samd();
auto Version() -> std::string;
@@ -37,8 +36,14 @@ class Samd {
kChargingFast,
// The battery is full charged, and we are still plugged in.
kFullCharge,
+ // Charging failed.
+ kFault,
+ // The battery status returned isn't a known enum value.
+ kUnknown,
};
+ static auto chargeStatusToString(ChargeStatus) -> std::string;
+
auto GetChargeStatus() -> std::optional<ChargeStatus>;
auto UpdateChargeStatus() -> void;
@@ -68,6 +73,8 @@ class Samd {
Samd& operator=(const Samd&) = delete;
private:
+ NvsStorage& nvs_;
+
uint8_t version_;
std::optional<ChargeStatus> charge_status_;
UsbStatus usb_status_;
diff --git a/src/drivers/nvs.cpp b/src/drivers/nvs.cpp
index e3c4aa06..6fac8c61 100644
--- a/src/drivers/nvs.cpp
+++ b/src/drivers/nvs.cpp
@@ -40,6 +40,7 @@ static constexpr char kKeyDisplayRows[] = "disprows";
static constexpr char kKeyHapticMotorType[] = "hapticmtype";
static constexpr char kKeyLraCalibration[] = "lra_cali";
static constexpr char kKeyDbAutoIndex[] = "dbautoindex";
+static constexpr char kKeyFastCharge[] = "fastchg";
static auto nvs_get_string(nvs_handle_t nvs, const char* key)
-> std::optional<std::string> {
@@ -239,6 +240,7 @@ NvsStorage::NvsStorage(nvs_handle_t handle)
display_rows_(kKeyDisplayRows),
haptic_motor_type_(kKeyHapticMotorType),
lra_calibration_(kKeyLraCalibration),
+ fast_charge_(kKeyFastCharge),
brightness_(kKeyBrightness),
sensitivity_(kKeyScrollSensitivity),
amp_max_vol_(kKeyAmpMaxVolume),
@@ -444,6 +446,16 @@ auto NvsStorage::OutputMode(Output out) -> void {
nvs_commit(handle_);
}
+auto NvsStorage::FastCharge() -> bool {
+ std::lock_guard<std::mutex> lock{mutex_};
+ return fast_charge_.get().value_or(true);
+}
+
+auto NvsStorage::FastCharge(bool en) -> void {
+ std::lock_guard<std::mutex> lock{mutex_};
+ fast_charge_.set(en);
+}
+
auto NvsStorage::ScreenBrightness() -> uint_fast8_t {
std::lock_guard<std::mutex> lock{mutex_};
return std::clamp<uint8_t>(brightness_.get().value_or(50), 0, 100);
diff --git a/src/drivers/samd.cpp b/src/drivers/samd.cpp
index e4aa73ad..c2308760 100644
--- a/src/drivers/samd.cpp
+++ b/src/drivers/samd.cpp
@@ -5,11 +5,13 @@
*/
#include "drivers/samd.hpp"
+#include <stdint.h>
#include <cstdint>
#include <optional>
#include <string>
+#include "drivers/nvs.hpp"
#include "esp_err.h"
#include "esp_log.h"
#include "hal/gpio_types.h"
@@ -32,7 +34,29 @@ namespace drivers {
static constexpr gpio_num_t kIntPin = GPIO_NUM_35;
-Samd::Samd() {
+auto Samd::chargeStatusToString(ChargeStatus status) -> std::string {
+ switch (status) {
+ case ChargeStatus::kNoBattery:
+ return "no_battery";
+ case ChargeStatus::kBatteryCritical:
+ return "critical";
+ case ChargeStatus::kDischarging:
+ return "discharging";
+ case ChargeStatus::kChargingRegular:
+ return "charge_regular";
+ case ChargeStatus::kChargingFast:
+ return "charge_fast";
+ case ChargeStatus::kFullCharge:
+ return "full_charge";
+ case ChargeStatus::kFault:
+ return "fault";
+ case ChargeStatus::kUnknown:
+ default:
+ return "unknown";
+ }
+}
+
+Samd::Samd(NvsStorage& nvs) : nvs_(nvs) {
gpio_set_direction(kIntPin, GPIO_MODE_INPUT);
// Being able to interface with the SAMD properly is critical. To ensure we
@@ -51,7 +75,7 @@ Samd::Samd() {
UpdateChargeStatus();
UpdateUsbStatus();
- SetFastChargeEnabled(true);
+ SetFastChargeEnabled(nvs.FastCharge());
}
Samd::~Samd() {}
@@ -78,16 +102,38 @@ auto Samd::UpdateChargeStatus() -> void {
return;
}
- // FIXME: Ideally we should be using the three 'charge status' bits to work
- // out whether we're actually charging, or if we've got a full charge,
- // critically low charge, etc.
+ // Lower two bits are the usb power status, next three are the BMS status.
+ // See 'gpio.c' in the SAMD21 firmware for how these bits get packed.
+ uint8_t charge_state = (raw_res & 0b11100) >> 2;
uint8_t usb_state = raw_res & 0b11;
- if (usb_state == 0) {
- charge_status_ = ChargeStatus::kDischarging;
- } else if (usb_state == 1) {
- charge_status_ = ChargeStatus::kChargingRegular;
- } else {
- charge_status_ = ChargeStatus::kChargingFast;
+ switch (charge_state) {
+ case 0b000:
+ charge_status_ = ChargeStatus::kNoBattery;
+ break;
+ case 0b001:
+ // BMS says we're charging; work out how fast we're charging.
+ if (usb_state >= 0b10 && nvs_.FastCharge()) {
+ charge_status_ = ChargeStatus::kChargingFast;
+ } else {
+ charge_status_ = ChargeStatus::kChargingRegular;
+ }
+ break;
+ case 0b010:
+ charge_status_ = ChargeStatus::kFullCharge;
+ break;
+ case 0b011:
+ charge_status_ = ChargeStatus::kFault;
+ break;
+ case 0b100:
+ charge_status_ = ChargeStatus::kBatteryCritical;
+ break;
+ case 0b101:
+ charge_status_ = ChargeStatus::kDischarging;
+ break;
+ case 0b110:
+ case 0b111:
+ charge_status_ = ChargeStatus::kUnknown;
+ break;
}
}
@@ -127,9 +173,15 @@ auto Samd::ResetToFlashSamd() -> void {
}
auto Samd::SetFastChargeEnabled(bool en) -> void {
+ // Always update NVS, so that the setting is right after the SAMD firmware is
+ // updated.
+ nvs_.FastCharge(en);
+
if (version_ < 4) {
return;
}
+ ESP_LOGI(kTag, "set fast charge %u", en);
+
I2CTransaction transaction;
transaction.start()
.write_addr(kAddress, I2C_MASTER_WRITE)