Display Drivers

ESPP contains a few different display drivers in the display_drivers component, corresponding to common display drivers on espressif development boards.

API Reference

Header File

Classes

class Gc9a01

Display driver for the GC9A01 display controller.

This code is modified from https://github.com/lvgl/lvgl_esp32_drivers/blob/master/lvgl_tft/GC9A01.c

See also: https://github.com/espressif/esp-bsp/blob/master/components/lcd/esp_lcd_gc9a01/esp_lcd_gc9a01.c

SmartKnob Config

  static constexpr std::string_view dev_kit = "Smartknob-HA";
  int clock_speed = 80 * 1000 * 1000;
  auto spi_num = SPI2_HOST;
  gpio_num_t mosi = GPIO_NUM_6;
  gpio_num_t sclk = GPIO_NUM_5;
  gpio_num_t spics = GPIO_NUM_15;
  gpio_num_t reset = GPIO_NUM_4;
  gpio_num_t dc_pin = (gpio_num_t)DC_PIN_NUM;
  gpio_num_t backlight = GPIO_NUM_7;
  size_t width = 240;
  size_t height = 240;
  size_t pixel_buffer_size = width * 50;
  bool backlight_on_value = true;
  bool reset_value = false;
  bool invert_colors = true;
  int offset_x = 0;
  int offset_y = 0;
  bool mirror_x = true;
  bool mirror_y = true;
  using DisplayDriver = espp::Gc9a01;
  auto rotation = espp::DisplayRotation::LANDSCAPE;

Gc9a01 Example

    // create the spi host
    spi_bus_config_t buscfg;
    memset(&buscfg, 0, sizeof(buscfg));
    buscfg.mosi_io_num = mosi;
    buscfg.miso_io_num = -1;
    buscfg.sclk_io_num = sclk;
    buscfg.quadwp_io_num = -1;
    buscfg.quadhd_io_num = -1;
    buscfg.max_transfer_sz = (int)(pixel_buffer_size * sizeof(lv_color_t));
    // create the spi device
    spi_device_interface_config_t devcfg;
    memset(&devcfg, 0, sizeof(devcfg));
    devcfg.mode = 0;
    devcfg.clock_speed_hz = clock_speed;
    devcfg.input_delay_ns = 0;
    devcfg.spics_io_num = spics;
    devcfg.queue_size = spi_queue_size;
    devcfg.pre_cb = lcd_spi_pre_transfer_callback;
    devcfg.post_cb = lcd_spi_post_transfer_callback;
    esp_err_t ret;
    // Initialize the SPI bus
    ret = spi_bus_initialize(spi_num, &buscfg, SPI_DMA_CH_AUTO);
    ESP_ERROR_CHECK(ret);
    // Attach the LCD to the SPI bus
    ret = spi_bus_add_device(spi_num, &devcfg, &spi);
    ESP_ERROR_CHECK(ret);

    // initialize the controller
    DisplayDriver::initialize(espp::display_drivers::Config{
        .lcd_write = lcd_write,
        .lcd_send_lines = lcd_send_lines,
        .reset_pin = reset,
        .data_command_pin = dc_pin,
        .reset_value = reset_value,
        .invert_colors = invert_colors,
        .offset_x = offset_x,
        .offset_y = offset_y,
        .mirror_x = mirror_x,
        .mirror_y = mirror_y,
    });
    // initialize the display / lvgl
    auto display = std::make_shared<Display>(
        Display::AllocatingConfig{.width = width,
                                  .height = height,
                                  .pixel_buffer_size = pixel_buffer_size,
                                  .flush_callback = DisplayDriver::flush,
                                  .rotation_callback = DisplayDriver::rotate,
                                  .backlight_pin = backlight,
                                  .backlight_on_value = backlight_on_value,
                                  .rotation = rotation});

    // initialize the gui
    Gui gui({});
    size_t iterations = 0;
    while (true) {
      auto label = fmt::format("Iterations: {}", iterations);
      gui.set_label(label);
      gui.set_meter(iterations % 100);
      iterations++;
      std::this_thread::sleep_for(100ms);
    }

Public Static Functions

static inline void initialize(const display_drivers::Config &config)

