Skip to content

Commit

Permalink
Merge pull request espressif#136 from espressif/bsp/graphic_lib_support
Browse files Browse the repository at this point in the history
bsp: Proposal of LCD API
  • Loading branch information
tore-espressif authored Mar 6, 2023
2 parents 579c1ac + e74b365 commit ea56f81
Show file tree
Hide file tree
Showing 26 changed files with 560 additions and 179 deletions.
2 changes: 1 addition & 1 deletion esp-box/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ idf_component_register(
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "priv_include"
REQUIRES driver spiffs
PRIV_REQUIRES esp_timer esp_lcd esp_lcd_touch
PRIV_REQUIRES esp_lcd
)
154 changes: 86 additions & 68 deletions esp-box/esp-box.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
* SPDX-License-Identifier: CC0-1.0
*/

#include "esp_timer.h"
#include "driver/gpio.h"
#include "driver/ledc.h"
#include "driver/spi_master.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_spiffs.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"

#include "bsp/esp-box.h"
#include "bsp/display.h"
#include "esp_lcd_touch_tt21100.h"
#include "esp_lvgl_port.h"
#include "bsp_err_check.h"
Expand Down Expand Up @@ -133,8 +134,65 @@ esp_err_t bsp_audio_poweramp_enable(bool enable)
#define LCD_PARAM_BITS 8
#define LCD_LEDC_CH CONFIG_BSP_DISPLAY_BRIGHTNESS_LEDC_CH

static lv_disp_t *bsp_display_lcd_init(void)
static esp_err_t bsp_display_brightness_init(void)
{
// Setup LEDC peripheral for PWM backlight control
const ledc_channel_config_t LCD_backlight_channel = {
.gpio_num = BSP_LCD_BACKLIGHT,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LCD_LEDC_CH,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = 1,
.duty = 0,
.hpoint = 0
};
const ledc_timer_config_t LCD_backlight_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_10_BIT,
.timer_num = 1,
.freq_hz = 5000,
.clk_cfg = LEDC_AUTO_CLK
};

BSP_ERROR_CHECK_RETURN_ERR(ledc_timer_config(&LCD_backlight_timer));
BSP_ERROR_CHECK_RETURN_ERR(ledc_channel_config(&LCD_backlight_channel));

return ESP_OK;
}

esp_err_t bsp_display_brightness_set(int brightness_percent)
{
if (brightness_percent > 100) {
brightness_percent = 100;
}
if (brightness_percent < 0) {
brightness_percent = 0;
}

ESP_LOGI(TAG, "Setting LCD backlight: %d%%", brightness_percent);
uint32_t duty_cycle = (1023 * brightness_percent) / 100; // LEDC resolution set to 10bits, thus: 100% = 1023
BSP_ERROR_CHECK_RETURN_ERR(ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle));
BSP_ERROR_CHECK_RETURN_ERR(ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH));

return ESP_OK;
}

esp_err_t bsp_display_backlight_off(void)
{
return bsp_display_brightness_set(0);
}

esp_err_t bsp_display_backlight_on(void)
{
return bsp_display_brightness_set(100);
}

esp_err_t bsp_display_new(esp_lcd_panel_handle_t *ret_panel, esp_lcd_panel_io_handle_t *ret_io)
{
esp_err_t ret = ESP_OK;

ESP_RETURN_ON_ERROR(bsp_display_brightness_init(), TAG, "Brightness init failed");

ESP_LOGD(TAG, "Initialize SPI bus");
const spi_bus_config_t buscfg = {
.sclk_io_num = BSP_LCD_PCLK,
Expand All @@ -144,10 +202,9 @@ static lv_disp_t *bsp_display_lcd_init(void)
.quadhd_io_num = GPIO_NUM_NC,
.max_transfer_sz = BSP_LCD_H_RES * 80 * sizeof(uint16_t),
};
BSP_ERROR_CHECK_RETURN_NULL(spi_bus_initialize(BSP_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO));
ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed");

ESP_LOGD(TAG, "Install panel IO");
esp_lcd_panel_io_handle_t io_handle = NULL;
const esp_lcd_panel_io_spi_config_t io_config = {
.dc_gpio_num = BSP_LCD_DC,
.cs_gpio_num = BSP_LCD_CS,
Expand All @@ -157,22 +214,38 @@ static lv_disp_t *bsp_display_lcd_init(void)
.spi_mode = 0,
.trans_queue_depth = 10,
};
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)BSP_LCD_SPI_NUM, &io_config, ret_io), err, TAG, "New panel IO failed");

// Attach the LCD to the SPI bus
BSP_ERROR_CHECK_RETURN_NULL(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)BSP_LCD_SPI_NUM, &io_config, &io_handle));

