From 737c0f74479838348b5010645493dfb5886d5419 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Thu, 2 Jan 2025 00:19:24 +0100 Subject: [PATCH] CoreS3 refactored & remove M5 libraries (#143) Remove dependencies M5Unified and M5GFX because: - Sometimes the release doesn't even compile - The amount of functions is too close to the limit (I recently had to remove some code/dependency to be able to make a build at all) - Graphics performance issue since last update - Touch screen performance issues (not perfect yet, but better) - Compatibility issues with Tactility SPI/I2C versus M5Unified/M5GFX variants. --- .gitmodules | 6 - App/idf_component.yml | 1 + Boards/M5stackCore2/README.md | 11 + .../M5stackCore2/Source/hal/Core2Display.cpp | 2 +- Boards/M5stackCoreS3/CMakeLists.txt | 4 +- Boards/M5stackCoreS3/README.md | 9 + .../M5stackCoreS3/Source/Axp2101/Axp2101.cpp | 74 +++++++ Boards/M5stackCoreS3/Source/Axp2101/Axp2101.h | 37 ++++ Boards/M5stackCoreS3/Source/CoreS3Constants.h | 4 + Boards/M5stackCoreS3/Source/InitBoot.cpp | 104 ++++++++++ Boards/M5stackCoreS3/Source/InitBoot.h | 3 + Boards/M5stackCoreS3/Source/InitLvgl.cpp | 31 +++ Boards/M5stackCoreS3/Source/InitLvgl.h | 3 + Boards/M5stackCoreS3/Source/M5stackCoreS3.cpp | 18 +- .../Source/hal/CoreS3Display.cpp | 189 ++++++++++++++++++ .../M5stackCoreS3/Source/hal/CoreS3Display.h | 35 ++++ .../Source/hal/CoreS3DisplayConstants.h | 11 + .../M5stackCoreS3/Source/hal/CoreS3Power.cpp | 83 ++++++++ Boards/M5stackCoreS3/Source/hal/CoreS3Power.h | 26 +++ .../Source/hal/CoreS3SdCard.cpp} | 19 +- .../Source/hal/CoreS3SdCard.h} | 2 +- .../M5stackCoreS3/Source/hal/CoreS3Touch.cpp | 73 +++++++ .../Source/hal/CoreS3Touch.h} | 2 +- Boards/M5stackShared/CMakeLists.txt | 5 - Boards/M5stackShared/Source/Bootstrap.cpp | 10 - Boards/M5stackShared/Source/Lvgl.cpp | 31 --- Boards/M5stackShared/Source/M5stackShared.h | 10 - .../Source/hal/M5stackDisplay.cpp | 89 --------- .../M5stackShared/Source/hal/M5stackDisplay.h | 25 --- .../M5stackShared/Source/hal/M5stackPower.cpp | 50 ----- .../M5stackShared/Source/hal/M5stackPower.h | 23 --- .../M5stackShared/Source/hal/M5stackTouch.cpp | 48 ----- CMakeLists.txt | 5 - Documentation/ideas.md | 2 + Libraries/M5GFX | 1 - Libraries/M5Unified | 1 - TactilityHeadless/Source/hal/SpiSdCard.cpp | 2 + 37 files changed, 724 insertions(+), 325 deletions(-) create mode 100644 Boards/M5stackCore2/README.md create mode 100644 Boards/M5stackCoreS3/README.md create mode 100644 Boards/M5stackCoreS3/Source/Axp2101/Axp2101.cpp create mode 100644 Boards/M5stackCoreS3/Source/Axp2101/Axp2101.h create mode 100644 Boards/M5stackCoreS3/Source/CoreS3Constants.h create mode 100644 Boards/M5stackCoreS3/Source/InitBoot.cpp create mode 100644 Boards/M5stackCoreS3/Source/InitBoot.h create mode 100644 Boards/M5stackCoreS3/Source/InitLvgl.cpp create mode 100644 Boards/M5stackCoreS3/Source/InitLvgl.h create mode 100644 Boards/M5stackCoreS3/Source/hal/CoreS3Display.cpp create mode 100644 Boards/M5stackCoreS3/Source/hal/CoreS3Display.h create mode 100644 Boards/M5stackCoreS3/Source/hal/CoreS3DisplayConstants.h create mode 100644 Boards/M5stackCoreS3/Source/hal/CoreS3Power.cpp create mode 100644 Boards/M5stackCoreS3/Source/hal/CoreS3Power.h rename Boards/{M5stackShared/Source/hal/M5stackSdCard.cpp => M5stackCoreS3/Source/hal/CoreS3SdCard.cpp} (59%) rename Boards/{M5stackShared/Source/hal/M5stackSdCard.h => M5stackCoreS3/Source/hal/CoreS3SdCard.h} (60%) create mode 100644 Boards/M5stackCoreS3/Source/hal/CoreS3Touch.cpp rename Boards/{M5stackShared/Source/hal/M5stackTouch.h => M5stackCoreS3/Source/hal/CoreS3Touch.h} (86%) delete mode 100644 Boards/M5stackShared/CMakeLists.txt delete mode 100644 Boards/M5stackShared/Source/Bootstrap.cpp delete mode 100644 Boards/M5stackShared/Source/Lvgl.cpp delete mode 100644 Boards/M5stackShared/Source/M5stackShared.h delete mode 100644 Boards/M5stackShared/Source/hal/M5stackDisplay.cpp delete mode 100644 Boards/M5stackShared/Source/hal/M5stackDisplay.h delete mode 100644 Boards/M5stackShared/Source/hal/M5stackPower.cpp delete mode 100644 Boards/M5stackShared/Source/hal/M5stackPower.h delete mode 100644 Boards/M5stackShared/Source/hal/M5stackTouch.cpp delete mode 160000 Libraries/M5GFX delete mode 160000 Libraries/M5Unified diff --git a/.gitmodules b/.gitmodules index fa5006af..b8d352fd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ -[submodule "Libraries/M5GFX"] - path = Libraries/M5GFX - url = https://github.com/m5stack/M5GFX.git -[submodule "Libraries/M5Unified"] - path = Libraries/M5Unified - url = https://github.com/m5stack/M5Unified.git [submodule "Libraries/FreeRTOS-Kernel"] path = Libraries/FreeRTOS-Kernel url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git diff --git a/App/idf_component.yml b/App/idf_component.yml index 95e21525..84cc49e7 100644 --- a/App/idf_component.yml +++ b/App/idf_component.yml @@ -2,5 +2,6 @@ dependencies: espressif/esp_lcd_ili9341: "2.0.0" espressif/esp_lcd_touch_cst816s: "1.0.3" espressif/esp_lcd_touch_gt911: "1.1.1~2" + espressif/esp_lcd_touch_ft5x06: "1.0.6~1" espressif/esp_lcd_touch: "1.1.2" idf: '5.3.1' diff --git a/Boards/M5stackCore2/README.md b/Boards/M5stackCore2/README.md new file mode 100644 index 00000000..3d538d67 --- /dev/null +++ b/Boards/M5stackCore2/README.md @@ -0,0 +1,11 @@ +# M5Stack Core2 + +This board implementation concerns the original Core2 hardware and **not** the v1.1 variant. + +Reference implementations: +- [ESP-BSP](https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_2) +- [M5Unified](https://github.com/m5stack/M5Unified) +- [M5GFX](https://github.com/m5stack/M5GFX) + +Docs: +- [M5Stack.com](https://docs.m5stack.com/en/core/Core2) diff --git a/Boards/M5stackCore2/Source/hal/Core2Display.cpp b/Boards/M5stackCore2/Source/hal/Core2Display.cpp index ea3efe69..b534bfee 100644 --- a/Boards/M5stackCore2/Source/hal/Core2Display.cpp +++ b/Boards/M5stackCore2/Source/hal/Core2Display.cpp @@ -12,7 +12,7 @@ #include "esp_lvgl_port.h" #include "Core2Touch.h" -#define TAG "yellow_display" +#define TAG "core2_display" bool Core2Display::start() { TT_LOG_I(TAG, "Starting"); diff --git a/Boards/M5stackCoreS3/CMakeLists.txt b/Boards/M5stackCoreS3/CMakeLists.txt index 7fa44bd8..6c14c994 100644 --- a/Boards/M5stackCoreS3/CMakeLists.txt +++ b/Boards/M5stackCoreS3/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( - SRC_DIRS "Source" + SRC_DIRS "Source" "Source/hal" "Source/Axp2101" INCLUDE_DIRS "Source" - REQUIRES Tactility M5stackShared vfs fatfs M5Unified + REQUIRES Tactility esp_lvgl_port esp_lcd esp_lcd_ili9341 esp_lcd_touch_ft5x06 driver vfs fatfs ) diff --git a/Boards/M5stackCoreS3/README.md b/Boards/M5stackCoreS3/README.md new file mode 100644 index 00000000..4de20c83 --- /dev/null +++ b/Boards/M5stackCoreS3/README.md @@ -0,0 +1,9 @@ +# M5Stack CoreS3 + +Reference implementations: +- [ESP-BSP](https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_s3) +- [M5Unified](https://github.com/m5stack/M5Unified) +- [M5GFX](https://github.com/m5stack/M5GFX) + +Docs: +- [M5Stack.com](https://docs.m5stack.com/en/core/CoreS3) diff --git a/Boards/M5stackCoreS3/Source/Axp2101/Axp2101.cpp b/Boards/M5stackCoreS3/Source/Axp2101/Axp2101.cpp new file mode 100644 index 00000000..675157a7 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/Axp2101/Axp2101.cpp @@ -0,0 +1,74 @@ +#include "Axp2101.h" +#include "Log.h" + +bool Axp2101::readRegister12(uint8_t reg, float& out) const { + std::uint8_t data[2] = {0}; + if (tt::hal::i2c::masterRead(port, DEFAULT_ADDRESS, reg, data, 2, DEFAULT_TIMEOUT) == ESP_OK) { + out = (data[0] & 0x0F) << 8 | data[1]; + return true; + } else { + return false; + } +} + +bool Axp2101::readRegister14(uint8_t reg, float& out) const { + std::uint8_t data[2] = {0}; + if (tt::hal::i2c::masterRead(port, DEFAULT_ADDRESS, reg, data, 2, DEFAULT_TIMEOUT) == ESP_OK) { + out = (data[0] & 0x3F) << 8 | data[1]; + return true; + } else { + return false; + } +} + +bool Axp2101::readRegister16(uint8_t reg, uint16_t& out) const { + std::uint8_t data[2] = {0}; + if (tt::hal::i2c::masterRead(port, DEFAULT_ADDRESS, reg, data, 2, DEFAULT_TIMEOUT) == ESP_OK) { + out = data[0] << 8 | data[1]; + return true; + } else { + return false; + } +} + +bool Axp2101::readRegister8(uint8_t reg, uint8_t& result) const { + return tt::hal::i2c::masterWriteRead(port, DEFAULT_ADDRESS, ®, 1, &result, 1, DEFAULT_TIMEOUT); +} + +bool Axp2101::writeRegister8(uint8_t reg, uint8_t value) const { + return tt::hal::i2c::masterWrite(port, DEFAULT_ADDRESS, reg, &value, 1, DEFAULT_TIMEOUT); +} + +bool Axp2101::getBatteryVoltage(float& vbatMillis) const { + return readRegister14(0x34, vbatMillis); +} + +bool Axp2101::getChargeStatus(ChargeStatus& status) const { + uint8_t value; + if (readRegister8(0x01, value)) { + value = (value >> 5) & 0b11; + status = (value == 1) ? CHARGE_STATUS_CHARGING : ((value == 2) ? CHARGE_STATUS_DISCHARGING : CHARGE_STATUS_STANDBY); + return true; + } else { + return false; + } +} + +bool Axp2101::isChargingEnabled(bool& enabled) const { + uint8_t value; + if (readRegister8(0x18, value)) { + enabled = value & 0b10; + return true; + } else { + return false; + } +} + +bool Axp2101::setChargingEnabled(bool enabled) const { + uint8_t value; + if (readRegister8(0x18, value)) { + return writeRegister8(0x18, (value & 0xFD) | (enabled << 1)); + } else { + return false; + } +} diff --git a/Boards/M5stackCoreS3/Source/Axp2101/Axp2101.h b/Boards/M5stackCoreS3/Source/Axp2101/Axp2101.h new file mode 100644 index 00000000..f4b82ea2 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/Axp2101/Axp2101.h @@ -0,0 +1,37 @@ +#pragma once + +#include "hal/i2c/I2c.h" + +/** + * References: + * - https://github.com/m5stack/M5Unified/blob/master/src/utility/AXP2101_Class.cpp + * - http://file.whycan.com/files/members/6736/AXP2101_Datasheet_V1.0_en_3832.pdf + */ +class Axp2101 { + + i2c_port_t port; + + static constexpr uint8_t DEFAULT_ADDRESS = 0x34; + static constexpr TickType_t DEFAULT_TIMEOUT = 1000 / portTICK_PERIOD_MS; + + bool readRegister8(uint8_t reg, uint8_t& result) const; + bool writeRegister8(uint8_t reg, uint8_t value) const; + bool readRegister12(uint8_t reg, float& out) const; + bool readRegister14(uint8_t reg, float& out) const; + bool readRegister16(uint8_t reg, uint16_t& out) const; + +public: + + enum ChargeStatus { + CHARGE_STATUS_CHARGING = 0b01, + CHARGE_STATUS_DISCHARGING = 0b10, + CHARGE_STATUS_STANDBY = 0b00 + }; + + Axp2101(i2c_port_t port) : port(port) {} + + bool getBatteryVoltage(float& vbatMillis) const; + bool getChargeStatus(ChargeStatus& status) const; + bool isChargingEnabled(bool& enabled) const; + bool setChargingEnabled(bool enabled) const; +}; diff --git a/Boards/M5stackCoreS3/Source/CoreS3Constants.h b/Boards/M5stackCoreS3/Source/CoreS3Constants.h new file mode 100644 index 00000000..766c1d87 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/CoreS3Constants.h @@ -0,0 +1,4 @@ +#pragma once + +#define AXP2101_ADDRESS 0x34 +#define AW9523_ADDRESS 0x58 diff --git a/Boards/M5stackCoreS3/Source/InitBoot.cpp b/Boards/M5stackCoreS3/Source/InitBoot.cpp new file mode 100644 index 00000000..699ff0d2 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/InitBoot.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include "Log.h" +#include "hal/CoreS3DisplayConstants.h" +#include "hal/i2c/I2c.h" +#include "CoreS3Constants.h" + +#define TAG "core2" + +#define CORES3_SPI2_PIN_SCLK GPIO_NUM_36 +#define CORES3_SPI2_PIN_MOSI GPIO_NUM_37 +#define CORES3_SPI2_PIN_MISO GPIO_NUM_35 + +/** + * For details see https://github.com/espressif/esp-bsp/blob/master/bsp/m5stack_core_s3/m5stack_core_s3.c + */ +static bool initSpi3() { + TT_LOG_I(TAG, LOG_MESSAGE_SPI_INIT_START_FMT, SPI3_HOST); + const spi_bus_config_t bus_config = { + .mosi_io_num = CORES3_SPI2_PIN_MOSI, + .miso_io_num = CORES3_SPI2_PIN_MISO, + .sclk_io_num = CORES3_SPI2_PIN_SCLK, + .data2_io_num = GPIO_NUM_NC, + .data3_io_num = GPIO_NUM_NC, + .data4_io_num = GPIO_NUM_NC, + .data5_io_num = GPIO_NUM_NC, + .data6_io_num = GPIO_NUM_NC, + .data7_io_num = GPIO_NUM_NC, + .max_transfer_sz = CORES3_LCD_DRAW_BUFFER_SIZE, + .flags = 0, + .isr_cpu_id = INTR_CPU_ID_AUTO, + .intr_flags = 0 + }; + + if (spi_bus_initialize(SPI3_HOST, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) { + TT_LOG_E(TAG, LOG_MESSAGE_SPI_INIT_FAILED_FMT, SPI3_HOST); + return false; + } + + return true; +} + +/** + * For details see https://github.com/espressif/esp-bsp/blob/master/bsp/m5stack_core_s3/m5stack_core_s3.c + */ +bool initGpioExpander() { + TT_LOG_I(TAG, "Init AW9523 GPIO expander"); + uint8_t aw9523_P0 = 0b10; + uint8_t aw9523_P1 = 0b10100000; + + // Enable LCD + aw9523_P1 |= (1 << 1); + + // Enable touch + aw9523_P0 |= (1); + + // SD card + aw9523_P0 |= (1 << 4); + + if (tt::hal::i2c::masterWrite(I2C_NUM_0, AW9523_ADDRESS, 0x02, &aw9523_P0, 1, 1000) != ESP_OK) { + TT_LOG_E(TAG, "Failed to enable LCD"); + return false; + } + + if (tt::hal::i2c::masterWrite(I2C_NUM_0, AW9523_ADDRESS, 0x03, &aw9523_P1, 1, 1000) != ESP_OK) { + TT_LOG_E(TAG, "Failed to enable touch"); + return false; + } + + return true; +} + +bool initPowerControl() { + TT_LOG_I(TAG, "Init power control"); + + uint8_t sdcard_3v3 = 0b00011100; + // TODO: Refactor to use Axp2101 class with https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/AXP2101_Class.cpp#L62 + if (tt::hal::i2c::masterWrite(I2C_NUM_0, AXP2101_ADDRESS, 0x95, &sdcard_3v3, 1, 1000) != ESP_OK) { + TT_LOG_E(TAG, "Failed to enable SD card"); + return false; + } + + // TODO: Refactor to use Axp2102 class with https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/AXP2101_Class.cpp#L42 + uint8_t axp_dld01_enable = 0xBF; // For backlight + if (tt::hal::i2c::masterWrite(I2C_NUM_0, AXP2101_ADDRESS, 0x90, &axp_dld01_enable, 1, 1000) != ESP_OK) { + TT_LOG_E(TAG, "Failed to enable display backlight"); + return false; + } + + // TODO: Refactor to use Axp2101 class with https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/AXP2101_Class.cpp#L62 + uint8_t axp_dld01_voltage = 0b00011000; // For backlight + if (tt::hal::i2c::masterWrite(I2C_NUM_0, AXP2101_ADDRESS, 0x99, &axp_dld01_voltage, 1, 1000) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set display backlight voltage"); + return false; + } + + return true; +} + +bool initBoot() { + TT_LOG_I(TAG, "initBoot"); + return initPowerControl() && initGpioExpander() && initSpi3(); +} \ No newline at end of file diff --git a/Boards/M5stackCoreS3/Source/InitBoot.h b/Boards/M5stackCoreS3/Source/InitBoot.h new file mode 100644 index 00000000..f3e5bf89 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/InitBoot.h @@ -0,0 +1,3 @@ +#pragma once + +bool initBoot(); diff --git a/Boards/M5stackCoreS3/Source/InitLvgl.cpp b/Boards/M5stackCoreS3/Source/InitLvgl.cpp new file mode 100644 index 00000000..faa92dfe --- /dev/null +++ b/Boards/M5stackCoreS3/Source/InitLvgl.cpp @@ -0,0 +1,31 @@ +#include "Log.h" +#include "Thread.h" +#include "lvgl/LvglSync.h" +#include "esp_lvgl_port.h" + +#define TAG "core2" + +// LVGL +// The minimum task stack seems to be about 3500, but that crashes the wifi app in some scenarios +// At 4000, it crashes when the fps renderer is available +#define CORE2_LVGL_TASK_STACK_DEPTH 8192 + +bool initLvgl() { + const lvgl_port_cfg_t lvgl_cfg = { + .task_priority = tt::THREAD_PRIORITY_RENDER, + .task_stack = CORE2_LVGL_TASK_STACK_DEPTH, + .task_affinity = -1, // core pinning + .task_max_sleep_ms = 500, + .timer_period_ms = 5 + }; + + TT_LOG_D(TAG, "LVGL port init"); + if (lvgl_port_init(&lvgl_cfg) != ESP_OK) { + TT_LOG_E(TAG, "LVGL port init failed"); + return false; + } + + tt::lvgl::syncSet(&lvgl_port_lock, &lvgl_port_unlock); + + return true; +} diff --git a/Boards/M5stackCoreS3/Source/InitLvgl.h b/Boards/M5stackCoreS3/Source/InitLvgl.h new file mode 100644 index 00000000..e57bd9bd --- /dev/null +++ b/Boards/M5stackCoreS3/Source/InitLvgl.h @@ -0,0 +1,3 @@ +#pragma once + +bool initLvgl(); diff --git a/Boards/M5stackCoreS3/Source/M5stackCoreS3.cpp b/Boards/M5stackCoreS3/Source/M5stackCoreS3.cpp index 72850afc..02bd4742 100644 --- a/Boards/M5stackCoreS3/Source/M5stackCoreS3.cpp +++ b/Boards/M5stackCoreS3/Source/M5stackCoreS3.cpp @@ -1,17 +1,21 @@ #include "M5stackCoreS3.h" -#include "M5stackShared.h" +#include "InitBoot.h" +#include "InitLvgl.h" +#include "hal/CoreS3Display.h" +#include "hal/CoreS3SdCard.h" +#include "hal/CoreS3Power.h" const tt::hal::Configuration m5stack_cores3 = { - .initBoot = m5stack_bootstrap, - .initLvgl = m5stack_lvgl_init, + .initBoot = initBoot, + .initLvgl = initLvgl, .createDisplay = createDisplay, - .sdcard = createM5SdCard(), - .power = m5stack_get_power, + .sdcard = createSdCard(), + .power = createPower, .i2c = { tt::hal::i2c::Configuration { .name = "Internal", .port = I2C_NUM_0, - .initMode = tt::hal::i2c::InitByExternal, + .initMode = tt::hal::i2c::InitByTactility, .canReinit = false, .hasMutableConfiguration = false, .config = (i2c_config_t) { @@ -29,7 +33,7 @@ const tt::hal::Configuration m5stack_cores3 = { tt::hal::i2c::Configuration { .name = "External", // Grove .port = I2C_NUM_1, - .initMode = tt::hal::i2c::InitByExternal, + .initMode = tt::hal::i2c::InitByTactility, .canReinit = true, .hasMutableConfiguration = true, .config = (i2c_config_t) { diff --git a/Boards/M5stackCoreS3/Source/hal/CoreS3Display.cpp b/Boards/M5stackCoreS3/Source/hal/CoreS3Display.cpp new file mode 100644 index 00000000..6b90c005 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3Display.cpp @@ -0,0 +1,189 @@ +#include "CoreS3Display.h" +#include "CoreS3DisplayConstants.h" +#include "Log.h" + +#include +#include + +#include "driver/gpio.h" +#include "esp_err.h" +#include "esp_lcd_ili9341.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lvgl_port.h" +#include "hal/i2c/I2c.h" +#include "CoreS3Constants.h" +#include "CoreS3Touch.h" + +#define TAG "cores3_display" + +bool CoreS3Display::start() { + TT_LOG_I(TAG, "Starting"); + + const esp_lcd_panel_io_spi_config_t panel_io_config = { + .cs_gpio_num = CORES3_LCD_PIN_CS, + .dc_gpio_num = CORES3_LCD_PIN_DC, + .spi_mode = 0, + .pclk_hz = 40000000, + .trans_queue_depth = 10, + .on_color_trans_done = nullptr, + .user_ctx = nullptr, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + .flags = { + .dc_high_on_cmd = 0, + .dc_low_on_data = 0, + .dc_low_on_param = 0, + .octal_mode = 0, + .quad_mode = 0, + .sio_mode = 0, + .lsb_first = 0, + .cs_high_active = 0 + } + }; + + if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)CORES3_LCD_SPI_HOST, &panel_io_config, &ioHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to create panel"); + return false; + } + + const esp_lcd_panel_dev_config_t panel_config = { + .reset_gpio_num = GPIO_NUM_NC, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR, + .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, + .bits_per_pixel = CORES3_LCD_BITS_PER_PIXEL, + .flags = { + .reset_active_high = false + }, + .vendor_config = nullptr + }; + + if (esp_lcd_new_panel_ili9341(ioHandle, &panel_config, &panelHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to create ili9341"); + return false; + } + + if (esp_lcd_panel_reset(panelHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to reset panel"); + return false; + } + + if (esp_lcd_panel_init(panelHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to init panel"); + return false; + } + + if (esp_lcd_panel_mirror(panelHandle, false, false) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set panel to mirror"); + return false; + } + + if (esp_lcd_panel_invert_color(panelHandle, true) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set panel to invert"); + return false; + } + + if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) { + TT_LOG_E(TAG, "Failed to turn display on"); + return false; + } + + const lvgl_port_display_cfg_t disp_cfg = { + .io_handle = ioHandle, + .panel_handle = panelHandle, + .control_handle = nullptr, + .buffer_size = CORES3_LCD_DRAW_BUFFER_SIZE, + .double_buffer = true, + .trans_size = 0, + .hres = CORES3_LCD_HORIZONTAL_RESOLUTION, + .vres = CORES3_LCD_VERTICAL_RESOLUTION, + .monochrome = false, + .rotation = { + .swap_xy = false, + .mirror_x = false, + .mirror_y = false, + }, + .color_format = LV_COLOR_FORMAT_RGB565, + .flags = { + .buff_dma = false, + .buff_spiram = true, + .sw_rotate = false, + .swap_bytes = true, + .full_refresh = false, + .direct_mode = false + } + }; + + displayHandle = lvgl_port_add_disp(&disp_cfg); + TT_LOG_I(TAG, "Finished"); + return displayHandle != nullptr; +} + +bool CoreS3Display::stop() { + tt_assert(displayHandle != nullptr); + + lvgl_port_remove_disp(displayHandle); + + if (esp_lcd_panel_del(panelHandle) != ESP_OK) { + return false; + } + + if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) { + return false; + } + + displayHandle = nullptr; + return true; +} + +/** + * Note: + * The datasheet implies this should work, but it doesn't: + * https://www.digikey.com/htmldatasheets/production/1640716/0/0/1/ILI9341-Datasheet.pdf + * + * This repo claims it only has 1 curve: + * https://github.com/brucemack/hello-ili9341 + * + * I'm leaving it in as I'm not sure if it's just my hardware that's problematic. + */ +void CoreS3Display::setGammaCurve(uint8_t index) { + uint8_t gamma_curve; + switch (index) { + case 0: + gamma_curve = 0x01; + break; + case 1: + gamma_curve = 0x04; + break; + case 2: + gamma_curve = 0x02; + break; + case 3: + gamma_curve = 0x08; + break; + default: + return; + } + const uint8_t param[] = { + gamma_curve + }; + + if (esp_lcd_panel_io_tx_param(ioHandle , LCD_CMD_GAMSET, param, 1) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set gamma"); + } +} + +void CoreS3Display::setBacklightDuty(uint8_t backlightDuty) { + const uint8_t voltage = 20 + ((8 * backlightDuty) / 255); // [0b00000, 0b11100] - under 20 is too dark + // TODO: Refactor to use Axp2102 class with https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/AXP2101_Class.cpp#L42 + if (tt::hal::i2c::masterWrite(I2C_NUM_0, AXP2101_ADDRESS, 0x99, &voltage, 1, 1000) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set display backlight voltage"); + } +} + +tt::hal::Touch* _Nullable CoreS3Display::createTouch() { + return static_cast(new CoreS3Touch()); +} + +tt::hal::Display* createDisplay() { + return static_cast(new CoreS3Display()); +} diff --git a/Boards/M5stackCoreS3/Source/hal/CoreS3Display.h b/Boards/M5stackCoreS3/Source/hal/CoreS3Display.h new file mode 100644 index 00000000..c1388a4d --- /dev/null +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3Display.h @@ -0,0 +1,35 @@ +#pragma once + +#include "lvgl.h" +#include "hal/Display.h" + +#include + +extern lv_disp_t* displayHandle; + +class CoreS3Display : public tt::hal::Display { + +private: + + esp_lcd_panel_io_handle_t ioHandle = nullptr; + esp_lcd_panel_handle_t panelHandle = nullptr; + lv_display_t* displayHandle = nullptr; + +public: + + bool start() override; + + bool stop() override; + + tt::hal::Touch* _Nullable createTouch() override; + + void setBacklightDuty(uint8_t backlightDuty) override; + bool supportsBacklightDuty() const override { return true; } + + void setGammaCurve(uint8_t index) override; + uint8_t getGammaCurveCount() const override { return 4; }; + + lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; } +}; + +tt::hal::Display* createDisplay(); diff --git a/Boards/M5stackCoreS3/Source/hal/CoreS3DisplayConstants.h b/Boards/M5stackCoreS3/Source/hal/CoreS3DisplayConstants.h new file mode 100644 index 00000000..c815eeb1 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3DisplayConstants.h @@ -0,0 +1,11 @@ +#pragma once + +// Display +#define CORES3_LCD_SPI_HOST SPI3_HOST +#define CORES3_LCD_PIN_CS GPIO_NUM_3 +#define CORES3_LCD_PIN_DC GPIO_NUM_35 +#define CORES3_LCD_HORIZONTAL_RESOLUTION 320 +#define CORES3_LCD_VERTICAL_RESOLUTION 240 +#define CORES3_LCD_BITS_PER_PIXEL 16 +#define CORES3_LCD_DRAW_BUFFER_HEIGHT (CORES3_LCD_VERTICAL_RESOLUTION / 10) +#define CORES3_LCD_DRAW_BUFFER_SIZE (CORES3_LCD_HORIZONTAL_RESOLUTION * CORES3_LCD_DRAW_BUFFER_HEIGHT * (CORES3_LCD_BITS_PER_PIXEL / 8)) diff --git a/Boards/M5stackCoreS3/Source/hal/CoreS3Power.cpp b/Boards/M5stackCoreS3/Source/hal/CoreS3Power.cpp new file mode 100644 index 00000000..52281d98 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3Power.cpp @@ -0,0 +1,83 @@ +#include "CoreS3Power.h" +#include "TactilityCore.h" + +#define TAG "core2_power" + +bool CoreS3Power::supportsMetric(MetricType type) const { + switch (type) { + case BATTERY_VOLTAGE: + case IS_CHARGING: + case CHARGE_LEVEL: + return true; + case CURRENT: + return false; + } + + return false; // Safety guard for when new enum values are introduced +} + +bool CoreS3Power::getMetric(Power::MetricType type, Power::MetricData& data) { + switch (type) { + case BATTERY_VOLTAGE: { + float milliVolt; + if (axpDevice.getBatteryVoltage(milliVolt)) { + data.valueAsUint32 = (uint32_t)milliVolt; + return true; + } else { + return false; + } + } + case CHARGE_LEVEL: { + float vbatMillis; + if (axpDevice.getBatteryVoltage(vbatMillis)) { + float vbat = vbatMillis / 1000.f; + float max_voltage = 4.20f; + float min_voltage = 2.69f; // From M5Unified + if (vbat > 2.69f) { + float charge_factor = (vbat - min_voltage) / (max_voltage - min_voltage); + data.valueAsUint8 = (uint8_t)(charge_factor * 100.f); + } else { + data.valueAsUint8 = 0; + } + return true; + } else { + return false; + } + } + case IS_CHARGING: { + Axp2101::ChargeStatus status; + if (axpDevice.getChargeStatus(status)) { + data.valueAsBool = (status == Axp2101::CHARGE_STATUS_CHARGING); + return true; + } else { + return false; + } + } + case CURRENT: + return false; + } + + return false; // Safety guard for when new enum values are introduced +} + +bool CoreS3Power::isAllowedToCharge() const { + bool enabled; + if (axpDevice.isChargingEnabled(enabled)) { + return enabled; + } else { + return false; + } +} + +void CoreS3Power::setAllowedToCharge(bool canCharge) { + axpDevice.setChargingEnabled(canCharge); +} + +static std::shared_ptr power; + +std::shared_ptr createPower() { + if (power == nullptr) { + power = std::make_shared(); + } + return power; +} diff --git a/Boards/M5stackCoreS3/Source/hal/CoreS3Power.h b/Boards/M5stackCoreS3/Source/hal/CoreS3Power.h new file mode 100644 index 00000000..654ba8c6 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3Power.h @@ -0,0 +1,26 @@ +#pragma once + +#include "hal/Power.h" +#include "Axp2101/Axp2101.h" +#include + +using namespace tt::hal; + +class CoreS3Power : public Power { + + Axp2101 axpDevice = Axp2101(I2C_NUM_0); + +public: + + CoreS3Power() = default; + ~CoreS3Power() override = default; + + bool supportsMetric(MetricType type) const override; + bool getMetric(Power::MetricType type, Power::MetricData& data) override; + + bool supportsChargeControl() const override { return true; } + bool isAllowedToCharge() const override; + void setAllowedToCharge(bool canCharge) override; +}; + +std::shared_ptr createPower(); diff --git a/Boards/M5stackShared/Source/hal/M5stackSdCard.cpp b/Boards/M5stackCoreS3/Source/hal/CoreS3SdCard.cpp similarity index 59% rename from Boards/M5stackShared/Source/hal/M5stackSdCard.cpp rename to Boards/M5stackCoreS3/Source/hal/CoreS3SdCard.cpp index f97401f2..47b266ab 100644 --- a/Boards/M5stackShared/Source/hal/M5stackSdCard.cpp +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3SdCard.cpp @@ -1,26 +1,27 @@ -#include "M5stackSdCard.h" +#include "CoreS3SdCard.h" #include "lvgl/LvglSync.h" #include "hal/SpiSdCard.h" #include -#include -#define SDCARD_PIN_CS GPIO_NUM_4 -#define SDCARD_SPI_FREQUENCY 800000U +#define CORES3_SDCARD_SPI_FREQUENCY 800000U +#define CORES3_SDCARD_PIN_CS GPIO_NUM_4 +#define CORES3_LCD_PIN_CS GPIO_NUM_3 -std::shared_ptr createM5SdCard() { +std::shared_ptr createSdCard() { auto* configuration = new tt::hal::SpiSdCard::Config( - SDCARD_SPI_FREQUENCY, - SDCARD_PIN_CS, + CORES3_SDCARD_SPI_FREQUENCY, + CORES3_SDCARD_PIN_CS, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC, SdCard::MountBehaviourAtBoot, tt::lvgl::getLvglSyncLockable(), { - GPIO_NUM_5 - } + CORES3_LCD_PIN_CS + }, + SPI3_HOST ); auto* sdcard = (SdCard*) new SpiSdCard( diff --git a/Boards/M5stackShared/Source/hal/M5stackSdCard.h b/Boards/M5stackCoreS3/Source/hal/CoreS3SdCard.h similarity index 60% rename from Boards/M5stackShared/Source/hal/M5stackSdCard.h rename to Boards/M5stackCoreS3/Source/hal/CoreS3SdCard.h index b9239dbf..a6671951 100644 --- a/Boards/M5stackShared/Source/hal/M5stackSdCard.h +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3SdCard.h @@ -4,4 +4,4 @@ using namespace tt::hal; -std::shared_ptr createM5SdCard(); +std::shared_ptr createSdCard(); diff --git a/Boards/M5stackCoreS3/Source/hal/CoreS3Touch.cpp b/Boards/M5stackCoreS3/Source/hal/CoreS3Touch.cpp new file mode 100644 index 00000000..b8f40769 --- /dev/null +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3Touch.cpp @@ -0,0 +1,73 @@ +#include "CoreS3Touch.h" +#include "Log.h" +#include "driver/i2c.h" +#include "esp_err.h" +#include "esp_lcd_touch_ft5x06.h" +#include "esp_lcd_touch.h" +#include "esp_lvgl_port.h" + +#define TAG "cores3_touch" + +bool CoreS3Touch::start(lv_display_t* display) { + TT_LOG_I(TAG, "Starting"); + esp_lcd_panel_io_handle_t ioHandle; + esp_lcd_touch_handle_t touchHandle; + + esp_lcd_panel_io_i2c_config_t touch_io_config = ESP_LCD_TOUCH_IO_I2C_FT5x06_CONFIG(); + + // TODO: Check when ESP-IDF publishes fix (5.3.2 or 5.4.x) + static_assert(ESP_IDF_VERSION == ESP_IDF_VERSION_VAL(5, 3, 1)); + esp_lcd_new_panel_io_i2c(I2C_NUM_0, &touch_io_config, &ioHandle); + /* + if (esp_lcd_new_panel_io_i2c(I2C_NUM_0, &touch_io_config, &ioHandle) != ESP_OK) { + TT_LOG_E(TAG, "Touch I2C IO init failed"); + return false; + } + */ + + esp_lcd_touch_config_t config = { + .x_max = 320, + .y_max = 240, + .rst_gpio_num = GPIO_NUM_NC, + .int_gpio_num = GPIO_NUM_NC, + .levels = { + .reset = 0, + .interrupt = 0, + }, + .flags = { + .swap_xy = 0, + .mirror_x = 0, + .mirror_y = 0, + }, + .process_coordinates = nullptr, + .interrupt_callback = nullptr, + .user_data = nullptr, + .driver_data = nullptr + }; + + if (esp_lcd_touch_new_i2c_ft5x06(ioHandle, &config, &touchHandle) != ESP_OK) { + TT_LOG_E(TAG, "Driver init failed"); + return false; + } + + const lvgl_port_touch_cfg_t touch_cfg = { + .disp = display, + .handle = touchHandle, + }; + + deviceHandle = lvgl_port_add_touch(&touch_cfg); + if (deviceHandle == nullptr) { + TT_LOG_E(TAG, "Adding touch failed"); + return false; + } + + TT_LOG_I(TAG, "Finished"); + return true; +} + +bool CoreS3Touch::stop() { + tt_assert(deviceHandle != nullptr); + lv_indev_delete(deviceHandle); + deviceHandle = nullptr; + return true; +} diff --git a/Boards/M5stackShared/Source/hal/M5stackTouch.h b/Boards/M5stackCoreS3/Source/hal/CoreS3Touch.h similarity index 86% rename from Boards/M5stackShared/Source/hal/M5stackTouch.h rename to Boards/M5stackCoreS3/Source/hal/CoreS3Touch.h index f26b6904..8edb2dbd 100644 --- a/Boards/M5stackShared/Source/hal/M5stackTouch.h +++ b/Boards/M5stackCoreS3/Source/hal/CoreS3Touch.h @@ -3,7 +3,7 @@ #include "hal/Touch.h" #include "TactilityCore.h" -class M5stackTouch : public tt::hal::Touch { +class CoreS3Touch : public tt::hal::Touch { private: lv_indev_t* _Nullable deviceHandle = nullptr; public: diff --git a/Boards/M5stackShared/CMakeLists.txt b/Boards/M5stackShared/CMakeLists.txt deleted file mode 100644 index bf3c2afd..00000000 --- a/Boards/M5stackShared/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" "Source/hal" - INCLUDE_DIRS "Source" - REQUIRES Tactility esp_lvgl_port M5Unified vfs fatfs -) diff --git a/Boards/M5stackShared/Source/Bootstrap.cpp b/Boards/M5stackShared/Source/Bootstrap.cpp deleted file mode 100644 index 3341ff20..00000000 --- a/Boards/M5stackShared/Source/Bootstrap.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "M5Unified.hpp" -#include "Log.h" - -#define TAG "m5stack_bootstrap" - -bool m5stack_bootstrap() { - TT_LOG_I(TAG, "Initializing M5Unified"); - M5.begin(); - return true; -} diff --git a/Boards/M5stackShared/Source/Lvgl.cpp b/Boards/M5stackShared/Source/Lvgl.cpp deleted file mode 100644 index 2c70e450..00000000 --- a/Boards/M5stackShared/Source/Lvgl.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "esp_lvgl_port.h" -#include "Log.h" -#include "Thread.h" -#include "lvgl/LvglSync.h" - -#define TAG "cores3_lvgl" - -_Nullable lv_disp_t* createDisplay(bool usePsram); -_Nullable lv_indev_t* createTouch(); - -bool m5stack_lvgl_init() { - static lv_display_t* display = nullptr; - - const lvgl_port_cfg_t lvgl_cfg = { - .task_priority = tt::Thread::PriorityHigh, - .task_stack = 8096, - .task_affinity = -1, // core pinning - .task_max_sleep_ms = 500, - .timer_period_ms = 5 - }; - - if (lvgl_port_init(&lvgl_cfg) != ESP_OK) { - TT_LOG_E(TAG, "lvgl_port_init failed"); - return false; - } - - // Set syncing functions - tt::lvgl::syncSet(&lvgl_port_lock, &lvgl_port_unlock); - - return true; -} diff --git a/Boards/M5stackShared/Source/M5stackShared.h b/Boards/M5stackShared/Source/M5stackShared.h deleted file mode 100644 index 7a91cdc1..00000000 --- a/Boards/M5stackShared/Source/M5stackShared.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "hal/Power.h" -#include "hal/M5stackTouch.h" -#include "hal/M5stackDisplay.h" -#include "hal/M5stackPower.h" -#include "hal/M5stackSdCard.h" - -extern bool m5stack_bootstrap(); -extern bool m5stack_lvgl_init(); diff --git a/Boards/M5stackShared/Source/hal/M5stackDisplay.cpp b/Boards/M5stackShared/Source/hal/M5stackDisplay.cpp deleted file mode 100644 index a42446ba..00000000 --- a/Boards/M5stackShared/Source/hal/M5stackDisplay.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "M5stackDisplay.h" -#include "M5stackTouch.h" -#include "Log.h" - -#include - -#define TAG "m5shared_display" - - -#include "M5Unified.hpp" -#include "esp_err.h" -#include "esp_lvgl_port.h" - -static void flush_callback(lv_display_t* display, const lv_area_t* area, uint8_t* px_map) { - M5GFX& gfx = *(M5GFX*)lv_display_get_driver_data(display); - - int32_t width = (area->x2 - area->x1 + 1); - int32_t height = (area->y2 - area->y1 + 1); - - gfx.startWrite(); - gfx.setAddrWindow(area->x1, area->y1, width, height); - gfx.writePixels((lgfx::rgb565_t*)px_map, width * height); - gfx.endWrite(); - - lv_display_flush_ready(display); -} - -_Nullable lv_disp_t* createDisplay(bool usePsram) { - M5GFX& gfx = M5.Display; - - static lv_display_t* display = lv_display_create(gfx.width(), gfx.height()); - LV_ASSERT_MALLOC(display) - if (display == nullptr) { - return nullptr; - } - - lv_display_set_driver_data(display, &gfx); - lv_display_set_flush_cb(display, flush_callback); - - const size_t bytes_per_pixel = 2; // assume 16-bit color - const size_t buffer_size = gfx.width() * gfx.height() * bytes_per_pixel / 8; - if (usePsram) { - static auto* buffer1 = (uint8_t*)heap_caps_malloc(buffer_size, MALLOC_CAP_SPIRAM); - LV_ASSERT_MALLOC(buffer1) - static auto* buffer2 = (uint8_t*)heap_caps_malloc(buffer_size, MALLOC_CAP_SPIRAM); - LV_ASSERT_MALLOC(buffer2) - lv_display_set_buffers( - display, - (void*)buffer1, - (void*)buffer2, - buffer_size, - LV_DISPLAY_RENDER_MODE_PARTIAL - ); - } else { - static auto* buffer = (uint8_t*)malloc(buffer_size); - LV_ASSERT_MALLOC(buffer) - lv_display_set_buffers( - display, - (void*)buffer, - nullptr, - buffer_size, - LV_DISPLAY_RENDER_MODE_PARTIAL - ); - } - - return display; -} - -bool M5stackDisplay::start() { - TT_LOG_I(TAG, "Starting"); - displayHandle = createDisplay(true); - TT_LOG_I(TAG, "Finished"); - return displayHandle != nullptr; -} - -bool M5stackDisplay::stop() { - tt_assert(displayHandle != nullptr); - lv_display_delete(displayHandle); - displayHandle = nullptr; - return true; -} - -tt::hal::Touch* _Nullable M5stackDisplay::createTouch() { - return static_cast(new M5stackTouch()); -} - -tt::hal::Display* createDisplay() { - return static_cast(new M5stackDisplay()); -} diff --git a/Boards/M5stackShared/Source/hal/M5stackDisplay.h b/Boards/M5stackShared/Source/hal/M5stackDisplay.h deleted file mode 100644 index 983f2fd3..00000000 --- a/Boards/M5stackShared/Source/hal/M5stackDisplay.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "lvgl.h" -#include "hal/Display.h" - -extern lv_disp_t* displayHandle; - -class M5stackDisplay : public tt::hal::Display { - -private: - - lv_display_t* displayHandle = nullptr; - -public: - - bool start() override; - - bool stop() override; - - tt::hal::Touch* _Nullable createTouch() override; - - lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; } -}; - -tt::hal::Display* createDisplay(); diff --git a/Boards/M5stackShared/Source/hal/M5stackPower.cpp b/Boards/M5stackShared/Source/hal/M5stackPower.cpp deleted file mode 100644 index 6902c7fe..00000000 --- a/Boards/M5stackShared/Source/hal/M5stackPower.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "M5stackPower.h" - -#include "M5Unified.h" - -#define TAG "m5stack_power" - -bool M5stackPower::supportsMetric(MetricType type) const { - switch (type) { - case IS_CHARGING: - case CURRENT: - case BATTERY_VOLTAGE: - case CHARGE_LEVEL: - return true; - } - - return false; // Safety guard for when new enum values are introduced -} - -bool M5stackPower::getMetric(Power::MetricType type, Power::MetricData& data) { - switch (type) { - case IS_CHARGING: - data.valueAsBool = M5.Power.isCharging(); - return true; - case CURRENT: - data.valueAsInt32 = M5.Power.getBatteryCurrent(); - return true; - case BATTERY_VOLTAGE: - data.valueAsUint32 = M5.Power.getBatteryVoltage(); - return true; - case CHARGE_LEVEL: - data.valueAsUint8 = M5.Power.getBatteryLevel(); - return true; - } - - return false; // Safety guard for when new enum values are introduced -} - -void M5stackPower::setAllowedToCharge(bool canCharge) { - M5.Power.setBatteryCharge(canCharge); -} - -static std::shared_ptr power; - -std::shared_ptr m5stack_get_power() { - if (power == nullptr) { - power = std::make_shared(); - } - return power; -} - diff --git a/Boards/M5stackShared/Source/hal/M5stackPower.h b/Boards/M5stackShared/Source/hal/M5stackPower.h deleted file mode 100644 index 5bc018a8..00000000 --- a/Boards/M5stackShared/Source/hal/M5stackPower.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "hal/Power.h" -#include - -using namespace tt::hal; - -class M5stackPower : public Power { - -public: - - M5stackPower() {} - ~M5stackPower() {} - - bool supportsMetric(MetricType type) const override; - bool getMetric(Power::MetricType type, Power::MetricData& data) override; - - bool supportsChargeControl() const { return true; } - bool isAllowedToCharge() const { return true; } /** We can call setChargingAllowed() but the actual value is unknown as it resets when re-plugging USB */ - void setAllowedToCharge(bool canCharge); -}; - -std::shared_ptr m5stack_get_power(); diff --git a/Boards/M5stackShared/Source/hal/M5stackTouch.cpp b/Boards/M5stackShared/Source/hal/M5stackTouch.cpp deleted file mode 100644 index 4c38618f..00000000 --- a/Boards/M5stackShared/Source/hal/M5stackTouch.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "M5stackTouch.h" -#include "M5Unified.hpp" -#include "esp_err.h" -#include "Log.h" - -#define TAG "m5stack_touch" - -static void touchReadCallback(TT_UNUSED lv_indev_t* indev, lv_indev_data_t* data) { - lgfx::touch_point_t point; // Making it static makes it unreliable - bool touched = M5.Lcd.getTouch(&point) > 0; - if (!touched) { - data->state = LV_INDEV_STATE_REL; - } else { - data->state = LV_INDEV_STATE_PR; - data->point.x = point.x; - data->point.y = point.y; - } -} - -_Nullable lv_indev_t* createTouch() { - static lv_indev_t* indev = lv_indev_create(); - LV_ASSERT_MALLOC(indev) - if (indev == nullptr) { - return nullptr; - } - - lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); - lv_indev_set_read_cb(indev, touchReadCallback); - return indev; -} -bool M5stackTouch::start(lv_display_t* display) { - - TT_LOG_I(TAG, "Adding touch to LVGL"); - deviceHandle = createTouch(); - if (deviceHandle == nullptr) { - TT_LOG_E(TAG, "Adding touch failed"); - return false; - } - - return true; -} - -bool M5stackTouch::stop() { - tt_assert(deviceHandle != nullptr); - lv_indev_delete(deviceHandle); - deviceHandle = nullptr; - return true; -} diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a89986c..6be975ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,9 +15,6 @@ if (DEFINED ENV{ESP_IDF_VERSION}) add_definitions(-DESP_TARGET) add_compile_definitions(ESP_TARGET) - add_definitions(-DARDUINO_M5STACK_CORE2) - add_compile_definitions(ARDUINO_M5STACK_CORE2) - set(COMPONENTS App) set(EXTRA_COMPONENT_DIRS "Boards" @@ -30,8 +27,6 @@ if (DEFINED ENV{ESP_IDF_VERSION}) "Libraries/elf_loader" "Libraries/lvgl" "Libraries/lv_screenshot" - "Libraries/M5Unified" - "Libraries/M5GFX" "Libraries/QRCode" ) diff --git a/Documentation/ideas.md b/Documentation/ideas.md index 2d8f2640..d9a05816 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -10,6 +10,8 @@ - Add statusbar icon for memory pressure. - Show error in WiFi screen (e.g. AlertDialog when SPI is not enabled and available memory is below a certain amount) - Clean up static_cast when casting to base class. +- M5Stack CoreS3 SD card mounts, but cannot be read. There is currently a notice about it [here](https://github.com/espressif/esp-bsp/blob/master/bsp/m5stack_core_s3/README.md). +- hal::I2c has inconsistent return values for read/write functions # TODOs - Call tt::lvgl::isSyncSet after HAL init and show error (and crash?) when it is not set. diff --git a/Libraries/M5GFX b/Libraries/M5GFX deleted file mode 160000 index ff11e09a..00000000 --- a/Libraries/M5GFX +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ff11e09ac0bb5ec29433e81abbdc66c26488ba44 diff --git a/Libraries/M5Unified b/Libraries/M5Unified deleted file mode 160000 index 77017d17..00000000 --- a/Libraries/M5Unified +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 77017d17b915f64587b4ddcbfa898547573cedfb diff --git a/TactilityHeadless/Source/hal/SpiSdCard.cpp b/TactilityHeadless/Source/hal/SpiSdCard.cpp index f7218a66..e42aaafc 100644 --- a/TactilityHeadless/Source/hal/SpiSdCard.cpp +++ b/TactilityHeadless/Source/hal/SpiSdCard.cpp @@ -64,6 +64,7 @@ bool SpiSdCard::mountInternal(const char* mountPoint) { // Init without card detect (CD) and write protect (WD) sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); + slot_config.host_id = config->spiHost; slot_config.gpio_cs = config->spiPinCs; slot_config.gpio_cd = config->spiPinCd; slot_config.gpio_wp = config->spiPinWp; @@ -74,6 +75,7 @@ bool SpiSdCard::mountInternal(const char* mountPoint) { // https://github.com/Xinyuan-LilyGO/T-Deck/blob/master/examples/UnitTest/UnitTest.ino // Observation: Using this automatically sets the bus to 20MHz host.max_freq_khz = config->spiFrequency; + host.slot = config->spiHost; esp_err_t result = esp_vfs_fat_sdspi_mount(mountPoint, &host, &slot_config, &mount_config, &card);