Store the config data and send the initialization commands to the display controller.

Parameters

config – display_drivers::Config structure

static inline void rotate(const DisplayRotation &rotation)

Set the display rotation.

Parameters

rotation – New display rotation.

static inline void flush(lv_display_t *disp, const lv_area_t *area, uint8_t *color_map)

Flush the pixel data for the provided area to the display.

Parameters
  • *drv – Pointer to the LVGL display driver.

  • *area – Pointer to the structure describing the pixel area.

  • *color_map – Pointer to array of colors to flush to the display.

static inline void set_drawing_area(const lv_area_t *area)

Set the drawing area for the display, resets the cursor to the starting position of the area.

Parameters

*area – Pointer to lv_area_t strcuture with start/end x/y coordinates.

static inline void set_drawing_area(size_t xs, size_t ys, size_t xe, size_t ye)

Set the drawing area for the display, resets the cursor to the starting position of the area.

Parameters
  • xs – Starting x coordinate of the area.

  • ys – Starting y coordinate of the area.

  • xe – Ending x coordinate of the area.

  • ye – Ending y coordinate of the area.

static inline void fill(lv_display_t *disp, const lv_area_t *area, uint8_t *color_map, uint32_t flags = 0)

Flush the pixel data for the provided area to the display.

Parameters
  • *drv – Pointer to the LVGL display driver.

  • *area – Pointer to the structure describing the pixel area.

  • *color_map – Pointer to array of colors to flush to the display.

  • flags – uint32_t user data / flags to pass to the lcd_write transfer function.

static inline void clear(size_t x, size_t y, size_t width, size_t height, uint16_t color = 0x0000)

Clear the display area, filling it with the provided color.

Parameters
  • x – X coordinate of the upper left corner of the display area.

  • y – Y coordinate of the upper left corner of the display area.

  • width – Width of the display area to clear.

  • height – Height of the display area to clear.

  • color – 16 bit color (default 0x0000) to fill with.

static inline void send_command(uint8_t command)

Sends the command, sets flags such that the pre-cb should set the DC pin to command mode.

Parameters

command – Command code to send

static inline void send_command(Command command)

Sends the command, sets flags such that the pre-cb should set the DC pin to command mode.

Parameters

command – Command code to send

static inline void send_data(const uint8_t *data, size_t length, uint32_t flags = 0)

Send data to the display. Adds (1<<DC_LEVEL_BIT) to the flags so that the pre-cb receives it in user data and can configure the DC pin to data mode.

Parameters
  • data – Pointer to array of bytes to be sent

  • length – Number of bytes of data to send.

  • flags – Optional (default = 0) flags associated with transfer.

static inline void set_offset(int x, int y)

Set the offset (upper left starting coordinate) of the display.

Note

This modifies internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – New starting x coordinate (so writing to x address 0 later will actually write to this offset).

  • y – New starting y coordinate (so writing to y address 0 later will actually write to this offset).

static inline void get_offset(int &x, int &y)

Get the offset (upper left starting coordinate) of the display.

Note

This returns internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – Reference variable that will be filled with the currently configured starting x coordinate that was provided in the config or set by set_offset().

  • y – Reference variable that will be filled with the currently configured starting y coordinate that was provided in the config or set by set_offset().

static inline void get_offset_rotated(int &x, int &y)

Get the offset (upper left starting coordinate) of the display after rotation.

Note

This returns internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – Reference variable that will be filled with the currently configured starting x coordinate that was provided in the config or set by set_offset(), updated for the current rotation.

  • y – Reference variable that will be filled with the currently configured starting y coordinate that was provided in the config or set by set_offset(), updated for the current rotation.

Header File

Classes

class Ili9341

Display driver for the ILI9341 display controller.

This code is modified from https://github.com/lvgl/lvgl_esp32_drivers/blob/master/lvgl_tft/ili9341.c and https://github.com/espressif/esp-dev-kits/blob/master/esp32-s2-hmi-devkit-1/components/screen/controller_driver/ili9341/ili9341.c

See also: https://github.com/espressif/esp-bsp/blob/master/components/lcd/esp_lcd_ili9341/esp_lcd_ili9341.c