ESP_LOGD(TAG, "Install LCD driver of st7789");
esp_lcd_panel_handle_t panel_handle = NULL;
ESP_LOGD(TAG, "Install LCD driver");
const esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = BSP_LCD_RST, // Shared with Touch reset
.color_space = ESP_LCD_COLOR_SPACE_BGR,
.bits_per_pixel = 16,
};
BSP_ERROR_CHECK_RETURN_NULL(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(*ret_io, &panel_config, ret_panel), err, TAG, "New panel failed");

esp_lcd_panel_reset(*ret_panel);
esp_lcd_panel_init(*ret_panel);
esp_lcd_panel_mirror(*ret_panel, true, true);
return ret;

err:
if (*ret_panel) {
esp_lcd_panel_del(*ret_panel);
}
if (*ret_io) {
esp_lcd_panel_io_del(*ret_io);
}
spi_bus_free(BSP_LCD_SPI_NUM);
return ret;
}

static lv_disp_t *bsp_display_lcd_init(void)
{
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_handle_t panel_handle = NULL;
BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new(&panel_handle, &io_handle));

esp_lcd_panel_reset(panel_handle);
esp_lcd_panel_init(panel_handle);
esp_lcd_panel_mirror(panel_handle, true, true);
esp_lcd_panel_disp_on_off(panel_handle, true);

/* Add LCD screen */
Expand Down Expand Up @@ -232,66 +305,11 @@ static lv_indev_t *bsp_display_indev_init(lv_disp_t *disp)
return lvgl_port_add_touch(&touch_cfg);
}

static esp_err_t bsp_display_brightness_init(void)
{
// Setup LEDC peripheral for PWM backlight control
const ledc_channel_config_t LCD_backlight_channel = {
.gpio_num = BSP_LCD_BACKLIGHT,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LCD_LEDC_CH,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = 1,
.duty = 0,
.hpoint = 0
};
const ledc_timer_config_t LCD_backlight_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_10_BIT,
.timer_num = 1,
.freq_hz = 5000,
.clk_cfg = LEDC_AUTO_CLK
};

BSP_ERROR_CHECK_RETURN_ERR(ledc_timer_config(&LCD_backlight_timer));
BSP_ERROR_CHECK_RETURN_ERR(ledc_channel_config(&LCD_backlight_channel));

return ESP_OK;
}

esp_err_t bsp_display_brightness_set(int brightness_percent)
{
if (brightness_percent > 100) {
brightness_percent = 100;
}
if (brightness_percent < 0) {
brightness_percent = 0;
}

ESP_LOGI(TAG, "Setting LCD backlight: %d%%", brightness_percent);
uint32_t duty_cycle = (1023 * brightness_percent) / 100; // LEDC resolution set to 10bits, thus: 100% = 1023
BSP_ERROR_CHECK_RETURN_ERR(ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle));
BSP_ERROR_CHECK_RETURN_ERR(ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH));

return ESP_OK;
}

esp_err_t bsp_display_backlight_off(void)
{
return bsp_display_brightness_set(0);
}

esp_err_t bsp_display_backlight_on(void)
{
return bsp_display_brightness_set(100);
}

