add some code

This commit is contained in:
2025-09-05 13:25:11 +08:00
parent 9ff0a99e7a
commit 3cf1229a85
8911 changed files with 2535396 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS "."
WHOLE_ARCHIVE)

View File

@@ -0,0 +1,6 @@
## IDF Component Manager Manifest File
dependencies:
idf: ">=4.4"
esp_lcd_st7796:
version: "*"
override_path: "../../../esp_lcd_st7796"

View File

@@ -0,0 +1,47 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils_memory.h"
#include "esp_heap_caps.h"
// Some resources are lazy allocated in the LCD driver, the threadhold is left for that case
#define TEST_MEMORY_LEAK_THRESHOLD (300)
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
/**
* __ _____ _____ _____ ___ __
* / _\/__ \___ |___ / _ \ / /_
* \ \ / /\/ / / / / (_) | '_ \
* _\ \ / / / / / / \__, | (_) |
* \__/ \/ /_/ /_/ /_/ \___/
*/
printf(" __ _____ _____ _____ ___ __\r\n");
printf("/ _\\/__ \\___ |___ / _ \\ / /_\r\n");
printf("\\ \\ / /\\/ / / / / (_) | '_ \\\r\n");
printf("_\\ \\ / / / / / / \\__, | (_) |\r\n");
printf("\\__/ \\/ /_/ /_/ /_/ \\___/\r\n");
unity_run_menu();
}

View File

