Compare commits

...

3 Commits

Author SHA1 Message Date
Ken Van Hoeylandt
65335578a4
Update CYD-E32R28T and fixed some minor issues (#319) 2025-09-06 15:12:40 +02:00
Ken Van Hoeylandt
c0ed8f0a44
Merge develop into main (#318)
- Disable `DisplayDriver` for `St7701Display` (on CYD 4848)
- Improve `GraphicsDemo`: check for feature capability and show alert dialog if there's an issue
- `DevelopmentService` installs to `/data` instead of `/sdcard`
- Fixed `tt_app_get_data_directory()` and `tt_app_get_data_directory_lvgl()` (C++ to C)
- `tt_kernel.h` now defines `MAX_TICKS`
- `tt_init.cpp` now exports `esp_log()` which is required since ESP-IDF 5.5
2025-09-06 14:44:41 +02:00
NellowTCS
a9b69010d8
CYD-E28R32T Implementation (#317)
- Add implementation for CYD-E28R28T. This implementation has the SD card working, using the same driver as the CYD-2432S028R.
- Edit .gitignore for some missing things.
- run chmod +x on some build scripts
- Make EspLcdDisplay's reference public for access from drivers (needed for driver St7789i8080)
> ```class EspLcdDisplay : public tt::hal::display::DisplayDevice {```
2025-09-06 13:52:46 +02:00
28 changed files with 326 additions and 28 deletions

View File

@ -27,6 +27,15 @@ jobs:
with: with:
board_id: cyd-2432s028r board_id: cyd-2432s028r
arch: esp32 arch: esp32
cyd-e32r28t:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Build"
uses: ./.github/actions/build-firmware
with:
board_id: cyd-e32r28t
arch: esp32
cyd-2432s032c: cyd-2432s032c:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

2
.gitignore vendored
View File

@ -7,6 +7,7 @@ build-sim/
cmake-build-*/ cmake-build-*/
CMakeCache.txt CMakeCache.txt
*.cbp *.cbp
CMakeFiles
release/ release/
@ -17,4 +18,5 @@ managed_components/
dependencies.lock dependencies.lock
.vscode/ .vscode/
.gitpod.yml

View File

@ -15,6 +15,8 @@ menu "Tactility App"
bool "CYD 2432S024C" bool "CYD 2432S024C"
config TT_BOARD_CYD_2432S028R config TT_BOARD_CYD_2432S028R
bool "CYD 2432S028R" bool "CYD 2432S028R"
config TT_BOARD_CYD_E32R28T
bool "CYD E32R28T"
config TT_BOARD_CYD_2432S032C config TT_BOARD_CYD_2432S032C
bool "CYD 2432S032C" bool "CYD 2432S032C"
config TT_BOARD_CYD_8048S043C config TT_BOARD_CYD_8048S043C

View File

@ -17,6 +17,9 @@
#elif defined(CONFIG_TT_BOARD_CYD_2432S028R) #elif defined(CONFIG_TT_BOARD_CYD_2432S028R)
#include "CYD2432S028R.h" #include "CYD2432S028R.h"
#define TT_BOARD_HARDWARE &cyd_2432s028r_config #define TT_BOARD_HARDWARE &cyd_2432s028r_config
#elif defined(CONFIG_TT_BOARD_CYD_E32R28T)
#include "E32R28T.h"
#define TT_BOARD_HARDWARE &cyd_e32r28t_config
#elif defined(CONFIG_TT_BOARD_CYD_2432S032C) #elif defined(CONFIG_TT_BOARD_CYD_2432S032C)
#include "CYD2432S032C.h" #include "CYD2432S032C.h"
#define TT_BOARD_HARDWARE &cyd_2432S032c_config #define TT_BOARD_HARDWARE &cyd_2432S032c_config

View File

@ -2,5 +2,5 @@
#include <Tactility/hal/Configuration.h> #include <Tactility/hal/Configuration.h>
// Resitive touch version of the 2.8" yellow board // Resistive touch version of the 2.8" yellow board
extern const tt::hal::Configuration cyd_2432s028r_config; extern const tt::hal::Configuration cyd_2432s028r_config;

View File

@ -32,4 +32,7 @@ public:
void setBacklightDuty(uint8_t backlightDuty) override; void setBacklightDuty(uint8_t backlightDuty) override;
bool supportsBacklightDuty() const override { return true; } bool supportsBacklightDuty() const override { return true; }
// TODO: Find out why it crashes
bool supportsDisplayDriver() const override { return false; }
}; };

View File

@ -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 ILI934x XPT2046SoftSPI PwmBacklight driver vfs fatfs
)

