SPI device migration (#490)
- Implement SPI devices in dts files for all devices - Removed `tt::hal::spi` HAL and its configurations - Fix for devicetree generator "boolean" support - Remove unused custom locks in all `DisplayDevice` implementations - Fixed some bugs with devices - Updated XPT2046 driver - Fix for `WifiEsp` deadlock - Export a lot of new `math.h` symbols with `tt_init.cpp` - Created `SpiDeviceLock` in `TactilityCore` as a wrapper for kernel SPI locking - Improved `TactilityKernel` SPI driver.
This commit is contained in:
committed by
GitHub
parent
74127a5f6c
commit
d27404964a
@@ -1,105 +0,0 @@
|
||||
#include "Xpt2046Power.h"
|
||||
#include "Xpt2046Touch.h"
|
||||
|
||||
#include <Tactility/Logger.h>
|
||||
#include <tactility/hal/Device.h>
|
||||
|
||||
static const auto LOGGER = tt::Logger("Xpt2046Power");
|
||||
|
||||
constexpr auto BATTERY_VOLTAGE_MIN = 3.2f;
|
||||
constexpr auto BATTERY_VOLTAGE_MAX = 4.2f;
|
||||
constexpr auto MAX_VOLTAGE_SAMPLES = 15;
|
||||
|
||||
static std::shared_ptr<Xpt2046Touch> findXp2046TouchDevice() {
|
||||
// Make a safe copy
|
||||
auto touch = tt::hal::findFirstDevice<tt::hal::touch::TouchDevice>(tt::hal::Device::Type::Touch);
|
||||
if (touch == nullptr) {
|
||||
LOGGER.error("Touch device not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (touch->getName() != "XPT2046") {
|
||||
LOGGER.error("Touch device name mismatch");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::reinterpret_pointer_cast<Xpt2046Touch>(touch);
|
||||
}
|
||||
|
||||
static uint8_t estimateChargeLevelFromVoltage(uint32_t milliVolt) {
|
||||
float volts = std::min((float)milliVolt / 1000.f, BATTERY_VOLTAGE_MAX);
|
||||
float voltage_percentage = (volts - BATTERY_VOLTAGE_MIN) / (BATTERY_VOLTAGE_MAX - BATTERY_VOLTAGE_MIN);
|
||||
float voltage_factor = std::min(1.0f, voltage_percentage);
|
||||
auto charge_level = (uint8_t) (voltage_factor * 100.f);
|
||||
LOGGER.verbose("mV = {}, scaled = {}, factor = {}, result = {}", milliVolt, volts, voltage_factor, charge_level);
|
||||
return charge_level;
|
||||
}
|
||||
|
||||
bool Xpt2046Power::supportsMetric(MetricType type) const {
|
||||
switch (type) {
|
||||
using enum MetricType;
|
||||
case BatteryVoltage:
|
||||
case ChargeLevel:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Xpt2046Power::getMetric(MetricType type, MetricData& data) {
|
||||
switch (type) {
|
||||
using enum MetricType;
|
||||
case BatteryVoltage:
|
||||
return readBatteryVoltageSampled(data.valueAsUint32);
|
||||
case ChargeLevel: {
|
||||
uint32_t milli_volt;
|
||||
if (readBatteryVoltageSampled(milli_volt)) {
|
||||
data.valueAsUint8 = estimateChargeLevelFromVoltage(milli_volt);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Xpt2046Power::readBatteryVoltageOnce(uint32_t& output) {
|
||||
if (xptTouch == nullptr) {
|
||||
xptTouch = findXp2046TouchDevice();
|
||||
if (xptTouch == nullptr) {
|
||||
LOGGER.error("XPT2046 touch device not found");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float vbat;
|
||||
if (!xptTouch->getVBat(vbat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert to mV
|
||||
output = (uint32_t)(vbat * 1000.f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Xpt2046Power::readBatteryVoltageSampled(uint32_t& output) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/power/PowerDevice.h>
|
||||
|
||||
class Xpt2046Touch;
|
||||
using tt::hal::power::PowerDevice;
|
||||
|
||||
/**
|
||||
* Power management based on the voltage measurement at the LCD panel.
|
||||
* This estimates the battery power left.
|
||||
*/
|
||||
class Xpt2046Power : public PowerDevice {
|
||||
|
||||
std::shared_ptr<Xpt2046Touch> xptTouch;
|
||||
|
||||
bool readBatteryVoltageOnce(uint32_t& output);
|
||||
bool readBatteryVoltageSampled(uint32_t& output);
|
||||
|
||||
public:
|
||||
|
||||
~Xpt2046Power() override = default;
|
||||
|
||||
std::string getName() const final { return "XPT2046 Power Measurement"; }
|
||||
std::string getDescription() const final { return "Power interface via XPT2046 voltage measurement"; }
|
||||
|
||||
bool supportsMetric(MetricType type) const override;
|
||||
bool getMetric(MetricType type, MetricData& data) override;
|
||||
};
|
||||
@@ -35,19 +35,3 @@ esp_lcd_touch_config_t Xpt2046Touch::createEspLcdTouchConfig() {
|
||||
.driver_data = nullptr
|
||||
};
|
||||
}
|
||||
|
||||
bool Xpt2046Touch::getVBat(float& outputVbat) {
|
||||
auto touch_handle = getTouchHandle();
|
||||
if (touch_handle == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_lcd_touch_xpt2046_read_battery_level(touch_handle, &outputVbat);
|
||||
tt::lvgl::unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,4 @@ public:
|
||||
std::string getName() const final { return "XPT2046"; }
|
||||
|
||||
std::string getDescription() const final { return "XPT2046 I2C touch driver"; }
|
||||
|
||||
bool getVBat(float& outputVbat);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user