WROVER-KIT ILI9341 Config

  static constexpr std::string_view dev_kit = "ESP-WROVER-DevKit";
  int clock_speed = 20 * 1000 * 1000;
  auto spi_num = SPI2_HOST;
  gpio_num_t mosi = GPIO_NUM_23;
  gpio_num_t sclk = GPIO_NUM_19;
  gpio_num_t spics = GPIO_NUM_22;
  gpio_num_t reset = GPIO_NUM_18;
  gpio_num_t dc_pin = (gpio_num_t)DC_PIN_NUM;
  gpio_num_t backlight = GPIO_NUM_5;
  size_t width = 320;
  size_t height = 240;
  size_t pixel_buffer_size = 16384;
  bool backlight_on_value = false;
  bool reset_value = false;
  bool invert_colors = false;
  int offset_x = 0;
  int offset_y = 0;
  bool mirror_x = false;
  bool mirror_y = false;
  using DisplayDriver = espp::Ili9341;
  auto rotation = espp::DisplayRotation::LANDSCAPE;

ili9341 Example

    // create the spi host
    spi_bus_config_t buscfg;
    memset(&buscfg, 0, sizeof(buscfg));
    buscfg.mosi_io_num = mosi;
    buscfg.miso_io_num = -1;
    buscfg.sclk_io_num = sclk;
    buscfg.quadwp_io_num = -1;
    buscfg.quadhd_io_num = -1;
    buscfg.max_transfer_sz = (int)(pixel_buffer_size * sizeof(lv_color_t));
    // create the spi device
    spi_device_interface_config_t devcfg;
    memset(&devcfg, 0, sizeof(devcfg));
    devcfg.mode = 0;
    devcfg.clock_speed_hz = clock_speed;
    devcfg.input_delay_ns = 0;
    devcfg.spics_io_num = spics;
    devcfg.queue_size = spi_queue_size;
    devcfg.pre_cb = lcd_spi_pre_transfer_callback;
    devcfg.post_cb = lcd_spi_post_transfer_callback;
    esp_err_t ret;
    // Initialize the SPI bus
    ret = spi_bus_initialize(spi_num, &buscfg, SPI_DMA_CH_AUTO);
    ESP_ERROR_CHECK(ret);
    // Attach the LCD to the SPI bus
    ret = spi_bus_add_device(spi_num, &devcfg, &spi);
    ESP_ERROR_CHECK(ret);

    // initialize the controller
    DisplayDriver::initialize(espp::display_drivers::Config{
        .lcd_write = lcd_write,
        .lcd_send_lines = lcd_send_lines,
        .reset_pin = reset,
        .data_command_pin = dc_pin,
        .reset_value = reset_value,
        .invert_colors = invert_colors,
        .offset_x = offset_x,
        .offset_y = offset_y,
        .mirror_x = mirror_x,
        .mirror_y = mirror_y,
    });
    // initialize the display / lvgl
    auto display = std::make_shared<Display>(
        Display::AllocatingConfig{.width = width,
                                  .height = height,
                                  .pixel_buffer_size = pixel_buffer_size,
                                  .flush_callback = DisplayDriver::flush,
                                  .rotation_callback = DisplayDriver::rotate,
                                  .backlight_pin = backlight,
                                  .backlight_on_value = backlight_on_value,
                                  .rotation = rotation});

    // initialize the gui
    Gui gui({});
    size_t iterations = 0;
    while (true) {
      auto label = fmt::format("Iterations: {}", iterations);
      gui.set_label(label);
      gui.set_meter(iterations % 100);
      iterations++;
      std::this_thread::sleep_for(100ms);
    }

Public Static Functions

static inline void initialize(const display_drivers::Config &config)

Store the config data and send the initialization commands to the display controller.

Parameters

config – display_drivers::Config structure

static inline void rotate(const DisplayRotation &rotation)

Set the display rotation.

Parameters

rotation – New display rotation.

static inline void flush(lv_display_t *disp, const lv_area_t *area, uint8_t *color_map)

Flush the pixel data for the provided area to the display.

