From 8335611796ddb5bbe665d897269833633b3fa8ec Mon Sep 17 00:00:00 2001 From: NellowTCS Date: Wed, 5 Nov 2025 01:04:40 -0700 Subject: [PATCH] Board Support: Heltec v3 (#407) --- .github/workflows/build-firmware.yml | 1 + Boards/heltec-wifi-lora-32-v3/CMakeLists.txt | 7 + .../Source/Configuration.cpp | 71 ++++++ .../Source/devices/Constants.h | 16 ++ .../Source/devices/Display.cpp | 19 ++ .../Source/devices/Display.h | 5 + .../Source/devices/Power.cpp | 20 ++ .../Source/devices/Power.h | 7 + Buildscripts/CDN/devices.properties | 6 + Drivers/SSD1306/CMakeLists.txt | 5 + Drivers/SSD1306/README.md | 3 + Drivers/SSD1306/Source/Ssd1306Display.cpp | 204 ++++++++++++++++++ Drivers/SSD1306/Source/Ssd1306Display.h | 90 ++++++++ Firmware/Kconfig | 2 + Tactility/Source/app/launcher/Launcher.cpp | 12 ++ sdkconfig.board.heltec-wifi-lora-32-v3 | 59 +++++ 16 files changed, 527 insertions(+) create mode 100644 Boards/heltec-wifi-lora-32-v3/CMakeLists.txt create mode 100644 Boards/heltec-wifi-lora-32-v3/Source/Configuration.cpp create mode 100644 Boards/heltec-wifi-lora-32-v3/Source/devices/Constants.h create mode 100644 Boards/heltec-wifi-lora-32-v3/Source/devices/Display.cpp create mode 100644 Boards/heltec-wifi-lora-32-v3/Source/devices/Display.h create mode 100644 Boards/heltec-wifi-lora-32-v3/Source/devices/Power.cpp create mode 100644 Boards/heltec-wifi-lora-32-v3/Source/devices/Power.h create mode 100644 Drivers/SSD1306/CMakeLists.txt create mode 100644 Drivers/SSD1306/README.md create mode 100644 Drivers/SSD1306/Source/Ssd1306Display.cpp create mode 100644 Drivers/SSD1306/Source/Ssd1306Display.h create mode 100644 sdkconfig.board.heltec-wifi-lora-32-v3 diff --git a/.github/workflows/build-firmware.yml b/.github/workflows/build-firmware.yml index d240760f..1b823233 100644 --- a/.github/workflows/build-firmware.yml +++ b/.github/workflows/build-firmware.yml @@ -31,6 +31,7 @@ jobs: { id: elecrow-crowpanel-basic-28, arch: esp32 }, { id: elecrow-crowpanel-basic-35, arch: esp32 }, { id: elecrow-crowpanel-basic-50, arch: esp32s3 }, + { id: heltec-wifi-lora-32-v3, arch: esp32s3 }, { id: lilygo-tdeck, arch: esp32s3 }, { id: lilygo-tdongle-s3, arch: esp32s3 }, { id: lilygo-tdisplay-s3, arch: esp32s3 }, diff --git a/Boards/heltec-wifi-lora-32-v3/CMakeLists.txt b/Boards/heltec-wifi-lora-32-v3/CMakeLists.txt new file mode 100644 index 00000000..1a17c5f3 --- /dev/null +++ b/Boards/heltec-wifi-lora-32-v3/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB_RECURSE SOURCE_FILES Source/*.c*) + +idf_component_register( + SRCS ${SOURCE_FILES} + INCLUDE_DIRS "Source" + REQUIRES Tactility EspLcdCompat SSD1306 ButtonControl EstimatedPower driver +) diff --git a/Boards/heltec-wifi-lora-32-v3/Source/Configuration.cpp b/Boards/heltec-wifi-lora-32-v3/Source/Configuration.cpp new file mode 100644 index 00000000..0ae50f4c --- /dev/null +++ b/Boards/heltec-wifi-lora-32-v3/Source/Configuration.cpp @@ -0,0 +1,71 @@ +#include "devices/Display.h" +#include "devices/Power.h" +#include "devices/Constants.h" + +#include +#include +#include + +#include "driver/gpio.h" +#include "driver/i2c.h" +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +static void enableOledPower() { + gpio_config_t io_conf = { + .pin_bit_mask = (1ULL << DISPLAY_PIN_POWER), + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, // The board has an external pull-up + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&io_conf); + gpio_set_level(DISPLAY_PIN_POWER, 0); // Active low + + vTaskDelay(pdMS_TO_TICKS(500)); // Add a small delay for power to stabilize + TT_LOG_I("OLED_POWER", "OLED power enabled"); +} + +static bool initBoot() { + // Enable power to the OLED before doing anything else + enableOledPower(); + + return true; +} + +using namespace tt::hal; + +static std::vector> createDevices() { + return { + createPower(), + ButtonControl::createOneButtonControl(0), + createDisplay() + }; +} + +extern const Configuration hardwareConfiguration = { + .initBoot = initBoot, + .uiScale = UiScale::Smallest, + .createDevices = createDevices, + .i2c = { + tt::hal::i2c::Configuration { + .name = "Internal", + .port = DISPLAY_I2C_PORT, + .initMode = tt::hal::i2c::InitMode::ByTactility, + .isMutable = true, + .config = (i2c_config_t) { + .mode = I2C_MODE_MASTER, + .sda_io_num = DISPLAY_PIN_SDA, + .scl_io_num = DISPLAY_PIN_SCL, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master = { + .clk_speed = DISPLAY_I2C_SPEED + }, + .clk_flags = 0 + } + } + }, + .spi {}, +}; diff --git a/Boards/heltec-wifi-lora-32-v3/Source/devices/Constants.h b/Boards/heltec-wifi-lora-32-v3/Source/devices/Constants.h new file mode 100644 index 00000000..27217d14 --- /dev/null +++ b/Boards/heltec-wifi-lora-32-v3/Source/devices/Constants.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +// Display +constexpr auto DISPLAY_I2C_ADDRESS = 0x3C; +constexpr auto DISPLAY_I2C_SPEED = 200000; +constexpr auto DISPLAY_I2C_PORT = I2C_NUM_0; +constexpr auto DISPLAY_PIN_SDA = GPIO_NUM_17; +constexpr auto DISPLAY_PIN_SCL = GPIO_NUM_18; +constexpr auto DISPLAY_PIN_RST = GPIO_NUM_21; +constexpr auto DISPLAY_HORIZONTAL_RESOLUTION = 128; +constexpr auto DISPLAY_VERTICAL_RESOLUTION = 64; +constexpr auto DISPLAY_PIN_POWER = GPIO_NUM_36; diff --git a/Boards/heltec-wifi-lora-32-v3/Source/devices/Display.cpp b/Boards/heltec-wifi-lora-32-v3/Source/devices/Display.cpp new file mode 100644 index 00000000..0a18d1ed --- /dev/null +++ b/Boards/heltec-wifi-lora-32-v3/Source/devices/Display.cpp @@ -0,0 +1,19 @@ +#include "Display.h" +#include "Constants.h" + +#include + +std::shared_ptr createDisplay() { + auto configuration = std::make_unique( + DISPLAY_I2C_PORT, + DISPLAY_I2C_ADDRESS, + DISPLAY_PIN_RST, + DISPLAY_HORIZONTAL_RESOLUTION, + DISPLAY_VERTICAL_RESOLUTION, + nullptr, // no touch + false // invert + ); + + auto display = std::make_shared(std::move(configuration)); + return std::static_pointer_cast(display); +} \ No newline at end of file diff --git a/Boards/heltec-wifi-lora-32-v3/Source/devices/Display.h b/Boards/heltec-wifi-lora-32-v3/Source/devices/Display.h new file mode 100644 index 00000000..7a9b967d --- /dev/null +++ b/Boards/heltec-wifi-lora-32-v3/Source/devices/Display.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +std::shared_ptr createDisplay(); diff --git a/Boards/heltec-wifi-lora-32-v3/Source/devices/Power.cpp b/Boards/heltec-wifi-lora-32-v3/Source/devices/Power.cpp new file mode 100644 index 00000000..652bbc20 --- /dev/null +++ b/Boards/heltec-wifi-lora-32-v3/Source/devices/Power.cpp @@ -0,0 +1,20 @@ +#include "Power.h" + +#include +#include +#include +#include + +// ADC enable pin on GPIO37 +constexpr auto ADC_CTRL = 37; + +std::shared_ptr createPower() { + ChargeFromAdcVoltage::Configuration configuration; + // 2.0 ratio, but +0.11 added as display voltage sag compensation. + configuration.adcMultiplier = 2.11; + + // Configure the ADC enable pin as an output + tt::hal::gpio::configure(ADC_CTRL, tt::hal::gpio::Mode::Output, false, false); + + return std::make_shared(configuration); +} \ No newline at end of file diff --git a/Boards/heltec-wifi-lora-32-v3/Source/devices/Power.h b/Boards/heltec-wifi-lora-32-v3/Source/devices/Power.h new file mode 100644 index 00000000..a878df85 --- /dev/null +++ b/Boards/heltec-wifi-lora-32-v3/Source/devices/Power.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include +#include + +std::shared_ptr createPower(); diff --git a/Buildscripts/CDN/devices.properties b/Buildscripts/CDN/devices.properties index 9d5a2519..8ed32e14 100644 --- a/Buildscripts/CDN/devices.properties +++ b/Buildscripts/CDN/devices.properties @@ -86,6 +86,12 @@ vendor=Elecrow boardName=CrowPanel Basic 5" incubating=false +[heltec-wifi-lora-32-v3] +vendor=Heltec +boardName=v3 +incubating=true +infoMessage=Due to the small size of the screen, the icons don't render properly. + [lilygo-tdeck] vendor=LilyGO boardName=T-Deck,T-Deck Plus diff --git a/Drivers/SSD1306/CMakeLists.txt b/Drivers/SSD1306/CMakeLists.txt new file mode 100644 index 00000000..a9519cf4 --- /dev/null +++ b/Drivers/SSD1306/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRC_DIRS "Source" + INCLUDE_DIRS "Source" + REQUIRES Tactility driver EspLcdCompat esp_lcd lvgl +) diff --git a/Drivers/SSD1306/README.md b/Drivers/SSD1306/README.md new file mode 100644 index 00000000..13a651e2 --- /dev/null +++ b/Drivers/SSD1306/README.md @@ -0,0 +1,3 @@ +# SSD1306 + +A very custom ESP32 LVGL driver for SSD1306 displays. diff --git a/Drivers/SSD1306/Source/Ssd1306Display.cpp b/Drivers/SSD1306/Source/Ssd1306Display.cpp new file mode 100644 index 00000000..930441cb --- /dev/null +++ b/Drivers/SSD1306/Source/Ssd1306Display.cpp @@ -0,0 +1,204 @@ +#include "Ssd1306Display.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TAG "ssd1306_display" + +// SSD1306 commands +#define SSD1306_CMD_SET_CHARGE_PUMP 0x8D +#define SSD1306_CMD_SET_SEGMENT_REMAP 0xA0 +#define SSD1306_CMD_SET_COM_SCAN_DIR 0xC0 +#define SSD1306_CMD_SET_COM_PIN_CFG 0xDA +#define SSD1306_CMD_SET_CONTRAST 0x81 +#define SSD1306_CMD_SET_PRECHARGE 0xD9 +#define SSD1306_CMD_SET_VCOMH_DESELECT 0xDB +#define SSD1306_CMD_DISPLAY_INVERT 0xA6 +#define SSD1306_CMD_DISPLAY_ON 0xAF +#define SSD1306_CMD_SET_MEMORY_ADDR_MODE 0x20 +#define SSD1306_CMD_SET_COLUMN_RANGE 0x21 +#define SSD1306_CMD_SET_PAGE_RANGE 0x22 + +// Helper to send I2C commands directly +static bool ssd1306_i2c_send_cmd(i2c_port_t port, uint8_t addr, uint8_t cmd) { + uint8_t data[2] = {0x00, cmd}; // 0x00 = command mode + esp_err_t ret = i2c_master_write_to_device(port, addr, data, sizeof(data), pdMS_TO_TICKS(1000)); + if (ret != ESP_OK) { + TT_LOG_E(TAG, "Failed to send command 0x%02X: %d", cmd, ret); + return false; + } + return true; +} + +bool Ssd1306Display::createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) { + const esp_lcd_panel_io_i2c_config_t io_config = { + .dev_addr = configuration->deviceAddress, + .control_phase_bytes = 1, + .dc_bit_offset = 6, + .flags = { + .dc_low_on_data = false, + .disable_control_phase = false, + }, + }; + + if (esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)configuration->port, &io_config, &ioHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to create IO handle"); + return false; + } + + return true; +} + +bool Ssd1306Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) { + // Manual hardware reset with proper timing for Heltec V3 + if (configuration->resetPin != GPIO_NUM_NC) { + gpio_config_t reset_gpio_config = { + .pin_bit_mask = 1ULL << configuration->resetPin, + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&reset_gpio_config); + + gpio_set_level(configuration->resetPin, 0); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level(configuration->resetPin, 1); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + // Create ESP-IDF panel (but don't call init - we'll do custom init) + esp_lcd_panel_dev_config_t panel_config = { + .reset_gpio_num = GPIO_NUM_NC, // Already handled above + .color_space = ESP_LCD_COLOR_SPACE_MONOCHROME, + .bits_per_pixel = 1, // Must be 1 for monochrome + .flags = { + .reset_active_high = false, + }, + .vendor_config = nullptr, + }; + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) + esp_lcd_panel_ssd1306_config_t ssd1306_config = { + .height = static_cast(configuration->verticalResolution), + }; + panel_config.vendor_config = &ssd1306_config; +#endif + + if (esp_lcd_new_panel_ssd1306(ioHandle, &panel_config, &panelHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to create panel"); + return false; + } + + // Don't call esp_lcd_panel_init() - it doesn't configure correctly for Heltec V3! + // Instead, send our custom initialization sequence directly via I2C + + auto port = configuration->port; + auto addr = configuration->deviceAddress; + + TT_LOG_I(TAG, "Sending Heltec V3 custom init sequence"); + + // Display off while configuring + ssd1306_i2c_send_cmd(port, addr, 0xAE); + vTaskDelay(pdMS_TO_TICKS(10)); // Important: let display stabilize after turning off + + // Set oscillator frequency (MUST come early in sequence) + ssd1306_i2c_send_cmd(port, addr, 0xD5); + ssd1306_i2c_send_cmd(port, addr, 0x80); + + // Set multiplex ratio + ssd1306_i2c_send_cmd(port, addr, 0xA8); + ssd1306_i2c_send_cmd(port, addr, configuration->verticalResolution - 1); + + // Set display offset + ssd1306_i2c_send_cmd(port, addr, 0xD3); + ssd1306_i2c_send_cmd(port, addr, 0x00); + + // Set display start line + ssd1306_i2c_send_cmd(port, addr, 0x40); + + // Enable charge pump (required for Heltec V3 - must be before memory mode) + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_SET_CHARGE_PUMP); + ssd1306_i2c_send_cmd(port, addr, 0x14); // Enable + + // Horizontal addressing mode + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_SET_MEMORY_ADDR_MODE); + ssd1306_i2c_send_cmd(port, addr, 0x00); + + // Segment remap (0xA1 for Heltec V3 orientation) + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_SET_SEGMENT_REMAP | 0x01); + + // COM scan direction (0xC8 = reversed) + ssd1306_i2c_send_cmd(port, addr, 0xC8); + + // COM pin configuration + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_SET_COM_PIN_CFG); + if (configuration->verticalResolution == 64) { + ssd1306_i2c_send_cmd(port, addr, 0x12); // Alternative COM pin config for 64-row displays + } else { + ssd1306_i2c_send_cmd(port, addr, 0x02); // Sequential COM pin config for 32-row displays + } + + // Contrast (0xCF = bright, good for Heltec OLED) + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_SET_CONTRAST); + ssd1306_i2c_send_cmd(port, addr, 0xCF); + + // Precharge period (0xF1 for Heltec OLED) + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_SET_PRECHARGE); + ssd1306_i2c_send_cmd(port, addr, 0xF1); + + // VCOMH deselect level + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_SET_VCOMH_DESELECT); + ssd1306_i2c_send_cmd(port, addr, 0x40); + + // Normal display mode (not inverse/all-on) + ssd1306_i2c_send_cmd(port, addr, 0xA6); + + // Invert display (0xA7) + // This is what your old working driver did unconditionally + ssd1306_i2c_send_cmd(port, addr, 0xA7); + + // Display ON + ssd1306_i2c_send_cmd(port, addr, SSD1306_CMD_DISPLAY_ON); + + vTaskDelay(pdMS_TO_TICKS(100)); // Let display stabilize + + TT_LOG_I(TAG, "Heltec V3 display initialized successfully"); + + return true; +} + +lvgl_port_display_cfg_t Ssd1306Display::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { + return { + .io_handle = ioHandle, + .panel_handle = panelHandle, + .control_handle = nullptr, + .buffer_size = configuration->bufferSize, + .double_buffer = false, + .trans_size = 0, + .hres = configuration->horizontalResolution, + .vres = configuration->verticalResolution, + .monochrome = true, // ESP-LVGL-port handles the conversion! + .rotation = { + .swap_xy = false, + .mirror_x = false, + .mirror_y = false, + }, + .color_format = LV_COLOR_FORMAT_RGB565, // Use RGB565, monochrome flag makes it work! + .flags = { + .buff_dma = false, + .buff_spiram = false, + .sw_rotate = false, + .swap_bytes = false, + .full_refresh = true, + .direct_mode = false + } + }; +} diff --git a/Drivers/SSD1306/Source/Ssd1306Display.h b/Drivers/SSD1306/Source/Ssd1306Display.h new file mode 100644 index 00000000..aa09dc6d --- /dev/null +++ b/Drivers/SSD1306/Source/Ssd1306Display.h @@ -0,0 +1,90 @@ +#pragma once + +#include +#include + +#include +#include +#include + +class Ssd1306Display final : public EspLcdDisplay { + +public: + + class Configuration { + + public: + + Configuration( + i2c_port_t port, + uint8_t deviceAddress, + gpio_num_t resetPin, + unsigned int horizontalResolution, // Typically 128 + unsigned int verticalResolution, // 32 or 64 + std::shared_ptr touch = nullptr, + bool invertColor = false + ) : port(port), + deviceAddress(deviceAddress), + resetPin(resetPin), + horizontalResolution(horizontalResolution), + verticalResolution(verticalResolution), + invertColor(invertColor), + touch(std::move(touch)) + {} + + i2c_port_t port; + uint8_t deviceAddress; + gpio_num_t resetPin = GPIO_NUM_NC; + unsigned int horizontalResolution; + unsigned int verticalResolution; + bool invertColor = false; + std::shared_ptr touch; + uint32_t bufferSize = 0; // Size in pixel count. 0 means default (full screen / 8) + int gapX = 0; // Column offset + int gapY = 0; // Not used for SSD1306 + }; + +private: + + std::unique_ptr configuration; + + bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override; + + bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) override; + + lvgl_port_display_cfg_t getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) override; + +public: + + explicit Ssd1306Display(std::unique_ptr inConfiguration) : + EspLcdDisplay(nullptr), + configuration(std::move(inConfiguration)) + { + assert(configuration != nullptr); + if (configuration->bufferSize == 0) { + // For monochrome displays, ESP-LVGL-PORT expects full pixel count + // It handles the monochrome conversion internally + configuration->bufferSize = configuration->horizontalResolution * configuration->verticalResolution; + } + } + + std::string getName() const override { return "SSD1306"; } + + std::string getDescription() const override { return "SSD1306 monochrome OLED display with ESP-LVGL-PORT monochrome support"; } + + std::shared_ptr _Nullable getTouchDevice() override { return configuration->touch; } + + void setBacklightDuty(uint8_t backlightDuty) override { + // SSD1306 does not have backlight control + } + + bool supportsBacklightDuty() const override { return false; } + + void setGammaCurve(uint8_t index) override { + // SSD1306 does not support gamma curves + } + + uint8_t getGammaCurveCount() const override { return 0; } +}; + +std::shared_ptr createDisplay(); diff --git a/Firmware/Kconfig b/Firmware/Kconfig index 0cf9c635..1e70324d 100644 --- a/Firmware/Kconfig +++ b/Firmware/Kconfig @@ -43,6 +43,8 @@ menu "Tactility App" bool "Elecrow CrowPanel Basic 3.5" config TT_BOARD_ELECROW_CROWPANEL_BASIC_50 bool "Elecrow CrowPanel Basic 5.0" + config TT_BOARD_HELTEC_V3 + bool "Heltec v3" config TT_BOARD_LILYGO_TDECK bool "LilyGo T-Deck" config TT_BOARD_LILYGO_TDONGLE_S3 diff --git a/Tactility/Source/app/launcher/Launcher.cpp b/Tactility/Source/app/launcher/Launcher.cpp index e6ef1ebf..dee92d9f 100644 --- a/Tactility/Source/app/launcher/Launcher.cpp +++ b/Tactility/Source/app/launcher/Launcher.cpp @@ -38,10 +38,22 @@ class LauncherApp final : public App { lv_obj_set_style_shadow_width(apps_button, 0, LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(apps_button, 0, LV_STATE_DEFAULT); + // create the image first auto* button_image = lv_image_create(apps_button); lv_image_set_src(button_image, imageFile); + + // Recolor handling: + // For color builds use theme primary color + // For 1-bit/monochrome builds force a visible color (black) + #if LV_COLOR_DEPTH == 1 + // Try forcing black recolor on monochrome builds + lv_obj_set_style_image_recolor(button_image, lv_color_black(), LV_STATE_DEFAULT); + lv_obj_set_style_image_recolor_opa(button_image, LV_OPA_COVER, LV_STATE_DEFAULT); + #else lv_obj_set_style_image_recolor(button_image, lv_theme_get_color_primary(parent), LV_STATE_DEFAULT); lv_obj_set_style_image_recolor_opa(button_image, LV_OPA_COVER, LV_STATE_DEFAULT); + #endif + // Ensure buttons are still tappable when the asset fails to load // Icon images are 40x40, so we get some extra padding too lv_obj_set_size(button_image, button_size, button_size); diff --git a/sdkconfig.board.heltec-wifi-lora-32-v3 b/sdkconfig.board.heltec-wifi-lora-32-v3 new file mode 100644 index 00000000..7810e57a --- /dev/null +++ b/sdkconfig.board.heltec-wifi-lora-32-v3 @@ -0,0 +1,59 @@ +# Software defaults +# Increase stack size for WiFi (fixes crash after scan) +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=6144 +CONFIG_LV_FONT_MONTSERRAT_14=y +CONFIG_LV_FONT_MONTSERRAT_18=y +CONFIG_LV_USE_USER_DATA=y +CONFIG_LV_USE_FS_STDIO=y +CONFIG_LV_FS_STDIO_LETTER=65 +CONFIG_LV_FS_STDIO_PATH="" +CONFIG_LV_FS_STDIO_CACHE_SIZE=4096 +CONFIG_LV_USE_LODEPNG=y +CONFIG_LV_USE_BUILTIN_MALLOC=n +CONFIG_LV_USE_CLIB_MALLOC=y +CONFIG_LV_USE_MSGBOX=n +CONFIG_LV_USE_SPINNER=n +CONFIG_LV_USE_WIN=n +CONFIG_LV_USE_SNAPSHOT=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2 +CONFIG_FREERTOS_SMP=n +CONFIG_FREERTOS_UNICORE=n +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=5120 +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FATFS_LFN_HEAP=y +CONFIG_FATFS_VOLUME_COUNT=3 +CONFIG_FATFS_SECTOR_512=y +CONFIG_WL_SECTOR_SIZE_512=y +CONFIG_WL_SECTOR_SIZE=512 +CONFIG_WL_SECTOR_MODE_SAFE=y +CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y + +# Hardware: Main +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-8mb.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions-8mb.csv" +CONFIG_TT_BOARD_HELTEC_V3=y +CONFIG_TT_BOARD_NAME="Heltec v3" +CONFIG_TT_BOARD_ID="heltec-wifi-lora-32-v3" +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_IDF_TARGET="esp32s3" +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_FLASHMODE_QIO=y +# Hardware: No PSRAM +# SPI Flash (can set back to 80MHz after ESP-IDF bug is resolved) +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +# LVGL +CONFIG_LV_DPI_DEF=90 +CONFIG_LV_DISP_DEF_REFR_PERIOD=10 +CONFIG_LV_THEME_DEFAULT_DARK=y +CONFIG_LV_COLOR_DEPTH=1 +CONFIG_LV_USE_THEME_MONO=y +CONFIG_LV_LOG_LEVEL=LV_LOG_LEVEL_TRACE +# USB +CONFIG_TINYUSB_MSC_ENABLED=y +CONFIG_TINYUSB_MSC_MOUNT_PATH="/sdcard" \ No newline at end of file