Screen¶
Screen is a very important display device as many information from various applications needs to be displayed to users. Both ESP32 and ESP32-S2 chips support screens driven by I2C interface, 8080 parallel interface, SPI interface and etc. The supported types of screen controllers are listed in the following table:
Controller |
Max Resolution |
Type |
---|---|---|
NT35510 |
480 x 865 |
Color |
ILI9806 |
480 x 865 |
Color |
RM68120 |
480 x 865 |
Color |
ILI9486 |
320 x 480 |
Color |
ILI9341 |
240 x 320 |
Color |
ST7789 |
240 x 320 |
Color |
ST7796 |
320 x 480 |
Color |
SSD1351 |
128 x 128 |
Color |
SSD1306 |
128 x 64 |
Mono |
SSD1307 |
128 x 39 |
Mono |
SSD1322 |
480 x 128 |
Gray |
Note
The 8080 parallel interface is implemented via the LCD mode in the I2S of ESP32, so sometimes it is called I2S interface
in this document.
Screen Driver Structure¶
In order to be more in line with the actual situation where a screen controller has multiple interfaces, the screen driver is divided into two parts: the interface driver
and the controller driver
.
The interface driver: conduct basic reads and writes of commands and data
The controller driver: display information on screen via interfaces
A controller driver can be designed to switch between different interfaces in hardware level by calling corresponding interface drivers.
Screen Types¶
A discussion about screen types will help us to have a clear understanding of drivers. Here, we use colors that can be displayed on the screen to classify screens, rather than the panel material of them such as OLED, LCD and etc. In general, the colors displayed on screen determines the BPP (Bits Per Pixel), and the differences in BPP lead to differences in how the program handles it. Here, we list some ways in which GRAM is mapped to pixel points in below:
From above figures, we can see that there are mainly two types of mapping:
When BPP >= 8, it is usually a color screen that supports RGB888, RGB666, RGB565 and other codings.
When BPP < 8, it is usually a mono screen that may either be black-and-white or gray.
When BPP < 8, a byte is mapped to multiple pixels, so a single pixel cannot be controlled directly. In this case, draw_pixel()
is not supported in the driver, and the parameters of set_window()
are also limited. When BPP >= 8, each single pixel can be accessed easily.
Attention
For color screens, the driver only supports RGB565 color coding.
Interface Driver¶
A screen controller usually has multiple interfaces. On ESP32, three kinds of interfaces as 8080 parallel interface
, SPI
and I2C
are typically used to connect to the screen. You can choose one of them as the interface when creating interface drivers via scr_interface_create()
.
Note
Please remember to select corresponding parameter types when creating different interfaces using scr_interface_create()
, e.g., select i2s_lcd_config_t
for I2S interface; select scr_interface_spi_config_t
for SPI interface.
To facilitate the use of these interfaces in the driver, all interfaces are defined in display/screen/screen_utility/interface_drv_def.h, which can be called easily by less parameters.
Note
Most screens use big-endian order to store data, while ESP32 uses small-endian mode. You can switch between them in the interface driver you used, based on swap_data
configurations. Please note: when using the SPI interface, the received data must be stored in RAM because the IDF’s SPI driver itself does not support this swapping function and an additional program in the interface driver will do the work, which require the data to be writable.
Controller Driver¶
Some common functions of the screen are abstracted using scr_driver_t
in this section according to display and other functions of different screen controllers, in order to port these common functions to different GUI libraries easily. For some non-generic functions of the screen, you need to call its specific functions.
Not all screens have implemented these common functions, since different screen controller has their own functions. For example, for screens with BPP < 8, the function draw_pixel()
is not supported. And calling an unsupported function will return ESP_ERR_NOT_SUPPORTED
.
Display Direction¶
The screen display direction set here is implemented entirely by the screen hardware, and this feature varies from one screen controller to another. There are 8 possible display directions. A display can be rotated by 0°, 90°, 180° or 270° and can also be viewed from the top or bottom, with 0° and top view as its default direction. These 8 (4 × 2) directions can also be represented as a combination of 3 binary switches: X-mirroring, Y-mirroring and X/Y swapping.
The total 8 combinations of display directions are listed in the following table. If the direction of your display is not correct, please check the configuration switches below to make it work properly.
0 [SCR_DIR_LRTB] |
SCR_MIRROR_Y [SCR_DIR_LRBT] |
||
SCR_MIRROR_X [SCR_DIR_RLTB] |
SCR_MIRROR_X| SCR_MIRROR_Y [SCR_DIR_RLBT] |
||
SCR_SWAP_XY [SCR_DIR_TBLR] |
SCR_SWAP_XY| SCR_MIRROR_Y [SCR_DIR_BTLR] |
||
SCR_SWAP_XY| SCR_MIRROR_X [SCR_DIR_TBRL] |
SCR_SWAP_XY| SCR_MIRROR_X| SCR_MIRROR_Y [SCR_DIR_BTRL] |
The implementations of display directions are not exactly the same for different screen controllers, and are usually divided into the following cases:
For color screens, 8 directions are supported.
For mono screens, e.g., SSD1306, only the first 4 directions defined in
scr_dir_t
are supported, which means they do not support X/Y swapping.
Note
The display direction is also related to the screen panel you used, and you may encounter two types of abnormal cases:
The display direction is set to
SCR_DIR_LRTB
, but the screen does not show as what listed in the above table. This may be because the alignment on the screen panel is mirrored in the X/Y direction, in which case you need to adjust the rotation to get the desired direction.After rotated, the screen does not show anything any more. This may be because the resolution of the screen panel is smaller than that of the screen controller, making the display area not falling completely on the screen panel, in which case you need to set a proper offset for the display area.
Offset of the Display Area¶
In some small screens, the resolution of the display area is usually smaller than that of the controller window. Please refer to the following figure:
In this figure, Controller window
is the window for screen controller, with its resolution as 240 × 320; Panel window
is the window for screen panel, with its resolution as 135 × 240, which is the display area. From this figure, we can see that the display area is shifted by 52 pixels horizontally and by 40 pixels vertically.
When the screen is rotated 90° anticlockwise, the display area is shifted by 40 pixels horizontally and by 53 pixels vertically, as shown in the figure below:
The screen controller driver will help you to change the offset value automatically according to the rotation of the screen to maintain a proper display. All you need to do is to properly configure the screen offset and the screen panel size in scr_controller_config_t
when it is in SCR_DIR_LRTB
direction.
Note
This only supports screens with BPP >= 8.
When the resolution of your screen controller is configurable and you find something wrong with the offset, it may be because the selected resolution does not match the actual one, and you should make modifications accordingly, for example, set the
ILI9806_RESOLUTION_VER
inili9806.c
as the actual resolution for ILI9806.
Application Example¶
Note
The following examples are no longer maintained. For LCD and LVGL examples, please refer to: i80_controller、 rgb_panel And spi_lcd_touch
Initialize the Screen¶
scr_driver_t g_lcd; // A screen driver
esp_err_t ret = ESP_OK;
/** Initialize 16bit 8080 interface */
i2s_lcd_config_t i2s_lcd_cfg = {
.data_width = 16,
.pin_data_num = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
},
.pin_num_cs = 45,
.pin_num_wr = 34,
.pin_num_rs = 33,
.clk_freq = 20000000,
.i2s_port = I2S_NUM_0,
.buffer_size = 32000,
.swap_data = false,
};
scr_interface_driver_t *iface_drv;
scr_interface_create(SCREEN_IFACE_8080, &i2s_lcd_cfg, &iface_drv);
/** Find screen driver for ILI9806 */
ret = scr_find_driver(SCREEN_CONTROLLER_ILI9806, &g_lcd);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "screen find failed");
return;
}
/** Configure screen controller */
scr_controller_config_t lcd_cfg = {
.interface_drv = iface_drv,
.pin_num_rst = -1, // The reset pin is not connected
.pin_num_bckl = -1, // The backlight pin is not connected
.rst_active_level = 0,
.bckl_active_level = 1,
.offset_hor = 0,
.offset_ver = 0,
.width = 480,
.height = 854,
.rotate = SCR_DIR_LRBT,
};
/** Initialize ILI9806 screen */
g_lcd.init(&lcd_cfg);
Note
By default, only the driver of ILI9341 screen is enabled. If you need to use other drivers, please go to menuconfig -> Component config -> LCD Drivers -> Select Screen Controller
to enable the corresponding screen drivers.
Display Images¶
/** Draw a red point at position (10, 20) */
lcd.draw_pixel(10, 20, COLOR_RED);
/** Draw a bitmap */
lcd.draw_bitmap(0, 0, width_of_pic, height_of_pic, pic_data);
Obtain Screen Information¶
scr_info_t lcd_info;
lcd.get_info(&lcd_info);
ESP_LOGI(TAG, "Screen name:%s | width:%d | height:%d", lcd_info.name, lcd_info.width, lcd_info.height);
API Reference¶
Header File¶
Functions¶
-
esp_err_t
scr_find_driver
(scr_controller_t controller, scr_driver_t *out_screen)¶ Find a screen driver.
- Return
ESP_OK on success
ESP_ERR_INVALID_ARG Arguments is NULL.
ESP_ERR_NOT_FOUND Screen controller was not found.
- Parameters
controller
: Screen controller to initializeout_screen
: Pointer to a screen driver
Structures¶
-
struct
scr_controller_config_t
¶ configuration of screen controller
Public Members
-
scr_interface_driver_t *
interface_drv
¶ Interface driver for screen
-
int8_t
pin_num_rst
¶ Pin to hardreset LCD
-
int8_t
pin_num_bckl
¶ Pin for control backlight
-
uint8_t
rst_active_level
¶ Reset pin active level
-
uint8_t
bckl_active_level
¶ Backlight active level
-
uint16_t
width
¶ Screen width
-
uint16_t
height
¶ Screen height
-
uint16_t
offset_hor
¶ Offset of horizontal
-
uint16_t
offset_ver
¶ Offset of vertical
-
scr_interface_driver_t *
-
struct
scr_info_t
¶ Information of screen.
Public Members
-
uint16_t
width
¶ Current screen width, it may change when apply to rotate
-
uint16_t
height
¶ Current screen height, it may change when apply to rotate
-
scr_color_type_t
color_type
¶ Color type of the screen, See scr_color_type_t struct
-
uint8_t
bpp
¶ Bits per pixel
-
const char *
name
¶ Name of the screen
-
uint16_t
-
struct
scr_driver_t
¶ Define a screen common function.
Public Members
-
esp_err_t (*
init
)(const scr_controller_config_t *lcd_conf)¶ Initialize screen.
- Return
ESP_OK on success
ESP_FAIL Driver not installed
- Parameters
lcd_conf
: Pointer to a structure with lcd config arguments. see struct scr_controller_config_t
-
esp_err_t (*
deinit
)(void)¶ Deinitialize screen.
- Return
ESP_OK on success
ESP_FAIL Deinitialize failed
ESP_ERR_NOT_SUPPORTED unsupported
-
esp_err_t (*
set_direction
)(scr_dir_t dir)¶ Set screen direction of rotation.
- Note
Not all screens support eight directions, it depends on the screen controller.
- Return
ESP_OK on success
ESP_FAIL Failed
- Parameters
dir
: Pointer to a scr_dir_t structure. You can set the direction in two ways, for example, set it to “SCR_DIR_LRBT” or “SCR_MIRROR_Y”, They are the same, depending on which expression you want to use
-
esp_err_t (*
set_window
)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)¶ Set screen window.
- Note
When the BPP of the screen controller is less than 8, the coordinate value is limited to a multiple of some number
- Return
ESP_OK on success
ESP_FAIL Failed
- Parameters
x0
: Starting point in X directiony0
: Starting point in Y directionx1
: End point in X directiony1
: End point in Y direction
-
esp_err_t (*
write_ram_data
)(uint16_t color)¶ Write a RAM data.
- Return
ESP_OK on success
ESP_FAIL Failed
- Parameters
color
: New color of a pixel
-
esp_err_t (*
draw_pixel
)(uint16_t x, uint16_t y, uint16_t color)¶ Draw one pixel in screen with color.
- Return
ESP_OK on success
ESP_FAIL Failed
- Parameters
x
: X co-ordinate of set orientationy
: Y co-ordinate of set orientationcolor
: New color of the pixel
-
esp_err_t (*
draw_bitmap
)(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)¶ Fill the pixels on LCD screen with bitmap.
- Return
ESP_OK on success
ESP_FAIL Failed
- Parameters
x
: Starting point in X directiony
: Starting point in Y directionw
: width of image in bitmap arrayh
: height of image in bitmap arraybitmap
: pointer to bitmap array
-
esp_err_t (*
get_info
)(scr_info_t *info)¶ Get screen information.
- Return
ESP_OK on success
ESP_FAIL Failed
- Parameters
info
: Pointer to a scr_info_t structure.
-
esp_err_t (*
Macros¶
-
COLOR_BLACK
¶
-
COLOR_NAVY
¶
-
COLOR_DARKGREEN
¶
-
COLOR_DARKCYAN
¶
-
COLOR_MAROON
¶
-
COLOR_PURPLE
¶
-
COLOR_OLIVE
¶
-
COLOR_LIGHTGREY
¶
-
COLOR_DARKGREY
¶
-
COLOR_BLUE
¶
-
COLOR_GREEN
¶
-
COLOR_CYAN
¶
-
COLOR_RED
¶
-
COLOR_MAGENTA
¶
-
COLOR_YELLOW
¶
-
COLOR_WHITE
¶
-
COLOR_ORANGE
¶
-
COLOR_GREENYELLOW
¶
-
COLOR_PINK
¶
-
COLOR_SILVER
¶
-
COLOR_GRAY
¶
-
COLOR_LIME
¶
-
COLOR_TEAL
¶
-
COLOR_FUCHSIA
¶
-
COLOR_ESP_BKGD
¶
Enumerations¶
-
enum
scr_dir_t
¶ Define all screen direction.
Values:
-
SCR_DIR_LRTB
¶ From left to right then from top to bottom, this consider as the original direction of the screen
-
SCR_DIR_LRBT
¶ From left to right then from bottom to top
-
SCR_DIR_RLTB
¶ From right to left then from top to bottom
-
SCR_DIR_RLBT
¶ From right to left then from bottom to top
-
SCR_DIR_TBLR
¶ From top to bottom then from left to right
-
SCR_DIR_BTLR
¶ From bottom to top then from left to right
-
SCR_DIR_TBRL
¶ From top to bottom then from right to left
-
SCR_DIR_BTRL
¶ From bottom to top then from right to left
-
SCR_DIR_MAX
¶
-
SCR_MIRROR_X
= 0x40¶ Mirror X-axis
-
SCR_MIRROR_Y
= 0x20¶ Mirror Y-axis
-
SCR_SWAP_XY
= 0x80¶ Swap XY axis
-
-
enum
scr_color_type_t
¶ The types of colors that can be displayed on the screen.
Values:
-
SCR_COLOR_TYPE_MONO
¶ The screen is monochrome
-
SCR_COLOR_TYPE_GRAY
¶ The screen is gray
-
SCR_COLOR_TYPE_RGB565
¶ The screen is colorful
-
-
enum
scr_controller_t
¶ All supported screen controllers.
Values:
-
SCREEN_CONTROLLER_ILI9341
¶
-
SCREEN_CONTROLLER_ILI9342
¶
-
SCREEN_CONTROLLER_ILI9806
¶
-
SCREEN_CONTROLLER_ILI9486
¶
-
SCREEN_CONTROLLER_ILI9488
¶
-
SCREEN_CONTROLLER_NT35510
¶
-
SCREEN_CONTROLLER_RM68120
¶
-
SCREEN_CONTROLLER_ST7789
¶
-
SCREEN_CONTROLLER_ST7796
¶
-
SCREEN_CONTROLLER_SSD1351
¶
-
SCREEN_CONTROLLER_SSD1963
¶
-
SCREEN_CONTROLLER_SSD1306
¶
-
SCREEN_CONTROLLER_SSD1307
¶
-
SCREEN_CONTROLLER_SSD1322
¶
-
Header File¶
Functions¶
-
esp_err_t
scr_interface_create
(scr_interface_type_t type, void *config, scr_interface_driver_t **out_driver)¶ Create screen interface driver.
- Return
ESP_OK on success
ESP_ERR_INVALID_ARG Arguments is NULL.
ESP_FAIL Initialize failed
ESP_ERR_NO_MEM: Cannot allocate memory.
- Parameters
type
: Type of screen interfaceconfig
: configuration of interface driverout_driver
: Pointer to a screen interface driver
-
esp_err_t
scr_interface_delete
(const scr_interface_driver_t *driver)¶ Delete screen interface driver.
- Return
ESP_OK on success
ESP_ERR_INVALID_ARG Arguments is NULL.
- Parameters
driver
: screen interface driver to delete
Structures¶
-
struct
scr_interface_spi_config_t
¶ SPI interface configuration.
-
struct
scr_interface_i2c_config_t
¶ I2C interface configuration.
Public Members
-
i2c_bus_handle_t
i2c_bus
¶ Handle of i2c bus
-
uint32_t
clk_speed
¶ I2C clock frequency for master mode, (no higher than 1MHz for now)
-
uint16_t
slave_addr
¶ I2C slave address
-
i2c_bus_handle_t
-
struct
scr_interface_driver_t
¶ Define common function for screen interface driver.
Public Members
-
scr_interface_type_t
type
¶ Interface bus type, see scr_interface_type_t struct
-
esp_err_t (*
write_command
)(void *handle, const uint8_t *cmd, uint32_t length)¶ Function to write command
-
esp_err_t (*
write_data
)(void *handle, uint16_t data)¶ Function to write a data
-
esp_err_t (*
write
)(void *handle, const uint8_t *data, uint32_t length)¶ Function to write a block data
-
esp_err_t (*
read
)(void *handle, uint8_t *data, uint32_t length)¶ Function to read a block data
-
esp_err_t (*
bus_acquire
)(void *handle)¶ Function to acquire interface bus
-
esp_err_t (*
bus_release
)(void *handle)¶ Function to release interface bus
-
scr_interface_type_t