Parameters
  • *drv – Pointer to the LVGL display driver.

  • *area – Pointer to the structure describing the pixel area.

  • *color_map – Pointer to array of colors to flush to the display.

static inline void set_drawing_area(const lv_area_t *area)

Set the drawing area for the display, resets the cursor to the starting position of the area.

Parameters

*area – Pointer to lv_area_t strcuture with start/end x/y coordinates.

static inline void set_drawing_area(size_t xs, size_t ys, size_t xe, size_t ye)

Set the drawing area for the display, resets the cursor to the starting position of the area.

Parameters
  • xs – Starting x coordinate of the area.

  • ys – Starting y coordinate of the area.

  • xe – Ending x coordinate of the area.

  • ye – Ending y coordinate of the area.

static inline void fill(lv_display_t *disp, const lv_area_t *area, uint8_t *color_map, uint32_t flags = 0)

Flush the pixel data for the provided area to the display.

Parameters
  • *drv – Pointer to the LVGL display driver.

  • *area – Pointer to the structure describing the pixel area.

  • *color_map – Pointer to array of colors to flush to the display.

  • flags – uint32_t user data / flags to pass to the lcd_write transfer function.

static inline void clear(size_t x, size_t y, size_t width, size_t height, uint16_t color = 0x0000)

Clear the display area, filling it with the provided color.

Parameters
  • x – X coordinate of the upper left corner of the display area.

  • y – Y coordinate of the upper left corner of the display area.

  • width – Width of the display area to clear.

  • height – Height of the display area to clear.

  • color – 16 bit color (default 0x0000) to fill with.

static inline void send_command(uint8_t command)

Sends the command, sets flags such that the pre-cb should set the DC pin to command mode.

Parameters

command – Command code to send

static inline void send_command(Command command)

Sends the command, sets flags such that the pre-cb should set the DC pin to command mode.

Parameters

command – Command code to send

static inline void send_data(const uint8_t *data, size_t length, uint32_t flags = 0)

Send data to the display. Adds (1<<DC_LEVEL_BIT) to the flags so that the pre-cb receives it in user data and can configure the DC pin to data mode.

Parameters
  • data – Pointer to array of bytes to be sent

  • length – Number of bytes of data to send.

  • flags – Optional (default = 0) flags associated with transfer.

static inline void set_offset(int x, int y)

Set the offset (upper left starting coordinate) of the display.

Note

This modifies internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – New starting x coordinate (so writing to x address 0 later will actually write to this offset).

  • y – New starting y coordinate (so writing to y address 0 later will actually write to this offset).

static inline void get_offset(int &x, int &y)

Get the offset (upper left starting coordinate) of the display.

Note

This returns internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – Reference variable that will be filled with the currently configured starting x coordinate that was provided in the config or set by set_offset().

  • y – Reference variable that will be filled with the currently configured starting y coordinate that was provided in the config or set by set_offset().

static inline void get_offset_rotated(int &x, int &y)

Get the offset (upper left starting coordinate) of the display after rotation.

Note

This returns internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – Reference variable that will be filled with the currently configured starting x coordinate that was provided in the config or set by set_offset(), updated for the current rotation.

  • y – Reference variable that will be filled with the currently configured starting y coordinate that was provided in the config or set by set_offset(), updated for the current rotation.

Header File

Classes

class St7789

Display driver for the ST7789 display controller.

This code is modified from https://github.com/lvgl/lvgl_esp32_drivers/blob/master/lvgl_tft/st7789.c and https://github.com/Bodmer/TFT_eSPI/blob/master/TFT_Drivers/ST7789_Defines.h

See also: https://github.com/espressif/esp-who/blob/master/components/screen/controller_driver/st7789/st7789.c or https://github.com/espressif/tflite-micro-esp-examples/blob/master/components/screen/controller_driver/st7789/st7789.c or https://esphome.io/api/st7789v_8h_source.html or https://github.com/mireq/esp32-st7789-demo/blob/master/components/st7789/include/st7789.h or https://github.com/mireq/esp32-st7789-demo/blob/master/components/st7789/st7789.c

