New kernel drivers and device migrations (#563)
This commit is contained in:
committed by
GitHub
parent
955416dac8
commit
8af6204ba1
@@ -1,7 +1,6 @@
|
||||
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||
file(GLOB_RECURSE SOURCE_FILES source/*.c*)
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility ButtonControl XPT2046SoftSPI PwmBacklight EstimatedPower ST7789-i8080 driver vfs fatfs
|
||||
REQUIRES TactilityKernel driver
|
||||
)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#include "devices/Power.h"
|
||||
#include "devices/Display.h"
|
||||
|
||||
#include <ButtonControl.h>
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
|
||||
bool initBoot();
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
static std::vector<std::shared_ptr<tt::hal::Device>> createDevices() {
|
||||
return {
|
||||
createDisplay(),
|
||||
std::make_shared<Power>(),
|
||||
ButtonControl::createOneButtonControl(0)
|
||||
};
|
||||
}
|
||||
|
||||
extern const Configuration hardwareConfiguration = {
|
||||
.initBoot = initBoot,
|
||||
.createDevices = createDevices
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
#include "devices/Power.h"
|
||||
#include "devices/Display.h"
|
||||
|
||||
#include "PwmBacklight.h"
|
||||
#include <Tactility/SystemEvents.h>
|
||||
#include <tactility/log.h>
|
||||
#include <Tactility/TactilityCore.h>
|
||||
|
||||
#define TAG "thmi"
|
||||
|
||||
static bool powerOn() {
|
||||
gpio_config_t power_signal_config = {
|
||||
.pin_bit_mask = (1ULL << THMI_POWERON_GPIO) | (1ULL << THMI_POWEREN_GPIO),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
|
||||
if (gpio_config(&power_signal_config) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gpio_set_level(THMI_POWERON_GPIO, 1) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gpio_set_level(THMI_POWEREN_GPIO, 1) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initBoot() {
|
||||
LOG_I(TAG, "Powering on the board...");
|
||||
if (!powerOn()) {
|
||||
LOG_E(TAG, "Failed to power on the board.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!driver::pwmbacklight::init(DISPLAY_BL, 30000)) {
|
||||
LOG_E(TAG, "Failed to initialize backlight.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#include <Xpt2046SoftSpi.h>
|
||||
#include <Tactility/hal/touch/TouchDevice.h>
|
||||
|
||||
#include "Display.h"
|
||||
#include "PwmBacklight.h"
|
||||
#include "St7789i8080Display.h"
|
||||
|
||||
static bool touchSpiInitialized = false;
|
||||
|
||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||
auto config = std::make_unique<Xpt2046SoftSpi::Configuration>(
|
||||
TOUCH_MOSI_PIN,
|
||||
TOUCH_MISO_PIN,
|
||||
TOUCH_SCK_PIN,
|
||||
TOUCH_CS_PIN,
|
||||
DISPLAY_HORIZONTAL_RESOLUTION,
|
||||
DISPLAY_VERTICAL_RESOLUTION
|
||||
);
|
||||
|
||||
return std::make_shared<Xpt2046SoftSpi>(std::move(config));
|
||||
}
|
||||
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||
// Create configuration
|
||||
auto config = St7789i8080Display::Configuration(
|
||||
DISPLAY_CS, // CS
|
||||
DISPLAY_DC, // DC
|
||||
DISPLAY_WR, // WR
|
||||
DISPLAY_RD, // RD
|
||||
{ DISPLAY_I80_D0, DISPLAY_I80_D1, DISPLAY_I80_D2, DISPLAY_I80_D3,
|
||||
DISPLAY_I80_D4, DISPLAY_I80_D5, DISPLAY_I80_D6, DISPLAY_I80_D7 }, // D0..D7
|
||||
DISPLAY_RST, // RST
|
||||
DISPLAY_BL // BL
|
||||
);
|
||||
|
||||
// Set resolution explicitly
|
||||
config.horizontalResolution = DISPLAY_HORIZONTAL_RESOLUTION;
|
||||
config.verticalResolution = DISPLAY_VERTICAL_RESOLUTION;
|
||||
config.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||
config.touch = createTouch();
|
||||
config.invertColor = false;
|
||||
|
||||
auto display = std::make_shared<St7789i8080Display>(config);
|
||||
return display;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#pragma once
|
||||
#include <driver/gpio.h>
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
|
||||
#include "driver/spi_common.h"
|
||||
|
||||
class St7789i8080Display;
|
||||
|
||||
constexpr auto DISPLAY_CS = GPIO_NUM_6;
|
||||
constexpr auto DISPLAY_DC = GPIO_NUM_7;
|
||||
constexpr auto DISPLAY_WR = GPIO_NUM_8;
|
||||
constexpr auto DISPLAY_RD = GPIO_NUM_NC;
|
||||
constexpr auto DISPLAY_RST = GPIO_NUM_NC;
|
||||
constexpr auto DISPLAY_BL = GPIO_NUM_38;
|
||||
constexpr auto DISPLAY_I80_D0 = GPIO_NUM_48;
|
||||
constexpr auto DISPLAY_I80_D1 = GPIO_NUM_47;
|
||||
constexpr auto DISPLAY_I80_D2 = GPIO_NUM_39;
|
||||
constexpr auto DISPLAY_I80_D3 = GPIO_NUM_40;
|
||||
constexpr auto DISPLAY_I80_D4 = GPIO_NUM_41;
|
||||
constexpr auto DISPLAY_I80_D5 = GPIO_NUM_42;
|
||||
constexpr auto DISPLAY_I80_D6 = GPIO_NUM_45;
|
||||
constexpr auto DISPLAY_I80_D7 = GPIO_NUM_46;
|
||||
constexpr auto DISPLAY_HORIZONTAL_RESOLUTION = 240;
|
||||
constexpr auto DISPLAY_VERTICAL_RESOLUTION = 320;
|
||||
|
||||
// Touch (XPT2046, resistive)
|
||||
constexpr auto TOUCH_SPI_HOST = SPI2_HOST;
|
||||
constexpr auto TOUCH_MISO_PIN = GPIO_NUM_4;
|
||||
constexpr auto TOUCH_MOSI_PIN = GPIO_NUM_3;
|
||||
constexpr auto TOUCH_SCK_PIN = GPIO_NUM_1;
|
||||
constexpr auto TOUCH_CS_PIN = GPIO_NUM_2;
|
||||
constexpr auto TOUCH_IRQ_PIN = GPIO_NUM_9;
|
||||
|
||||
// Factory function for registration
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||
@@ -1,90 +0,0 @@
|
||||
#include "Power.h"
|
||||
|
||||
#include <driver/adc.h>
|
||||
#include <tactility/log.h>
|
||||
|
||||
constexpr auto* TAG = "Power";
|
||||
|
||||
bool Power::adcInitCalibration() {
|
||||
bool calibrated = false;
|
||||
|
||||
esp_err_t efuse_read_result = esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP_FIT);
|
||||
if (efuse_read_result == ESP_ERR_NOT_SUPPORTED) {
|
||||
LOG_W(TAG, "Calibration scheme not supported, skip software calibration");
|
||||
} else if (efuse_read_result == ESP_ERR_INVALID_VERSION) {
|
||||
LOG_W(TAG, "eFuse not burnt, skip software calibration");
|
||||
} else if (efuse_read_result == ESP_OK) {
|
||||
calibrated = true;
|
||||
LOG_I(TAG, "Calibration success");
|
||||
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, static_cast<adc_bits_width_t>(ADC_WIDTH_BIT_DEFAULT), 0, &adcCharacteristics);
|
||||
} else {
|
||||
LOG_W(TAG, "eFuse read failed, skipping calibration");
|
||||
}
|
||||
|
||||
return calibrated;
|
||||
}
|
||||
|
||||
uint32_t Power::adcReadValue() const {
|
||||
int adc_raw = adc1_get_raw(ADC1_CHANNEL_4);
|
||||
LOG_D(TAG, "Raw data: %d", adc_raw);
|
||||
|
||||
uint32_t voltage;
|
||||
|
||||
if (calibrated) {
|
||||
voltage = esp_adc_cal_raw_to_voltage(adc_raw, &adcCharacteristics);
|
||||
LOG_D(TAG, "Calibrated data: %d mV", (int)voltage);
|
||||
} else {
|
||||
voltage = (adc_raw * 3300) / 4095; // fallback
|
||||
LOG_D(TAG, "Estimated data: %d mV", (int)voltage);
|
||||
}
|
||||
|
||||
return voltage;
|
||||
}
|
||||
|
||||
bool Power::ensureInitialized() {
|
||||
if (!initialized) {
|
||||
|
||||
if (adc1_config_width(ADC_WIDTH_BIT_12) != ESP_OK) {
|
||||
LOG_E(TAG, "ADC1 config width failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_11) != ESP_OK) {
|
||||
LOG_E(TAG, "ADC1 config attenuation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
calibrated = adcInitCalibration();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Power::supportsMetric(MetricType type) const {
|
||||
switch (type) {
|
||||
using enum MetricType;
|
||||
case BatteryVoltage:
|
||||
case ChargeLevel:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Power::getMetric(MetricType type, MetricData& data) {
|
||||
if (!ensureInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MetricType::BatteryVoltage:
|
||||
data.valueAsUint32 = adcReadValue() * 2;
|
||||
return true;
|
||||
case MetricType::ChargeLevel:
|
||||
data.valueAsUint8 = chargeFromAdcVoltage.estimateCharge(adcReadValue() * 2);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <esp_adc_cal.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <ChargeFromVoltage.h>
|
||||
#include <Tactility/hal/power/PowerDevice.h>
|
||||
|
||||
constexpr auto THMI_POWEREN_GPIO = GPIO_NUM_10;
|
||||
constexpr auto THMI_POWERON_GPIO = GPIO_NUM_14;
|
||||
|
||||
using tt::hal::power::PowerDevice;
|
||||
|
||||
class Power final : public PowerDevice {
|
||||
|
||||
ChargeFromVoltage chargeFromAdcVoltage = ChargeFromVoltage(3.3f, 4.2f);
|
||||
esp_adc_cal_characteristics_t adcCharacteristics;
|
||||
bool initialized = false;
|
||||
bool calibrated = false;
|
||||
|
||||
bool adcInitCalibration();
|
||||
uint32_t adcReadValue() const;
|
||||
|
||||
bool ensureInitialized();
|
||||
|
||||
public:
|
||||
|
||||
std::string getName() const override { return "T-HMI Power"; }
|
||||
std::string getDescription() const override { return "Power measurement via ADC"; }
|
||||
|
||||
bool supportsMetric(MetricType type) const override;
|
||||
bool getMetric(MetricType type, MetricData& data) override;
|
||||
};
|
||||
@@ -12,10 +12,15 @@ hardware.tinyUsb=true
|
||||
hardware.esptoolFlashFreq=120M
|
||||
hardware.bluetooth=true
|
||||
|
||||
dependencies.useDeprecatedHal=false
|
||||
|
||||
storage.userDataLocation=SD
|
||||
|
||||
display.size=2.8"
|
||||
display.shape=rectangle
|
||||
display.dpi=125
|
||||
|
||||
touch.calibrationSupported=true
|
||||
touch.calibrationRequired=false
|
||||
|
||||
lvgl.colorDepth=16
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
dependencies:
|
||||
- Platforms/platform-esp32
|
||||
- Drivers/xpt2046-softspi-module
|
||||
- Drivers/st7789-i8080-module
|
||||
- Drivers/button-control-module
|
||||
dts: lilygo,thmi.dts
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/battery_sense.h>
|
||||
#include <tactility/bindings/esp32_adc_oneshot.h>
|
||||
#include <tactility/bindings/esp32_ble.h>
|
||||
#include <tactility/bindings/esp32_wifi_pinned.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_sdmmc.h>
|
||||
#include <tactility/bindings/esp32_spi.h>
|
||||
#include <tactility/bindings/display_placeholder.h>
|
||||
#include <tactility/bindings/pointer_placeholder.h>
|
||||
#include <tactility/bindings/esp32_i8080.h>
|
||||
#include <tactility/bindings/esp32_ledc_backlight.h>
|
||||
#include <tactility/bindings/gpio_hog.h>
|
||||
#include <bindings/button_control.h>
|
||||
#include <bindings/st7789_i8080.h>
|
||||
#include <bindings/xpt2046_softspi.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@@ -28,23 +33,84 @@
|
||||
compatible = "espressif,esp32-gpio";
|
||||
gpio-count = <49>;
|
||||
};
|
||||
|
||||
spi0 {
|
||||
compatible = "espressif,esp32-spi";
|
||||
host = <SPI2_HOST>;
|
||||
cs-gpios = <&gpio0 6 GPIO_FLAG_NONE>, // Display
|
||||
<&gpio0 2 GPIO_FLAG_NONE>; // Touch
|
||||
pin-mosi = <&gpio0 3 GPIO_FLAG_NONE>;
|
||||
pin-miso = <&gpio0 4 GPIO_FLAG_NONE>;
|
||||
pin-sclk = <&gpio0 1 GPIO_FLAG_NONE>;
|
||||
|
||||
// Board power-enable pins. Must be asserted before the i8080 bus/display below start, since
|
||||
// devicetree devices are constructed and started earlier (kernel_init()) than the deprecated
|
||||
// HAL's initBoot() used to run. gpio-hog nodes run in declaration order, so they must stay
|
||||
// before the i8080 bus node.
|
||||
power_on {
|
||||
compatible = "tactility,gpio-hog";
|
||||
pin = <&gpio0 14 GPIO_FLAG_NONE>;
|
||||
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
||||
};
|
||||
|
||||
power_en {
|
||||
compatible = "tactility,gpio-hog";
|
||||
pin = <&gpio0 10 GPIO_FLAG_NONE>;
|
||||
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
||||
};
|
||||
|
||||
adc0 {
|
||||
compatible = "espressif,esp32-adc-oneshot";
|
||||
unit-id = <ADC_UNIT_1>;
|
||||
channels = <ADC_CHANNEL_4 ADC_ATTEN_DB_12 ADC_BITWIDTH_DEFAULT>;
|
||||
};
|
||||
|
||||
// Battery voltage sits behind a 2:1 divider before reaching the ADC (see the deprecated HAL's
|
||||
// old Power.cpp: adcReadValue() * 2). 3300mV matches its uncalibrated fallback reference
|
||||
// voltage. Charge-percent curve is battery-sense's own fixed 3200-4200mV estimate (see
|
||||
// TactilityKernel/source/drivers/battery_sense.cpp) rather than the old driver's 3300-4200mV
|
||||
// ChargeFromVoltage curve - a shared kernel driver, not a per-board tunable.
|
||||
battery-sense {
|
||||
compatible = "battery-sense";
|
||||
io-channel = <&adc0 0>;
|
||||
reference-voltage-mv = <3300>;
|
||||
multiplier = <2000>;
|
||||
};
|
||||
|
||||
display_backlight {
|
||||
compatible = "espressif,esp32-ledc-backlight";
|
||||
// Off by default so display power-on won't show the screen from before the last power loss.
|
||||
// The display backlight is turned on during the boot process.
|
||||
status = "disabled";
|
||||
pin-backlight = <&gpio0 38 GPIO_FLAG_NONE>;
|
||||
frequency-hz = <30000>;
|
||||
};
|
||||
|
||||
i8080_0 {
|
||||
compatible = "espressif,esp32-i8080";
|
||||
pin-dc = <&gpio0 7 GPIO_FLAG_NONE>;
|
||||
pin-wr = <&gpio0 8 GPIO_FLAG_NONE>;
|
||||
pin-d0 = <&gpio0 48 GPIO_FLAG_NONE>;
|
||||
pin-d1 = <&gpio0 47 GPIO_FLAG_NONE>;
|
||||
pin-d2 = <&gpio0 39 GPIO_FLAG_NONE>;
|
||||
pin-d3 = <&gpio0 40 GPIO_FLAG_NONE>;
|
||||
pin-d4 = <&gpio0 41 GPIO_FLAG_NONE>;
|
||||
pin-d5 = <&gpio0 42 GPIO_FLAG_NONE>;
|
||||
pin-d6 = <&gpio0 45 GPIO_FLAG_NONE>;
|
||||
pin-d7 = <&gpio0 46 GPIO_FLAG_NONE>;
|
||||
// horizontal-resolution * vertical-resolution / 10 (partial buffer) * 2 bytes/pixel
|
||||
max-transfer-bytes = <15360>;
|
||||
cs-gpios = <&gpio0 6 GPIO_FLAG_NONE>;
|
||||
|
||||
display@0 {
|
||||
compatible = "display-placeholder";
|
||||
compatible = "sitronix,st7789-i8080";
|
||||
horizontal-resolution = <240>;
|
||||
vertical-resolution = <320>;
|
||||
pixel-clock-hz = <16000000>;
|
||||
backlight = <&display_backlight>;
|
||||
gamma-curve = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
touch@1 {
|
||||
compatible = "pointer-placeholder";
|
||||
};
|
||||
touch {
|
||||
compatible = "xptek,xpt2046-softspi";
|
||||
pin-mosi = <&gpio0 3 GPIO_FLAG_NONE>;
|
||||
pin-miso = <&gpio0 4 GPIO_FLAG_NONE>;
|
||||
pin-sck = <&gpio0 1 GPIO_FLAG_NONE>;
|
||||
pin-cs = <&gpio0 2 GPIO_FLAG_NONE>;
|
||||
x-max = <240>;
|
||||
y-max = <320>;
|
||||
};
|
||||
|
||||
sdmmc0 {
|
||||
|
||||
Reference in New Issue
Block a user