lv_disp_t *bsp_display_start(void)
{
const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
BSP_ERROR_CHECK_RETURN_NULL(lvgl_port_init(&lvgl_cfg));

BSP_ERROR_CHECK_RETURN_NULL(bsp_display_brightness_init());

BSP_NULL_CHECK(disp = bsp_display_lcd_init(), NULL);

BSP_NULL_CHECK(bsp_display_indev_init(disp), NULL);
Expand Down
2 changes: 1 addition & 1 deletion esp-box/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2.2.1"
version: "2.3.0"
description: Board Support Package for ESP-BOX
url: https://github.com/espressif/esp-bsp/tree/master/esp-box

Expand Down
42 changes: 42 additions & 0 deletions esp-box/include/bsp/display.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

/**
* @file
* @brief BSP LCD
*
* This file offers API for basic LCD control.
* It is useful for users who want to use the LCD without the default Graphical Library LVGL.
*
* For standard LCD initialization, you can call all-in-one function bsp_display_start().
*/

#pragma once
#include "esp_lcd_types.h"

/**
* @brief Create new display panel
*
* For maximum flexibility, this function performs only reset and initialization of the display.
* You must turn on the display explicitly by calling esp_lcd_panel_disp_on_off().
* The display's backlight is not turned on either. You can use bsp_display_backlight_on/off(),
* bsp_display_brightness_set() (on supported boards) or implement your own backlight control.
*
* If you want to free resources allocated by this function, you can use esp_lcd API, ie.:
*
* \code{.c}
* esp_lcd_panel_del(panel);
* esp_lcd_panel_io_del(io);
* spi_bus_free(spi_num_from_configuration);
* \endcode
*
* @param[out] ret_panel esp_lcd panel handle
* @param[out] ret_io esp_lcd IO handle
* @return
* - ESP_OK On success
* - Else esp_lcd failure
*/
esp_err_t bsp_display_new(esp_lcd_panel_handle_t *ret_panel, esp_lcd_panel_io_handle_t *ret_io);
2 changes: 1 addition & 1 deletion esp32_s2_kaluga_kit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ idf_component_register(
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "priv_include"
REQUIRES driver
PRIV_REQUIRES esp_lcd esp_timer
PRIV_REQUIRES esp_lcd
)
49 changes: 34 additions & 15 deletions esp32_s2_kaluga_kit/esp32_s2_kaluga_kit.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include "esp_timer.h"
#include "bsp/esp32_s2_kaluga_kit.h"
#include "driver/spi_master.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"

#include "bsp/esp32_s2_kaluga_kit.h"
#include "bsp/display.h"
#include "esp_lvgl_port.h"
#include "bsp_err_check.h"

Expand Down Expand Up @@ -205,8 +207,9 @@ esp_err_t bsp_touchpad_calibrate(bsp_touchpad_button_t tch_pad, float tch_thresh
#define LCD_CMD_BITS (8)
#define LCD_PARAM_BITS (8)

static lv_disp_t *bsp_display_lcd_init(void)
esp_err_t bsp_display_new(esp_lcd_panel_handle_t *ret_panel, esp_lcd_panel_io_handle_t *ret_io)
{
esp_err_t ret = ESP_OK;
ESP_LOGD(TAG, "Initialize SPI bus");
const spi_bus_config_t buscfg = {
.sclk_io_num = BSP_LCD_SPI_CLK,
Expand All @@ -216,10 +219,9 @@ static lv_disp_t *bsp_display_lcd_init(void)
.quadhd_io_num = GPIO_NUM_NC,
.max_transfer_sz = BSP_LCD_H_RES * BSP_LCD_V_RES * sizeof(lv_color_t),
};
BSP_ERROR_CHECK_RETURN_NULL(spi_bus_initialize(BSP_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO));
ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed");

ESP_LOGD(TAG, "Install panel IO");
esp_lcd_panel_io_handle_t io_handle = NULL;
const esp_lcd_panel_io_spi_config_t io_config = {
.dc_gpio_num = BSP_LCD_DC,
.cs_gpio_num = BSP_LCD_SPI_CS,
Expand All @@ -229,23 +231,40 @@ static lv_disp_t *bsp_display_lcd_init(void)
.spi_mode = 0,
.trans_queue_depth = 10,
};
// Attach the LCD to the SPI bus
BSP_ERROR_CHECK_RETURN_NULL(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)BSP_LCD_SPI_NUM, &io_config, &io_handle));
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)BSP_LCD_SPI_NUM, &io_config, ret_io), err, TAG, "New panel IO failed");

ESP_LOGD(TAG, "Install LCD driver for ST7789");
esp_lcd_panel_handle_t panel_handle = NULL;
ESP_LOGD(TAG, "Install LCD driver");
const esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = BSP_LCD_RST,
.color_space = ESP_LCD_COLOR_SPACE_RGB,
.bits_per_pixel = 16,
};
BSP_ERROR_CHECK_RETURN_NULL(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(*ret_io, &panel_config, ret_panel), err, TAG, "New panel failed");

esp_lcd_panel_reset(*ret_panel);
esp_lcd_panel_init(*ret_panel);
esp_lcd_panel_mirror(*ret_panel, true, false);
esp_lcd_panel_swap_xy(*ret_panel, true);
esp_lcd_panel_invert_color(*ret_panel, false);
return ret;

err:
if (*ret_panel) {
esp_lcd_panel_del(*ret_panel);
}
if (*ret_io) {
esp_lcd_panel_io_del(*ret_io);
}
spi_bus_free(BSP_LCD_SPI_NUM);
return ret;
}

static lv_disp_t *bsp_display_lcd_init(void)
{
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_handle_t panel_handle = NULL;
BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new(&panel_handle, &io_handle));

esp_lcd_panel_reset(panel_handle);
esp_lcd_panel_init(panel_handle);
esp_lcd_panel_mirror(panel_handle, true, false);
esp_lcd_panel_swap_xy(panel_handle, true);
esp_lcd_panel_invert_color(panel_handle, false);
esp_lcd_panel_disp_on_off(panel_handle, true);

/* Add LCD screen */
Expand Down
2 changes: 1 addition & 1 deletion esp32_s2_kaluga_kit/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2.1.3"
version: "2.2.0"
description: Board Support Package for ESP32-S2-Kaluga kit
url: https://github.com/espressif/esp-bsp/tree/master/esp32_s2_kaluga_kit

Expand Down
Loading

0 comments on commit ea56f81

Please sign in to comment.