spi_lcd_display

[中文]

Overview

The display functions abstract drivers for different screen interfaces. Users create a handle according to the screen type. Refer to bk_display.h for interface descriptions.

This section explains how the display module drives SPI LCDs, including API usage, parameter descriptions, and notes.

Development Intro

1. Backlight

In the BK7258 SDK, the default LCD backlight pin is GPIO7. If your IO differs, configure it in your solution. Backlight control is user-managed; you can wrap open/close functions as in the SDK examples.

2. LCD Device

The BK7258 SDK already includes several SPI LCD devices. If your device differs, add a new device per the section below.

Code Flow

1. Create LCD Controller

Parameters: - handle: Output parameter that stores the created display controller handle - config: Controller configuration containing LCD device info and GPIO pins

Example:

bk_display_spi_ctlr_config_t spi_ctlr_config = {
    .lcd_device = &lcd_device_st7796u,
    .spi_id = 0,
    .dc_pin = GPIO_8,
    .reset_pin = GPIO_40,
    .te_pin = 0,
};

static bk_display_ctlr_handle_t lcd_display_handle = NULL;
avdk_err_t ret = bk_display_spi_new(&lcd_display_handle, &spi_ctlr_config);
if (ret != AVDK_ERR_OK) {
    // error handling
}

Attention

If the TE feature is unused, te_pin can be set to any value. lcd_device is the panel descriptor pointer that provides resolution, interface type, etc. It is mandatory.

2. Open LCD Display

Parameters: - handle: display controller handle

Description: Open LCD display and initialize the controller.

Example:

// Turn on backlight
lcd_backlight_open(GPIO_7);

// Open display controller
ret = bk_display_open(lcd_display_handle);
if (ret != AVDK_ERR_OK) {
    // error handling
}

Attention

Due to hardware differences, backlight must be configured by the user.

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.

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;
}

// 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 source formats are RGB formats; refer to the panel spec for exact formats.

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
lcd_backlight_close(GPIO_7);

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

6. Add a new lcd device

static const lcd_qspi_init_cmd_t gc9d01_init_cmds[] =
{
    {0xFE, {0x00}, 0},
    {0xEF, {0x00}, 0},
    {0x80, {0xFF}, 1},
    {0x81, {0xFF}, 1},
    {0x82, {0xFF}, 1},
    {0x83, {0xFF}, 1},
    {0x84, {0xFF}, 1},
    {0x85, {0xFF}, 1},
    {0x86, {0xFF}, 1},
    {0x87, {0xFF}, 1},
    {0x88, {0xFF}, 1},
    {0x89, {0xFF}, 1},
    {0x8A, {0xFF}, 1},
    {0x8B, {0xFF}, 1},
    {0x8C, {0xFF}, 1},
    {0x8D, {0xFF}, 1},
    {0x8E, {0xFF}, 1},
    {0x8F, {0xFF}, 1},
    {0x3A, {0x05}, 1},
    {0xEC, {0x01}, 1},
    {0x74, {0x02, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00}, 7},
    {0x98, {0x3E, 0x99, 0x3E}, 3},
    {0XB5, {0x0D, 0x0D}, 2},
    {0x60, {0x38, 0x0F, 0x79, 0x67}, 4},
    {0x61, {0x38, 0x11, 0x79, 0x67}, 4},
    {0x64, {0x38, 0x17, 0x71, 0x5F, 0x79, 0x67}, 6},
    {0x65, {0x38, 0x13, 0x71, 0x5B, 0x79, 0x67}, 6},
    {0x6A, {0x00, 0x00}, 2},
    {0x6C, {0x22, 0x02, 0x22, 0x02, 0x22, 0x22, 0x50}, 7},
    {0x6E, {0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x0F, 0x0F, 0x0D, 0x0D, 0x0B, 0x0B, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0A, 0x0C, 0x0C, 0x0E, 0x0E, 0x10, 0x10, 0x00, 0x00, 0x02, 0x02, 0x04, 0x04}, 32},
    {0xBF, {0x01}, 1},
    {0xF9, {0x40}, 1},
    {0x9B, {0x3B}, 1},
    {0x93, {0x33, 0x7F, 0x00}, 3},
    {0x7E, {0x30}, 1},
    {0x70, {0x0D, 0x02, 0x08, 0x0D, 0x02, 0x08}, 6},
    {0x71, {0x0D, 0x02, 0x08}, 3},
    {0X91, {0x0E, 0x09}, 2},
    {0xC3, {0x18}, 1},
    {0xC4, {0x18}, 1},
    {0xC9, {0x3C}, 1},
    {0xF0, {0x13, 0x15, 0x04, 0x05, 0x01, 0x38}, 6},
    {0xF2, {0x13, 0x15, 0x04, 0x05, 0x01, 0x34}, 6},
    {0xF1, {0x4B, 0xB8, 0x7B, 0x34, 0x35, 0xEF}, 6},
    {0xF3, {0x47, 0xB4, 0x72, 0x34, 0x35, 0xDA}, 6},
    {0x36, {0x00}, 1},
    {0x34, {0x00}, 0},
    {0x11, {0x00}, 0},
    {0x00, {0x78}, 0xFF},
    {0x29, {0x00}, 0},
};

static const lcd_spi_t lcd_spi_gc9d01_config =
{
    .clk = LCD_QSPI_60M,
    .init_cmd = gc9d01_init_cmds,
    .device_init_cmd_len = sizeof(gc9d01_init_cmds) / sizeof (lcd_qspi_init_cmd_t),
    .frame_len = (PPI_160X160 >> 16) * (PPI_160X160 & 0xFFFF) * 2,
};

const lcd_device_t lcd_device_gc9d01 =
{
    .id = LCD_DEVICE_GC9D01,
    .name = "gc9d01",
    .type = LCD_TYPE_SPI,
    .ppi = PPI_160X160,
    .spi = &lcd_spi_gc9d01_config,
    .init = NULL,
    .lcd_off = NULL,
};

Reference Project

  • SPI LCD Example: ./projects/spi_lcd_example

Notes

  1. Ensure the display controller is created and opened successfully before calling flush

  2. The frame release callback must be implemented correctly to avoid memory leaks

  3. Different LCD devices require correct GPIO configuration

  4. Frame buffer size should be calculated based on actual resolution and pixel format

  5. Close and delete the controller promptly after operations to release resources