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
@@ -121,7 +121,6 @@ std::shared_ptr<tt::hal::display::DisplayDriver> EspLcdDisplay::getDisplayDriver
|
||||
|
||||
displayDriver = std::make_shared<EspLcdDisplayDriver>(
|
||||
panelHandle,
|
||||
lock,
|
||||
lvgl_port_config.hres,
|
||||
lvgl_port_config.vres,
|
||||
color_format
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/Lock.h>
|
||||
#include <tactility/check.h>
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
|
||||
@@ -14,8 +13,8 @@ class EspLcdDisplay : public tt::hal::display::DisplayDevice {
|
||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
||||
lv_display_t* lvglDisplay = nullptr;
|
||||
std::shared_ptr<tt::hal::display::DisplayDriver> displayDriver;
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
lcd_rgb_element_order_t rgbElementOrder;
|
||||
/** @warning This is never changed, so a driver that needs BGR is not supported */
|
||||
lcd_rgb_element_order_t rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -34,12 +33,10 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
EspLcdDisplay(std::shared_ptr<tt::Lock> lock) : lock(lock) {}
|
||||
EspLcdDisplay() = default;
|
||||
|
||||
~EspLcdDisplay() override;
|
||||
|
||||
std::shared_ptr<tt::Lock> getLock() const { return lock; }
|
||||
|
||||
bool start() final;
|
||||
|
||||
bool stop() final;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/hal/display/DisplayDriver.h>
|
||||
|
||||
#include <esp_lcd_panel_ops.h>
|
||||
@@ -8,7 +7,6 @@
|
||||
class EspLcdDisplayDriver : public tt::hal::display::DisplayDriver {
|
||||
|
||||
esp_lcd_panel_handle_t panelHandle;
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
uint16_t hRes;
|
||||
uint16_t vRes;
|
||||
tt::hal::display::ColorFormat colorFormat;
|
||||
@@ -17,11 +15,10 @@ public:
|
||||
|
||||
EspLcdDisplayDriver(
|
||||
esp_lcd_panel_handle_t panelHandle,
|
||||
std::shared_ptr<tt::Lock> lock,
|
||||
uint16_t hRes,
|
||||
uint16_t vRes,
|
||||
tt::hal::display::ColorFormat colorFormat
|
||||
) : panelHandle(panelHandle), lock(lock), hRes(hRes), vRes(vRes), colorFormat(colorFormat) {}
|
||||
) : panelHandle(panelHandle), hRes(hRes), vRes(vRes), colorFormat(colorFormat) {}
|
||||
|
||||
tt::hal::display::ColorFormat getColorFormat() const override {
|
||||
return colorFormat;
|
||||
@@ -35,6 +32,4 @@ public:
|
||||
uint16_t getPixelWidth() const override { return hRes; }
|
||||
|
||||
uint16_t getPixelHeight() const override { return vRes; }
|
||||
|
||||
std::shared_ptr<tt::Lock> getLock() const override { return lock; }
|
||||
};
|
||||
|
||||
@@ -221,7 +221,6 @@ std::shared_ptr<tt::hal::display::DisplayDriver> EspLcdDisplayV2::getDisplayDriv
|
||||
|
||||
displayDriver = std::make_shared<EspLcdDisplayDriver>(
|
||||
panelHandle,
|
||||
lock,
|
||||
lvgl_port_config.hres,
|
||||
lvgl_port_config.vres,
|
||||
color_format
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/Lock.h>
|
||||
#include <tactility/check.h>
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <esp_lcd_panel_dev.h>
|
||||
@@ -35,7 +34,6 @@ class EspLcdDisplayV2 : public tt::hal::display::DisplayDevice {
|
||||
esp_lcd_panel_handle_t _Nullable panelHandle = nullptr;
|
||||
lv_display_t* _Nullable lvglDisplay = nullptr;
|
||||
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable displayDriver;
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
std::shared_ptr<EspLcdConfiguration> configuration;
|
||||
|
||||
bool applyConfiguration() const;
|
||||
@@ -67,18 +65,12 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
EspLcdDisplayV2(const std::shared_ptr<EspLcdConfiguration>& configuration, const std::shared_ptr<tt::Lock>& lock) :
|
||||
lock(lock),
|
||||
explicit EspLcdDisplayV2(const std::shared_ptr<EspLcdConfiguration>& configuration) :
|
||||
configuration(configuration)
|
||||
{
|
||||
assert(configuration != nullptr);
|
||||
assert(lock != nullptr);
|
||||
}
|
||||
{}
|
||||
|
||||
~EspLcdDisplayV2() override;
|
||||
|
||||
std::shared_ptr<tt::Lock> getLock() const { return lock; }
|
||||
|
||||
bool start() final;
|
||||
|
||||
bool stop() final;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "EspLcdDisplayV2.h"
|
||||
#include <Tactility/hal/spi/Spi.h>
|
||||
|
||||
#include <driver/spi_common.h>
|
||||
|
||||
#include <esp_lcd_io_spi.h>
|
||||
#include <esp_lcd_types.h>
|
||||
@@ -23,7 +24,7 @@ public:
|
||||
};
|
||||
|
||||
explicit EspLcdSpiDisplay(const std::shared_ptr<EspLcdConfiguration>& configuration, const std::shared_ptr<SpiConfiguration> spiConfiguration, int gammaCurveCount) :
|
||||
EspLcdDisplayV2(configuration, tt::hal::spi::getLock(spiConfiguration->spiHostDevice)),
|
||||
EspLcdDisplayV2(configuration),
|
||||
spiConfiguration(spiConfiguration),
|
||||
gammaCurveCount(gammaCurveCount)
|
||||
{}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/spi/Spi.h"
|
||||
|
||||
#include <EspLcdDisplay.h>
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/spi_common.h>
|
||||
#include <esp_lcd_panel_io.h>
|
||||
#include <esp_lcd_types.h>
|
||||
#include <functional>
|
||||
@@ -13,8 +12,6 @@
|
||||
|
||||
class Gc9a01Display final : public EspLcdDisplay {
|
||||
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
|
||||
public:
|
||||
|
||||
class Configuration {
|
||||
@@ -83,12 +80,8 @@ private:
|
||||
public:
|
||||
|
||||
explicit Gc9a01Display(std::unique_ptr<Configuration> inConfiguration) :
|
||||
EspLcdDisplay(tt::hal::spi::getLock(inConfiguration->spiHostDevice)),
|
||||
configuration(std::move(inConfiguration)
|
||||
) {
|
||||
assert(configuration != nullptr);
|
||||
assert(getLock() != nullptr);
|
||||
}
|
||||
) {}
|
||||
|
||||
std::string getName() const override { return "GC9A01"; }
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
class Ili934xDisplay final : public EspLcdSpiDisplay {
|
||||
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
|
||||
public:
|
||||
|
||||
/** Minimal set of overrides for EspLcdConfiguration */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <Tactility/hal/spi/Spi.h>
|
||||
#include <driver/spi_common.h>
|
||||
|
||||
#include <EspLcdDisplay.h>
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
bool mirrorX = false,
|
||||
bool mirrorY = false,
|
||||
bool invertColor = false,
|
||||
uint32_t bufferSize = 0 // Size in pixel count. 0 means default, which is 1/20 of the screen size
|
||||
uint32_t bufferSize = 0 // Size in pixel count. 0 means default, which is 1/10 of the screen size
|
||||
) : spiHostDevice(spiHostDevice),
|
||||
csPin(csPin),
|
||||
dcPin(dcPin),
|
||||
@@ -75,7 +75,6 @@ private:
|
||||
public:
|
||||
|
||||
explicit Ili9488Display(std::unique_ptr<Configuration> inConfiguration) :
|
||||
EspLcdDisplay(tt::hal::spi::getLock(inConfiguration->spiHostDevice)),
|
||||
configuration(std::move(inConfiguration)
|
||||
) {
|
||||
assert(configuration != nullptr);
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <Tactility/RecursiveMutex.h>
|
||||
#include <EspLcdDisplayDriver.h>
|
||||
#include <esp_lcd_panel_rgb.h>
|
||||
#include <esp_lvgl_port_disp.h>
|
||||
|
||||
class RgbDisplay final : public tt::hal::display::DisplayDevice {
|
||||
|
||||
std::shared_ptr<tt::Lock> lock = std::make_shared<tt::RecursiveMutex>();
|
||||
|
||||
public:
|
||||
|
||||
struct BufferConfiguration final {
|
||||
@@ -75,7 +72,7 @@ public:
|
||||
assert(configuration != nullptr);
|
||||
}
|
||||
|
||||
~RgbDisplay();
|
||||
~RgbDisplay() override;
|
||||
|
||||
std::string getName() const override { return "RGB Display"; }
|
||||
std::string getDescription() const override { return "RGB Display"; }
|
||||
@@ -108,7 +105,7 @@ public:
|
||||
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable getDisplayDriver() override {
|
||||
if (displayDriver == nullptr) {
|
||||
auto config = getLvglPortDisplayConfig();
|
||||
displayDriver = std::make_shared<EspLcdDisplayDriver>(panelHandle, lock, config.hres, config.vres, tt::hal::display::ColorFormat::RGB888);
|
||||
displayDriver = std::make_shared<EspLcdDisplayDriver>(panelHandle, config.hres, config.vres, tt::hal::display::ColorFormat::RGB888);
|
||||
}
|
||||
return displayDriver;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,6 @@ private:
|
||||
public:
|
||||
|
||||
explicit Ssd1306Display(std::unique_ptr<Configuration> inConfiguration) :
|
||||
EspLcdDisplay(nullptr),
|
||||
configuration(std::move(inConfiguration))
|
||||
{
|
||||
assert(configuration != nullptr);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/spi/Spi.h"
|
||||
|
||||
#include <EspLcdDisplay.h>
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/spi_common.h>
|
||||
#include <esp_lcd_panel_io.h>
|
||||
#include <esp_lcd_types.h>
|
||||
#include <functional>
|
||||
@@ -13,8 +12,6 @@
|
||||
|
||||
class St7735Display final : public EspLcdDisplay {
|
||||
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
|
||||
public:
|
||||
|
||||
class Configuration {
|
||||
@@ -88,12 +85,8 @@ private:
|
||||
public:
|
||||
|
||||
explicit St7735Display(std::unique_ptr<Configuration> inConfiguration) :
|
||||
EspLcdDisplay(tt::hal::spi::getLock(inConfiguration->spiHostDevice)),
|
||||
configuration(std::move(inConfiguration)
|
||||
) {
|
||||
assert(configuration != nullptr);
|
||||
assert(getLock() != nullptr);
|
||||
}
|
||||
) {}
|
||||
|
||||
std::string getName() const override { return "ST7735"; }
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
class St7789Display final : public EspLcdSpiDisplay {
|
||||
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
|
||||
public:
|
||||
|
||||
/** Minimal set of overrides for EspLcdConfiguration */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <Tactility/hal/spi/Spi.h>
|
||||
#include <driver/spi_common.h>
|
||||
|
||||
#include <EspLcdDisplay.h>
|
||||
#include <functional>
|
||||
@@ -78,7 +78,6 @@ private:
|
||||
public:
|
||||
|
||||
explicit St7796Display(std::unique_ptr<Configuration> inConfiguration) :
|
||||
EspLcdDisplay(tt::hal::spi::getLock(inConfiguration->spiHostDevice)),
|
||||
configuration(std::move(inConfiguration)
|
||||
) {
|
||||
assert(configuration != nullptr);
|
||||
|
||||
@@ -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