TTGO St7789 Config

  static constexpr std::string_view dev_kit = "TTGO T-Display";
  int clock_speed = 60 * 1000 * 1000;
  auto spi_num = SPI2_HOST;
  gpio_num_t mosi = GPIO_NUM_19;
  gpio_num_t sclk = GPIO_NUM_18;
  gpio_num_t spics = GPIO_NUM_5;
  gpio_num_t reset = GPIO_NUM_23;
  gpio_num_t dc_pin = (gpio_num_t)DC_PIN_NUM;
  gpio_num_t backlight = GPIO_NUM_4;
  size_t width = 240;
  size_t height = 135;
  size_t pixel_buffer_size = 12800;
  bool backlight_on_value = false;
  bool reset_value = false;
  bool invert_colors = false;
  int offset_x = 40;
  int offset_y = 53;
  bool mirror_x = false;
  bool mirror_y = false;
  using DisplayDriver = espp::St7789;
  auto rotation = espp::DisplayRotation::PORTRAIT;

ESP32-S3-BOX St7789 Config

  static constexpr std::string_view dev_kit = "ESP32-S3-BOX";
  int clock_speed = 60 * 1000 * 1000;
  auto spi_num = SPI2_HOST;
  gpio_num_t mosi = GPIO_NUM_6;
  gpio_num_t sclk = GPIO_NUM_7;
  gpio_num_t spics = GPIO_NUM_5;
  gpio_num_t reset = GPIO_NUM_48;
  gpio_num_t dc_pin = (gpio_num_t)DC_PIN_NUM;
  gpio_num_t backlight = GPIO_NUM_45;
  size_t width = 320;
  size_t height = 240;
  size_t pixel_buffer_size = width * 50;
  bool backlight_on_value = true;
  bool reset_value = false;
  bool invert_colors = true;
  int offset_x = 0;
  int offset_y = 0;
  bool mirror_x = true;
  bool mirror_y = true;
  using DisplayDriver = espp::St7789;
  auto rotation = espp::DisplayRotation::LANDSCAPE;

st7789 Example

    // create the spi host
    spi_bus_config_t buscfg;
    memset(&buscfg, 0, sizeof(buscfg));
    buscfg.mosi_io_num = mosi;
    buscfg.miso_io_num = -1;
    buscfg.sclk_io_num = sclk;
    buscfg.quadwp_io_num = -1;
    buscfg.quadhd_io_num = -1;
    buscfg.max_transfer_sz = (int)(pixel_buffer_size * sizeof(lv_color_t));
    // create the spi device
    spi_device_interface_config_t devcfg;
    memset(&devcfg, 0, sizeof(devcfg));
    devcfg.mode = 0;
    devcfg.clock_speed_hz = clock_speed;
    devcfg.input_delay_ns = 0;
    devcfg.spics_io_num = spics;
    devcfg.queue_size = spi_queue_size;
    devcfg.pre_cb = lcd_spi_pre_transfer_callback;
    devcfg.post_cb = lcd_spi_post_transfer_callback;
    esp_err_t ret;
    // Initialize the SPI bus
    ret = spi_bus_initialize(spi_num, &buscfg, SPI_DMA_CH_AUTO);
    ESP_ERROR_CHECK(ret);
    // Attach the LCD to the SPI bus
    ret = spi_bus_add_device(spi_num, &devcfg, &spi);
    ESP_ERROR_CHECK(ret);

    // initialize the controller
    DisplayDriver::initialize(espp::display_drivers::Config{
        .lcd_write = lcd_write,
        .lcd_send_lines = lcd_send_lines,
        .reset_pin = reset,
        .data_command_pin = dc_pin,
        .reset_value = reset_value,
        .invert_colors = invert_colors,
        .offset_x = offset_x,
        .offset_y = offset_y,
        .mirror_x = mirror_x,
        .mirror_y = mirror_y,
    });
    // initialize the display / lvgl
    auto display = std::make_shared<Display>(
        Display::AllocatingConfig{.width = width,
                                  .height = height,
                                  .pixel_buffer_size = pixel_buffer_size,
                                  .flush_callback = DisplayDriver::flush,
                                  .rotation_callback = DisplayDriver::rotate,
                                  .backlight_pin = backlight,
                                  .backlight_on_value = backlight_on_value,
                                  .rotation = rotation});

    // initialize the gui
    Gui gui({});
    size_t iterations = 0;
    while (true) {
      auto label = fmt::format("Iterations: {}", iterations);
      gui.set_label(label);
      gui.set_meter(iterations % 100);
      iterations++;
      std::this_thread::sleep_for(100ms);
    }