View File

@ -0,0 +1,73 @@
#include "E32R28T.h"
#include "devices/SdCard.h"
#include "devices/Display.h"
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
#define CYD_SPI_TRANSFER_SIZE_LIMIT (240 * 320 / 4 * 2)
static bool initBoot() {
return driver::pwmbacklight::init(CYD_BACKLIGHT_PIN);
}
static tt::hal::DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
const tt::hal::Configuration cyd_e32r28t_config = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {},
.spi = {
tt::hal::spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_12,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_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,
.data_io_default_level = false,
.max_transfer_sz = CYD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
tt::hal::spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_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,
.data_io_default_level = false,
.max_transfer_sz = CYD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
}
};

View File

@ -0,0 +1,6 @@
#pragma once
#include <Tactility/hal/Configuration.h>
// Resistive touch version of the waveshare 2.8" yellow board
extern const tt::hal::Configuration cyd_e32r28t_config;

View File

@ -0,0 +1,41 @@
#include "Display.h"
#include <Xpt2046SoftSpi.h>
#include <Ili934xDisplay.h>
#include <PwmBacklight.h>
#include <Tactility/hal/touch/TouchDevice.h>
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
auto config = std::make_unique<Xpt2046SoftSpi::Configuration>(
CYD_TOUCH_MOSI_PIN,
CYD_TOUCH_MISO_PIN,
CYD_TOUCH_SCK_PIN,
CYD_TOUCH_CS_PIN,
CYD_DISPLAY_HORIZONTAL_RESOLUTION,
CYD_DISPLAY_VERTICAL_RESOLUTION,
false,
true,
false
);
return std::make_shared<Xpt2046SoftSpi>(std::move(config));
}
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
auto configuration = std::make_unique<Ili934xDisplay::Configuration>(
CYD_DISPLAY_SPI_HOST,
CYD_DISPLAY_PIN_CS,
CYD_DISPLAY_PIN_DC,
CYD_DISPLAY_HORIZONTAL_RESOLUTION,
CYD_DISPLAY_VERTICAL_RESOLUTION,
createTouch(),
false,
true,
false,
false,
0,
LCD_RGB_ELEMENT_ORDER_BGR
);
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
return std::make_shared<Ili934xDisplay>(std::move(configuration));
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <Tactility/hal/display/DisplayDevice.h>
#include <memory>
// Display
#define CYD_DISPLAY_SPI_HOST SPI2_HOST
#define CYD_DISPLAY_PIN_CS GPIO_NUM_15
#define CYD_DISPLAY_PIN_DC GPIO_NUM_2
#define CYD_DISPLAY_HORIZONTAL_RESOLUTION 240
#define CYD_DISPLAY_VERTICAL_RESOLUTION 320
#define CYD_DISPLAY_DRAW_BUFFER_HEIGHT (CYD_DISPLAY_VERTICAL_RESOLUTION / 10)
#define CYD_DISPLAY_DRAW_BUFFER_SIZE (CYD_DISPLAY_HORIZONTAL_RESOLUTION * CYD_DISPLAY_DRAW_BUFFER_HEIGHT)
// Touch (Software SPI)
#define CYD_TOUCH_MISO_PIN GPIO_NUM_39
#define CYD_TOUCH_MOSI_PIN GPIO_NUM_32
#define CYD_TOUCH_SCK_PIN GPIO_NUM_25
#define CYD_TOUCH_CS_PIN GPIO_NUM_33
#define CYD_TOUCH_IRQ_PIN GPIO_NUM_36
// Backlight
#define CYD_BACKLIGHT_PIN GPIO_NUM_21
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();

View File

@ -0,0 +1,21 @@
#include "SdCard.h"
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
using tt::hal::sdcard::SpiSdCardDevice;
std::shared_ptr<SdCardDevice> createSdCard() {
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
GPIO_NUM_5,
GPIO_NUM_NC,
GPIO_NUM_NC,
GPIO_NUM_NC,
SdCardDevice::MountBehaviour::AtBoot,
std::make_shared<tt::Mutex>(),
std::vector<gpio_num_t>(),
SPI3_HOST
);
return std::make_shared<SpiSdCardDevice>(
std::move(configuration)
);
}

