From 6a97ed15c66649424454d634f601a9213ef1cb81 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sat, 10 Jan 2026 21:24:28 +0100 Subject: [PATCH] M5Stack Tab5 WIP --- .github/workflows/build.yml | 1 + .../guition-jc1060p470ciwy/device.properties | 2 +- Devices/m5stack-tab5/CMakeLists.txt | 7 + Devices/m5stack-tab5/Source/Configuration.cpp | 102 ++++++++++++ .../m5stack-tab5/Source/devices/Display.cpp | 57 +++++++ Devices/m5stack-tab5/Source/devices/Display.h | 6 + .../Source/devices/Ili9881cDisplay.cpp | 148 ++++++++++++++++++ .../Source/devices/Ili9881cDisplay.h | 44 ++++++ .../m5stack-tab5/Source/devices/SdCard.cpp | 127 +++++++++++++++ Devices/m5stack-tab5/Source/devices/SdCard.h | 6 + Devices/m5stack-tab5/device.properties | 28 ++++ Firmware/Kconfig | 2 + Firmware/idf_component.yml | 5 + .../Source/app/appsettings/AppSettings.cpp | 2 +- Tactility/Source/hal/Hal.cpp | 4 +- 15 files changed, 537 insertions(+), 4 deletions(-) create mode 100644 Devices/m5stack-tab5/CMakeLists.txt create mode 100644 Devices/m5stack-tab5/Source/Configuration.cpp create mode 100644 Devices/m5stack-tab5/Source/devices/Display.cpp create mode 100644 Devices/m5stack-tab5/Source/devices/Display.h create mode 100644 Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.cpp create mode 100644 Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.h create mode 100644 Devices/m5stack-tab5/Source/devices/SdCard.cpp create mode 100644 Devices/m5stack-tab5/Source/devices/SdCard.h create mode 100644 Devices/m5stack-tab5/device.properties diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c3441d4..7493cd9b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,6 +62,7 @@ jobs: { id: m5stack-cores3, arch: esp32s3 }, { id: m5stack-stickc-plus, arch: esp32 }, { id: m5stack-stickc-plus2, arch: esp32 }, + { id: m5stack-tab5, arch: esp32p4 }, { id: unphone, arch: esp32s3 }, { id: waveshare-esp32-s3-geek, arch: esp32s3 }, { id: waveshare-s3-lcd-13, arch: esp32s3 }, diff --git a/Devices/guition-jc1060p470ciwy/device.properties b/Devices/guition-jc1060p470ciwy/device.properties index ae177ffb..a5a8abcc 100644 --- a/Devices/guition-jc1060p470ciwy/device.properties +++ b/Devices/guition-jc1060p470ciwy/device.properties @@ -1,6 +1,6 @@ [general] vendor=Guition -name=JC1060P470CIWY +name=JC1060P470C-I-W-Y [hardware] target=ESP32P4 diff --git a/Devices/m5stack-tab5/CMakeLists.txt b/Devices/m5stack-tab5/CMakeLists.txt new file mode 100644 index 00000000..c84b1ada --- /dev/null +++ b/Devices/m5stack-tab5/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB_RECURSE SOURCE_FILES Source/*.c*) + +idf_component_register( + SRCS ${SOURCE_FILES} + INCLUDE_DIRS "Source" + REQUIRES Tactility esp_lvgl_port esp_lcd EspLcdCompat esp_lcd_ili9881c GT911 PwmBacklight driver vfs fatfs +) diff --git a/Devices/m5stack-tab5/Source/Configuration.cpp b/Devices/m5stack-tab5/Source/Configuration.cpp new file mode 100644 index 00000000..2387ebd5 --- /dev/null +++ b/Devices/m5stack-tab5/Source/Configuration.cpp @@ -0,0 +1,102 @@ +#include "devices/Display.h" +#include "devices/SdCard.h" + +#include + +using namespace tt::hal; + +static const auto LOGGER = tt::Logger("Tab5"); + +static DeviceVector createDevices() { + return { + createDisplay(), + createSdCard(), + }; +} + +static bool initBoot() { + // From https://github.com/m5stack/M5GFX/blob/03565ccc96cb0b73c8b157f5ec3fbde439b034ad/src/M5GFX.cpp + static constexpr uint8_t reg_data_io1_1[] = { + 0x03, 0b01111111, 0, // PI4IO_REG_IO_DIR + 0x05, 0b01000110, 0, // PI4IO_REG_OUT_SET (bit4=LCD Reset,bit5=GT911 TouchReset LOW) + 0x07, 0b00000000, 0, // PI4IO_REG_OUT_H_IM + 0x0D, 0b01111111, 0, // PI4IO_REG_PULL_SEL + 0x0B, 0b01111111, 0, // PI4IO_REG_PULL_EN + 0xFF,0xFF,0xFF, + }; + + // From https://github.com/m5stack/M5GFX/blob/03565ccc96cb0b73c8b157f5ec3fbde439b034ad/src/M5GFX.cpp + static constexpr uint8_t reg_data_io1_2[] = { + 0x05, 0b01110110, 0, // PI4IO_REG_OUT_SET (bit4=LCD Reset,bit5=GT911 TouchReset HIGH) + 0xFF,0xFF,0xFF, + }; + + // From https://github.com/m5stack/M5GFX/blob/03565ccc96cb0b73c8b157f5ec3fbde439b034ad/src/M5GFX.cpp + static constexpr uint8_t reg_data_io2[] = { + 0x03, 0b10111001, 0, // PI4IO_REG_IO_DIR + 0x07, 0b00000110, 0, // PI4IO_REG_OUT_H_IM + 0x0D, 0b10111001, 0, // PI4IO_REG_PULL_SEL + 0x0B, 0b11111001, 0, // PI4IO_REG_PULL_EN + 0x09, 0b01000000, 0, // PI4IO_REG_IN_DEF_STA + 0x11, 0b10111111, 0, // PI4IO_REG_INT_MASK + 0x05, 0b10001001, 0, // PI4IO_REG_OUT_SET + 0xFF,0xFF,0xFF, + }; + + // constexpr auto pi4io1_i2c_addr = 0x43; + // if (i2c::masterWrite(I2C_NUM_0, pi4io1_i2c_addr, reg_data_io1_1, sizeof(reg_data_io1_1))) { + // LOGGER.error("I2C init of PI4IO1 failed"); + // } + // + // if (i2c::masterWrite(I2C_NUM_0, pi4io1_i2c_addr, reg_data_io2, sizeof(reg_data_io2))) { + // LOGGER.error("I2C init of PI4IO1 failed"); + // } + // + // tt::kernel::delayTicks(10); + // if (i2c::masterWrite(I2C_NUM_0, pi4io1_i2c_addr, reg_data_io1_2, sizeof(reg_data_io1_2))) { + // LOGGER.error("I2C init of PI4IO1 failed"); + // } + + return true; +} + +extern const Configuration hardwareConfiguration = { + .initBoot = initBoot, + .createDevices = createDevices, + .i2c = { + i2c::Configuration { + .name = "Internal", + .port = I2C_NUM_0, + .initMode = i2c::InitMode::ByTactility, + .isMutable = false, + .config = (i2c_config_t) { + .mode = I2C_MODE_MASTER, + .sda_io_num = GPIO_NUM_31, + .scl_io_num = GPIO_NUM_32, + .sda_pullup_en = true, + .scl_pullup_en = true, + .master = { + .clk_speed = 400000 + }, + .clk_flags = 0 + } + }, + // i2c::Configuration { + // .name = "Port A", + // .port = I2C_NUM_1, + // .initMode = i2c::InitMode::ByTactility, + // .isMutable = false, + // .config = (i2c_config_t) { + // .mode = I2C_MODE_MASTER, + // .sda_io_num = GPIO_NUM_53, + // .scl_io_num = GPIO_NUM_54, + // .sda_pullup_en = true, + // .scl_pullup_en = true, + // .master = { + // .clk_speed = 400000 + // }, + // .clk_flags = 0 + // } + // } + } +}; diff --git a/Devices/m5stack-tab5/Source/devices/Display.cpp b/Devices/m5stack-tab5/Source/devices/Display.cpp new file mode 100644 index 00000000..61eb7f78 --- /dev/null +++ b/Devices/m5stack-tab5/Source/devices/Display.cpp @@ -0,0 +1,57 @@ +#include "Display.h" +#include "Ili9881cDisplay.h" + +#include +#include +#include +#include + +constexpr auto LCD_PIN_RESET = GPIO_NUM_0; // Match P4 EV board reset line +constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_22; + +static std::shared_ptr createTouch() { + auto configuration = std::make_unique( + I2C_NUM_0, + 273, + 1280, + false, // swapXY + false, // mirrorX + false, // mirrorY + GPIO_NUM_NC, // reset pin + GPIO_NUM_23 // interrupt pin + ); + + return std::make_shared(std::move(configuration)); +} + +std::shared_ptr createDisplay() { + // Initialize PWM backlight + if (!driver::pwmbacklight::init(LCD_PIN_BACKLIGHT, 20000, LEDC_TIMER_1, LEDC_CHANNEL_0)) { + tt::Logger("Tab5").warn("Failed to initialize backlight"); + } + + auto touch = createTouch(); + + auto configuration = std::make_shared(EspLcdConfiguration { + .horizontalResolution = 720, + .verticalResolution = 1280, + .gapX = 0, + .gapY = 0, + .monochrome = false, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = false, + .bufferSize = 0, // 0 = default (1/10 of screen) + .touch = touch, + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = LCD_PIN_RESET, + .lvglColorFormat = LV_COLOR_FORMAT_RGB565, + .lvglSwapBytes = false, + .rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB, + .bitsPerPixel = 16 + }); + + const auto display = std::make_shared(configuration); + return std::reinterpret_pointer_cast(display); +} diff --git a/Devices/m5stack-tab5/Source/devices/Display.h b/Devices/m5stack-tab5/Source/devices/Display.h new file mode 100644 index 00000000..344191d6 --- /dev/null +++ b/Devices/m5stack-tab5/Source/devices/Display.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +std::shared_ptr createDisplay(); diff --git a/Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.cpp b/Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.cpp new file mode 100644 index 00000000..27a07b10 --- /dev/null +++ b/Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.cpp @@ -0,0 +1,148 @@ +#include "Ili9881cDisplay.h" + +#include + +#include + +static const auto LOGGER = tt::Logger("ILI9881C"); + +Ili9881cDisplay::~Ili9881cDisplay() { + // TODO: This should happen during ::stop(), but this isn't currently exposed + if (mipiDsiBus != nullptr) { + esp_lcd_del_dsi_bus(mipiDsiBus); + mipiDsiBus = nullptr; + } + if (ldoChannel != nullptr) { + esp_ldo_release_channel(ldoChannel); + ldoChannel = nullptr; + } +} + +bool Ili9881cDisplay::createMipiDsiBus() { + esp_ldo_channel_config_t ldo_mipi_phy_config = { + .chan_id = 3, + .voltage_mv = 2500, + .flags = { + .adjustable = 0, + .owned_by_hw = 0, + .bypass = 0 + } + }; + + if (esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldoChannel) != ESP_OK) { + LOGGER.error("Failed to acquire LDO channel for MIPI DSI PHY"); + return false; + } + + LOGGER.info("Powered on"); + + // Create bus + // TODO: use MIPI_DSI_PHY_CLK_SRC_DEFAULT() in future ESP-IDF 6.0.0 update with esp_lcd_jd9165 library version 2.x + const esp_lcd_dsi_bus_config_t bus_config = { + .bus_id = 0, + .num_data_lanes = 2, + .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, + .lane_bit_rate_mbps = 960 + }; + + if (esp_lcd_new_dsi_bus(&bus_config, &mipiDsiBus) != ESP_OK) { + LOGGER.error("Failed to create bus"); + return false; + } + + LOGGER.info("Bus created"); + return true; +} + +bool Ili9881cDisplay::createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) { + // Initialize MIPI DSI bus if not already done + if (mipiDsiBus == nullptr) { + if (!createMipiDsiBus()) { + return false; + } + } + + // Use DBI interface to send LCD commands and parameters + esp_lcd_dbi_io_config_t dbi_config = ILI9881C_PANEL_IO_DBI_CONFIG(); + + if (esp_lcd_new_panel_io_dbi(mipiDsiBus, &dbi_config, &ioHandle) != ESP_OK) { + LOGGER.error("Failed to create panel IO"); + return false; + } + + return true; +} + +esp_lcd_panel_dev_config_t Ili9881cDisplay::createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) { + return { + .reset_gpio_num = resetPin, + .rgb_ele_order = espLcdConfiguration->rgbElementOrder, + .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, + .bits_per_pixel = static_cast(espLcdConfiguration->bitsPerPixel), + .flags = { + .reset_active_high = 0 + }, + .vendor_config = nullptr // Will be set in createPanelHandle + }; +} + +bool Ili9881cDisplay::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) { + // Create DPI panel configuration + // Override default timings + // TODO: Use ILI9881C_800_1280_PANEL_60HZ_DPI_CONFIG() when ILI9881C library is updated + static const esp_lcd_dpi_panel_config_t dpi_config = { + .virtual_channel = 0, + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = 80, + .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565, + .in_color_format = LCD_COLOR_FMT_RGB565, + .out_color_format = LCD_COLOR_FMT_RGB565, + .num_fbs = 1, + .video_timing = { + .h_size = 720, + .v_size = 1280, + .hsync_pulse_width = 40, + .hsync_back_porch = 140, + .hsync_front_porch = 40, + .vsync_pulse_width = 4, + .vsync_back_porch = 20, + .vsync_front_porch = 20, + }, + .flags = { + .use_dma2d = 1, + .disable_lp = 0 + } + }; + + ili9881c_vendor_config_t vendor_config = { + .init_cmds = nullptr, + .init_cmds_size = 0, + .mipi_config = { + .dsi_bus = mipiDsiBus, + .dpi_config = &dpi_config, + .lane_num = 2 + }, + }; + + // Create a mutable copy of panelConfig to set vendor_config + esp_lcd_panel_dev_config_t mutable_panel_config = panelConfig; + mutable_panel_config.vendor_config = &vendor_config; + + if (esp_lcd_new_panel_ili9881c(ioHandle, &mutable_panel_config, &panelHandle) != ESP_OK) { + LOGGER.error("Failed to create panel"); + return false; + } + + LOGGER.info("Panel created successfully"); + // Defer reset/init to base class applyConfiguration to avoid double initialization + return true; +} + +lvgl_port_display_dsi_cfg_t Ili9881cDisplay::getLvglPortDisplayDsiConfig(esp_lcd_panel_io_handle_t /*ioHandle*/, esp_lcd_panel_handle_t /*panelHandle*/) { + // Disable avoid_tearing to prevent stalls/blank flashes when other tasks (e.g. flash writes) block timing + return lvgl_port_display_dsi_cfg_t{ + .flags = { + .avoid_tearing = 0, + }, + }; +} diff --git a/Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.h b/Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.h new file mode 100644 index 00000000..e2819f86 --- /dev/null +++ b/Devices/m5stack-tab5/Source/devices/Ili9881cDisplay.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +#include +#include + +class Ili9881cDisplay final : public EspLcdDisplayV2 { + + class NoLock final : public tt::Lock { + bool lock(TickType_t timeout) const override { return true; } + void unlock() const override { /* NO-OP */ } + }; + + esp_lcd_dsi_bus_handle_t mipiDsiBus = nullptr; + esp_ldo_channel_handle_t ldoChannel = nullptr; + + bool createMipiDsiBus(); + +protected: + + bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override; + + esp_lcd_panel_dev_config_t createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) override; + + bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) override; + + bool useDsiPanel() const override { return true; } + + lvgl_port_display_dsi_cfg_t getLvglPortDisplayDsiConfig(esp_lcd_panel_io_handle_t /*ioHandle*/, esp_lcd_panel_handle_t /*panelHandle*/) override; + +public: + + Ili9881cDisplay( + const std::shared_ptr& configuration + ) : EspLcdDisplayV2(configuration, std::make_shared()) {} + + ~Ili9881cDisplay() override; + + std::string getName() const override { return "ILI9881C"; } + + std::string getDescription() const override { return "ILI9881C MIPI-DSI display"; } +}; diff --git a/Devices/m5stack-tab5/Source/devices/SdCard.cpp b/Devices/m5stack-tab5/Source/devices/SdCard.cpp new file mode 100644 index 00000000..54e355da --- /dev/null +++ b/Devices/m5stack-tab5/Source/devices/SdCard.cpp @@ -0,0 +1,127 @@ +#include "SdCard.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using tt::hal::sdcard::SdCardDevice; + +static const auto LOGGER = tt::Logger("Tab5SdCard"); + +// ESP32-P4 Slot 0 uses IO MUX (fixed pins, not manually configurable) +// CLK=43, CMD=44, D0=39, D1=40, D2=41, D3=42 (defined automatically by hardware) + +class SdCardDeviceImpl final : public SdCardDevice { + + class NoLock final : public tt::Lock { + bool lock(TickType_t timeout) const override { return true; } + void unlock() const override { /* NO-OP */ } + }; + + std::shared_ptr lock = std::make_shared(); + sdmmc_card_t* card = nullptr; + bool mounted = false; + std::string mountPath; + +public: + SdCardDeviceImpl() : SdCardDevice(MountBehaviour::AtBoot) {} + ~SdCardDeviceImpl() override { + if (mounted) { + unmount(); + } + } + + std::string getName() const override { return "SD Card"; } + std::string getDescription() const override { return "SD card via SDMMC host"; } + + bool mount(const std::string& newMountPath) override { + if (mounted) { + return true; + } + + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 5, + .allocation_unit_size = 64 * 1024, + .disk_status_check_enable = false, + .use_one_fat = false, + }; + + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + host.slot = SDMMC_HOST_SLOT_0; + host.max_freq_khz = SDMMC_FREQ_DEFAULT; // 20MHz - more stable for initialization + host.flags = SDMMC_HOST_FLAG_4BIT; // Force 4-bit mode + // Configure LDO power supply for SD card (critical on ESP32-P4) + esp_ldo_channel_handle_t ldo_handle = nullptr; + esp_ldo_channel_config_t ldo_config = { + .chan_id = 4, // LDO channel 4 for SD power + .voltage_mv = 3300, // 3.3V + .flags { + .adjustable = 0, + .owned_by_hw = 0, + .bypass = 0 + } + }; + + esp_err_t ldo_ret = esp_ldo_acquire_channel(&ldo_config, &ldo_handle); + if (ldo_ret != ESP_OK) { + LOGGER.warn("Failed to acquire LDO for SD power: {} (continuing anyway)", esp_err_to_name(ldo_ret)); + } + + // Slot 0 uses IO MUX - pins are fixed and not specified + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + slot_config.width = 4; + slot_config.cd = SDMMC_SLOT_NO_CD; // No card detect + slot_config.wp = SDMMC_SLOT_NO_WP; // No write protect + slot_config.flags = 0; + + esp_err_t ret = esp_vfs_fat_sdmmc_mount(newMountPath.c_str(), &host, &slot_config, &mount_config, &card); + if (ret != ESP_OK) { + LOGGER.error("Failed to mount SD card: {}", esp_err_to_name(ret)); + card = nullptr; + return false; + } + + mountPath = newMountPath; + mounted = true; + LOGGER.info("SD card mounted at {}", mountPath); + return true; + } + + bool unmount() override { + if (!mounted) { + return true; + } + + esp_err_t ret = esp_vfs_fat_sdcard_unmount(mountPath.c_str(), card); + if (ret != ESP_OK) { + LOGGER.error("Failed to unmount SD card: {}", esp_err_to_name(ret)); + return false; + } + card = nullptr; + mounted = false; + LOGGER.info("SD card unmounted"); + return true; + } + + std::string getMountPath() const override { + return mountPath; + } + + std::shared_ptr getLock() const override { return lock; } + + State getState(TickType_t /*timeout*/) const override { + return mounted ? State::Mounted : State::Unmounted; + } +}; + +std::shared_ptr createSdCard() { + return std::make_shared(); +} diff --git a/Devices/m5stack-tab5/Source/devices/SdCard.h b/Devices/m5stack-tab5/Source/devices/SdCard.h new file mode 100644 index 00000000..3e170a56 --- /dev/null +++ b/Devices/m5stack-tab5/Source/devices/SdCard.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +// Create SD card device for jc1060p470ciwy using SDMMC slot 0 (4-bit) +std::shared_ptr createSdCard(); diff --git a/Devices/m5stack-tab5/device.properties b/Devices/m5stack-tab5/device.properties new file mode 100644 index 00000000..c2568966 --- /dev/null +++ b/Devices/m5stack-tab5/device.properties @@ -0,0 +1,28 @@ +[general] +vendor=M5Stack +name=Tab5 + +[hardware] +target=ESP32P4 +flashSize=16MB +spiRam=true +spiRamMode=OCT +spiRamSpeed=200M +esptoolFlashFreq=80M + +[display] +size=5" +shape=rectangle +dpi=294 + +[lvgl] +colorDepth=16 + +[sdkconfig] +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +CONFIG_ESP_HOSTED_ENABLED=y +CONFIG_ESP_HOSTED_P4_DEV_BOARD_FUNC_BOARD=y +CONFIG_ESP_HOSTED_SDIO_HOST_INTERFACE=y +CONFIG_SLAVE_IDF_TARGET_ESP32C6=y diff --git a/Firmware/Kconfig b/Firmware/Kconfig index 1aded79f..364e2e4a 100644 --- a/Firmware/Kconfig +++ b/Firmware/Kconfig @@ -69,6 +69,8 @@ menu "Tactility App" bool "M5Stack StickC Plus" config TT_DEVICE_M5STACK_STICKC_PLUS2 bool "M5Stack StickC Plus2" + config TT_DEVICE_M5STACK_TAB5 + bool "M5Stack Tab5" config TT_DEVICE_UNPHONE bool "unPhone" config TT_DEVICE_WAVESHARE_ESP32_S3_GEEK diff --git a/Firmware/idf_component.yml b/Firmware/idf_component.yml index 8226a1d7..0d4e737f 100644 --- a/Firmware/idf_component.yml +++ b/Firmware/idf_component.yml @@ -43,6 +43,11 @@ dependencies: rules: # More hardware seems to be supported - enable as needed - if: "target in [esp32p4]" + espressif/esp_lcd_ili9881c: + version: "1.1.0" + rules: + # More hardware seems to be supported - enable as needed + - if: "target in [esp32p4]" espressif/esp_lcd_panel_io_additions: "1.0.1" espressif/esp_tinyusb: version: "1.7.6~1" diff --git a/Tactility/Source/app/appsettings/AppSettings.cpp b/Tactility/Source/app/appsettings/AppSettings.cpp index b0268378..2d2a12d2 100644 --- a/Tactility/Source/app/appsettings/AppSettings.cpp +++ b/Tactility/Source/app/appsettings/AppSettings.cpp @@ -26,7 +26,7 @@ class AppSettingsApp final : public App { public: void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { - auto* toolbar = lvgl::toolbar_create(parent, "External Apps"); + auto* toolbar = lvgl::toolbar_create(parent, "Installed Apps"); lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0); lv_obj_t* list = lv_list_create(parent); diff --git a/Tactility/Source/hal/Hal.cpp b/Tactility/Source/hal/Hal.cpp index 4e26fb72..88d8e8b1 100644 --- a/Tactility/Source/hal/Hal.cpp +++ b/Tactility/Source/hal/Hal.cpp @@ -80,8 +80,8 @@ void init(const Configuration& configuration) { kernel::publishSystemEvent(kernel::SystemEvent::BootInitUartEnd); if (configuration.initBoot != nullptr) { - LOGGER.info("Init power"); - tt_check(configuration.initBoot(), "Init power failed"); + LOGGER.info("Init boot"); + tt_check(configuration.initBoot(), "Init boot failed"); } registerDevices(configuration);