Public Static Functions

static inline void initialize(const display_drivers::Config &config)

Store the config data and send the initialization commands to the display controller.

Parameters

config – display_drivers::Config structure

static inline void rotate(const DisplayRotation &rotation)

Set the display rotation.

Parameters

rotation – New display rotation.

static inline void flush(lv_display_t *disp, const lv_area_t *area, uint8_t *color_map)

Flush the pixel data for the provided area to the display.

Parameters
  • *drv – Pointer to the LVGL display driver.

  • *area – Pointer to the structure describing the pixel area.

  • *color_map – Pointer to array of colors to flush to the display.

static inline void set_drawing_area(const lv_area_t *area)

Set the drawing area for the display, resets the cursor to the starting position of the area.

Parameters

*area – Pointer to lv_area_t strcuture with start/end x/y coordinates.

static inline void set_drawing_area(size_t xs, size_t ys, size_t xe, size_t ye)

Set the drawing area for the display, resets the cursor to the starting position of the area.

Parameters
  • xs – Starting x coordinate of the area.

  • ys – Starting y coordinate of the area.

  • xe – Ending x coordinate of the area.

  • ye – Ending y coordinate of the area.

static inline void fill(lv_display_t *disp, const lv_area_t *area, uint8_t *color_map, uint32_t flags = 0)

Flush the pixel data for the provided area to the display.

Parameters
  • *drv – Pointer to the LVGL display driver.

  • *area – Pointer to the structure describing the pixel area.

  • *color_map – Pointer to array of colors to flush to the display.

  • flags – uint32_t user data / flags to pass to the lcd_write transfer function.

static inline void clear(size_t x, size_t y, size_t width, size_t height, uint16_t color = 0x0000)

Clear the display area, filling it with the provided color.

Parameters
  • x – X coordinate of the upper left corner of the display area.

  • y – Y coordinate of the upper left corner of the display area.

  • width – Width of the display area to clear.

  • height – Height of the display area to clear.

  • color – 16 bit color (default 0x0000) to fill with.

static inline void send_command(uint8_t command)

Sends the command, sets flags (to 0) such that the pre-cb should set the DC pin to command mode.

Parameters

command – Command code to send

static inline void send_command(Command command)

Sends the command, sets flags such that the pre-cb should set the DC pin to command mode.

Parameters

command – Command code to send

static inline void send_data(const uint8_t *data, size_t length, uint32_t flags = 0)

Send data to the display. Adds (1<<DC_LEVEL_BIT) to the flags so that the pre-cb receives it in user data and can configure the DC pin to data mode.

Parameters
  • data – Pointer to array of bytes to be sent

  • length – Number of bytes of data to send.

  • flags – Optional (default = 0) flags associated with transfer.

static inline void set_offset(int x, int y)

Set the offset (upper left starting coordinate) of the display.

Note

This modifies internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – New starting x coordinate (so writing to x address 0 later will actually write to this offset).

  • y – New starting y coordinate (so writing to y address 0 later will actually write to this offset).

static inline void get_offset(int &x, int &y)

Get the offset (upper left starting coordinate) of the display.

Note

This returns internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – Reference variable that will be filled with the currently configured starting x coordinate that was provided in the config or set by set_offset().

  • y – Reference variable that will be filled with the currently configured starting y coordinate that was provided in the config or set by set_offset().

static inline void get_offset_rotated(int &x, int &y)

Get the offset (upper left starting coordinate) of the display after rotation.

Note

This returns internal variables that are used when sending coordinates / filling parts of the display.

Parameters
  • x – Reference variable that will be filled with the currently configured starting x coordinate that was provided in the config or set by set_offset(), updated for the current rotation.

  • y – Reference variable that will be filled with the currently configured starting y coordinate that was provided in the config or set by set_offset(), updated for the current rotation.