mcu_lcd_display
Overview
The display API abstracts different screen interface drivers. Users create a handle based on the screen type.
display hardware features:
Supports multiple screen types, such as RGB LCD (RGB565, RGB888) and MCU LCD (8-bit, 16-bit).
- Supports pixel conversion, where the input data format can differ from the LCD output format. For example, you can provide YUYV frames for flushing.
YUYV to RGB565/RGB888/RGB666
RGB565 to RGB888
RGB888 to RGB565
RGB565 to RGB666
RGB888 to RGB666
For RGB565 format, used GPIO bits are the higher bits: R3-R7 high bits, G2-G7 high bits, B3-B7 high bits.
This section describes how the display module drives MCU LCDs, including API usage, parameter descriptions, and notes.
For MCU LCD example projects, see:
For API reference, see:
Development Intro
1. Power LDO Control
By default in the BK7258 board SDK, the LCD LDO control pin is GPIO13. If your I/O differs, configure GPIOs explicitly in your application.
2. Backlight Control
Configure the LCD backlight control pin using the GPIO driver in your application.
3. LCD Device
In the BK7258 board SDK, the default LCD RGB device is st7796s. If your device differs, add your custom device to the solution.
For adding devices, see: - LCD Device Addition Guide
3. MCU Output Format (8-bit / 16-bit) Configuration
The MCU interface supports 8 data lines (D0-7) and 16 data lines (D0-15). There are format constraints for RGB565/666/888 as follows:
8-bit supports RGB565 and RGB888 output: out_fmt = PIXEL_FMT_RGB565, out_fmt = PIXEL_FMT_RGB888;
16-bit supports only RGB666 output: out_fmt = PIXEL_FMT_RGB666
16-bit supports only RGB888 output: out_fmt = PIXEL_FMT_RGB888_16BIT
Configure the MCU screen output format via out_fmt in lcd_device_t of the lcd device. The following config shows: The display module input data source is YUYV, the MCU interface is 8-bit RGB565, the display module converts YUYV to RGB565 internally and outputs to the MCU LCD.
Code Example
const lcd_device_t lcd_device_st7796s =
{
.id = LCD_DEVICE_ST7796S,
.name = "st7796s",
.type = LCD_TYPE_MCU8080,
.width = 320,
.height = 480,
.mcu = &lcd_mcu,
.src_fmt = PIXEL_FMT_YUYV,
.out_fmt = PIXEL_FMT_RGB565,
.lcd_init = lcd_st7796s_init,
.lcd_off = st7796s_lcd_off,
};
API Call Flow Overview
The typical MCU LCD Display usage flow is as follows:
┌─────────────────────────────────────────────────────────────┐
│ MCU LCD Display API Call Flow │
└─────────────────────────────────────────────────────────────┘
1. Hardware Setup ──→ Configure LCD LDO and backlight GPIO
└─ Enable power and backlight control
2. bk_display_mcu_new() ──→ Create MCU LCD controller instance
└─ Configure LCD device and TE pin
3. bk_display_open() ──→ Open display controller
└─ Initialize LCD hardware
4. bk_display_flush() ──→ Refresh display (can be called multiple times)
└─ Send frame data to LCD
5. bk_display_close() ──→ Close display controller
└─ Stop hardware, disable clock
6. bk_display_delete() ──→ Delete controller instance
└─ Release resources
Attention
APIs must be called in the above sequence
Display must be created and opened before flushing
MCU LCD uses 8-bit or 16-bit data bus as configured
Frame free callback must be properly implemented
For complete usage example and detailed API descriptions, please refer to the Chinese documentation. The English version provides the same API structure and parameters.
Code Flow
1. Create MCU LCD Controller
- Parameters:
handle: Output parameter that stores the created display controller handleconfig: Controller configuration containing LCD device info and GPIO pins
Example:
#include <components/bk_display/bk_display.h>
#include <components/bk_display/bk_display_types.h>
static bk_display_ctlr_handle_t lcd_display_handle = NULL;
static const lcd_device_t *lcd_device = &lcd_device_st7796s;
// Create MCU LCD controller
bk_display_mcu_ctlr_config_t lcd_display_config = {0};
lcd_display_config.lcd_device = lcd_device;
lcd_display_config.te_pin = INVALID_GPIO_PIN; // TE pin (optional)
avdk_err_t ret = bk_display_mcu_new(&lcd_display_handle, &lcd_display_config);
if (ret != AVDK_ERR_OK) {
// error handling
}
Attention
lcd_device provides screen resolution, interface type and other info and is mandatory. te_pin is the Tearing Effect signal. If the screen does not support TE, set to -1.
2. Open LCD Display
Parameters:
- handle: display controller handle
Description: Open LCD display and initialize the controller.
Example:
// Enable LCD LDO. If your board drives the pin directly, just use the GPIO driver
gpio_dev_unmap(lcd_ldo_io);
BK_LOG_ON_ERR(bk_gpio_enable_output(lcd_ldo_io));
BK_LOG_ON_ERR(bk_gpio_pull_up(lcd_ldo_io));
bk_gpio_set_output_high(lcd_ldo_io);
// Turn on backlight via GPIO or PWM
gpio_dev_unmap(bl_io);
BK_LOG_ON_ERR(bk_gpio_enable_output(bl_io));
BK_LOG_ON_ERR(bk_gpio_pull_up(bl_io));
bk_gpio_set_output_high(bl_io);
// Open display controller
ret = bk_display_open(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
// error handling
}
3. Flush LCD Display
Parameters:
- handle: display controller handle
- frame: pointer to the frame to display
- free_t: callback to release the frame
- Description:
Refresh the LCD with the frame data.
Supported source formats: PIXEL_FMT_RGB565, PIXEL_FMT_RGB888, PIXEL_FMT_YUYV; set in frame->fmt.
The frame release callback free_t: after the next frame is provided, the display module will call free_t to release the previous frame. If there is only one frame, the release is called on close.
If the source resolution is larger than the LCD resolution, the display module shows the centered area by default.
Attention
If the source resolution is smaller than the LCD resolution, due to LCD refresh characteristics the display will be abnormal.
Example:
// Frame release callback
static avdk_err_t display_frame_free_cb(void *frame)
{
frame_buffer_display_free((frame_buffer_t *)frame);
return AVDK_ERR_OK;
}
// Allocate display frame buffer
uint32_t frame_size = lcd_device->width * lcd_device->height * 2; // RGB565
frame_buffer_t *disp_frame = frame_buffer_display_malloc(frame_size);
if (!disp_frame) {
// handle allocation failure
}
// Configure frame
disp_frame->fmt = PIXEL_FMT_RGB565; // source data format
disp_frame->width = lcd_device->width;
disp_frame->height = lcd_device->height;
// Fill with random color data
lcd_fill_rand_color(frame_size, disp_frame->frame);
// Flush display
ret = bk_display_flush(lcd_display_handle, (void *)disp_frame, display_frame_free_cb);
if (ret != AVDK_ERR_OK) {
// error handling; manually free frame
display_frame_free_cb(disp_frame);
}
Attention
1: display_frame_free_cb releases the frame after refresh completes. If you do not need to free the frame, set free_t to NULL. 2: Supported input formats for flushing: PIXEL_FMT_RGB565, PIXEL_FMT_RGB888, PIXEL_FMT_RGB666, PIXEL_FMT_YUYV.
4. Close LCD Display
Parameters:
- handle: display controller handle
Description: Close LCD display and stop the controller.
Example:
// Close display controller
ret = bk_display_close(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
// error handling
}
// Turn off backlight (drive GPIO low or stop PWM)
bk_gpio_set_output_low(bl_io);
// Disable LCD LDO
bk_gpio_set_output_low(lcd_ldo_io);
5. Delete LCD Controller
Parameters:
- handle: display controller handle
Description: Delete the LCD controller and free resources.
Example:
// Delete display controller
ret = bk_display_delete(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
// error handling
}
lcd_display_handle = NULL; // reset handle
Notes
Ensure the display controller is created and opened successfully before calling flush
The frame release callback must be implemented correctly to avoid memory leaks
Frame buffer size should be calculated based on actual resolution and pixel format
Close and delete the controller promptly after operations to release resources
MCU LCDs commonly use 16-bit or 8-bit data bus; configure per actual screen
API List
bk_display_new: Create display controller
bk_display_open: Open display controller
bk_display_flush: Flush display
bk_display_close: Close display controller
bk_display_delete: Delete display controller