Merge develop into main (#313)
- Add app path get() functions to `TactilityC` - Improved `Dispatcher` and `DispatcherThread` - Improved `PubSub` (type safety) - Created test for `DispatcherThread` and `PubSub` - Save properties files on app exit (various apps) by posting it to the main dispatcher (fixes UI hanging briefly on app exit) - Fixed bug with `SystemSettings` being read from the wrong file path. - `loadPropertiesFile()` now uses `file::readLines()` instead of doing that manually - Increased timer task stack size (required due to issues when reading a properties file for the very first time) - General cleanup - Created `EstimatedPower` driver that uses an ADC pin to measure voltage and estimate the battery charge that is left. - Cleanup of T-Deck board (updated to new style)
This commit is contained in:
committed by
GitHub
parent
5cc5b50694
commit
0f8380e8fe
@@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||
idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility EspLcdCompat ST7789 GT911 PwmBacklight driver esp_adc
|
||||
REQUIRES Tactility EspLcdCompat ST7789 GT911 PwmBacklight EstimatedPower driver
|
||||
)
|
||||
|
||||
@@ -30,7 +30,7 @@ static bool powerOn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tdeckInit() {
|
||||
bool initBoot() {
|
||||
ESP_LOGI(TAG, LOG_MESSAGE_POWER_ON_START);
|
||||
if (!powerOn()) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_POWER_ON_FAILED);
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "hal/TdeckDisplay.h"
|
||||
#include "hal/TdeckDisplayConstants.h"
|
||||
#include "hal/TdeckKeyboard.h"
|
||||
#include "hal/TdeckPower.h"
|
||||
#include "hal/TdeckSdCard.h"
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
#define TDECK_SPI_TRANSFER_SIZE_LIMIT (TDECK_LCD_HORIZONTAL_RESOLUTION * TDECK_LCD_SPI_TRANSFER_HEIGHT * (LV_COLOR_DEPTH / 8))
|
||||
#include "devices/Display.h"
|
||||
#include "devices/Power.h"
|
||||
#include "devices/Sdcard.h"
|
||||
#include "devices/TdeckKeyboard.h"
|
||||
|
||||
bool tdeckInit();
|
||||
#define TDECK_SPI_TRANSFER_SIZE_LIMIT (320 * 240 * (LV_COLOR_DEPTH / 8))
|
||||
|
||||
bool initBoot();
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> createDevices() {
|
||||
return {
|
||||
createPower(),
|
||||
createDisplay(),
|
||||
std::make_shared<TdeckKeyboard>(),
|
||||
createSdCard()
|
||||
};
|
||||
}
|
||||
|
||||
extern const Configuration lilygo_tdeck = {
|
||||
.initBoot = tdeckInit,
|
||||
.createDisplay = createDisplay,
|
||||
.createKeyboard = createKeyboard,
|
||||
.sdcard = createTdeckSdCard(),
|
||||
.power = tdeck_get_power,
|
||||
.initBoot = initBoot,
|
||||
.createDevices = createDevices,
|
||||
.i2c = {
|
||||
i2c::Configuration {
|
||||
.name = "Internal",
|
||||
|
||||
+7
-5
@@ -1,13 +1,15 @@
|
||||
#include "TdeckDisplay.h"
|
||||
#include "TdeckDisplayConstants.h"
|
||||
#include "Display.h"
|
||||
|
||||
#include <Gt911Touch.h>
|
||||
#include <PwmBacklight.h>
|
||||
#include <St7789Display.h>
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
|
||||
#define TAG "tdeck_display"
|
||||
#define TDECK_LCD_SPI_HOST SPI2_HOST
|
||||
#define TDECK_LCD_PIN_CS GPIO_NUM_12
|
||||
#define TDECK_LCD_PIN_DC GPIO_NUM_11 // RS
|
||||
#define TDECK_LCD_HORIZONTAL_RESOLUTION 320
|
||||
#define TDECK_LCD_VERTICAL_RESOLUTION 240
|
||||
#define TDECK_LCD_SPI_TRANSFER_HEIGHT (TDECK_LCD_VERTICAL_RESOLUTION / 10)
|
||||
|
||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||
// Note for future changes: Reset pin is 48 and interrupt pin is 47
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/display/DisplayDevice.h"
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <ChargeFromAdcVoltage.h>
|
||||
#include <EstimatedPower.h>
|
||||
|
||||
std::shared_ptr<PowerDevice> createPower() {
|
||||
ChargeFromAdcVoltage::Configuration configuration;
|
||||
// 2.0 ratio, but +.11 added as display voltage sag compensation.
|
||||
configuration.adcMultiplier = 2.11;
|
||||
|
||||
return std::make_shared<EstimatedPower>(configuration);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/power/PowerDevice.h>
|
||||
|
||||
std::shared_ptr<tt::hal::power::PowerDevice> createPower();
|
||||
+2
-4
@@ -1,17 +1,15 @@
|
||||
#include "TdeckSdCard.h"
|
||||
#include "Sdcard.h"
|
||||
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||
|
||||
#include <esp_vfs_fat.h>
|
||||
|
||||
using tt::hal::sdcard::SpiSdCardDevice;
|
||||
|
||||
constexpr auto TDECK_SDCARD_PIN_CS = GPIO_NUM_39;
|
||||
constexpr auto TDECK_LCD_PIN_CS = GPIO_NUM_12;
|
||||
constexpr auto TDECK_RADIO_PIN_CS = GPIO_NUM_9;
|
||||
|
||||
std::shared_ptr<SdCardDevice> createTdeckSdCard() {
|
||||
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
|
||||
TDECK_SDCARD_PIN_CS,
|
||||
GPIO_NUM_NC,
|
||||
+1
-1
@@ -4,4 +4,4 @@
|
||||
|
||||
using tt::hal::sdcard::SdCardDevice;
|
||||
|
||||
std::shared_ptr<SdCardDevice> createTdeckSdCard();
|
||||
std::shared_ptr<SdCardDevice> createSdCard();
|
||||
+3
-8
@@ -2,10 +2,9 @@
|
||||
#include <Tactility/hal/i2c/I2c.h>
|
||||
#include <driver/i2c.h>
|
||||
|
||||
#define TAG "tdeck_keyboard"
|
||||
|
||||
#define TDECK_KEYBOARD_I2C_BUS_HANDLE I2C_NUM_0
|
||||
#define TDECK_KEYBOARD_SLAVE_ADDRESS 0x55
|
||||
constexpr auto* TAG = "TdeckKeyboard";
|
||||
constexpr auto TDECK_KEYBOARD_I2C_BUS_HANDLE = I2C_NUM_0;
|
||||
constexpr auto TDECK_KEYBOARD_SLAVE_ADDRESS = 0x55;
|
||||
|
||||
static bool keyboard_i2c_read(uint8_t* output) {
|
||||
return tt::hal::i2c::masterRead(TDECK_KEYBOARD_I2C_BUS_HANDLE, TDECK_KEYBOARD_SLAVE_ADDRESS, output, 1, 100 / portTICK_PERIOD_MS);
|
||||
@@ -61,7 +60,3 @@ bool TdeckKeyboard::stopLvgl() {
|
||||
bool TdeckKeyboard::isAttached() const {
|
||||
return tt::hal::i2c::masterHasDeviceAtAddress(TDECK_KEYBOARD_I2C_BUS_HANDLE, TDECK_KEYBOARD_SLAVE_ADDRESS, 100);
|
||||
}
|
||||
|
||||
std::shared_ptr<tt::hal::keyboard::KeyboardDevice> createKeyboard() {
|
||||
return std::make_shared<TdeckKeyboard>();
|
||||
}
|
||||
-4
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <Tactility/hal/keyboard/KeyboardDevice.h>
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <esp_lcd_panel_io_interface.h>
|
||||
#include <esp_lcd_touch.h>
|
||||
|
||||
class TdeckKeyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||
|
||||
@@ -19,5 +17,3 @@ public:
|
||||
bool isAttached() const override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
};
|
||||
|
||||
std::shared_ptr<tt::hal::keyboard::KeyboardDevice> createKeyboard();
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define TDECK_LCD_SPI_HOST SPI2_HOST
|
||||
#define TDECK_LCD_PIN_CS GPIO_NUM_12
|
||||
#define TDECK_LCD_PIN_DC GPIO_NUM_11 // RS
|
||||
#define TDECK_LCD_HORIZONTAL_RESOLUTION 320
|
||||
#define TDECK_LCD_VERTICAL_RESOLUTION 240
|
||||
#define TDECK_LCD_SPI_TRANSFER_HEIGHT (TDECK_LCD_VERTICAL_RESOLUTION / 10)
|
||||
@@ -1,130 +0,0 @@
|
||||
#include "TdeckPower.h"
|
||||
|
||||
#include <Tactility/Log.h>
|
||||
|
||||
#define TAG "power"
|
||||
|
||||
/**
|
||||
* 2.0 ratio, but +.11 added as display voltage sag compensation.
|
||||
*/
|
||||
#define ADC_MULTIPLIER 2.11
|
||||
|
||||
#define ADC_REF_VOLTAGE 3.3f
|
||||
#define BATTERY_VOLTAGE_MIN 3.2f
|
||||
#define BATTERY_VOLTAGE_MAX 4.2f
|
||||
|
||||
static adc_oneshot_unit_init_cfg_t adcConfig = {
|
||||
.unit_id = ADC_UNIT_1,
|
||||
.clk_src = ADC_RTC_CLK_SRC_DEFAULT,
|
||||
.ulp_mode = ADC_ULP_MODE_DISABLE,
|
||||
};
|
||||
|
||||
static adc_oneshot_chan_cfg_t adcChannelConfig = {
|
||||
.atten = ADC_ATTEN_DB_12,
|
||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||
};
|
||||
|
||||
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);
|
||||
TT_LOG_V(TAG, "mV = %lu, scaled = %.2f, factor = %.2f, result = %d", milliVolt, volts, voltage_factor, charge_level);
|
||||
return charge_level;
|
||||
}
|
||||
|
||||
TdeckPower::TdeckPower() {
|
||||
if (adc_oneshot_new_unit(&adcConfig, &adcHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "ADC config failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (adc_oneshot_config_channel(adcHandle, ADC_CHANNEL_3, &adcChannelConfig) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "ADC channel config failed");
|
||||
|
||||
adc_oneshot_del_unit(adcHandle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TdeckPower::~TdeckPower() {
|
||||
if (adcHandle) {
|
||||
adc_oneshot_del_unit(adcHandle);
|
||||
}
|
||||
}
|
||||
|
||||
bool TdeckPower::supportsMetric(MetricType type) const {
|
||||
switch (type) {
|
||||
using enum MetricType;
|
||||
case BatteryVoltage:
|
||||
case ChargeLevel:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false; // Safety guard for when new enum values are introduced
|
||||
}
|
||||
|
||||
bool TdeckPower::getMetric(MetricType type, MetricData& data) {
|
||||
switch (type) {
|
||||
using enum MetricType;
|
||||
case BatteryVoltage:
|
||||
return readBatteryVoltageSampled(data.valueAsUint32);
|
||||
case ChargeLevel:
|
||||
if (readBatteryVoltageSampled(data.valueAsUint32)) {
|
||||
data.valueAsUint32 = estimateChargeLevelFromVoltage(data.valueAsUint32);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false; // Safety guard for when new enum values are introduced
|
||||
}
|
||||
|
||||
bool TdeckPower::readBatteryVoltageOnce(uint32_t& output) {
|
||||
int raw;
|
||||
if (adc_oneshot_read(adcHandle, ADC_CHANNEL_3, &raw) == ESP_OK) {
|
||||
output = ADC_MULTIPLIER * ((1000.f * ADC_REF_VOLTAGE) / 4096.f) * (float)raw;
|
||||
TT_LOG_V(TAG, "Raw = %d, voltage = %lu", raw, output);
|
||||
return true;
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Read failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_VOLTAGE_SAMPLES 15
|
||||
|
||||
bool TdeckPower::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;
|
||||
}
|
||||
}
|
||||
|
||||
static std::shared_ptr<PowerDevice> power;
|
||||
|
||||
std::shared_ptr<PowerDevice> tdeck_get_power() {
|
||||
if (power == nullptr) {
|
||||
power = std::make_shared<TdeckPower>();
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/power/PowerDevice.h"
|
||||
#include <esp_adc/adc_oneshot.h>
|
||||
#include <memory>
|
||||
|
||||
using tt::hal::power::PowerDevice;
|
||||
|
||||
class TdeckPower : public PowerDevice {
|
||||
|
||||
adc_oneshot_unit_handle_t adcHandle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
TdeckPower();
|
||||
~TdeckPower();
|
||||
|
||||
std::string getName() const final { return "ADC Power Measurement"; }
|
||||
std::string getDescription() const final { return "Power measurement interface via ADC pin"; }
|
||||
|
||||
bool supportsMetric(MetricType type) const override;
|
||||
bool getMetric(MetricType type, MetricData& data) override;
|
||||
|
||||
private:
|
||||
|
||||
bool readBatteryVoltageSampled(uint32_t& output);
|
||||
bool readBatteryVoltageOnce(uint32_t& output);
|
||||
};
|
||||
|
||||
std::shared_ptr<PowerDevice> tdeck_get_power();
|
||||
Reference in New Issue
Block a user