@@ -0,0 +1,135 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc_caps.h"
#if SOC_LCD_I80_SUPPORTED
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "soc/soc_caps.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_io.h"
#include "unity.h"
#include "unity_test_runner.h"
#include "esp_lcd_st7796.h"
#define TEST_LCD_H_RES (320)
#define TEST_LCD_V_RES (480)
#define TEST_LCD_BIT_PER_PIXEL (16)
#define TEST_LCD_DATA_WIDTH (8)
#define TEST_PIN_NUM_LCD_CS (GPIO_NUM_17)
#define TEST_PIN_NUM_LCD_DC (GPIO_NUM_46)
#define TEST_PIN_NUM_LCD_WR (GPIO_NUM_3)
#define TEST_PIN_NUM_LCD_DATA0 (GPIO_NUM_9)
#define TEST_PIN_NUM_LCD_DATA1 (GPIO_NUM_12)
#define TEST_PIN_NUM_LCD_DATA2 (GPIO_NUM_11)
#define TEST_PIN_NUM_LCD_DATA3 (GPIO_NUM_14)
#define TEST_PIN_NUM_LCD_DATA4 (GPIO_NUM_13)
#if CONFIG_IDF_TARGET_ESP32S2
#define TEST_PIN_NUM_LCD_DATA5 (GPIO_NUM_8)
#else
#define TEST_PIN_NUM_LCD_DATA5 (GPIO_NUM_47)
#endif
#define TEST_PIN_NUM_LCD_DATA6 (GPIO_NUM_21)
#define TEST_PIN_NUM_LCD_DATA7 (GPIO_NUM_45)
#define TEST_PIN_NUM_LCD_DATA8 (-1)
#define TEST_PIN_NUM_LCD_DATA9 (-1)
#define TEST_PIN_NUM_LCD_DATA10 (-1)
#define TEST_PIN_NUM_LCD_DATA11 (-1)
#define TEST_PIN_NUM_LCD_DATA12 (-1)
#define TEST_PIN_NUM_LCD_DATA13 (-1)
#define TEST_PIN_NUM_LCD_DATA14 (-1)
#define TEST_PIN_NUM_LCD_DATA15 (-1)
#define TEST_PIN_NUM_LCD_RST (GPIO_NUM_NC)
#define TEST_DELAY_TIME_MS (3000)
static char *TAG = "st7796_test";
static SemaphoreHandle_t refresh_finish = NULL;
IRAM_ATTR static bool test_notify_refresh_ready(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
{
BaseType_t need_yield = pdFALSE;
xSemaphoreGiveFromISR(refresh_finish, &need_yield);
return (need_yield == pdTRUE);
}
static void test_draw_bitmap(esp_lcd_panel_handle_t panel_handle)
{
refresh_finish = xSemaphoreCreateBinary();
TEST_ASSERT_NOT_NULL(refresh_finish);
uint16_t row_line = TEST_LCD_V_RES / TEST_LCD_BIT_PER_PIXEL;
uint8_t byte_per_pixel = TEST_LCD_BIT_PER_PIXEL / 8;
uint8_t *color = (uint8_t *)heap_caps_calloc(1, row_line * TEST_LCD_H_RES * byte_per_pixel, MALLOC_CAP_DMA);
TEST_ASSERT_NOT_NULL(color);
for (int j = 0; j < TEST_LCD_BIT_PER_PIXEL; j++) {
for (int i = 0; i < row_line * TEST_LCD_H_RES; i++) {
for (int k = 0; k < byte_per_pixel; k++) {
color[i * byte_per_pixel + k] = (BIT(j) >> (k * 8)) & 0xff;
}
}
TEST_ESP_OK(esp_lcd_panel_draw_bitmap(panel_handle, 0, j * row_line, TEST_LCD_H_RES, (j + 1) * row_line, color));
xSemaphoreTake(refresh_finish, portMAX_DELAY);
}
free(color);
}
TEST_CASE("test st7796 to draw color bar with I80 interface", "[st7796][i80]")
{
ESP_LOGI(TAG, "Initialize Intel 8080 bus");
esp_lcd_i80_bus_handle_t i80_bus = NULL;
esp_lcd_i80_bus_config_t bus_config = ST7796_PANEL_BUS_I80_CONFIG(
TEST_LCD_H_RES * TEST_LCD_V_RES * TEST_LCD_BIT_PER_PIXEL / 8, TEST_LCD_DATA_WIDTH,
TEST_PIN_NUM_LCD_DC, TEST_PIN_NUM_LCD_WR,
TEST_PIN_NUM_LCD_DATA0, TEST_PIN_NUM_LCD_DATA1, TEST_PIN_NUM_LCD_DATA2, TEST_PIN_NUM_LCD_DATA3,
TEST_PIN_NUM_LCD_DATA4, TEST_PIN_NUM_LCD_DATA5, TEST_PIN_NUM_LCD_DATA6, TEST_PIN_NUM_LCD_DATA7,
TEST_PIN_NUM_LCD_DATA8, TEST_PIN_NUM_LCD_DATA9, TEST_PIN_NUM_LCD_DATA10, TEST_PIN_NUM_LCD_DATA11,
TEST_PIN_NUM_LCD_DATA12, TEST_PIN_NUM_LCD_DATA13, TEST_PIN_NUM_LCD_DATA14, TEST_PIN_NUM_LCD_DATA15);
TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus));
ESP_LOGI(TAG, "Install panel IO");
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_io_i80_config_t io_config = ST7796_PANEL_IO_I80_CONFIG(TEST_PIN_NUM_LCD_CS, test_notify_refresh_ready, NULL);
TEST_ESP_OK(esp_lcd_new_panel_io_i80(i80_bus, &io_config, &io_handle));
ESP_LOGI(TAG, "Install ST7796 panel driver");
const esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_PIN_NUM_LCD_RST,
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
.color_space = ESP_LCD_COLOR_SPACE_BGR,
#else
.rgb_endian = LCD_RGB_ENDIAN_BGR,
#endif
.bits_per_pixel = TEST_LCD_BIT_PER_PIXEL,
};
esp_lcd_panel_handle_t panel_handle = NULL;
TEST_ESP_OK(esp_lcd_new_panel_st7796(io_handle, &panel_config, &panel_handle));
TEST_ESP_OK(esp_lcd_panel_reset(panel_handle));
TEST_ESP_OK(esp_lcd_panel_init(panel_handle));
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
TEST_ESP_OK(esp_lcd_panel_disp_off(panel_handle, false));
#else
TEST_ESP_OK(esp_lcd_panel_disp_on_off(panel_handle, true));
#endif
test_draw_bitmap(panel_handle);
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_TIME_MS));
TEST_ESP_OK(esp_lcd_panel_del(panel_handle));
TEST_ESP_OK(esp_lcd_panel_io_del(io_handle));
TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus));
}
#endif

View File

