LilyGo T-Dongle S3
T-Dongle S3
The LilyGo T-Dongle S3 is a development board for the ESP32-S3 module. It features a USB-A connector which doubles as a micro-SD card reader, a color LCD, an RGB LED, and a button.
The espp::TDongleS3 component provides a singleton hardware abstraction for initializing the display and LED subsystems.
API Reference
Header File
Classes
-
class TDongleS3 : public espp::BaseComponent
The TDongleS3 class provides an interface to the LilyGo T-Dongle-S3 ESP32-S3 development board.
The class provides access to the following features:
RGB LED
The class is a singleton and can be accessed using the get() method.
Example
espp::TDongleS3 &tdongle = espp::TDongleS3::get(); tdongle.set_log_level(espp::Logger::Verbosity::INFO); // initialize the LED if (!tdongle.initialize_led()) { logger.error("Failed to initialize led!"); return; } // initialize the LCD if (!tdongle.initialize_lcd()) { logger.error("Failed to initialize LCD!"); return; } // set the pixel buffer to be a full screen buffer static constexpr size_t pixel_buffer_size = tdongle.lcd_width() * tdongle.lcd_height(); // initialize the LVGL display for the T-Dongle-S3 if (!tdongle.initialize_display(pixel_buffer_size)) { logger.error("Failed to initialize display!"); return; } // initialize the button, which we'll use to cycle the rotation of the display espp::Button button(espp::Button::Config{ .name = "Boot Button", .interrupt_config = espp::Interrupt::PinConfig{.gpio_num = GPIO_NUM_0, .callback = [](const auto &event) { if (event.active) { // lock the display mutex std::lock_guard<std::mutex> lock(lvgl_mutex); static auto rotation = LV_DISPLAY_ROTATION_0; rotation = static_cast<lv_display_rotation_t>( (static_cast<int>(rotation) + 1) % 4); fmt::print("Setting rotation to {}\n", (int)rotation); lv_display_t *disp = _lv_refr_get_disp_refreshing(); lv_disp_set_rotation(disp, rotation); } }, .active_level = espp::Interrupt::ActiveLevel::LOW, .interrupt_type = espp::Interrupt::Type::ANY_EDGE, .pullup_enabled = false, .pulldown_enabled = false}, }); // set the LED to be red espp::Hsv hsv(150.0f, 1.0f, 1.0f); float brightness = 5.0f; // 5% brightness tdongle.led(hsv, brightness); // set the background color to black lv_obj_t *bg = lv_obj_create(lv_screen_active()); lv_obj_set_size(bg, tdongle.lcd_width(), tdongle.lcd_height()); lv_obj_set_style_bg_color(bg, lv_color_make(0, 0, 0), 0); // add text in the center of the screen lv_obj_t *label = lv_label_create(lv_screen_active()); lv_label_set_text(label, "Drawing circles\nto the screen."); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); // start a simple thread to do the lv_task_handler every 16ms espp::Task lv_task({.callback = [](std::mutex &m, std::condition_variable &cv) -> bool { { // lock the display mutex std::lock_guard<std::mutex> lock(lvgl_mutex); lv_task_handler(); } std::unique_lock<std::mutex> lock(m); cv.wait_for(lock, 16ms); return false; }, .task_config = { .name = "lv_task", .core_id = 1, }}); lv_task.start(); // set the display brightness to be 75% tdongle.brightness(75.0f); // make a task to constantly shift the hue of the LED espp::Task led_task({.callback = [&](std::mutex &m, std::condition_variable &cv) -> bool { static float hue = 0.0f; hue += 1.0f; if (hue >= 360.0f) { hue = 0.0f; } espp::Hsv hsv(hue, 1.0f, 1.0f); espp::TDongleS3::get().led(hsv, brightness); std::unique_lock<std::mutex> lock(m); cv.wait_for(lock, 25ms); return false; }, .task_config = { .name = "led_task", }}); led_task.start(); while (true) { auto start = esp_timer_get_time(); // if there are 10 circles on the screen, clear them static constexpr int max_circles = 10; if (circles.size() >= max_circles) { // lock the lvgl mutex std::lock_guard<std::mutex> lock(lvgl_mutex); clear_circles(); } else { // draw a circle of circles on the screen (just draw the next circle) static constexpr int middle_x = tdongle.lcd_width() / 2; static constexpr int middle_y = tdongle.lcd_height() / 2; static constexpr int radius = 30; float angle = circles.size() * 2.0f * M_PI / max_circles; int x = middle_x + radius * cos(angle); int y = middle_y + radius * sin(angle); // lock the lvgl mutex std::lock_guard<std::mutex> lock(lvgl_mutex); draw_circle(x, y, 5); } auto end = esp_timer_get_time(); auto elapsed = end - start; std::this_thread::sleep_for(100ms - std::chrono::microseconds(elapsed)); }
Public Types
-
using Pixel = lv_color16_t
Alias for the pixel type used by the T-Dongle-S3 display.
Public Functions
-
bool initialize_led()
Initialize the RGB LED
- Returns
true if the RGB LED was successfully initialized, false otherwise
-
std::shared_ptr<LedStrip> led() const
Get a shared pointer to the RGB LED
- Returns
A shared pointer to the RGB LED
-
bool led(const Hsv &hsv, float brightness = 100.0f)
Set the color of the LED
- Parameters
hsv – The color of the LED in HSV format
brightness – The brightness of the LED as a percentage (0 - 100)
- Returns
true if the color was successfully set, false otherwise
-
bool led(const Rgb &rgb, float brightness = 100.0f)
Set the color of the LED
- Parameters
rgb – The color of the LED in RGB format
brightness – The brightness of the LED as a percentage (0 - 100)
- Returns
true if the color was successfully set, false otherwise
-
bool initialize_lcd()
Initialize the LCD (low level display driver)
- Returns
true if the LCD was successfully initialized, false otherwise
- bool initialize_display (size_t pixel_buffer_size, const espp::Task::BaseConfig &task_config={.name="Display",.stack_size_bytes=4096,.priority=10,.core_id=0}, int update_period_ms=16)
Initialize the display (lvgl display driver)
Note
This will also allocate two full frame buffers in the SPIRAM
- Parameters
pixel_buffer_size – The size of the pixel buffer
task_config – The task configuration for the display task
update_period_ms – The update period of the display task
- Returns
true if the display was successfully initialized, false otherwise
-
std::shared_ptr<Display<Pixel>> display() const
Get a shared pointer to the display
- Returns
A shared pointer to the display
-
void brightness(float brightness)
Set the brightness of the backlight
- Parameters
brightness – The brightness of the backlight as a percentage (0 - 100)
-
float brightness() const
Get the brightness of the backlight
- Returns
The brightness of the backlight as a percentage (0 - 100)
-
Pixel *vram0() const
Get the VRAM 0 pointer (DMA memory used by LVGL)
Note
This is the memory used by LVGL for rendering
Note
This is null unless initialize_display() has been called
- Returns
The VRAM 0 pointer
-
Pixel *vram1() const
Get the VRAM 1 pointer (DMA memory used by LVGL)
Note
This is the memory used by LVGL for rendering
Note
This is null unless initialize_display() has been called
- Returns
The VRAM 1 pointer
-
uint8_t *frame_buffer0() const
Get the frame buffer 0 pointer
Note
This memory is designed to be used by the application developer and is provided as a convenience. It is not used by the display driver.
Note
This is null unless initialize_display() has been called
- Returns
The frame buffer 0 pointer
-
uint8_t *frame_buffer1() const
Get the frame buffer 1 pointer
Note
This memory is designed to be used by the application developer and is provided as a convenience. It is not used by the display driver.
Note
This is null unless initialize_display() has been called
- Returns
The frame buffer 1 pointer
-
void write_lcd(const uint8_t *data, size_t length, uint32_t user_data)
Write data to the LCD
Note
This method is designed to be used by the display driver
Note
This method queues the data to be written to the LCD, only blocking if there is an ongoing SPI transaction
- Parameters
data – The data to write
length – The length of the data
user_data – User data to pass to the spi transaction callback
-
void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data)
Write a frame to the LCD
Note
This method queues the data to be written to the LCD, only blocking if there is an ongoing SPI transaction
- Parameters
x – The x coordinate
y – The y coordinate
width – The width of the frame, in pixels
height – The height of the frame, in pixels
data – The data to write
-
void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data)
Write lines to the LCD
Note
This method queues the data to be written to the LCD, only blocking if there is an ongoing SPI transaction
- Parameters
xs – The x start coordinate
ys – The y start coordinate
xe – The x end coordinate
ye – The y end coordinate
data – The data to write
user_data – User data to pass to the spi transaction callback
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters
rate_limit – The rate limit to use for the logger
Public Static Functions
-
static inline TDongleS3 &get()
Access the singleton instance of the TDongleS3 class.
- Returns
Reference to the singleton instance of the TDongleS3 class
-
static inline constexpr size_t num_leds()
Get the number of LEDs in the strip
- Returns
The number of LEDs in the strip
-
static inline constexpr size_t lcd_width()
Get the width of the LCD in pixels
- Returns
The width of the LCD in pixels
-
static inline constexpr size_t lcd_height()
Get the height of the LCD in pixels
- Returns
The height of the LCD in pixels
-
static inline constexpr auto get_lcd_dc_gpio()
Get the GPIO pin for the LCD data/command signal
- Returns
The GPIO pin for the LCD data/command signal