mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-22 08:25:06 +00:00
Compare commits
2 Commits
e2ec39304c
...
0d8c0a37cc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d8c0a37cc | ||
|
|
ab2aa2c4d4 |
1
.github/workflows/build-firmware.yml
vendored
1
.github/workflows/build-firmware.yml
vendored
@ -35,6 +35,7 @@ jobs:
|
|||||||
{ id: lilygo-tdongle-s3, arch: esp32s3 },
|
{ id: lilygo-tdongle-s3, arch: esp32s3 },
|
||||||
{ id: lilygo-tdisplay-s3, arch: esp32s3 },
|
{ id: lilygo-tdisplay-s3, arch: esp32s3 },
|
||||||
{ id: lilygo-tlora-pager, arch: esp32s3 },
|
{ id: lilygo-tlora-pager, arch: esp32s3 },
|
||||||
|
{ id: lilygo-tdisplay, arch: esp32 },
|
||||||
{ id: m5stack-cardputer, arch: esp32s3 },
|
{ id: m5stack-cardputer, arch: esp32s3 },
|
||||||
{ id: m5stack-cardputer-adv, arch: esp32s3 },
|
{ id: m5stack-cardputer-adv, arch: esp32s3 },
|
||||||
{ id: m5stack-core2, arch: esp32 },
|
{ id: m5stack-core2, arch: esp32 },
|
||||||
|
|||||||
@ -34,7 +34,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = createTouch(),
|
.touch = createTouch(),
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = GPIO_NUM_NC
|
.resetPin = GPIO_NUM_NC,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -35,6 +35,7 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.touch = createTouch(),
|
.touch = createTouch(),
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = GPIO_NUM_NC,
|
.resetPin = GPIO_NUM_NC,
|
||||||
|
.lvglSwapBytes = false,
|
||||||
.rgbElementOrder = LCD_RGB_ELEMENT_ORDER_BGR // BGR for this display
|
.rgbElementOrder = LCD_RGB_ELEMENT_ORDER_BGR // BGR for this display
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = createTouch(),
|
.touch = createTouch(),
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = GPIO_NUM_NC
|
.resetPin = GPIO_NUM_NC,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -31,7 +31,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = createTouch(),
|
.touch = createTouch(),
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = GPIO_NUM_NC
|
.resetPin = GPIO_NUM_NC,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -31,7 +31,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = createTouch(),
|
.touch = createTouch(),
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = GPIO_NUM_NC
|
.resetPin = GPIO_NUM_NC,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
7
Boards/lilygo-tdisplay/CMakeLists.txt
Normal file
7
Boards/lilygo-tdisplay/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||||
|
|
||||||
|
idf_component_register(
|
||||||
|
SRCS ${SOURCE_FILES}
|
||||||
|
INCLUDE_DIRS "Source"
|
||||||
|
REQUIRES Tactility ButtonControl esp_lvgl_port ST7789 PwmBacklight driver
|
||||||
|
)
|
||||||
50
Boards/lilygo-tdisplay/Source/Configuration.cpp
Normal file
50
Boards/lilygo-tdisplay/Source/Configuration.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "devices/Display.h"
|
||||||
|
|
||||||
|
#include <PwmBacklight.h>
|
||||||
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
|
#include <ButtonControl.h>
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static bool initBoot() {
|
||||||
|
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::shared_ptr<Device>> createDevices() {
|
||||||
|
return {
|
||||||
|
createDisplay(),
|
||||||
|
ButtonControl::createTwoButtonControl(35, 0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Configuration hardwareConfiguration = {
|
||||||
|
.initBoot = initBoot,
|
||||||
|
.uiScale = UiScale::Smallest,
|
||||||
|
.createDevices = createDevices,
|
||||||
|
.i2c = {},
|
||||||
|
.spi {
|
||||||
|
spi::Configuration {
|
||||||
|
.device = SPI2_HOST,
|
||||||
|
.dma = SPI_DMA_CH_AUTO,
|
||||||
|
.config = {
|
||||||
|
.mosi_io_num = GPIO_NUM_19,
|
||||||
|
.miso_io_num = GPIO_NUM_NC,
|
||||||
|
.sclk_io_num = GPIO_NUM_18,
|
||||||
|
.quadwp_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 = LCD_SPI_TRANSFER_SIZE_LIMIT,
|
||||||
|
.flags = 0,
|
||||||
|
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||||
|
.intr_flags = 0
|
||||||
|
},
|
||||||
|
.initMode = spi::InitMode::ByTactility,
|
||||||
|
.isMutable = false,
|
||||||
|
.lock = tt::lvgl::getSyncLock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
32
Boards/lilygo-tdisplay/Source/devices/Display.cpp
Normal file
32
Boards/lilygo-tdisplay/Source/devices/Display.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
#include <PwmBacklight.h>
|
||||||
|
#include <St7789Display.h>
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
|
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,
|
||||||
|
.lvglSwapBytes = true
|
||||||
|
};
|
||||||
|
|
||||||
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
.spiHostDevice = LCD_SPI_HOST,
|
||||||
|
.csPin = LCD_PIN_CS,
|
||||||
|
.dcPin = LCD_PIN_DC,
|
||||||
|
.pixelClockFrequency = 62'500'000,
|
||||||
|
.transactionQueueDepth = 10
|
||||||
|
});
|
||||||
|
|
||||||
|
return std::make_shared<St7789Display>(panel_configuration, spi_configuration);
|
||||||
|
}
|
||||||
19
Boards/lilygo-tdisplay/Source/devices/Display.h
Normal file
19
Boards/lilygo-tdisplay/Source/devices/Display.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
#include <driver/spi_common.h>
|
||||||
|
|
||||||
|
constexpr auto LCD_SPI_HOST = SPI2_HOST;
|
||||||
|
constexpr auto LCD_PIN_CS = GPIO_NUM_5;
|
||||||
|
constexpr auto LCD_PIN_DC = GPIO_NUM_16;
|
||||||
|
constexpr auto LCD_PIN_RESET = GPIO_NUM_23;
|
||||||
|
constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_4;
|
||||||
|
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<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
@ -16,7 +16,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = nullptr,
|
.touch = nullptr,
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = LCD_PIN_RESET
|
.resetPin = LCD_PIN_RESET,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -16,7 +16,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = nullptr,
|
.touch = nullptr,
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = LCD_PIN_RESET
|
.resetPin = LCD_PIN_RESET,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -50,7 +50,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = nullptr,
|
.touch = nullptr,
|
||||||
.backlightDutyFunction = setBrightness,
|
.backlightDutyFunction = setBrightness,
|
||||||
.resetPin = LCD_PIN_RESET
|
.resetPin = LCD_PIN_RESET,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -16,7 +16,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = nullptr,
|
.touch = nullptr,
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = LCD_PIN_RESET
|
.resetPin = LCD_PIN_RESET,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -16,7 +16,8 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
.bufferSize = LCD_BUFFER_SIZE,
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
.touch = nullptr,
|
.touch = nullptr,
|
||||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
.resetPin = GPIO_NUM_42
|
.resetPin = GPIO_NUM_42,
|
||||||
|
.lvglSwapBytes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
|||||||
@ -92,6 +92,11 @@ boardName=T-Deck,T-Deck Plus
|
|||||||
incubating=false
|
incubating=false
|
||||||
infoMessage=If two serial devices are visible, try them both.<br/><br/>To put the device into bootloader mode: <br/>1. Press the trackball and then the reset button at the same time,<br/>2. Let go of the reset button, then the trackball.<br/><br/>When this website reports that flashing is finished, you likely have to press the reset button.
|
infoMessage=If two serial devices are visible, try them both.<br/><br/>To put the device into bootloader mode: <br/>1. Press the trackball and then the reset button at the same time,<br/>2. Let go of the reset button, then the trackball.<br/><br/>When this website reports that flashing is finished, you likely have to press the reset button.
|
||||||
|
|
||||||
|
[lilygo-tdisplay]
|
||||||
|
vendor=LilyGO
|
||||||
|
boardName=T-Display
|
||||||
|
incubating=true
|
||||||
|
|
||||||
[lilygo-tdisplay-s3]
|
[lilygo-tdisplay-s3]
|
||||||
vendor=LilyGO
|
vendor=LilyGO
|
||||||
boardName=T-Display S3
|
boardName=T-Display S3
|
||||||
|
|||||||
@ -18,7 +18,7 @@ std::shared_ptr<EspLcdConfiguration> St7789Display::createEspLcdConfiguration(co
|
|||||||
.backlightDutyFunction = configuration.backlightDutyFunction,
|
.backlightDutyFunction = configuration.backlightDutyFunction,
|
||||||
.resetPin = configuration.resetPin,
|
.resetPin = configuration.resetPin,
|
||||||
.lvglColorFormat = LV_COLOR_FORMAT_RGB565,
|
.lvglColorFormat = LV_COLOR_FORMAT_RGB565,
|
||||||
.lvglSwapBytes = false,
|
.lvglSwapBytes = configuration.lvglSwapBytes,
|
||||||
.rgbElementOrder = configuration.rgbElementOrder,
|
.rgbElementOrder = configuration.rgbElementOrder,
|
||||||
.bitsPerPixel = 16,
|
.bitsPerPixel = 16,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -26,6 +26,7 @@ public:
|
|||||||
std::shared_ptr<tt::hal::touch::TouchDevice> touch;
|
std::shared_ptr<tt::hal::touch::TouchDevice> touch;
|
||||||
std::function<void(uint8_t)> _Nullable backlightDutyFunction;
|
std::function<void(uint8_t)> _Nullable backlightDutyFunction;
|
||||||
gpio_num_t resetPin;
|
gpio_num_t resetPin;
|
||||||
|
bool lvglSwapBytes;
|
||||||
lcd_rgb_element_order_t rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB;
|
lcd_rgb_element_order_t rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,8 @@ menu "Tactility App"
|
|||||||
bool "LilyGo T-Dongle S3"
|
bool "LilyGo T-Dongle S3"
|
||||||
config TT_BOARD_LILYGO_TLORA_PAGER
|
config TT_BOARD_LILYGO_TLORA_PAGER
|
||||||
bool "LilyGo T-Lora Pager"
|
bool "LilyGo T-Lora Pager"
|
||||||
|
config TT_BOARD_LILYGO_TDISPLAY
|
||||||
|
bool "LilyGo T-Display"
|
||||||
config TT_BOARD_M5STACK_CARDPUTER
|
config TT_BOARD_M5STACK_CARDPUTER
|
||||||
bool "M5Stack Cardputer"
|
bool "M5Stack Cardputer"
|
||||||
config TT_BOARD_M5STACK_CARDPUTER_ADV
|
config TT_BOARD_M5STACK_CARDPUTER_ADV
|
||||||
|
|||||||
@ -5,7 +5,14 @@ namespace tt::hal::usb {
|
|||||||
enum class Mode {
|
enum class Mode {
|
||||||
Default, // Default state of USB stack
|
Default, // Default state of USB stack
|
||||||
None, // State after TinyUSB was used and (partially) deinitialized
|
None, // State after TinyUSB was used and (partially) deinitialized
|
||||||
MassStorageSdmmc
|
MassStorageSdmmc,
|
||||||
|
MassStorageFlash // For internal flash /data partition
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BootMode {
|
||||||
|
None,
|
||||||
|
Sdmmc,
|
||||||
|
Flash
|
||||||
};
|
};
|
||||||
|
|
||||||
bool startMassStorageWithSdmmc();
|
bool startMassStorageWithSdmmc();
|
||||||
@ -18,4 +25,11 @@ void rebootIntoMassStorageSdmmc();
|
|||||||
bool isUsbBootMode();
|
bool isUsbBootMode();
|
||||||
void resetUsbBootMode();
|
void resetUsbBootMode();
|
||||||
|
|
||||||
|
BootMode getUsbBootMode();
|
||||||
|
|
||||||
|
// Flash-based mass storage
|
||||||
|
bool startMassStorageWithFlash();
|
||||||
|
bool canRebootIntoMassStorageFlash();
|
||||||
|
void rebootIntoMassStorageFlash();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3,11 +3,13 @@
|
|||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
|
#include "esp_vfs_fat.h"
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
esp_err_t initPartitionsEsp();
|
esp_err_t initPartitionsEsp();
|
||||||
|
wl_handle_t getDataPartitionWlHandle();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif // ESP_PLATFORM
|
#endif // ESP_PLATFORM
|
||||||
|
|||||||
@ -2,4 +2,6 @@
|
|||||||
|
|
||||||
bool tusbIsSupported();
|
bool tusbIsSupported();
|
||||||
bool tusbStartMassStorageWithSdmmc();
|
bool tusbStartMassStorageWithSdmmc();
|
||||||
|
bool tusbStartMassStorageWithFlash();
|
||||||
void tusbStop();
|
void tusbStop();
|
||||||
|
bool tusbCanStartMassStorageWithFlash();
|
||||||
@ -22,6 +22,10 @@ static esp_err_t initNvsFlashSafely() {
|
|||||||
|
|
||||||
static wl_handle_t data_wl_handle = WL_INVALID_HANDLE;
|
static wl_handle_t data_wl_handle = WL_INVALID_HANDLE;
|
||||||
|
|
||||||
|
wl_handle_t getDataPartitionWlHandle() {
|
||||||
|
return data_wl_handle;
|
||||||
|
}
|
||||||
|
|
||||||
size_t getSectorSize() {
|
size_t getSectorSize() {
|
||||||
#if defined(CONFIG_FATFS_SECTOR_512)
|
#if defined(CONFIG_FATFS_SECTOR_512)
|
||||||
return 512;
|
return 512;
|
||||||
|
|||||||
@ -71,8 +71,19 @@ class BootApp : public App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Rebooting into mass storage device mode");
|
TT_LOG_I(TAG, "Rebooting into mass storage device mode");
|
||||||
|
auto mode = hal::usb::getUsbBootMode(); // Get mode before reset
|
||||||
hal::usb::resetUsbBootMode();
|
hal::usb::resetUsbBootMode();
|
||||||
hal::usb::startMassStorageWithSdmmc();
|
if (mode == hal::usb::BootMode::Flash) {
|
||||||
|
if (!hal::usb::startMassStorageWithFlash()) {
|
||||||
|
TT_LOG_E(TAG, "Unable to start flash mass storage");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (mode == hal::usb::BootMode::Sdmmc) {
|
||||||
|
if (!hal::usb::startMassStorageWithSdmmc()) {
|
||||||
|
TT_LOG_E(TAG, "Unable to start SD mass storage");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,32 +11,50 @@
|
|||||||
|
|
||||||
namespace tt::app::usbsettings {
|
namespace tt::app::usbsettings {
|
||||||
|
|
||||||
static void onRebootMassStorage(TT_UNUSED lv_event_t* event) {
|
static void onRebootMassStorageSdmmc(TT_UNUSED lv_event_t* event) {
|
||||||
hal::usb::rebootIntoMassStorageSdmmc();
|
hal::usb::rebootIntoMassStorageSdmmc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flash reboot handler
|
||||||
|
static void onRebootMassStorageFlash(TT_UNUSED lv_event_t* event) {
|
||||||
|
hal::usb::rebootIntoMassStorageFlash();
|
||||||
|
}
|
||||||
|
|
||||||
class UsbSettingsApp : public App {
|
class UsbSettingsApp : public App {
|
||||||
|
|
||||||
void onShow(AppContext& app, lv_obj_t* parent) override {
|
void onShow(AppContext& app, lv_obj_t* parent) override {
|
||||||
auto* toolbar = lvgl::toolbar_create(parent, app);
|
auto* toolbar = lvgl::toolbar_create(parent, app);
|
||||||
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
||||||
|
|
||||||
if (hal::usb::canRebootIntoMassStorageSdmmc()) {
|
// Create a wrapper container for buttons
|
||||||
auto* button = lv_button_create(parent);
|
auto* wrapper = lv_obj_create(parent);
|
||||||
auto* label = lv_label_create(button);
|
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
|
||||||
lv_label_set_text(label, "Reboot as USB storage");
|
lv_obj_set_flex_align(wrapper, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
lv_obj_align(button, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_set_size(wrapper, lv_pct(100), LV_SIZE_CONTENT);
|
||||||
lv_obj_add_event_cb(button, onRebootMassStorage, LV_EVENT_SHORT_CLICKED, nullptr);
|
lv_obj_align(wrapper, LV_ALIGN_CENTER, 0, 0);
|
||||||
} else {
|
|
||||||
|
bool hasSd = hal::usb::canRebootIntoMassStorageSdmmc();
|
||||||
|
bool hasFlash = hal::usb::canRebootIntoMassStorageFlash();
|
||||||
|
|
||||||
|
if (hasSd) {
|
||||||
|
auto* button_sd = lv_button_create(wrapper);
|
||||||
|
auto* label_sd = lv_label_create(button_sd);
|
||||||
|
lv_label_set_text(label_sd, "Reboot as USB storage (SD)");
|
||||||
|
lv_obj_add_event_cb(button_sd, onRebootMassStorageSdmmc, LV_EVENT_SHORT_CLICKED, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasFlash) {
|
||||||
|
auto* button_flash = lv_button_create(wrapper);
|
||||||
|
auto* label_flash = lv_label_create(button_flash);
|
||||||
|
lv_label_set_text(label_flash, "Reboot as USB storage (Flash)");
|
||||||
|
lv_obj_add_event_cb(button_flash, onRebootMassStorageFlash, LV_EVENT_SHORT_CLICKED, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasSd && !hasFlash) {
|
||||||
bool supported = hal::usb::isSupported();
|
bool supported = hal::usb::isSupported();
|
||||||
const char* first = supported ? "USB storage not available:" : "USB driver not supported";
|
const char* message = supported ? "USB storage not available" : "USB driver not supported";
|
||||||
const char* second = supported ? "SD card not mounted" : "on this hardware";
|
auto* label = lv_label_create(wrapper);
|
||||||
auto* label_a = lv_label_create(parent);
|
lv_label_set_text(label, message);
|
||||||
lv_label_set_text(label_a, first);
|
|
||||||
lv_obj_align(label_a, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
auto* label_b = lv_label_create(parent);
|
|
||||||
lv_label_set_text(label_b, second);
|
|
||||||
lv_obj_align_to(label_b, label_a, LV_ALIGN_OUT_BOTTOM_MID, 0, 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,14 +9,15 @@
|
|||||||
namespace tt::hal::usb {
|
namespace tt::hal::usb {
|
||||||
|
|
||||||
constexpr auto* TAG = "usb";
|
constexpr auto* TAG = "usb";
|
||||||
constexpr auto BOOT_FLAG = 42;
|
constexpr auto BOOT_FLAG_SDMMC = 42; // Existing
|
||||||
|
constexpr auto BOOT_FLAG_FLASH = 43; // For flash mode
|
||||||
|
|
||||||
struct BootMode {
|
struct BootModeData {
|
||||||
uint32_t flag = 0;
|
uint32_t flag = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Mode currentMode = Mode::Default;
|
static Mode currentMode = Mode::Default;
|
||||||
static RTC_NOINIT_ATTR BootMode bootMode;
|
static RTC_NOINIT_ATTR BootModeData bootModeData;
|
||||||
|
|
||||||
sdmmc_card_t* _Nullable getCard() {
|
sdmmc_card_t* _Nullable getCard() {
|
||||||
auto sdcards = findDevices<sdcard::SpiSdCardDevice>(Device::Type::SdCard);
|
auto sdcards = findDevices<sdcard::SpiSdCardDevice>(Device::Type::SdCard);
|
||||||
@ -87,17 +88,55 @@ bool canRebootIntoMassStorageSdmmc() {
|
|||||||
|
|
||||||
void rebootIntoMassStorageSdmmc() {
|
void rebootIntoMassStorageSdmmc() {
|
||||||
if (tusbIsSupported()) {
|
if (tusbIsSupported()) {
|
||||||
bootMode.flag = BOOT_FLAG;
|
bootModeData.flag = BOOT_FLAG_SDMMC;
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NEW: Flash mass storage functions
|
||||||
|
bool startMassStorageWithFlash() {
|
||||||
|
if (!canStartNewMode()) {
|
||||||
|
TT_LOG_E(TAG, "Can't start flash mass storage");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tusbStartMassStorageWithFlash()) {
|
||||||
|
currentMode = Mode::MassStorageFlash;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
TT_LOG_E(TAG, "Failed to init flash mass storage");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canRebootIntoMassStorageFlash() {
|
||||||
|
return tusbCanStartMassStorageWithFlash();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rebootIntoMassStorageFlash() {
|
||||||
|
if (tusbCanStartMassStorageWithFlash()) {
|
||||||
|
bootModeData.flag = BOOT_FLAG_FLASH;
|
||||||
esp_restart();
|
esp_restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isUsbBootMode() {
|
bool isUsbBootMode() {
|
||||||
return bootMode.flag == BOOT_FLAG;
|
return bootModeData.flag == BOOT_FLAG_SDMMC || bootModeData.flag == BOOT_FLAG_FLASH; // Support both
|
||||||
|
}
|
||||||
|
|
||||||
|
BootMode getUsbBootMode() {
|
||||||
|
switch (bootModeData.flag) {
|
||||||
|
case BOOT_FLAG_SDMMC:
|
||||||
|
return BootMode::Sdmmc;
|
||||||
|
case BOOT_FLAG_FLASH:
|
||||||
|
return BootMode::Flash;
|
||||||
|
default:
|
||||||
|
return BootMode::None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetUsbBootMode() {
|
void resetUsbBootMode() {
|
||||||
bootMode.flag = 0;
|
bootModeData.flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,10 +9,14 @@ namespace tt::hal::usb {
|
|||||||
bool startMassStorageWithSdmmc() { return false; }
|
bool startMassStorageWithSdmmc() { return false; }
|
||||||
void stop() {}
|
void stop() {}
|
||||||
Mode getMode() { return Mode::Default; }
|
Mode getMode() { return Mode::Default; }
|
||||||
|
BootMode getUsbBootMode() { return BootMode::None; }
|
||||||
bool isSupported() { return false; }
|
bool isSupported() { return false; }
|
||||||
|
|
||||||
bool canRebootIntoMassStorageSdmmc() { return false; }
|
bool canRebootIntoMassStorageSdmmc() { return false; }
|
||||||
void rebootIntoMassStorageSdmmc() {}
|
void rebootIntoMassStorageSdmmc() {}
|
||||||
|
bool startMassStorageWithFlash() { return false; }
|
||||||
|
bool canRebootIntoMassStorageFlash() { return false; }
|
||||||
|
void rebootIntoMassStorageFlash() {}
|
||||||
bool isUsbBootMode() { return false; }
|
bool isUsbBootMode() { return false; }
|
||||||
void resetUsbBootMode() {}
|
void resetUsbBootMode() {}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
#include "Tactility/hal/usb/UsbTusb.h"
|
#include "Tactility/hal/usb/UsbTusb.h"
|
||||||
|
#include <Tactility/PartitionsEsp.h>
|
||||||
|
|
||||||
#include <sdkconfig.h>
|
#include <sdkconfig.h>
|
||||||
|
|
||||||
@ -9,10 +10,12 @@
|
|||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
#include <tinyusb.h>
|
#include <tinyusb.h>
|
||||||
#include <tusb_msc_storage.h>
|
#include <tusb_msc_storage.h>
|
||||||
|
#include <wear_levelling.h>
|
||||||
|
|
||||||
#define TAG "usb"
|
#define TAG "usb"
|
||||||
#define EPNUM_MSC 1
|
#define EPNUM_MSC 1
|
||||||
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN)
|
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN)
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
|
||||||
namespace tt::hal::usb {
|
namespace tt::hal::usb {
|
||||||
extern sdmmc_card_t* _Nullable getCard();
|
extern sdmmc_card_t* _Nullable getCard();
|
||||||
@ -90,9 +93,9 @@ static uint8_t const msc_hs_configuration_desc[] = {
|
|||||||
|
|
||||||
static void storage_mount_changed_cb(tinyusb_msc_event_t* event) {
|
static void storage_mount_changed_cb(tinyusb_msc_event_t* event) {
|
||||||
if (event->mount_changed_data.is_mounted) {
|
if (event->mount_changed_data.is_mounted) {
|
||||||
TT_LOG_I(TAG, "Mounted");
|
TT_LOG_I(TAG, "MSC Mounted");
|
||||||
} else {
|
} else {
|
||||||
TT_LOG_I(TAG, "Unmounted");
|
TT_LOG_I(TAG, "MSC Unmounted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,22 +155,62 @@ bool tusbStartMassStorageWithSdmmc() {
|
|||||||
|
|
||||||
auto result = tinyusb_msc_storage_init_sdmmc(&config_sdmmc);
|
auto result = tinyusb_msc_storage_init_sdmmc(&config_sdmmc);
|
||||||
if (result != ESP_OK) {
|
if (result != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "TinyUSB init failed: %s", esp_err_to_name(result));
|
TT_LOG_E(TAG, "TinyUSB SDMMC init failed: %s", esp_err_to_name(result));
|
||||||
|
} else {
|
||||||
|
TT_LOG_I(TAG, "TinyUSB SDMMC init success");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result == ESP_OK;
|
return result == ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tusbStartMassStorageWithFlash() {
|
||||||
|
TT_LOG_I(TAG, "Starting flash MSC");
|
||||||
|
ensureDriverInstalled();
|
||||||
|
|
||||||
|
wl_handle_t handle = tt::getDataPartitionWlHandle();
|
||||||
|
if (handle == WL_INVALID_HANDLE) {
|
||||||
|
TT_LOG_E(TAG, "WL not mounted for /data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tinyusb_msc_spiflash_config_t config_flash = {
|
||||||
|
.wl_handle = handle,
|
||||||
|
.callback_mount_changed = storage_mount_changed_cb,
|
||||||
|
.callback_premount_changed = nullptr,
|
||||||
|
.mount_config = {
|
||||||
|
.format_if_mount_failed = false,
|
||||||
|
.max_files = 5,
|
||||||
|
.allocation_unit_size = 0,
|
||||||
|
.disk_status_check_enable = false,
|
||||||
|
.use_one_fat = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_err_t result = tinyusb_msc_storage_init_spiflash(&config_flash);
|
||||||
|
if (result != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "TinyUSB flash init failed: %s", esp_err_to_name(result));
|
||||||
|
} else {
|
||||||
|
TT_LOG_I(TAG, "TinyUSB flash init success");
|
||||||
|
}
|
||||||
|
return result == ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void tusbStop() {
|
void tusbStop() {
|
||||||
tinyusb_msc_storage_deinit();
|
tinyusb_msc_storage_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tusbCanStartMassStorageWithFlash() {
|
||||||
|
return tusbIsSupported() && (tt::getDataPartitionWlHandle() != WL_INVALID_HANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
bool tusbIsSupported() { return false; }
|
bool tusbIsSupported() { return false; }
|
||||||
bool tusbStartMassStorageWithSdmmc() { return false; }
|
bool tusbStartMassStorageWithSdmmc() { return false; }
|
||||||
|
bool tusbStartMassStorageWithFlash() { return false; }
|
||||||
void tusbStop() {}
|
void tusbStop() {}
|
||||||
|
bool tusbCanStartMassStorageWithFlash() { return false; }
|
||||||
|
|
||||||
#endif // TinyUSB enabled
|
#endif // CONFIG_TINYUSB_MSC_ENABLED
|
||||||
|
|
||||||
#endif // ESP_PLATFORM
|
#endif // ESP_PLATFORM
|
||||||
|
|||||||
56
sdkconfig.board.lilygo-tdisplay
Normal file
56
sdkconfig.board.lilygo-tdisplay
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# 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-16mb.csv"
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions-16mb.csv"
|
||||||
|
CONFIG_TT_BOARD_LILYGO_TDISPLAY=y
|
||||||
|
CONFIG_TT_BOARD_NAME="LilyGo T-Display"
|
||||||
|
CONFIG_TT_BOARD_ID="lilygo-tdisplay"
|
||||||
|
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
|
||||||
|
CONFIG_IDF_TARGET="esp32"
|
||||||
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||||
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||||
|
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||||
|
CONFIG_FLASHMODE_QIO=y
|
||||||
|
# LVGL
|
||||||
|
CONFIG_LV_DISP_DEF_REFR_PERIOD=10
|
||||||
|
CONFIG_LV_DPI_DEF=186
|
||||||
|
CONFIG_LV_THEME_DEFAULT_DARK=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
|
||||||
Loading…
x
Reference in New Issue
Block a user