@@ -0,0 +1,225 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc_caps.h"
#if SOC_MIPI_DSI_SUPPORTED
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_io.h"
#include "esp_ldo_regulator.h"
#include "esp_dma_utils.h"
#include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils_memory.h"
#include "esp_lcd_mipi_dsi.h"
#include "esp_lcd_st7796.h"
#define TEST_LCD_H_RES (320)
#define TEST_LCD_V_RES (480)
#define TEST_LCD_BIT_PER_PIXEL (24)
#define TEST_PIN_NUM_LCD_RST (-1)
#define TEST_PIN_NUM_BK_LIGHT (-1) // set to -1 if not used
#define TEST_LCD_BK_LIGHT_ON_LEVEL (1)
#define TEST_LCD_BK_LIGHT_OFF_LEVEL !TEST_LCD_BK_LIGHT_ON_LEVEL
#if TEST_LCD_BIT_PER_PIXEL == 24
#define TEST_MIPI_DPI_PX_FORMAT (LCD_COLOR_PIXEL_FORMAT_RGB888)
#elif TEST_LCD_BIT_PER_PIXEL == 18
#define TEST_MIPI_DPI_PX_FORMAT (LCD_COLOR_PIXEL_FORMAT_RGB666)
#elif TEST_LCD_BIT_PER_PIXEL == 16
#define TEST_MIPI_DPI_PX_FORMAT (LCD_COLOR_PIXEL_FORMAT_RGB565)
#endif
#define TEST_DELAY_TIME_MS (3000)
#define TEST_MIPI_DSI_PHY_PWR_LDO_CHAN (3)
#define TEST_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV (2500)
static char *TAG = "st7796_test";
static esp_ldo_channel_handle_t ldo_mipi_phy = NULL;
static esp_lcd_panel_handle_t panel_handle = NULL;
static esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
static esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;
static SemaphoreHandle_t refresh_finish = NULL;
IRAM_ATTR static bool test_notify_refresh_ready(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx)
{
SemaphoreHandle_t refresh_finish = (SemaphoreHandle_t)user_ctx;
BaseType_t need_yield = pdFALSE;
xSemaphoreGiveFromISR(refresh_finish, &need_yield);
return (need_yield == pdTRUE);
}
static void test_init_lcd(void)
{
#if TEST_PIN_NUM_BK_LIGHT >= 0
ESP_LOGI(TAG, "Turn on LCD backlight");
gpio_config_t bk_gpio_config = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1ULL << TEST_PIN_NUM_BK_LIGHT
};
TEST_ESP_OK(gpio_config(&bk_gpio_config));
TEST_ESP_OK(gpio_set_level(TEST_PIN_NUM_BK_LIGHT, TEST_LCD_BK_LIGHT_ON_LEVEL));
#endif
// Turn on the power for MIPI DSI PHY, so it can go from "No Power" state to "Shutdown" state
#ifdef TEST_MIPI_DSI_PHY_PWR_LDO_CHAN
ESP_LOGI(TAG, "MIPI DSI PHY Powered on");
esp_ldo_channel_config_t ldo_mipi_phy_config = {
.chan_id = TEST_MIPI_DSI_PHY_PWR_LDO_CHAN,
.voltage_mv = TEST_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV,
};
TEST_ESP_OK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy));
#endif
ESP_LOGI(TAG, "Initialize MIPI DSI bus");
esp_lcd_dsi_bus_config_t bus_config = ST7796_PANEL_BUS_DSI_1CH_CONFIG();
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
ESP_LOGI(TAG, "Install panel IO");
esp_lcd_dbi_io_config_t dbi_config = ST7796_PANEL_IO_DBI_CONFIG();
TEST_ESP_OK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io));
ESP_LOGI(TAG, "Install LCD driver of st7796");
esp_lcd_dpi_panel_config_t dpi_config = ST7796_320_480_PANEL_60HZ_DPI_CONFIG(TEST_MIPI_DPI_PX_FORMAT);
st7796_vendor_config_t vendor_config = {
.flags.use_mipi_interface = 1,
.mipi_config.dsi_bus = mipi_dsi_bus,
.mipi_config.dpi_config = &dpi_config,
};
const esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_PIN_NUM_LCD_RST,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = TEST_LCD_BIT_PER_PIXEL,
.vendor_config = &vendor_config,
};
TEST_ESP_OK(esp_lcd_new_panel_st7796(mipi_dbi_io, &panel_config, &panel_handle));
TEST_ESP_OK(esp_lcd_panel_reset(panel_handle));
TEST_ESP_OK(esp_lcd_panel_init(panel_handle));
TEST_ESP_OK(esp_lcd_panel_disp_on_off(panel_handle, true));
refresh_finish = xSemaphoreCreateBinary();
TEST_ASSERT_NOT_NULL(refresh_finish);
esp_lcd_dpi_panel_event_callbacks_t cbs = {
.on_color_trans_done = test_notify_refresh_ready,
};
TEST_ESP_OK(esp_lcd_dpi_panel_register_event_callbacks(panel_handle, &cbs, refresh_finish));
}
static void test_deinit_lcd(void)
{
TEST_ESP_OK(esp_lcd_panel_del(panel_handle));
TEST_ESP_OK(esp_lcd_panel_io_del(mipi_dbi_io));
TEST_ESP_OK(esp_lcd_del_dsi_bus(mipi_dsi_bus));
panel_handle = NULL;
mipi_dbi_io = NULL;
mipi_dsi_bus = NULL;
if (ldo_mipi_phy) {
TEST_ESP_OK(esp_ldo_release_channel(ldo_mipi_phy));
ldo_mipi_phy = NULL;
}
vSemaphoreDelete(refresh_finish);
refresh_finish = NULL;
#if TEST_PIN_NUM_BK_LIGHT >= 0
TEST_ESP_OK(gpio_reset_pin(TEST_PIN_NUM_BK_LIGHT));
TEST_ESP_OK(gpio_reset_pin(TEST_PIN_NUM_POWER));
#endif
}
static void test_draw_color_bar(esp_lcd_panel_handle_t panel_handle, uint16_t h_res, uint16_t v_res)
{
uint8_t byte_per_pixel = (TEST_LCD_BIT_PER_PIXEL + 7) / 8;
uint16_t row_line = v_res / byte_per_pixel / 8;
uint8_t *color = (uint8_t *)heap_caps_calloc(1, row_line * h_res * byte_per_pixel, MALLOC_CAP_DMA);
for (int j = 0; j < byte_per_pixel * 8; j++) {
for (int i = 0; i < row_line * h_res; i++) {
for (int k = 0; k < byte_per_pixel; k++) {
color[i * byte_per_pixel + k] = (BIT(j) >> (k * 8)) & 0xff;
}
}
TEST_ESP_OK(esp_lcd_panel_draw_bitmap(panel_handle, 0, j * row_line, h_res, (j + 1) * row_line, color));
xSemaphoreTake(refresh_finish, portMAX_DELAY);
}
uint16_t color_line = row_line * byte_per_pixel * 8;
uint16_t res_line = v_res - color_line;
if (res_line) {
for (int i = 0; i < res_line * h_res; i++) {
for (int k = 0; k < byte_per_pixel; k++) {
color[i * byte_per_pixel + k] = 0xff;
}
}
TEST_ESP_OK(esp_lcd_panel_draw_bitmap(panel_handle, 0, color_line, h_res, v_res, color));
xSemaphoreTake(refresh_finish, portMAX_DELAY);
}
free(color);
}
TEST_CASE("test st7796 to draw pattern with MIPI interface", "[st7796][draw_pattern]")
{
ESP_LOGI(TAG, "Initialize LCD device");
test_init_lcd();
ESP_LOGI(TAG, "Show color bar pattern drawn by hardware");
TEST_ESP_OK(esp_lcd_dpi_panel_set_pattern(panel_handle, MIPI_DSI_PATTERN_BAR_VERTICAL));
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_TIME_MS));
TEST_ESP_OK(esp_lcd_dpi_panel_set_pattern(panel_handle, MIPI_DSI_PATTERN_BAR_HORIZONTAL));
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_TIME_MS));
TEST_ESP_OK(esp_lcd_dpi_panel_set_pattern(panel_handle, MIPI_DSI_PATTERN_NONE));
ESP_LOGI(TAG, "Deinitialize LCD device");
test_deinit_lcd();
}
TEST_CASE("test st7796 to draw color bar with MIPI interface", "[st7796][draw_color_bar]")
{
ESP_LOGI(TAG, "Initialize LCD device");
test_init_lcd();
ESP_LOGI(TAG, "Show color bar drawn by software");
test_draw_color_bar(panel_handle, TEST_LCD_H_RES, TEST_LCD_V_RES);
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_TIME_MS));
ESP_LOGI(TAG, "Deinitialize LCD device");
test_deinit_lcd();
}
TEST_CASE("test st7796 to rotate with MIPI interface", "[st7796][rotate]")
{
ESP_LOGI(TAG, "Initialize LCD device");
test_init_lcd();
ESP_LOGI(TAG, "Mirror the screen");
for (size_t i = 0; i < 4; i++) {
TEST_ASSERT_NOT_EQUAL(esp_lcd_panel_mirror(panel_handle, i & 2, i & 1), ESP_FAIL);
ESP_LOGI(TAG, "Mirror: %d", i);
test_draw_color_bar(panel_handle, TEST_LCD_H_RES, TEST_LCD_V_RES);
vTaskDelay(pdMS_TO_TICKS(1000));
}
ESP_LOGI(TAG, "Deinitialize LCD device");
test_deinit_lcd();
}
#endif