View File

@ -0,0 +1,7 @@
#pragma once
#include <Tactility/hal/sdcard/SdCardDevice.h>
using tt::hal::sdcard::SdCardDevice;
std::shared_ptr<SdCardDevice> createSdCard();

0
Buildscripts/Flashing/flash.ps1 Normal file → Executable file
View File

View File

@ -25,6 +25,8 @@ function(INIT_TACTILITY_GLOBALS SDKCONFIG_FILE)
set(TACTILITY_BOARD_PROJECT CYD-2432S024C) set(TACTILITY_BOARD_PROJECT CYD-2432S024C)
elseif (board_id STREQUAL "cyd-2432s028r") elseif (board_id STREQUAL "cyd-2432s028r")
set(TACTILITY_BOARD_PROJECT CYD-2432S028R) set(TACTILITY_BOARD_PROJECT CYD-2432S028R)
elseif (board_id STREQUAL "cyd-e32r28t")
set(TACTILITY_BOARD_PROJECT CYD-E32R28T)
elseif (board_id STREQUAL "cyd-2432s032c") elseif (board_id STREQUAL "cyd-2432s032c")
set(TACTILITY_BOARD_PROJECT CYD-2432S032C) set(TACTILITY_BOARD_PROJECT CYD-2432S032C)
elseif (board_id STREQUAL "cyd-4848s040c") elseif (board_id STREQUAL "cyd-4848s040c")

0
Buildscripts/build.ps1 Normal file → Executable file
View File

0
Buildscripts/release.ps1 Normal file → Executable file
View File

View File

@ -5,14 +5,17 @@
- Fix Development service: when no SD card is present, the app fails to install. Consider installing to `/data` - Fix Development service: when no SD card is present, the app fails to install. Consider installing to `/data`
Note: Change app install to "transfer file" functionality. We can have a proper install when we have app packaging. Note: Change app install to "transfer file" functionality. We can have a proper install when we have app packaging.
Note: Consider installation path option in interface Note: Consider installation path option in interface
- Update ILI934x to v2.0.1
- External app loading: Check the version of Tactility and check ESP target hardware to check for compatibility. - External app loading: Check the version of Tactility and check ESP target hardware to check for compatibility.
- Make a URL handler. Use it for handling local files. Match file types with apps. - Make a URL handler. Use it for handling local files. Match file types with apps.
Create some kind of "intent" handler like on Android. Create some kind of "intent" handler like on Android.
The intent can have an action (e.g. view), a URL and an optional bundle. The intent can have an action (e.g. view), a URL and an optional bundle.
The manifest can provide the intent handler The manifest can provide the intent handler
- App packaging
- Bug: GraphicsDemo should check if display supports the DisplayDriver interface (and same for touch) and show an AlertDialog error if there's a problem - Bug: GraphicsDemo should check if display supports the DisplayDriver interface (and same for touch) and show an AlertDialog error if there's a problem
- Update ILI934x to v2.0.1
- App packaging
- Create an "app install paths" settings app to add/remove paths.
Scan these paths on startup.
Make the AppList use the scan results.
## Lower Priority ## Lower Priority

View File

