Unphone battery status (#176)
This commit is contained in:
parent
c3bcf93698
commit
97b8007aca
@ -1,6 +1,7 @@
|
|||||||
#include "UnPhoneFeatures.h"
|
#include "UnPhoneFeatures.h"
|
||||||
#include "hal/Configuration.h"
|
#include "hal/Configuration.h"
|
||||||
#include "hal/UnPhoneDisplay.h"
|
#include "hal/UnPhoneDisplay.h"
|
||||||
|
#include "hal/UnPhonePower.h"
|
||||||
#include "hal/UnPhoneSdCard.h"
|
#include "hal/UnPhoneSdCard.h"
|
||||||
|
|
||||||
bool unPhoneInitPower();
|
bool unPhoneInitPower();
|
||||||
@ -16,6 +17,7 @@ extern const tt::hal::Configuration unPhone = {
|
|||||||
.initLvgl = unPhoneInitLvgl,
|
.initLvgl = unPhoneInitLvgl,
|
||||||
.createDisplay = createDisplay,
|
.createDisplay = createDisplay,
|
||||||
.sdcard = createUnPhoneSdCard(),
|
.sdcard = createUnPhoneSdCard(),
|
||||||
|
.power = unPhoneGetPower,
|
||||||
.i2c = {
|
.i2c = {
|
||||||
tt::hal::i2c::Configuration {
|
tt::hal::i2c::Configuration {
|
||||||
.name = "Internal",
|
.name = "Internal",
|
||||||
|
|||||||
92
Boards/UnPhone/Source/hal/UnPhonePower.cpp
Normal file
92
Boards/UnPhone/Source/hal/UnPhonePower.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "UnPhonePower.h"
|
||||||
|
#include "UnPhoneTouch.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#define TAG "unphone_power"
|
||||||
|
|
||||||
|
#define BATTERY_VOLTAGE_MIN 3.2f
|
||||||
|
#define BATTERY_VOLTAGE_MAX 4.2f
|
||||||
|
|
||||||
|
static uint8_t estimateChargeLevelFromVoltage(uint32_t milliVolt) {
|
||||||
|
float volts = TT_MIN((float)milliVolt / 1000.f, BATTERY_VOLTAGE_MAX);
|
||||||
|
float voltage_percentage = (volts - BATTERY_VOLTAGE_MIN) / (BATTERY_VOLTAGE_MAX - BATTERY_VOLTAGE_MIN);
|
||||||
|
float voltage_factor = TT_MIN(1.0f, voltage_percentage);
|
||||||
|
auto charge_level = (uint8_t) (voltage_factor * 100.f);
|
||||||
|
TT_LOG_V(TAG, "mV = %lu, scaled = %.2f, factor = %.2f, result = %d", milliVolt, volts, voltage_factor, charge_level);
|
||||||
|
return charge_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnPhonePower::supportsMetric(MetricType type) const {
|
||||||
|
switch (type) {
|
||||||
|
case MetricType::BatteryVoltage:
|
||||||
|
case MetricType::ChargeLevel:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnPhonePower::getMetric(Power::MetricType type, Power::MetricData& data) {
|
||||||
|
switch (type) {
|
||||||
|
case MetricType::BatteryVoltage:
|
||||||
|
return readBatteryVoltageSampled(data.valueAsUint32);
|
||||||
|
case MetricType::ChargeLevel: {
|
||||||
|
uint32_t milli_volt;
|
||||||
|
if (readBatteryVoltageSampled(milli_volt)) {
|
||||||
|
data.valueAsUint8 = estimateChargeLevelFromVoltage(milli_volt);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnPhonePower::readBatteryVoltageOnce(uint32_t& output) const {
|
||||||
|
auto* touch = UnPhoneTouch::getInstance();
|
||||||
|
if (touch != nullptr) {
|
||||||
|
float vbat;
|
||||||
|
if (touch->getVBat(vbat)) {
|
||||||
|
// Convert to mV
|
||||||
|
output = (uint32_t)(vbat * 1000.f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_VOLTAGE_SAMPLES 15
|
||||||
|
|
||||||
|
bool UnPhonePower::readBatteryVoltageSampled(uint32_t& output) const {
|
||||||
|
size_t samples_read = 0;
|
||||||
|
uint32_t sample_accumulator = 0;
|
||||||
|
uint32_t sample_read_buffer;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MAX_VOLTAGE_SAMPLES; ++i) {
|
||||||
|
if (readBatteryVoltageOnce(sample_read_buffer)) {
|
||||||
|
sample_accumulator += sample_read_buffer;
|
||||||
|
samples_read++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samples_read > 0) {
|
||||||
|
output = sample_accumulator / samples_read;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<Power> power;
|
||||||
|
|
||||||
|
std::shared_ptr<Power> unPhoneGetPower() {
|
||||||
|
if (power == nullptr) {
|
||||||
|
power = std::make_shared<UnPhonePower>();
|
||||||
|
}
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
24
Boards/UnPhone/Source/hal/UnPhonePower.h
Normal file
24
Boards/UnPhone/Source/hal/UnPhonePower.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hal/Power.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
class UnPhonePower : public Power {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UnPhonePower() = default;
|
||||||
|
~UnPhonePower() = default;
|
||||||
|
|
||||||
|
bool supportsMetric(MetricType type) const override;
|
||||||
|
bool getMetric(Power::MetricType type, Power::MetricData& data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool readBatteryVoltageOnce(uint32_t& output) const;
|
||||||
|
bool readBatteryVoltageSampled(uint32_t& output) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<Power> unPhoneGetPower();
|
||||||
@ -1,15 +1,18 @@
|
|||||||
#include "UnPhoneTouch.h"
|
#include "UnPhoneTouch.h"
|
||||||
|
|
||||||
#include "esp_err.h"
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "esp_lvgl_port.h"
|
#include "esp_err.h"
|
||||||
#include "esp_lcd_touch_xpt2046.h"
|
#include "esp_lcd_touch_xpt2046.h"
|
||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
#include "lvgl/LvglSync.h"
|
||||||
|
|
||||||
#define TAG "unphone_touch"
|
#define TAG "unphone_touch"
|
||||||
|
|
||||||
#define UNPHONE_TOUCH_X_MAX 320
|
#define UNPHONE_TOUCH_X_MAX 320
|
||||||
#define UNPHONE_TOUCH_Y_MAX 480
|
#define UNPHONE_TOUCH_Y_MAX 480
|
||||||
|
|
||||||
|
UnPhoneTouch* UnPhoneTouch::instance = nullptr;
|
||||||
|
|
||||||
bool UnPhoneTouch::start(lv_display_t* display) {
|
bool UnPhoneTouch::start(lv_display_t* display) {
|
||||||
const esp_lcd_panel_io_spi_config_t io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(GPIO_NUM_38);
|
const esp_lcd_panel_io_spi_config_t io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(GPIO_NUM_38);
|
||||||
|
|
||||||
@ -57,10 +60,12 @@ bool UnPhoneTouch::start(lv_display_t* display) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance = this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneTouch::stop() {
|
bool UnPhoneTouch::stop() {
|
||||||
|
instance = nullptr;
|
||||||
cleanup();
|
cleanup();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -81,3 +86,15 @@ void UnPhoneTouch::cleanup() {
|
|||||||
ioHandle = nullptr;
|
ioHandle = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UnPhoneTouch::getVBat(float& outputVbat) {
|
||||||
|
if (touchHandle != nullptr) {
|
||||||
|
// Shares the SPI bus with the display, so we have to sync/lock as this method might be called from anywhere
|
||||||
|
if (tt::lvgl::lock(50 / portTICK_PERIOD_MS)) {
|
||||||
|
esp_lcd_touch_xpt2046_read_battery_level(touchHandle, &outputVbat);
|
||||||
|
tt::lvgl::unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@ -6,13 +6,24 @@
|
|||||||
#include "esp_lcd_touch.h"
|
#include "esp_lcd_touch.h"
|
||||||
|
|
||||||
class UnPhoneTouch : public tt::hal::Touch {
|
class UnPhoneTouch : public tt::hal::Touch {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static UnPhoneTouch* instance;
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
||||||
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
||||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
bool start(lv_display_t* display) override;
|
||||||
bool stop() override;
|
bool stop() override;
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||||
|
|
||||||
|
bool getVBat(float& outputVbat);
|
||||||
|
|
||||||
|
/** Used for accessing getVBat() in Power driver */
|
||||||
|
static UnPhoneTouch* getInstance() { return instance; }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -72,7 +72,7 @@ void log(LogLevel level, const char* tag, const char* format, ...);
|
|||||||
tt::log(tt::LogLevel::Info, tag, format, ##__VA_ARGS__)
|
tt::log(tt::LogLevel::Info, tag, format, ##__VA_ARGS__)
|
||||||
#define TT_LOG_D(tag, format, ...) \
|
#define TT_LOG_D(tag, format, ...) \
|
||||||
tt::log(tt::LogLevel::Debug, tag, format, ##__VA_ARGS__)
|
tt::log(tt::LogLevel::Debug, tag, format, ##__VA_ARGS__)
|
||||||
#define TT_LOG_T(tag, format, ...) \
|
#define TT_LOG_V(tag, format, ...) \
|
||||||
tt::log(tt::LogLevel::Trace, tag, format, ##__VA_ARGS__)
|
tt::log(tt::LogLevel::Trace, tag, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
#endif // ESP_TARGET
|
#endif // ESP_TARGET
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user