diff --git a/Boards/CYD-2432S028RV3/Source/CYD2432S028RV3.cpp b/Boards/CYD-2432S028RV3/Source/CYD2432S028RV3.cpp index 0e1d75ba..7095aea8 100644 --- a/Boards/CYD-2432S028RV3/Source/CYD2432S028RV3.cpp +++ b/Boards/CYD-2432S028RV3/Source/CYD2432S028RV3.cpp @@ -5,25 +5,20 @@ #include #include -// SPI Transfer -#define CYD_SPI_TRANSFER_SIZE_LIMIT (CYD2432S028RV3_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8) -// Display backlight (PWM) -#define CYD2432S028RV3_LCD_PIN_BACKLIGHT GPIO_NUM_21 - using namespace tt::hal; static bool initBoot() { - //Set the RGB Led Pins to output and turn them off + // Set the RGB LED Pins to output and turn them off ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); //Red ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); //Green ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT)); //Blue - //0 on, 1 off... yep it's backwards. + // 0 on, 1 off... yep it's backwards. ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_4, 1)); //Red ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); //Green ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_17, 1)); //Blue - return driver::pwmbacklight::init(CYD2432S028RV3_LCD_PIN_BACKLIGHT); + return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT); } static DeviceVector createDevices() { @@ -71,7 +66,7 @@ const Configuration cyd_2432s028rv3_config = { .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, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/CYD-2432S028RV3/Source/devices/Display.cpp b/Boards/CYD-2432S028RV3/Source/devices/Display.cpp index c6760ba9..f4231499 100644 --- a/Boards/CYD-2432S028RV3/Source/devices/Display.cpp +++ b/Boards/CYD-2432S028RV3/Source/devices/Display.cpp @@ -7,12 +7,12 @@ constexpr auto* TAG = "CYD"; static std::shared_ptr createTouch() { auto configuration = std::make_unique( - CYD_TOUCH_MOSI_PIN, - CYD_TOUCH_MISO_PIN, - CYD_TOUCH_SCK_PIN, - CYD_TOUCH_CS_PIN, - CYD2432S028RV3_LCD_HORIZONTAL_RESOLUTION, // 240 - CYD2432S028RV3_LCD_VERTICAL_RESOLUTION, // 320 + TOUCH_MOSI_PIN, + TOUCH_MISO_PIN, + TOUCH_SCK_PIN, + TOUCH_CS_PIN, + LCD_HORIZONTAL_RESOLUTION, // 240 + LCD_VERTICAL_RESOLUTION, // 320 false, // swapXY true, // mirrorX false // mirrorY @@ -31,24 +31,28 @@ static std::shared_ptr createTouch() { } std::shared_ptr createDisplay() { - auto touch = createTouch(); + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 0, + .gapY = 0, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = false, + .bufferSize = LCD_BUFFER_SIZE, + .touch = createTouch(), + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = GPIO_NUM_NC + }; - auto configuration = std::make_unique( - CYD2432S028RV3_LCD_SPI_HOST, - CYD2432S028RV3_LCD_PIN_CS, - CYD2432S028RV3_LCD_PIN_DC, - CYD2432S028RV3_LCD_HORIZONTAL_RESOLUTION, - CYD2432S028RV3_LCD_VERTICAL_RESOLUTION, - touch, - false, // swapXY - false, // mirrorX - false, // mirrorY - false, // invertColor - CYD2432S028RV3_LCD_DRAW_BUFFER_SIZE - ); + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 80'000'000, + .transactionQueueDepth = 10 + }); - configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; - - auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/CYD-2432S028RV3/Source/devices/Display.h b/Boards/CYD-2432S028RV3/Source/devices/Display.h index 709766b2..368b6aeb 100644 --- a/Boards/CYD-2432S028RV3/Source/devices/Display.h +++ b/Boards/CYD-2432S028RV3/Source/devices/Display.h @@ -1,22 +1,28 @@ #pragma once -#include "Tactility/hal/display/DisplayDevice.h" +#include + +#include +#include + #include // Display -#define CYD2432S028RV3_LCD_SPI_HOST SPI2_HOST -#define CYD2432S028RV3_LCD_HORIZONTAL_RESOLUTION 240 -#define CYD2432S028RV3_LCD_VERTICAL_RESOLUTION 320 -#define CYD2432S028RV3_LCD_DRAW_BUFFER_HEIGHT (CYD2432S028RV3_LCD_VERTICAL_RESOLUTION / 10) -#define CYD2432S028RV3_LCD_DRAW_BUFFER_SIZE (CYD2432S028RV3_LCD_HORIZONTAL_RESOLUTION * CYD2432S028RV3_LCD_DRAW_BUFFER_HEIGHT) -#define CYD2432S028RV3_LCD_PIN_CS GPIO_NUM_15 -#define CYD2432S028RV3_LCD_PIN_DC GPIO_NUM_2 +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_15; +constexpr auto LCD_PIN_DC = GPIO_NUM_2; +constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_21; +constexpr auto LCD_HORIZONTAL_RESOLUTION = 240; +constexpr auto LCD_VERTICAL_RESOLUTION = 320; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 10; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; // 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 +constexpr auto TOUCH_MISO_PIN = GPIO_NUM_39; +constexpr auto TOUCH_MOSI_PIN = GPIO_NUM_32; +constexpr auto TOUCH_SCK_PIN = GPIO_NUM_25; +constexpr auto TOUCH_CS_PIN = GPIO_NUM_33; +constexpr auto TOUCH_IRQ_PIN = GPIO_NUM_36; std::shared_ptr createDisplay(); diff --git a/Boards/CYD-JC2432W328C/Source/JC2432W328C.cpp b/Boards/CYD-JC2432W328C/Source/JC2432W328C.cpp index 60034d6e..275d4e77 100644 --- a/Boards/CYD-JC2432W328C/Source/JC2432W328C.cpp +++ b/Boards/CYD-JC2432W328C/Source/JC2432W328C.cpp @@ -8,8 +8,6 @@ using namespace tt::hal; -#define CYD_SPI_TRANSFER_SIZE_LIMIT (JC2432W328C_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8) - static bool initBoot() { //Set the RGB Led Pins to output and turn them off ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); //Red @@ -21,7 +19,7 @@ static bool initBoot() { ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); //Green ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_17, 1)); //Blue - return driver::pwmbacklight::init(JC2432W328C_LCD_PIN_BACKLIGHT); + return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT); } static DeviceVector createDevices() { @@ -88,7 +86,7 @@ const Configuration cyd_jc2432w328c_config = { .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, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/CYD-JC2432W328C/Source/devices/Display.cpp b/Boards/CYD-JC2432W328C/Source/devices/Display.cpp index 1d999461..ebf43413 100644 --- a/Boards/CYD-JC2432W328C/Source/devices/Display.cpp +++ b/Boards/CYD-JC2432W328C/Source/devices/Display.cpp @@ -7,32 +7,36 @@ static std::shared_ptr createTouch() { auto configuration = std::make_unique( I2C_NUM_0, - 240, - 320 + LCD_HORIZONTAL_RESOLUTION, + LCD_VERTICAL_RESOLUTION ); return std::make_shared(std::move(configuration)); } std::shared_ptr createDisplay() { - auto touch = createTouch(); + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 0, + .gapY = 0, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = false, + .bufferSize = LCD_BUFFER_SIZE, + .touch = createTouch(), + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = GPIO_NUM_NC + }; - auto configuration = std::make_unique( - JC2432W328C_LCD_SPI_HOST, - JC2432W328C_LCD_PIN_CS, - JC2432W328C_LCD_PIN_DC, - JC2432W328C_LCD_HORIZONTAL_RESOLUTION, - JC2432W328C_LCD_VERTICAL_RESOLUTION, - touch, - false, - false, - false, - false, - JC2432W328C_LCD_DRAW_BUFFER_SIZE - ); + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 80'000'000, + .transactionQueueDepth = 10 + }); - configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; - - auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/CYD-JC2432W328C/Source/devices/Display.h b/Boards/CYD-JC2432W328C/Source/devices/Display.h index b3cd143d..5a00ee0c 100644 --- a/Boards/CYD-JC2432W328C/Source/devices/Display.h +++ b/Boards/CYD-JC2432W328C/Source/devices/Display.h @@ -1,18 +1,23 @@ #pragma once -#include "Tactility/hal/display/DisplayDevice.h" +#include "Display.h" + +#include #include +#include +#include // Display backlight (PWM) -#define JC2432W328C_LCD_PIN_BACKLIGHT GPIO_NUM_27 +constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_27; // Display -#define JC2432W328C_LCD_SPI_HOST SPI2_HOST -#define JC2432W328C_LCD_HORIZONTAL_RESOLUTION 240 -#define JC2432W328C_LCD_VERTICAL_RESOLUTION 320 -#define JC2432W328C_LCD_DRAW_BUFFER_HEIGHT (JC2432W328C_LCD_VERTICAL_RESOLUTION / 10) -#define JC2432W328C_LCD_DRAW_BUFFER_SIZE (JC2432W328C_LCD_HORIZONTAL_RESOLUTION * JC2432W328C_LCD_DRAW_BUFFER_HEIGHT) -#define JC2432W328C_LCD_PIN_CS GPIO_NUM_15 -#define JC2432W328C_LCD_PIN_DC GPIO_NUM_2 +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_15; +constexpr auto LCD_PIN_DC = GPIO_NUM_2; +constexpr auto LCD_HORIZONTAL_RESOLUTION = 240; +constexpr auto LCD_VERTICAL_RESOLUTION = 320; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 10; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; std::shared_ptr createDisplay(); diff --git a/Boards/CYD-JC2432W328C/Source/devices/SdCard.h b/Boards/CYD-JC2432W328C/Source/devices/SdCard.h index 4da9f5b9..fea58cef 100644 --- a/Boards/CYD-JC2432W328C/Source/devices/SdCard.h +++ b/Boards/CYD-JC2432W328C/Source/devices/SdCard.h @@ -1,6 +1,6 @@ #pragma once -#include "Tactility/hal/sdcard/SdCardDevice.h" +#include using tt::hal::sdcard::SdCardDevice; diff --git a/Boards/ElecrowCrowpanelAdvance28/Source/CrowPanelAdvance28.cpp b/Boards/ElecrowCrowpanelAdvance28/Source/CrowPanelAdvance28.cpp index b9b9d583..82f185e4 100644 --- a/Boards/ElecrowCrowpanelAdvance28/Source/CrowPanelAdvance28.cpp +++ b/Boards/ElecrowCrowpanelAdvance28/Source/CrowPanelAdvance28.cpp @@ -1,12 +1,10 @@ #include "PwmBacklight.h" -#include "Tactility/lvgl/LvglSync.h" #include "devices/Display.h" #include "devices/SdCard.h" +#include #include -#define CROWPANEL_SPI_TRANSFER_SIZE_LIMIT (CROWPANEL_LCD_HORIZONTAL_RESOLUTION * CROWPANEL_LCD_SPI_TRANSFER_HEIGHT * (LV_COLOR_DEPTH / 8)) - using namespace tt::hal; static bool initBoot() { @@ -60,7 +58,7 @@ extern const Configuration crowpanel_advance_28 = { .data6_io_num = GPIO_NUM_NC, .data7_io_num = GPIO_NUM_NC, .data_io_default_level = false, - .max_transfer_sz = CROWPANEL_SPI_TRANSFER_SIZE_LIMIT, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.cpp b/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.cpp index 0627b99a..f65cd01c 100644 --- a/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.cpp +++ b/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.cpp @@ -8,8 +8,8 @@ static std::shared_ptr createTouch() { // Note for future changes: Reset pin is 48 and interrupt pin is 47 auto configuration = std::make_unique( I2C_NUM_0, - 240, - 320, + LCD_HORIZONTAL_RESOLUTION, + LCD_VERTICAL_RESOLUTION, false, false, false @@ -19,23 +19,28 @@ static std::shared_ptr createTouch() { } std::shared_ptr createDisplay() { - auto touch = createTouch(); + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 0, + .gapY = 0, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = true, + .bufferSize = LCD_BUFFER_SIZE, + .touch = createTouch(), + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = GPIO_NUM_NC + }; - auto configuration = std::make_unique( - CROWPANEL_LCD_SPI_HOST, - CROWPANEL_LCD_PIN_CS, - CROWPANEL_LCD_PIN_DC, - 240, - 320, - touch, - false, - false, - false, - true - ); + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 80'000'000, + .transactionQueueDepth = 10 + }); - configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; - - auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.h b/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.h index e1a299f3..6f986d05 100644 --- a/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.h +++ b/Boards/ElecrowCrowpanelAdvance28/Source/devices/Display.h @@ -2,11 +2,16 @@ #include -#define CROWPANEL_LCD_SPI_HOST SPI2_HOST -#define CROWPANEL_LCD_PIN_CS GPIO_NUM_40 -#define CROWPANEL_LCD_PIN_DC GPIO_NUM_41 // RS -#define CROWPANEL_LCD_HORIZONTAL_RESOLUTION 320 -#define CROWPANEL_LCD_VERTICAL_RESOLUTION 240 -#define CROWPANEL_LCD_SPI_TRANSFER_HEIGHT (CROWPANEL_LCD_VERTICAL_RESOLUTION / 10) +#include +#include + +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_40; +constexpr auto LCD_PIN_DC = GPIO_NUM_41; // RS +constexpr auto LCD_HORIZONTAL_RESOLUTION = 240; +constexpr auto LCD_VERTICAL_RESOLUTION = 320; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 10; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; std::shared_ptr createDisplay(); diff --git a/Boards/LilygoTdeck/Source/LilygoTdeck.cpp b/Boards/LilygoTdeck/Source/LilygoTdeck.cpp index f5de109f..4f3eaccb 100644 --- a/Boards/LilygoTdeck/Source/LilygoTdeck.cpp +++ b/Boards/LilygoTdeck/Source/LilygoTdeck.cpp @@ -6,8 +6,6 @@ #include "devices/Sdcard.h" #include "devices/TdeckKeyboard.h" -#define TDECK_SPI_TRANSFER_SIZE_LIMIT (320 * 240 * (LV_COLOR_DEPTH / 8)) - bool initBoot(); using namespace tt::hal; @@ -75,7 +73,7 @@ extern const Configuration lilygo_tdeck = { .data6_io_num = GPIO_NUM_NC, .data7_io_num = GPIO_NUM_NC, .data_io_default_level = false, - .max_transfer_sz = TDECK_SPI_TRANSFER_SIZE_LIMIT, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/LilygoTdeck/Source/devices/Display.cpp b/Boards/LilygoTdeck/Source/devices/Display.cpp index ef04affb..be73e8ae 100644 --- a/Boards/LilygoTdeck/Source/devices/Display.cpp +++ b/Boards/LilygoTdeck/Source/devices/Display.cpp @@ -4,13 +4,6 @@ #include #include -#define TDECK_LCD_SPI_HOST SPI2_HOST -#define TDECK_LCD_PIN_CS GPIO_NUM_12 -#define TDECK_LCD_PIN_DC GPIO_NUM_11 // RS -#define TDECK_LCD_HORIZONTAL_RESOLUTION 320 -#define TDECK_LCD_VERTICAL_RESOLUTION 240 -#define TDECK_LCD_SPI_TRANSFER_HEIGHT (TDECK_LCD_VERTICAL_RESOLUTION / 10) - static std::shared_ptr createTouch() { // Note for future changes: Reset pin is 48 and interrupt pin is 47 auto configuration = std::make_unique( @@ -26,23 +19,28 @@ static std::shared_ptr createTouch() { } std::shared_ptr createDisplay() { - auto touch = createTouch(); + St7789Display::Configuration panel_configuration = { + .horizontalResolution = 320, + .verticalResolution = 240, + .gapX = 0, + .gapY = 0, + .swapXY = true, + .mirrorX = true, + .mirrorY = false, + .invertColor = true, + .bufferSize = LCD_BUFFER_SIZE, + .touch = createTouch(), + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = GPIO_NUM_NC + }; - auto configuration = std::make_unique( - TDECK_LCD_SPI_HOST, - TDECK_LCD_PIN_CS, - TDECK_LCD_PIN_DC, - 320, - 240, - touch, - true, - true, - false, - true - ); + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 80'000'000, + .transactionQueueDepth = 10 + }); - configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; - - auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/LilygoTdeck/Source/devices/Display.h b/Boards/LilygoTdeck/Source/devices/Display.h index 7a9b967d..fba2239c 100644 --- a/Boards/LilygoTdeck/Source/devices/Display.h +++ b/Boards/LilygoTdeck/Source/devices/Display.h @@ -1,5 +1,16 @@ #pragma once #include +#include +#include + +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_12; +constexpr auto LCD_PIN_DC = GPIO_NUM_11; // RS +constexpr auto LCD_HORIZONTAL_RESOLUTION = 320; +constexpr auto LCD_VERTICAL_RESOLUTION = 240; +constexpr auto LCD_BUFFER_HEIGHT = (LCD_VERTICAL_RESOLUTION / 3); +constexpr auto LCD_BUFFER_SIZE = (LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT); +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; std::shared_ptr createDisplay(); diff --git a/Boards/M5stackCardputer/Source/M5stackCardputer.cpp b/Boards/M5stackCardputer/Source/M5stackCardputer.cpp index 9b8137a0..3a481d1b 100644 --- a/Boards/M5stackCardputer/Source/M5stackCardputer.cpp +++ b/Boards/M5stackCardputer/Source/M5stackCardputer.cpp @@ -9,8 +9,6 @@ #include #include -#define SPI_TRANSFER_SIZE_LIMIT (LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8) - using namespace tt::hal; static DeviceVector createDevices() { @@ -62,7 +60,7 @@ extern const Configuration m5stack_cardputer = { .data6_io_num = GPIO_NUM_NC, .data7_io_num = GPIO_NUM_NC, .data_io_default_level = false, - .max_transfer_sz = SPI_TRANSFER_SIZE_LIMIT, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/M5stackCardputer/Source/devices/Display.cpp b/Boards/M5stackCardputer/Source/devices/Display.cpp index b9bfa346..98544c2f 100644 --- a/Boards/M5stackCardputer/Source/devices/Display.cpp +++ b/Boards/M5stackCardputer/Source/devices/Display.cpp @@ -4,25 +4,28 @@ #include std::shared_ptr createDisplay() { - auto configuration = std::make_unique( - LCD_SPI_HOST, - LCD_PIN_CS, - LCD_PIN_DC, - LCD_HORIZONTAL_RESOLUTION, - LCD_VERTICAL_RESOLUTION, - nullptr, - true, - true, - false, - true, - 0, - 53, // Should be 52 according to https://github.com/m5stack/M5GFX/blob/master/src/M5GFX.cpp but this leaves a gap at the bottom - 40 - ); + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 53, // Should be 52 according to https://github.com/m5stack/M5GFX/blob/master/src/M5GFX.cpp but this leaves a gap at the bottom + .gapY = 40, + .swapXY = true, + .mirrorX = true, + .mirrorY = false, + .invertColor = true, + .bufferSize = LCD_BUFFER_SIZE, + .touch = nullptr, + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = LCD_PIN_RESET + }; - configuration->resetPin = LCD_PIN_RESET; - configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 80'000'000, + .transactionQueueDepth = 10 + }); - auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/M5stackCardputer/Source/devices/Display.h b/Boards/M5stackCardputer/Source/devices/Display.h index c466c7dc..09dcd812 100644 --- a/Boards/M5stackCardputer/Source/devices/Display.h +++ b/Boards/M5stackCardputer/Source/devices/Display.h @@ -1,15 +1,18 @@ #pragma once -#include "Tactility/hal/display/DisplayDevice.h" +#include #include +#include +#include -#define LCD_SPI_HOST SPI2_HOST -#define LCD_PIN_CS GPIO_NUM_37 -#define LCD_PIN_DC GPIO_NUM_34 // RS -#define LCD_PIN_RESET GPIO_NUM_33 -#define LCD_HORIZONTAL_RESOLUTION 240 -#define LCD_VERTICAL_RESOLUTION 135 -#define LCD_DRAW_BUFFER_HEIGHT (LCD_VERTICAL_RESOLUTION / 10) -#define LCD_DRAW_BUFFER_SIZE (LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT) +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_37; +constexpr auto LCD_PIN_DC = GPIO_NUM_34; // RS +constexpr auto LCD_PIN_RESET = GPIO_NUM_33; +constexpr auto LCD_HORIZONTAL_RESOLUTION = 240; +constexpr auto LCD_VERTICAL_RESOLUTION = 135; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 10; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; std::shared_ptr createDisplay(); diff --git a/Boards/M5stackStickCPlus/Source/M5StackStickCPlus.cpp b/Boards/M5stackStickCPlus/Source/M5StackStickCPlus.cpp index 5f5ab6c4..65eacdff 100644 --- a/Boards/M5stackStickCPlus/Source/M5StackStickCPlus.cpp +++ b/Boards/M5stackStickCPlus/Source/M5StackStickCPlus.cpp @@ -5,15 +5,9 @@ #include -#define SPI_TRANSFER_SIZE_LIMIT (LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8) - using namespace tt::hal; -constexpr auto* TAG = "StickCPlus"; - bool initBoot() { - TT_LOG_I(TAG, "initBoot"); - // CH552 applies 4 V to GPIO 0, which reduces Wi-Fi sensitivity // Setting output to high adds a bias of 3.3 V and suppresses over-voltage: gpio::configure(0, gpio::Mode::Output, false, false); @@ -85,7 +79,7 @@ extern const Configuration m5stack_stickc_plus = { .data6_io_num = GPIO_NUM_NC, .data7_io_num = GPIO_NUM_NC, .data_io_default_level = false, - .max_transfer_sz = SPI_TRANSFER_SIZE_LIMIT, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/M5stackStickCPlus/Source/devices/Display.cpp b/Boards/M5stackStickCPlus/Source/devices/Display.cpp index 82c45907..801db69d 100644 --- a/Boards/M5stackStickCPlus/Source/devices/Display.cpp +++ b/Boards/M5stackStickCPlus/Source/devices/Display.cpp @@ -38,26 +38,28 @@ static void setBrightness(uint8_t brightness) { } std::shared_ptr createDisplay() { - auto configuration = std::make_unique( - LCD_SPI_HOST, - LCD_PIN_CS, - LCD_PIN_DC, - LCD_HORIZONTAL_RESOLUTION, - LCD_VERTICAL_RESOLUTION, - nullptr, - false, - false, - false, - true, - LCD_DRAW_BUFFER_SIZE, - 52, - 40 - ); + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 52, + .gapY = 40, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = true, + .bufferSize = LCD_BUFFER_SIZE, + .touch = nullptr, + .backlightDutyFunction = setBrightness, + .resetPin = LCD_PIN_RESET + }; - configuration->pixelClockFrequency = 40'000'000; - configuration->resetPin = LCD_PIN_RESET; + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 40'000'000, + .transactionQueueDepth = 10 + }); - configuration->backlightDutyFunction = setBrightness; - const auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/M5stackStickCPlus/Source/devices/Display.h b/Boards/M5stackStickCPlus/Source/devices/Display.h index 2cacfee8..bcab89c0 100644 --- a/Boards/M5stackStickCPlus/Source/devices/Display.h +++ b/Boards/M5stackStickCPlus/Source/devices/Display.h @@ -1,15 +1,18 @@ #pragma once -#include "Tactility/hal/display/DisplayDevice.h" +#include #include +#include +#include -#define LCD_SPI_HOST SPI2_HOST -#define LCD_PIN_CS GPIO_NUM_5 -#define LCD_PIN_DC GPIO_NUM_23 -#define LCD_PIN_RESET GPIO_NUM_18 -#define LCD_HORIZONTAL_RESOLUTION 135 -#define LCD_VERTICAL_RESOLUTION 240 -#define LCD_DRAW_BUFFER_HEIGHT (LCD_VERTICAL_RESOLUTION / 3) -#define LCD_DRAW_BUFFER_SIZE (LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT) +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_5; +constexpr auto LCD_PIN_DC = GPIO_NUM_23; +constexpr auto LCD_PIN_RESET = GPIO_NUM_18; +constexpr auto LCD_HORIZONTAL_RESOLUTION = 135; +constexpr auto LCD_VERTICAL_RESOLUTION = 240; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 3; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; std::shared_ptr createDisplay(); diff --git a/Boards/M5stackStickCPlus2/Source/M5StackStickCPlus2.cpp b/Boards/M5stackStickCPlus2/Source/M5StackStickCPlus2.cpp index aa8cb0e0..051f3c40 100644 --- a/Boards/M5stackStickCPlus2/Source/M5StackStickCPlus2.cpp +++ b/Boards/M5stackStickCPlus2/Source/M5StackStickCPlus2.cpp @@ -5,15 +5,9 @@ #include #include -#define SPI_TRANSFER_SIZE_LIMIT (LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8) - using namespace tt::hal; -constexpr auto* TAG = "StickCPlus2"; - bool initBoot() { - TT_LOG_I(TAG, "initBoot"); - // CH552 applies 4 V to GPIO 0, which reduces Wi-Fi sensitivity // Setting output to high adds a bias of 3.3 V and suppresses over-voltage: gpio::configure(0, gpio::Mode::Output, false, false); @@ -87,7 +81,7 @@ extern const Configuration m5stack_stickc_plus2 = { .data6_io_num = GPIO_NUM_NC, .data7_io_num = GPIO_NUM_NC, .data_io_default_level = false, - .max_transfer_sz = SPI_TRANSFER_SIZE_LIMIT, + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/M5stackStickCPlus2/Source/devices/Display.cpp b/Boards/M5stackStickCPlus2/Source/devices/Display.cpp index f97b88c8..f4573233 100644 --- a/Boards/M5stackStickCPlus2/Source/devices/Display.cpp +++ b/Boards/M5stackStickCPlus2/Source/devices/Display.cpp @@ -4,26 +4,28 @@ #include std::shared_ptr createDisplay() { - auto configuration = std::make_unique( - LCD_SPI_HOST, - LCD_PIN_CS, - LCD_PIN_DC, - LCD_HORIZONTAL_RESOLUTION, - LCD_VERTICAL_RESOLUTION, - nullptr, - false, - false, - false, - true, - LCD_DRAW_BUFFER_SIZE, - 52, - 40 - ); + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 52, + .gapY = 40, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = true, + .bufferSize = LCD_BUFFER_SIZE, + .touch = nullptr, + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = LCD_PIN_RESET + }; - configuration->pixelClockFrequency = 40'000'000; - configuration->resetPin = LCD_PIN_RESET; - configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = LCD_SPI_HOST, + .csPin = LCD_PIN_CS, + .dcPin = LCD_PIN_DC, + .pixelClockFrequency = 40'000'000, + .transactionQueueDepth = 10 + }); - const auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/M5stackStickCPlus2/Source/devices/Display.h b/Boards/M5stackStickCPlus2/Source/devices/Display.h index 87c666dc..396fe2d9 100644 --- a/Boards/M5stackStickCPlus2/Source/devices/Display.h +++ b/Boards/M5stackStickCPlus2/Source/devices/Display.h @@ -2,14 +2,17 @@ #include "Tactility/hal/display/DisplayDevice.h" #include +#include +#include -#define LCD_SPI_HOST SPI2_HOST -#define LCD_PIN_CS GPIO_NUM_5 -#define LCD_PIN_DC GPIO_NUM_14 -#define LCD_PIN_RESET GPIO_NUM_12 -#define LCD_HORIZONTAL_RESOLUTION 135 -#define LCD_VERTICAL_RESOLUTION 240 -#define LCD_DRAW_BUFFER_HEIGHT (LCD_VERTICAL_RESOLUTION / 3) -#define LCD_DRAW_BUFFER_SIZE (LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT) +constexpr auto LCD_SPI_HOST = SPI2_HOST; +constexpr auto LCD_PIN_CS = GPIO_NUM_5; +constexpr auto LCD_PIN_DC = GPIO_NUM_14; +constexpr auto LCD_PIN_RESET = GPIO_NUM_12; +constexpr auto LCD_HORIZONTAL_RESOLUTION = 135; +constexpr auto LCD_VERTICAL_RESOLUTION = 240; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 3; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; std::shared_ptr createDisplay(); diff --git a/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.cpp b/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.cpp index 0663244e..09b35315 100644 --- a/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.cpp +++ b/Boards/WaveshareS3Lcd13/Source/WaveshareS3Lcd13.cpp @@ -58,7 +58,7 @@ extern const Configuration waveshare_s3_lcd_13 = { .data6_io_num = GPIO_NUM_NC, .data7_io_num = GPIO_NUM_NC, .data_io_default_level = false, - .max_transfer_sz = ((240 * (240 / 10)) * LV_COLOR_DEPTH / 8), + .max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT, .flags = 0, .isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO, .intr_flags = 0 diff --git a/Boards/WaveshareS3Lcd13/Source/devices/Display.cpp b/Boards/WaveshareS3Lcd13/Source/devices/Display.cpp index d555483c..34c1428d 100644 --- a/Boards/WaveshareS3Lcd13/Source/devices/Display.cpp +++ b/Boards/WaveshareS3Lcd13/Source/devices/Display.cpp @@ -4,24 +4,28 @@ #include std::shared_ptr createDisplay() { + St7789Display::Configuration panel_configuration = { + .horizontalResolution = LCD_HORIZONTAL_RESOLUTION, + .verticalResolution = LCD_VERTICAL_RESOLUTION, + .gapX = 0, + .gapY = 0, + .swapXY = false, + .mirrorX = false, + .mirrorY = false, + .invertColor = true, + .bufferSize = LCD_BUFFER_SIZE, + .touch = nullptr, + .backlightDutyFunction = driver::pwmbacklight::setBacklightDuty, + .resetPin = GPIO_NUM_42 + }; - auto configuration = std::make_unique( - SPI2_HOST, - GPIO_NUM_39, - GPIO_NUM_38, - 240, - 240, - nullptr, - false, - false, - false, - true - ); + auto spi_configuration = std::make_shared(St7789Display::SpiConfiguration { + .spiHostDevice = SPI2_HOST, + .csPin = GPIO_NUM_39, + .dcPin = GPIO_NUM_38, + .pixelClockFrequency = 80'000'000, + .transactionQueueDepth = 10 + }); - - configuration->resetPin = GPIO_NUM_42; - configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty; - - auto display = std::make_shared(std::move(configuration)); - return std::reinterpret_pointer_cast(display); + return std::make_shared(panel_configuration, spi_configuration); } diff --git a/Boards/WaveshareS3Lcd13/Source/devices/Display.h b/Boards/WaveshareS3Lcd13/Source/devices/Display.h index b3ce9fb5..e08682b4 100644 --- a/Boards/WaveshareS3Lcd13/Source/devices/Display.h +++ b/Boards/WaveshareS3Lcd13/Source/devices/Display.h @@ -1,5 +1,11 @@ #pragma once -#include "Tactility/hal/display/DisplayDevice.h" +#include -std::shared_ptr createDisplay(); \ No newline at end of file +std::shared_ptr createDisplay(); + +constexpr auto LCD_HORIZONTAL_RESOLUTION = 240; +constexpr auto LCD_VERTICAL_RESOLUTION = 240; +constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 3; +constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT; +constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8; diff --git a/Buildscripts/build-and-release-all.sh b/Buildscripts/build-and-release-all.sh deleted file mode 100755 index 37737cab..00000000 --- a/Buildscripts/build-and-release-all.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/sh - -function build() { - Buildscripts/build.sh $1 -} - -function release() { - Buildscripts/release.sh $1 -} - -function releaseSdk() { - Buildscripts/release-sdk.sh $1 -} - -SECONDS=0 - -build elecrow-crowpanel-advance-28 -release elecrow-crowpanel-advance-28 - -build elecrow-crowpanel-advance-35 -release elecrow-crowpanel-advance-35 - -build elecrow-crowpanel-advance-50 -release elecrow-crowpanel-advance-50 - -build elecrow-crowpanel-basic-28 -release elecrow-crowpanel-basic-28 - -build elecrow-crowpanel-basic-35 -release elecrow-crowpanel-basic-35 - -build elecrow-crowpanel-basic-50 -release elecrow-crowpanel-basic-50 - -build lilygo-tdeck -release lilygo-tdeck - -build lilygo-tdongle-s3 -release lilygo-tdongle-s3 - -build lilygo-tlora-pager -release lilygo-tlora-pager - -releaseSdk release/TactilitySDK-esp32s3 - -build cyd-2432s024c -release cyd-2432s024c - -build cyd-2432s028r -release cyd-2432s028r - -build cyd-2432s032c -release cyd-2432s032c - -build cyd-4848s040c -release cyd-4848s040c - -build cyd-8048s043c -release cyd-8048s043c - -build cyd-e32r28t -release cyd-e32r28t - -build cyd-jc2432w328c -release cyd-jc2432w328c - -build cyd-jc8048w550c -release cyd-jc8048w550c - -build m5stack-core2 -release m5stack-core2 - -releaseSdk release/TactilitySDK-esp32 - -build m5stack-cardputer -release m5stack-cardputer - -build m5stack-cores3 -release m5stack-cores3 - -build m5stack-stickc-plus -release m5stack-stickc-plus - -build m5stack-stickc-plus2 -release m5stack-stickc-plus2 - -build waveshare-s3-touch-43 -release waveshare-s3-touch-43 - -build waveshare-s3-touch-lcd-147 -release waveshare-s3-touch-lcd-147 - -build waveshare-s3-touch-lcd-128 -release waveshare-s3-touch-lcd-128 - -build waveshare-s3-lcd-13 -release waveshare-s3-lcd-13 - -build unphone -release unphone - -duration=$SECONDS - -echo "Finished in $((duration / 60)) minutes and $((duration % 60)) seconds." \ No newline at end of file diff --git a/Buildscripts/build.ps1 b/Buildscripts/build.ps1 deleted file mode 100755 index 135e8465..00000000 --- a/Buildscripts/build.ps1 +++ /dev/null @@ -1,50 +0,0 @@ -<# -.SYNOPSIS - Usage: build.ps1 [boardname] - Example: build.ps1 lilygo-tdeck - Description: Makes a clean build for the specified board. -#> - -function EchoNewPhase { - param ( - [string]$message - ) - Write-Host "⏳ $message" -ForegroundColor Cyan -} - -function FatalError { - param ( - [string]$message - ) - Write-Host "⚠️ $message" -ForegroundColor Red - exit 0 -} - -$sdkconfig_file = "sdkconfig.board.$($args[0])" - -if ($args.Count -lt 1) { - FatalError "Must pass board name as first argument. (e.g. lilygo_tdeck)" -} - -if (-Not (Test-Path $sdkconfig_file)) { - FatalError "Board not found: $sdkconfig_file" -} - -EchoNewPhase "Cleaning build folder" -$BuildFolder = "build" -if (Test-Path $BuildFolder) { - Remove-Item -Path $BuildFolder -Recurse -Force - EchoNewPhase "Build folder deleted" -} else { - EchoNewPhase "Build folder doesn't exist." -} - -EchoNewPhase "Building $sdkconfig_file" - -Copy-Item -Path $sdkconfig_file -Destination "sdkconfig" - -try { - & idf.py build -} catch { - FatalError "Failed to build esp32s3 SDK" -} diff --git a/Buildscripts/build.sh b/Buildscripts/build.sh deleted file mode 100755 index b4abca05..00000000 --- a/Buildscripts/build.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# -# Usage: build.sh [boardname] -# Example: build.sh lilygo-tdeck -# Description: Makes a clean build for the specified board. -# - -echoNewPhase() { - echo -e "⏳ \e[36m${1}\e[0m" -} - -fatalError() { - echo -e "⚠️ \e[31m${1}\e[0m" - exit 0 -} - -sdkconfig_file="sdkconfig.board.${1}" - -if [ $# -lt 1 ]; then - fatalError "Must pass board name as first argument. (e.g. lilygo_tdeck)" -fi - -if [ ! -f $sdkconfig_file ]; then - fatalError "Board not found: ${sdkconfig_file}" -fi - -echoNewPhase "Cleaning build folder" - -#rm -rf build - -echoNewPhase "Building $sdkconfig_file" - -cp $sdkconfig_file sdkconfig -idf.py build -if [[ $? != 0 ]]; then - fatalError "Failed to build esp32s3 SDK" -fi - diff --git a/Buildscripts/release.ps1 b/Buildscripts/release.ps1 deleted file mode 100755 index ec975733..00000000 --- a/Buildscripts/release.ps1 +++ /dev/null @@ -1,79 +0,0 @@ -<# -.SYNOPSIS -Releases the current build labeled as a release for the specified board name. - -.DESCRIPTION -Usage: .\release.ps1 [boardname] -Example: .\release.ps1 lilygo-tdeck - -.PARAMETER board -The name of the board to release. -#> - -function EchoNewPhase { - param( - [string]$Message - ) - Write-Host "⏳ $message" -ForegroundColor Cyan -} - -function FatalError { - param( - [string]$Message - ) - Write-Host "⚠️ $message" -ForegroundColor Red - exit 0 -} - -function Release-Symbols { - param( - [string]$TargetPath - ) - - EchoNewPhase "Making symbols release at '$TargetPath'" - New-Item -ItemType Directory -Path $TargetPath -Force | Out-Null - Copy-Item -Path "build\*.elf" -Destination $TargetPath -Force -} - -function Release-Build { - param( - [string]$TargetPath - ) - - EchoNewPhase "Making release at '$TargetPath'" - - $binPath = Join-Path $TargetPath "Binaries" - $partitionTablePath = Join-Path $binPath "partition_table" - $bootloaderPath = Join-Path $binPath "bootloader" - - New-Item -ItemType Directory -Path $binPath -Force | Out-Null - New-Item -ItemType Directory -Path $partitionTablePath -Force | Out-Null - New-Item -ItemType Directory -Path $bootloaderPath -Force | Out-Null - - Copy-Item -Path "build\*.bin" -Destination $binPath -Force - Copy-Item -Path "build\bootloader\*.bin" -Destination $bootloaderPath -Force - Copy-Item -Path "build\partition_table\*.bin" -Destination $partitionTablePath -Force - Copy-Item -Path "build\flash_args" -Destination $binPath -Force - Copy-Item -Path "build\flasher_args.json" -Destination $binPath -Force - - Copy-Item -Path "Buildscripts\Flashing\*" -Destination $TargetPath -Force -} - -# Script start -$releasePath = "release" -$sdkconfig_file = "sdkconfig.board.$($args[0])" -$board = "$($args[0])" - -if ($args.Count -lt 1) { - FatalError "Must pass board name as first argument. (e.g. lilygo_tdeck)" -} - -if (-not (Test-Path $sdkconfig_file)) { - FatalError "Board not found: $sdkconfig_file" -} - -$targetReleasePath = Join-Path $releasePath "Tactility-$board" -$targetSymbolsPath = Join-Path $releasePath "Tactility-$board-symbols" - -Release-Build $targetReleasePath -Release-Symbols $targetSymbolsPath diff --git a/Buildscripts/runtests.sh b/Buildscripts/runtests.sh deleted file mode 100755 index 0f484589..00000000 --- a/Buildscripts/runtests.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -cmake -S ./ -B build-sim -cmake --build build-sim --target build-tests -j 14 -build-sim/Tests/TactilityCore/TactilityCoreTests --exit -build-sim/Tests/Tactility/TactilityTests --exit - diff --git a/Documentation/ideas.md b/Documentation/ideas.md index 739501c3..e49a5a84 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -3,6 +3,7 @@ ## Before release - Make better esp_lcd driver (and test all devices) +- AppInstall.cpp fails to untar large files on Cardputer (EFF large word list doesn't fit in memory). Make a buffered reader & writer. ## Higher Priority diff --git a/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.cpp b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.cpp new file mode 100644 index 00000000..0d39e782 --- /dev/null +++ b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.cpp @@ -0,0 +1,226 @@ +#include "EspLcdDisplayV2.h" +#include "EspLcdDisplayDriver.h" + +#include +#include +#include +#include +#include + +constexpr auto* TAG = "EspLcdDispV2"; + +inline unsigned int getBufferSize(const std::shared_ptr& configuration) { + if (configuration->bufferSize != DEFAULT_BUFFER_SIZE) { + return configuration->bufferSize; + } else { + return configuration->horizontalResolution * (configuration->verticalResolution / 10); + } +} + +EspLcdDisplayV2::~EspLcdDisplayV2() { + if (displayDriver != nullptr && displayDriver.use_count() > 1) { + tt_crash("DisplayDriver is still in use. This will cause memory access violations."); + } +} + +bool EspLcdDisplayV2::applyConfiguration() const { + 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_invert_color(panelHandle, configuration->invertColor) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set panel to invert"); + return false; + } + + // Warning: it looks like LVGL rotation is broken when "gap" is set and the screen is moved to a non-default orientation + int gap_x = configuration->swapXY ? configuration->gapY : configuration->gapX; + int gap_y = configuration->swapXY ? configuration->gapX : configuration->gapY; + if (esp_lcd_panel_set_gap(panelHandle, gap_x, gap_y) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set panel gap"); + return false; + } + + if (esp_lcd_panel_swap_xy(panelHandle, configuration->swapXY) != ESP_OK) { + TT_LOG_E(TAG, "Failed to swap XY "); + return false; + } + + if (esp_lcd_panel_mirror(panelHandle, configuration->mirrorX, configuration->mirrorY) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set panel to mirror"); + return false; + } + + if (esp_lcd_panel_invert_color(panelHandle, configuration->invertColor) != 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; + } + + return true; +} + +bool EspLcdDisplayV2::start() { + if (!createIoHandle(ioHandle)) { + TT_LOG_E(TAG, "Failed to create IO handle"); + return false; + } + + esp_lcd_panel_dev_config_t panel_config = createPanelConfig(configuration, configuration->resetPin); + + if (!createPanelHandle(ioHandle, panel_config, panelHandle)) { + TT_LOG_E(TAG, "Failed to create panel handle"); + esp_lcd_panel_io_del(ioHandle); + ioHandle = nullptr; + return false; + } + + if (!applyConfiguration()) { + esp_lcd_panel_del(panelHandle); + panelHandle = nullptr; + esp_lcd_panel_io_del(ioHandle); + ioHandle = nullptr; + return false; + } + + return true; +} + +bool EspLcdDisplayV2::stop() { + if (lvglDisplay != nullptr) { + stopLvgl(); + lvglDisplay = nullptr; + } + + if (panelHandle != nullptr && esp_lcd_panel_del(panelHandle) != ESP_OK) { + return false; + } + + if (ioHandle != nullptr && esp_lcd_panel_io_del(ioHandle) != ESP_OK) { + return false; + } + + if (displayDriver != nullptr && displayDriver.use_count() > 1) { + TT_LOG_W(TAG, "DisplayDriver is still in use."); + } + + return true; +} + +bool EspLcdDisplayV2::startLvgl() { + assert(lvglDisplay == nullptr); + + if (displayDriver != nullptr && displayDriver.use_count() > 1) { + TT_LOG_W(TAG, "DisplayDriver is still in use."); + } + + auto lvgl_port_config = getLvglPortDisplayConfig(configuration, ioHandle, panelHandle); + + if (isRgbPanel()) { + auto rgb_config = getLvglPortDisplayRgbConfig(ioHandle, panelHandle); + lvglDisplay = lvgl_port_add_disp_rgb(&lvgl_port_config , &rgb_config); + } else { + lvglDisplay = lvgl_port_add_disp(&lvgl_port_config ); + } + + auto touch_device = getTouchDevice(); + if (touch_device != nullptr && touch_device->supportsLvgl()) { + touch_device->startLvgl(lvglDisplay); + } + + return lvglDisplay != nullptr; +} + +bool EspLcdDisplayV2::stopLvgl() { + if (lvglDisplay == nullptr) { + return false; + } + + auto touch_device = getTouchDevice(); + if (touch_device != nullptr) { + touch_device->stopLvgl(); + } + + lvgl_port_remove_disp(lvglDisplay); + lvglDisplay = nullptr; + return true; +} + +lvgl_port_display_cfg_t EspLcdDisplayV2::getLvglPortDisplayConfig(std::shared_ptr configuration, esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { + return lvgl_port_display_cfg_t { + .io_handle = ioHandle, + .panel_handle = panelHandle, + .control_handle = nullptr, + .buffer_size = getBufferSize(configuration), + .double_buffer = false, + .trans_size = 0, + .hres = configuration->horizontalResolution, + .vres = configuration->verticalResolution, + .monochrome = configuration->monochrome, + .rotation = { + .swap_xy = configuration->swapXY, + .mirror_x = configuration->mirrorX, + .mirror_y = configuration->mirrorY, + }, + .color_format = configuration->lvglColorFormat, + .flags = { + .buff_dma = 1, + .buff_spiram = 0, + .sw_rotate = 0, + .swap_bytes = configuration->lvglSwapBytes, + .full_refresh = 0, + .direct_mode = 0 + } + }; +} + +std::shared_ptr EspLcdDisplayV2::getDisplayDriver() { + assert(lvglDisplay == nullptr); // Still attached to LVGL context. Call stopLvgl() first. + if (displayDriver == nullptr) { + auto lvgl_port_config = getLvglPortDisplayConfig(configuration, ioHandle, panelHandle); + auto panel_config = createPanelConfig(configuration, GPIO_NUM_NC); + + tt::hal::display::ColorFormat color_format; + if (lvgl_port_config.color_format == LV_COLOR_FORMAT_I1) { + color_format = tt::hal::display::ColorFormat::Monochrome; + } else if (lvgl_port_config.color_format == LV_COLOR_FORMAT_RGB565) { + if (panel_config.rgb_ele_order == LCD_RGB_ELEMENT_ORDER_RGB) { + if (lvgl_port_config.flags.swap_bytes) { + color_format = tt::hal::display::ColorFormat::RGB565Swapped; + } else { + color_format = tt::hal::display::ColorFormat::RGB565; + } + } else { + if (lvgl_port_config.flags.swap_bytes) { + color_format = tt::hal::display::ColorFormat::BGR565Swapped; + } else { + color_format = tt::hal::display::ColorFormat::BGR565; + } + } + } else if (lvgl_port_config.color_format == LV_COLOR_FORMAT_RGB888) { + color_format = tt::hal::display::ColorFormat::RGB888; + } else { + tt_crash("unsupported driver"); + } + + displayDriver = std::make_shared( + panelHandle, + lock, + lvgl_port_config.hres, + lvgl_port_config.vres, + color_format + ); + } + return displayDriver; +} + diff --git a/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h new file mode 100644 index 00000000..3d36b051 --- /dev/null +++ b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h @@ -0,0 +1,111 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include + +constexpr auto DEFAULT_BUFFER_SIZE = 0; + +struct EspLcdConfiguration { + unsigned int horizontalResolution; + unsigned int verticalResolution; + int gapX; + int gapY; + bool monochrome; + bool swapXY; + bool mirrorX; + bool mirrorY; + bool invertColor; + uint32_t bufferSize; // Size in pixel count. 0 means default, which is 1/10 of the screen size + std::shared_ptr touch; + std::function _Nullable backlightDutyFunction; + gpio_num_t resetPin; + lv_color_format_t lvglColorFormat; + bool lvglSwapBytes; +}; + +class EspLcdDisplayV2 : public tt::hal::display::DisplayDevice { + esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr; + esp_lcd_panel_handle_t _Nullable panelHandle = nullptr; + lv_display_t* _Nullable lvglDisplay = nullptr; + std::shared_ptr _Nullable displayDriver; + std::shared_ptr lock; + std::shared_ptr configuration; + + bool applyConfiguration() const; + + lvgl_port_display_cfg_t getLvglPortDisplayConfig(std::shared_ptr configuration, esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle); + +protected: + + + virtual bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) = 0; + + virtual esp_lcd_panel_dev_config_t createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) = 0; + + virtual bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) = 0; + + virtual bool isRgbPanel() const { return false; } + + virtual lvgl_port_display_rgb_cfg_t getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { tt_crash("Not supported"); } + + // Used for sending commands such as setting curves + esp_lcd_panel_io_handle_t getIoHandle() const { return ioHandle; } + +public: + + EspLcdDisplayV2(const std::shared_ptr& configuration, const std::shared_ptr& lock) : + lock(lock), + configuration(configuration) + { + assert(configuration != nullptr); + assert(lock != nullptr); + } + + ~EspLcdDisplayV2() override; + + std::shared_ptr getLock() const { return lock; } + + bool start() final; + + bool stop() final; + + // region LVGL + + bool supportsLvgl() const final { return true; } + + bool startLvgl() final; + + bool stopLvgl() final; + + lv_display_t* _Nullable getLvglDisplay() const final { return lvglDisplay; } + + // endregion + + std::shared_ptr _Nullable getTouchDevice() override { return configuration->touch; } + + // region Backlight + + void setBacklightDuty(uint8_t backlightDuty) override { + if (configuration->backlightDutyFunction != nullptr) { + configuration->backlightDutyFunction(backlightDuty); + } + } + + bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; } + + // endregion + + // region DisplayDriver + + bool supportsDisplayDriver() const override { return true; } + + /** @return a NativeDisplay instance if this device supports it */ + std::shared_ptr _Nullable getDisplayDriver() final; + + // endregion +}; diff --git a/Drivers/EspLcdCompat/Source/EspLcdSpiDisplay.cpp b/Drivers/EspLcdCompat/Source/EspLcdSpiDisplay.cpp new file mode 100644 index 00000000..48c5b0c4 --- /dev/null +++ b/Drivers/EspLcdCompat/Source/EspLcdSpiDisplay.cpp @@ -0,0 +1,70 @@ +#include "EspLcdSpiDisplay.h" + +#include +#include + +constexpr auto* TAG = "EspLcdSpiDsp"; + +bool EspLcdSpiDisplay::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) { + TT_LOG_I(TAG, "createIoHandle"); + + const esp_lcd_panel_io_spi_config_t panel_io_config = { + .cs_gpio_num = spiConfiguration->csPin, + .dc_gpio_num = spiConfiguration->dcPin, + .spi_mode = 0, + .pclk_hz = spiConfiguration->pixelClockFrequency, + .trans_queue_depth = spiConfiguration->transactionQueueDepth, + .on_color_trans_done = nullptr, + .user_ctx = nullptr, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + .cs_ena_pretrans = 0, + .cs_ena_posttrans = 0, + .flags = { + .dc_high_on_cmd = 0, + .dc_low_on_data = 0, + .dc_low_on_param = 0, + .octal_mode = 0, + .quad_mode = 0, + .sio_mode = 1, + .lsb_first = 0, + .cs_high_active = 0 + } + }; + + if (esp_lcd_new_panel_io_spi(spiConfiguration->spiHostDevice, &panel_io_config, &outHandle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to create panel"); + return false; + } + + return true; +} + +void EspLcdSpiDisplay::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 + }; + + auto io_handle = getIoHandle(); + assert(io_handle != nullptr); + if (esp_lcd_panel_io_tx_param(io_handle, LCD_CMD_GAMSET, param, 1) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set gamma"); + } +} diff --git a/Drivers/EspLcdCompat/Source/EspLcdSpiDisplay.h b/Drivers/EspLcdCompat/Source/EspLcdSpiDisplay.h new file mode 100644 index 00000000..0ef5eb0e --- /dev/null +++ b/Drivers/EspLcdCompat/Source/EspLcdSpiDisplay.h @@ -0,0 +1,48 @@ +#pragma once + +#include "EspLcdDisplayV2.h" +#include + +#include +#include + +/** + * Adds IO implementations on top of EspLcdDisplayV2 + * @warning This is an abstract class. You need to extend it to use it. + */ +class EspLcdSpiDisplay : public EspLcdDisplayV2 { + +public: + + struct SpiConfiguration { + spi_host_device_t spiHostDevice; + gpio_num_t csPin; + gpio_num_t dcPin; + unsigned int pixelClockFrequency = 80'000'000; // Hertz + size_t transactionQueueDepth = 10; + }; + + explicit EspLcdSpiDisplay(const std::shared_ptr& configuration, const std::shared_ptr spiConfiguration, int gammaCurveCount) : + EspLcdDisplayV2(configuration, tt::hal::spi::getLock(spiConfiguration->spiHostDevice)), + spiConfiguration(spiConfiguration), + gammaCurveCount(gammaCurveCount) + {} + +private: + + std::shared_ptr spiConfiguration; + int gammaCurveCount; + +protected: + + bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override; + + // region Gamma + + void setGammaCurve(uint8_t index) override; + + uint8_t getGammaCurveCount() const override { return gammaCurveCount; } + + // endregion +}; + diff --git a/Drivers/ST7789/Source/St7789Display.cpp b/Drivers/ST7789/Source/St7789Display.cpp index 3d1925c4..2db16b8f 100644 --- a/Drivers/ST7789/Source/St7789Display.cpp +++ b/Drivers/ST7789/Source/St7789Display.cpp @@ -1,53 +1,30 @@ #include "St7789Display.h" -#include - -#include -#include #include -#include -constexpr auto TAG = "ST7789"; - -bool St7789Display::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) { - TT_LOG_I(TAG, "Starting"); - - const esp_lcd_panel_io_spi_config_t panel_io_config = { - .cs_gpio_num = configuration->csPin, - .dc_gpio_num = configuration->dcPin, - .spi_mode = 0, - .pclk_hz = configuration->pixelClockFrequency, - .trans_queue_depth = configuration->transactionQueueDepth, - .on_color_trans_done = nullptr, - .user_ctx = nullptr, - .lcd_cmd_bits = 8, - .lcd_param_bits = 8, - .cs_ena_pretrans = 0, - .cs_ena_posttrans = 0, - .flags = { - .dc_high_on_cmd = 0, - .dc_low_on_data = 0, - .dc_low_on_param = 0, - .octal_mode = 0, - .quad_mode = 0, - .sio_mode = 1, - .lsb_first = 0, - .cs_high_active = 0 - } - }; - - if (esp_lcd_new_panel_io_spi(configuration->spiHostDevice, &panel_io_config, &outHandle) != ESP_OK) { - TT_LOG_E(TAG, "Failed to create panel"); - return false; - } - - return true; +std::shared_ptr St7789Display::createEspLcdConfiguration(const Configuration& configuration) { + return std::make_shared(EspLcdConfiguration { + .horizontalResolution = configuration.horizontalResolution, + .verticalResolution = configuration.verticalResolution, + .gapX = configuration.gapX, + .gapY = configuration.gapY, + .monochrome = false, + .swapXY = configuration.swapXY, + .mirrorX = configuration.mirrorX, + .mirrorY = configuration.mirrorY, + .invertColor = configuration.invertColor, + .bufferSize = configuration.bufferSize, + .touch = configuration.touch, + .backlightDutyFunction = configuration.backlightDutyFunction, + .resetPin = configuration.resetPin, + .lvglColorFormat = LV_COLOR_FORMAT_RGB565, + .lvglSwapBytes = false + }); } -bool St7789Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) { - - const esp_lcd_panel_dev_config_t panel_config = { - .reset_gpio_num = configuration->resetPin, +esp_lcd_panel_dev_config_t St7789Display::createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) { + return { + .reset_gpio_num = resetPin, .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = 16, @@ -56,115 +33,8 @@ bool St7789Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lc }, .vendor_config = nullptr }; - - if (esp_lcd_new_panel_st7789(ioHandle, &panel_config, &panelHandle) != ESP_OK) { - TT_LOG_E(TAG, "Failed to create panel"); - 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_invert_color(panelHandle, configuration->invertColor) != ESP_OK) { - TT_LOG_E(TAG, "Failed to set panel to invert"); - return false; - } - - // Warning: it looks like LVGL rotation is broken when "gap" is set and the screen is moved to a non-default orientation - int gap_x = configuration->swapXY ? configuration->gapY : configuration->gapX; - int gap_y = configuration->swapXY ? configuration->gapX : configuration->gapY; - if (esp_lcd_panel_set_gap(panelHandle, gap_x, gap_y) != ESP_OK) { - TT_LOG_E(TAG, "Failed to set panel gap"); - return false; - } - - if (esp_lcd_panel_swap_xy(panelHandle, configuration->swapXY) != ESP_OK) { - TT_LOG_E(TAG, "Failed to swap XY "); - return false; - } - - if (esp_lcd_panel_mirror(panelHandle, configuration->mirrorX, configuration->mirrorY) != ESP_OK) { - TT_LOG_E(TAG, "Failed to set panel to mirror"); - return false; - } - - if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) { - TT_LOG_E(TAG, "Failed to turn display on"); - return false; - } - - return true; } -lvgl_port_display_cfg_t St7789Display::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { - return lvgl_port_display_cfg_t { - .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 = false, - .rotation = { - .swap_xy = configuration->swapXY, - .mirror_x = configuration->mirrorX, - .mirror_y = configuration->mirrorY, - }, - .color_format = LV_COLOR_FORMAT_RGB565, - .flags = { - .buff_dma = true, - .buff_spiram = false, - .sw_rotate = false, - .swap_bytes = false, - .full_refresh = false, - .direct_mode = false - } - }; -} -/** - * 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 St7789Display::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 - }; - - auto io_handle = getIoHandle(); - assert(io_handle != nullptr); - if (esp_lcd_panel_io_tx_param(io_handle, LCD_CMD_GAMSET, param, 1) != ESP_OK) { - TT_LOG_E(TAG, "Failed to set gamma"); - } +bool St7789Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) { + return esp_lcd_new_panel_st7789(ioHandle, &panelConfig, &panelHandle) == ESP_OK; } diff --git a/Drivers/ST7789/Source/St7789Display.h b/Drivers/ST7789/Source/St7789Display.h index 42782192..69ac68d2 100644 --- a/Drivers/ST7789/Source/St7789Display.h +++ b/Drivers/ST7789/Source/St7789Display.h @@ -2,113 +2,57 @@ #include "Tactility/hal/spi/Spi.h" -#include +#include #include #include -#include -#include #include #include -class St7789Display final : public EspLcdDisplay { +class St7789Display final : public EspLcdSpiDisplay { std::shared_ptr lock; public: - class Configuration { - - public: - - Configuration( - spi_host_device_t spiHostDevice, - gpio_num_t csPin, - gpio_num_t dcPin, - unsigned int horizontalResolution, - unsigned int verticalResolution, - std::shared_ptr touch, - bool swapXY = false, - bool mirrorX = false, - bool mirrorY = false, - bool invertColor = false, - uint32_t bufferSize = 0, // Size in pixel count. 0 means default, which is 1/10 of the screen size - int gapX = 0, - int gapY = 0 - ) : spiHostDevice(spiHostDevice), - csPin(csPin), - dcPin(dcPin), - horizontalResolution(horizontalResolution), - verticalResolution(verticalResolution), - gapX(gapX), - gapY(gapY), - swapXY(swapXY), - mirrorX(mirrorX), - mirrorY(mirrorY), - invertColor(invertColor), - bufferSize(bufferSize), - touch(std::move(touch)) - { - if (this->bufferSize == 0) { - this->bufferSize = horizontalResolution * verticalResolution / 10; - } - } - - spi_host_device_t spiHostDevice; - gpio_num_t csPin; - gpio_num_t dcPin; - gpio_num_t resetPin = GPIO_NUM_NC; - unsigned int pixelClockFrequency = 80'000'000; // Hertz - size_t transactionQueueDepth = 10; + /** Minimal set of overrides for EspLcdConfiguration */ + struct Configuration { unsigned int horizontalResolution; unsigned int verticalResolution; int gapX; int gapY; - bool swapXY = false; - bool mirrorX = false; - bool mirrorY = false; - bool invertColor = false; - uint32_t bufferSize = 0; // Size in pixel count. 0 means default, which is 1/10 of the screen size + bool swapXY; + bool mirrorX; + bool mirrorY; + bool invertColor; + uint32_t bufferSize; // Pixel count, not byte count. Set to 0 for default (1/10th of display size) std::shared_ptr touch; - std::function _Nullable backlightDutyFunction = nullptr; + std::function _Nullable backlightDutyFunction; + gpio_num_t resetPin; }; private: - std::unique_ptr configuration; + static std::shared_ptr createEspLcdConfiguration(const Configuration& configuration); - 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, 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; + bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) override; public: - explicit St7789Display(std::unique_ptr inConfiguration) : - EspLcdDisplay(tt::hal::spi::getLock(inConfiguration->spiHostDevice)), - configuration(std::move(inConfiguration) - ) { - assert(configuration != nullptr); - assert(getLock() != nullptr); + explicit St7789Display(const Configuration& configuration, const std::shared_ptr& spiConfiguration) : + EspLcdSpiDisplay( + createEspLcdConfiguration(configuration), + spiConfiguration, + 4 + ) + { } std::string getName() const override { return "ST7789"; } std::string getDescription() const override { return "ST7789 display"; } - - std::shared_ptr _Nullable getTouchDevice() override { return configuration->touch; } - - void setBacklightDuty(uint8_t backlightDuty) override { - if (configuration->backlightDutyFunction != nullptr) { - configuration->backlightDutyFunction(backlightDuty); - } - } - - bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; } - - void setGammaCurve(uint8_t index) override; - uint8_t getGammaCurveCount() const override { return 4; }; }; std::shared_ptr createDisplay(); diff --git a/Tactility/Include/Tactility/hal/spi/Spi.h b/Tactility/Include/Tactility/hal/spi/Spi.h index 3ee19051..e349eea1 100644 --- a/Tactility/Include/Tactility/hal/spi/Spi.h +++ b/Tactility/Include/Tactility/hal/spi/Spi.h @@ -42,7 +42,10 @@ bool stop(spi_host_device_t device); /** @return true if communications were started successfully */ bool isStarted(spi_host_device_t device); -/** @return the lock that represents the specified device. Can be used with third party SPI implementations or native API calls (e.g. ESP-IDF). */ +/** + * Return the lock for the specified SPI device. Never returns nullptr. + * @return the lock that represents the specified device. Can be used with third party SPI implementations or native API calls (e.g. ESP-IDF). + */ std::shared_ptr getLock(spi_host_device_t device); } // namespace tt::hal::spi diff --git a/Tactility/Private/Tactility/TactilityPrivate.h b/Tactility/Private/Tactility/TactilityPrivate.h index ebabce00..243edb95 100644 --- a/Tactility/Private/Tactility/TactilityPrivate.h +++ b/Tactility/Private/Tactility/TactilityPrivate.h @@ -1,9 +1,8 @@ #pragma once -#include - namespace tt { +void prepareFileSystems(); void registerApps(); } diff --git a/Tactility/Source/PreferencesEsp.cpp b/Tactility/Source/PreferencesEsp.cpp index 86f749dd..239a2d1e 100644 --- a/Tactility/Source/PreferencesEsp.cpp +++ b/Tactility/Source/PreferencesEsp.cpp @@ -88,8 +88,8 @@ bool Preferences::hasString(const std::string& key) const { void Preferences::putBool(const std::string& key, bool value) { nvs_handle_t handle; if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) { - if (nvs_set_u8(handle, key.c_str(), (uint8_t)value) != ESP_OK) { - TT_LOG_E(TAG, "Failed to write %s:%s", namespace_, key.c_str()); + if (nvs_set_u8(handle, key.c_str(), value) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str()); } else if (nvs_commit(handle) != ESP_OK) { TT_LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str()); } @@ -103,7 +103,7 @@ void Preferences::putInt32(const std::string& key, int32_t value) { nvs_handle_t handle; if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) { if (nvs_set_i32(handle, key.c_str(), value) != ESP_OK) { - TT_LOG_E(TAG, "Failed to write %s:%s", namespace_, key.c_str()); + TT_LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str()); } else if (nvs_commit(handle) != ESP_OK) { TT_LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str()); } @@ -117,7 +117,7 @@ void Preferences::putInt64(const std::string& key, int64_t value) { nvs_handle_t handle; if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) { if (nvs_set_i64(handle, key.c_str(), value) != ESP_OK) { - TT_LOG_E(TAG, "Failed to write %s:%s", namespace_, key.c_str()); + TT_LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str()); } else if (nvs_commit(handle) != ESP_OK) { TT_LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str()); } @@ -130,8 +130,9 @@ void Preferences::putInt64(const std::string& key, int64_t value) { void Preferences::putString(const std::string& key, const std::string& text) { nvs_handle_t handle; if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) { - nvs_set_str(handle, key.c_str(), text.c_str()); - if (nvs_commit(handle) != ESP_OK) { + if (nvs_set_str(handle, key.c_str(), text.c_str()) != ESP_OK) { + TT_LOG_E(TAG, "Failed to set %s:%s", namespace_, key.c_str()); + } else if (nvs_commit(handle) != ESP_OK) { TT_LOG_E(TAG, "Failed to commit %s:%s", namespace_, key.c_str()); } nvs_close(handle); diff --git a/Tactility/Source/Tactility.cpp b/Tactility/Source/Tactility.cpp index f3958b6d..4dccce5c 100644 --- a/Tactility/Source/Tactility.cpp +++ b/Tactility/Source/Tactility.cpp @@ -233,6 +233,38 @@ static void registerAndStartPrimaryServices() { #endif } +void createTempDirectory(const std::string& rootPath) { + auto temp_path = std::format("{}/tmp", rootPath); + if (!file::isDirectory(temp_path)) { + auto lock = file::getLock(rootPath)->asScopedLock(); + if (lock.lock(1000 / portTICK_PERIOD_MS)) { + if (mkdir(temp_path.c_str(), 0777) == 0) { + TT_LOG_I(TAG, "Created %s", temp_path.c_str()); + } else { + TT_LOG_E(TAG, "Failed to create %s", temp_path.c_str()); + } + } else { + TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, rootPath.c_str()); + } + } else { + TT_LOG_I(TAG, "Found existing %s", temp_path.c_str()); + } +} + +void prepareFileSystems() { + // Temporary directories for SD cards + auto sdcard_devices = hal::findDevices(hal::Device::Type::SdCard); + for (const auto& sdcard : sdcard_devices) { + if (sdcard->isMounted()) { + createTempDirectory(sdcard->getMountPath()); + } + } + // Temporary directory for /data + if (file::isDirectory(file::MOUNT_POINT_DATA)) { + createTempDirectory(file::MOUNT_POINT_DATA); + } +} + void registerApps() { registerInternalApps(); auto data_apps_path = std::format("{}/apps", file::MOUNT_POINT_DATA); diff --git a/Tactility/Source/app/boot/Boot.cpp b/Tactility/Source/app/boot/Boot.cpp index 73f2d545..36f825fa 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -100,11 +100,7 @@ class BootApp : public App { // TODO: Support for multiple displays TT_LOG_I(TAG, "Setup display"); setupDisplay(); // Set backlight - - // This event will likely block as other systems are initialized - // e.g. Wi-Fi reads AP configs from SD card - TT_LOG_I(TAG, "Publish event"); - kernel::publishSystemEvent(kernel::SystemEvent::BootSplash); + prepareFileSystems(); if (!setupUsbBootMode()) { TT_LOG_I(TAG, "initFromBootApp"); @@ -114,6 +110,11 @@ class BootApp : public App { startNextApp(); } + // This event will likely block as other systems are initialized + // e.g. Wi-Fi reads AP configs from SD card + TT_LOG_I(TAG, "Publish event"); + kernel::publishSystemEvent(kernel::SystemEvent::BootSplash); + return 0; } diff --git a/Tactility/Source/lvgl/wrappers/list.cpp b/Tactility/Source/lvgl/wrappers/list.cpp index 348fc107..8b32f5d4 100644 --- a/Tactility/Source/lvgl/wrappers/list.cpp +++ b/Tactility/Source/lvgl/wrappers/list.cpp @@ -10,18 +10,19 @@ extern lv_obj_t* __real_lv_list_create(lv_obj_t* parent); extern lv_obj_t* __real_lv_list_add_button(lv_obj_t* list, const void* icon, const char* txt); lv_obj_t* __wrap_lv_list_create(lv_obj_t* parent) { - auto list = __real_lv_list_create(parent); + auto* list = __real_lv_list_create(parent); if (tt::hal::getConfiguration()->uiScale == tt::hal::UiScale::Smallest) { lv_obj_set_style_pad_row(list, 2, LV_STATE_DEFAULT); lv_obj_set_style_pad_column(list, 2, LV_STATE_DEFAULT); + lv_obj_set_style_pad_all(list, 2, LV_STATE_DEFAULT); } return list; } lv_obj_t* __wrap_lv_list_add_button(lv_obj_t* list, const void* icon, const char* txt) { - auto button = __real_lv_list_add_button(list, icon, txt); + auto* button = __real_lv_list_add_button(list, icon, txt); if (tt::hal::getConfiguration()->uiScale == tt::hal::UiScale::Smallest) { lv_obj_set_style_pad_ver(button, 2, LV_STATE_DEFAULT);