@ -8,7 +8,7 @@
#include <esp_lvgl_port_disp.h> #include <esp_lvgl_port_disp.h>
#include <Tactility/Check.h> #include <Tactility/Check.h>
class EspLcdDisplay : tt::hal::display::DisplayDevice { class EspLcdDisplay : public tt::hal::display::DisplayDevice {
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr; esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
esp_lcd_panel_handle_t _Nullable panelHandle = nullptr; esp_lcd_panel_handle_t _Nullable panelHandle = nullptr;
@ -56,7 +56,7 @@ public:
// endregion // endregion
// region NativeDisplay // region DisplayDriver
bool supportsDisplayDriver() const override { return true; } bool supportsDisplayDriver() const override { return true; }

View File

@ -5,22 +5,55 @@
#include <esp_log.h> #include <esp_log.h>
#include <tt_app.h> #include <tt_app.h>
#include <tt_app_alertdialog.h>
#include <tt_lvgl.h> #include <tt_lvgl.h>
constexpr auto TAG = "Main"; constexpr auto TAG = "Main";
static void onCreate(AppHandle appHandle, void* data) { /** Find a DisplayDevice that supports the DisplayDriver interface */
static bool findUsableDisplay(DeviceId& deviceId) {
uint16_t display_count = 0; uint16_t display_count = 0;
if (!tt_hal_device_find(DEVICE_TYPE_DISPLAY, &deviceId, &display_count, 1)) {
ESP_LOGE(TAG, "No display device found");
return false;
}
if (!tt_hal_display_driver_supported(deviceId)) {
ESP_LOGE(TAG, "Display doesn't support driver mode");
return false;
}
return true;
}
/** Find a TouchDevice that supports the TouchDriver interface */
static bool findUsableTouch(DeviceId& deviceId) {
uint16_t touch_count = 0;
if (!tt_hal_device_find(DEVICE_TYPE_TOUCH, &deviceId, &touch_count, 1)) {
ESP_LOGE(TAG, "No touch device found");
return false;
}
if (!tt_hal_touch_driver_supported(deviceId)) {
ESP_LOGE(TAG, "Touch doesn't support driver mode");
return false;
}
return true;
}
static void onCreate(AppHandle appHandle, void* data) {
DeviceId display_id; DeviceId display_id;
if (!tt_hal_device_find(DEVICE_TYPE_DISPLAY, &display_id, &display_count, 1)) { if (!findUsableDisplay(display_id)) {
ESP_LOGI(TAG, "No display device found"); tt_app_stop();
tt_app_alertdialog_start("Error", "The display doesn't support the required features.", nullptr, 0);
return; return;
} }
uint16_t touch_count = 0;
DeviceId touch_id; DeviceId touch_id;
if (!tt_hal_device_find(DEVICE_TYPE_TOUCH, &touch_id, &touch_count, 1)) { if (!findUsableTouch(touch_id)) {
ESP_LOGI(TAG, "No touch device found"); tt_app_stop();
tt_app_alertdialog_start("Error", "The touch driver doesn't support the required features.", nullptr, 0);
return; return;
} }

View File

@ -251,7 +251,7 @@ esp_err_t DevelopmentService::handleAppInstall(httpd_req_t* request) {
content_left -= content_read; content_left -= content_read;
// Write file // Write file
auto file_path = std::format("/sdcard/{}", filename_entry->second); auto file_path = std::format("/data/{}", filename_entry->second);
auto* file = fopen(file_path.c_str(), "wb"); auto* file = fopen(file_path.c_str(), "wb");
auto file_bytes_written = fwrite(buffer.get(), 1, file_size, file); auto file_bytes_written = fwrite(buffer.get(), 1, file_size, file);
fclose(file); fclose(file);

View File

@ -29,7 +29,7 @@ bool tt_app_has_result(AppHandle handle);
* @param[out] buffer the output buffer (recommended size is 256 bytes) * @param[out] buffer the output buffer (recommended size is 256 bytes)
* @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function * @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function
*/ */
void tt_app_get_data_directory(AppPathsHandle handle, char* buffer, size_t& size); void tt_app_get_data_directory(AppPathsHandle handle, char* buffer, size_t* size);
/** Get the path to the data directory of this app, with LVGL drive letter prefix applied. /** Get the path to the data directory of this app, with LVGL drive letter prefix applied.
* The recommended buffer size is 256 bytes. * The recommended buffer size is 256 bytes.
@ -37,7 +37,7 @@ void tt_app_get_data_directory(AppPathsHandle handle, char* buffer, size_t& size
* @param[out] buffer the output buffer (recommended size is 256 bytes) * @param[out] buffer the output buffer (recommended size is 256 bytes)
* @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function * @param[inout] size used as input for maximum buffer size (including null terminator) and is set with the path string length by this function
*/ */
void tt_app_get_data_directory_lvgl(AppPathsHandle handle, char* buffer, size_t& size); void tt_app_get_data_directory_lvgl(AppPathsHandle handle, char* buffer, size_t* size);
/** /**
* Start an app by id. * Start an app by id.

View File

@ -8,6 +8,8 @@ extern "C" {
typedef unsigned long TickType; typedef unsigned long TickType;
#define MAX_TICKS INT32_MAX
/** /**
* Stall the current task for the specified amount of time. * Stall the current task for the specified amount of time.
* @param milliseconds the time in milliseconds to stall. * @param milliseconds the time in milliseconds to stall.

View File

@ -33,38 +33,40 @@ void tt_app_stop() {
tt::app::stop(); tt::app::stop();
} }
void tt_app_get_data_directory(AppPathsHandle handle, char* buffer, size_t& size) { void tt_app_get_data_directory(AppPathsHandle handle, char* buffer, size_t* size) {
assert(buffer != nullptr); assert(buffer != nullptr);
assert(size > 0); assert(size != nullptr);
assert(*size > 0);
auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths(); auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
auto data_path = paths->getDataDirectory(); auto data_path = paths->getDataDirectory();
auto expected_length = data_path.length() + 1; auto expected_length = data_path.length() + 1;
if (size < expected_length) { if (*size < expected_length) {
TT_LOG_E(TAG, "Path buffer not large enough (%d < %d)", size, expected_length); TT_LOG_E(TAG, "Path buffer not large enough (%d < %d)", size, expected_length);
size = 0; *size = 0;
buffer[0] = 0; buffer[0] = 0;
return; return;
} }
strcpy(buffer, data_path.c_str()); strcpy(buffer, data_path.c_str());
size = data_path.length(); *size = data_path.length();
} }
void tt_app_get_data_directory_lvgl(AppPathsHandle handle, char* buffer, size_t& size) { void tt_app_get_data_directory_lvgl(AppPathsHandle handle, char* buffer, size_t* size) {
assert(buffer != nullptr); assert(buffer != nullptr);
assert(size > 0); assert(size != nullptr);
assert(*size > 0);
auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths(); auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
auto data_path = paths->getDataDirectoryLvgl(); auto data_path = paths->getDataDirectoryLvgl();
auto expected_length = data_path.length() + 1; auto expected_length = data_path.length() + 1;
if (size < expected_length) { if (*size < expected_length) {
TT_LOG_E(TAG, "Path buffer not large enough (%d < %d)", size, expected_length); TT_LOG_E(TAG, "Path buffer not large enough (%d < %d)", size, expected_length);
size = 0; *size = 0;
buffer[0] = 0; buffer[0] = 0;
return; return;
} }
strcpy(buffer, data_path.c_str()); strcpy(buffer, data_path.c_str());
size = data_path.length(); *size = data_path.length();
} }
} }

View File

@ -105,6 +105,7 @@ const esp_elfsym elf_symbols[] {
ESP_ELFSYM_EXPORT(tolower), ESP_ELFSYM_EXPORT(tolower),
ESP_ELFSYM_EXPORT(toupper), ESP_ELFSYM_EXPORT(toupper),
// ESP-IDF // ESP-IDF
ESP_ELFSYM_EXPORT(esp_log),
ESP_ELFSYM_EXPORT(esp_log_write), ESP_ELFSYM_EXPORT(esp_log_write),
ESP_ELFSYM_EXPORT(esp_log_timestamp), ESP_ELFSYM_EXPORT(esp_log_timestamp),
// Tactility // Tactility

View File

@ -0,0 +1,56 @@
# Software defaults
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072
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=4096
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_FATFS_LFN_HEAP=y
CONFIG_FATFS_VOLUME_COUNT=3
# Hardware: Main
CONFIG_TT_BOARD_CYD_E32R28T=y
CONFIG_TT_BOARD_NAME="CYD E32R28T"
CONFIG_TT_BOARD_ID="cyd-e32r28t"
CONFIG_IDF_TARGET="esp32"
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_FLASHMODE_QIO=y
# LVGL
CONFIG_LV_DISP_DEF_REFR_PERIOD=10
CONFIG_LV_DPI_DEF=130 # Adjusted for 2.8" 240x320 (~130 DPI)
CONFIG_LVGL_BUFFER_WIDTH=240
CONFIG_LVGL_BUFFER_HEIGHT=40
CONFIG_LVGL_COLOR_DEPTH=16
# Drivers
CONFIG_DISPLAY_DRIVER_ILI9341=y
CONFIG_TOUCH_DRIVER_XPT2046=y
CONFIG_TOUCH_CALIBRATION=y
CONFIG_SD_CARD_ENABLE=y
# Fix for IRAM
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y
CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH=y
CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y