tft working

This commit is contained in:
Mitchell Marino 2024-05-26 13:12:10 -05:00
commit eed5455c8c
13 changed files with 2215 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.devcontainer
.vscode
build
managed_components
sdkconfig.old

6
CMakeLists.txt Executable file
View File

@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(blk_box_full_test)

8
Makefile Executable file
View File

@ -0,0 +1,8 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := hello_world
include $(IDF_PATH)/make/project.mk

52
README.md Executable file
View File

@ -0,0 +1,52 @@
# Hello World Example
Starts a FreeRTOS task to print "Hello World".
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## How to use example
Follow detailed instructions provided specifically for this example.
Select the instructions depending on Espressif chip installed on your development board:
- [ESP32 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html)
- [ESP32-S2 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
## Example folder contents
The project **hello_world** contains one source file in C language [hello_world_main.c](main/hello_world_main.c). The file is located in folder [main](main).
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` files that provide set of directives and instructions describing the project's source files and targets (executable, library, or both).
Below is short explanation of remaining files in the project folder.
```
├── CMakeLists.txt
├── example_test.py Python script used for automated example testing
├── main
│   ├── CMakeLists.txt
│   ├── component.mk Component make file
│   └── hello_world_main.c
├── Makefile Makefile used by legacy GNU Make
└── README.md This is the file you are currently reading
```
For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html) of the ESP-IDF Programming Guide.
## Troubleshooting
* Program upload failure
* Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs.
* The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again.
## Technical support and feedback
Please use the following feedback channels:
* For technical queries, go to the [esp32.com](https://esp32.com/) forum
* For a feature request or bug report, create a [GitHub issue](https://github.com/espressif/esp-idf/issues)
We will get back to you as soon as possible.

21
dependencies.lock Normal file
View File

@ -0,0 +1,21 @@
dependencies:
atanisoft/esp_lcd_ili9488:
component_hash: 828cc2277e57298c2d35f5179d746aa6771f539c4c6d5663920505d52ddbe3a0
source:
service_url: https://api.components.espressif.com/
type: service
version: 1.0.9
idf:
component_hash: null
source:
type: idf
version: 4.4.7
lvgl/lvgl:
component_hash: d7c1ac037ae6e85d94897f807d6e7ba0946a83e720074fc95a4f6241da9f9f53
source:
service_url: https://api.components.espressif.com/
type: service
version: 8.4.0
manifest_hash: d6c4f15d0e89c896af47a265876fc6ab3f32f58ccf826dfd2e8b5606bca71cf7
target: esp32s3
version: 1.0.0

20
example_test.py Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
from __future__ import division, print_function, unicode_literals
import ttfw_idf
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'], ci_target=['esp32'])
def test_examples_hello_world(env, extra_data):
app_name = 'hello_world'
dut = env.get_dut(app_name, 'examples/get-started/hello_world')
dut.start_app()
res = dut.expect(ttfw_idf.MINIMUM_FREE_HEAP_SIZE_RE)
if not res:
raise ValueError('Maximum heap size info not found')
ttfw_idf.print_heap_size(app_name, dut.app.config_name, dut.TARGET, res[0])
if __name__ == '__main__':
test_examples_hello_world()

2
main/CMakeLists.txt Executable file
View File

@ -0,0 +1,2 @@
idf_component_register(SRCS "main.cpp"
INCLUDE_DIRS "")

4
main/component.mk Executable file
View File

@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

269
main/drivers/tft.hpp Normal file
View File

@ -0,0 +1,269 @@
/*
* SPDX-FileCopyrightText: 2022 atanisoft (github.com/atanisoft)
*
* SPDX-License-Identifier: MIT
*/
#include <driver/gpio.h>
#include <driver/ledc.h>
#include <driver/spi_master.h>
#include <esp_err.h>
#include <esp_freertos_hooks.h>
#include <esp_log.h>
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_vendor.h>
#include <esp_lcd_panel_ops.h>
#include <esp_lcd_ili9488.h>
#include <esp_timer.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <lvgl.h>
#include <stdio.h>
#include "sdkconfig.h"
// Uncomment the following line to enable using double buffering of LVGL color
// data.
// #define USE_DOUBLE_BUFFERING 1
static const char *TAG = "lcd_driver";
#define DISPLAY_HORIZONTAL_PIXELS 320
#define DISPLAY_VERTICAL_PIXELS 480
#define DISPLAY_COMMAND_BITS 8
#define DISPLAY_PARAMETER_BITS 8
#define DISPLAY_REFRESH_HZ 40000000
#define DISPLAY_SPI_QUEUE_LEN 10
#define SPI_MAX_TRANSFER_SIZE 32768
#define TFT_PIN_MOSI GPIO_NUM_17
#define TFT_PIN_MISO GPIO_NUM_18
#define TFT_PIN_CLK GPIO_NUM_16
#define TFT_PIN_CS GPIO_NUM_NC
#define TFT_PIN_DC GPIO_NUM_15
#define TFT_PIN_RESET GPIO_NUM_8
#define TFT_INVERT_COLOR false
// Default to 50 lines of color data
#define LV_BUFFER_SIZE DISPLAY_HORIZONTAL_PIXELS * 50
#define LVGL_UPDATE_PERIOD_MS 5
#define BACKLIGHT_LEDC_MODE LEDC_LOW_SPEED_MODE
#define BACKLIGHT_LEDC_CHANNEL LEDC_CHANNEL_0
#define BACKLIGHT_LEDC_TIMER LEDC_TIMER_1
#define BACKLIGHT_LEDC_TIMER_RESOLUTION LEDC_TIMER_10_BIT
#define BACKLIGHT_LEDC_FRQUENCY 5000
static esp_lcd_panel_io_handle_t lcd_io_handle = NULL;
static esp_lcd_panel_handle_t lcd_handle = NULL;
static lv_disp_draw_buf_t lv_disp_buf;
static lv_disp_drv_t lv_disp_drv;
static lv_disp_t *lv_display = NULL;
static lv_color_t *lv_buf_1 = NULL;
static lv_color_t *lv_buf_2 = NULL;
static lv_obj_t *meter = NULL;
static lv_style_t style_screen;
static void update_meter_value(void *indic, int32_t v)
{
lv_meter_set_indicator_end_value(meter, (lv_meter_indicator_t*)indic, v);
}
static bool notify_lvgl_flush_ready(esp_lcd_panel_io_handle_t panel_io,
esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
{
lv_disp_drv_t *disp_driver = (lv_disp_drv_t *)user_ctx;
lv_disp_flush_ready(disp_driver);
return false;
}
static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
int offsetx1 = area->x1;
int offsetx2 = area->x2;
int offsety1 = area->y1;
int offsety2 = area->y2;
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
}
static void IRAM_ATTR lvgl_tick_cb(void *param)
{
lv_tick_inc(LVGL_UPDATE_PERIOD_MS);
}
void initialize_spi()
{
ESP_LOGI(TAG, "Initializing SPI bus (MOSI:%d, MISO:%d, CLK:%d)",
TFT_PIN_MOSI, TFT_PIN_MISO, TFT_PIN_CLK);
spi_bus_config_t bus =
{
.mosi_io_num = TFT_PIN_MOSI,
.miso_io_num = TFT_PIN_MISO,
.sclk_io_num = TFT_PIN_CLK,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.max_transfer_sz = SPI_MAX_TRANSFER_SIZE,
.flags = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO |
SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MASTER,
.intr_flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM
};
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &bus, SPI_DMA_CH_AUTO));
}
void initialize_display()
{
const esp_lcd_panel_io_spi_config_t io_config =
{
.cs_gpio_num = TFT_PIN_CS,
.dc_gpio_num = TFT_PIN_DC,
.spi_mode = 0,
.pclk_hz = DISPLAY_REFRESH_HZ,
.trans_queue_depth = DISPLAY_SPI_QUEUE_LEN,
.on_color_trans_done = notify_lvgl_flush_ready,
.user_ctx = &lv_disp_drv,
.lcd_cmd_bits = DISPLAY_COMMAND_BITS,
.lcd_param_bits = DISPLAY_PARAMETER_BITS,
.flags =
{
.dc_low_on_data = 0,
.octal_mode = 0,
.lsb_first = 0
}
};
const esp_lcd_panel_dev_config_t lcd_config =
{
.reset_gpio_num = TFT_PIN_RESET,
.color_space = ESP_LCD_COLOR_SPACE_BGR,
.bits_per_pixel = 18,
.flags =
{
.reset_active_high = 0
},
.vendor_config = NULL
};
ESP_ERROR_CHECK(
esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SPI2_HOST, &io_config, &lcd_io_handle));
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9488(lcd_io_handle, &lcd_config, LV_BUFFER_SIZE, &lcd_handle));
ESP_ERROR_CHECK(esp_lcd_panel_reset(lcd_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(lcd_handle));
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(lcd_handle, false));
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(lcd_handle, false));
ESP_ERROR_CHECK(esp_lcd_panel_mirror(lcd_handle, true, false));
ESP_ERROR_CHECK(esp_lcd_panel_set_gap(lcd_handle, 0, 0));
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
ESP_ERROR_CHECK(esp_lcd_panel_disp_off(lcd_handle, false));
#else
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(lcd_handle, true));
#endif
}
void initialize_lvgl()
{
ESP_LOGI(TAG, "Initializing LVGL");
lv_init();
ESP_LOGI(TAG, "Allocating %zu bytes for LVGL buffer", LV_BUFFER_SIZE * sizeof(lv_color_t));
lv_buf_1 = (lv_color_t *)heap_caps_malloc(LV_BUFFER_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
#if USE_DOUBLE_BUFFERING
ESP_LOGI(TAG, "Allocating %zu bytes for second LVGL buffer", LV_BUFFER_SIZE * sizeof(lv_color_t));
lv_buf_2 = (lv_color_t *)heap_caps_malloc(LV_BUFFER_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
#endif
ESP_LOGI(TAG, "Creating LVLG display buffer");
lv_disp_draw_buf_init(&lv_disp_buf, lv_buf_1, lv_buf_2, LV_BUFFER_SIZE);
ESP_LOGI(TAG, "Initializing %dx%d display", DISPLAY_HORIZONTAL_PIXELS, DISPLAY_VERTICAL_PIXELS);
lv_disp_drv_init(&lv_disp_drv);
lv_disp_drv.hor_res = DISPLAY_HORIZONTAL_PIXELS;
lv_disp_drv.ver_res = DISPLAY_VERTICAL_PIXELS;
lv_disp_drv.flush_cb = lvgl_flush_cb;
lv_disp_drv.draw_buf = &lv_disp_buf;
lv_disp_drv.user_data = lcd_handle;
lv_display = lv_disp_drv_register(&lv_disp_drv);
ESP_LOGI(TAG, "Creating LVGL tick timer");
const esp_timer_create_args_t lvgl_tick_timer_args =
{
.callback = &lvgl_tick_cb,
.name = "lvgl_tick"
};
esp_timer_handle_t lvgl_tick_timer = NULL;
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, LVGL_UPDATE_PERIOD_MS * 1000));
}
void create_demo_ui()
{
lv_obj_t *scr = lv_disp_get_scr_act(NULL);
// Set the background color of the display to black.
lv_style_init(&style_screen);
lv_style_set_bg_color(&style_screen, lv_color_black());
lv_obj_add_style(lv_scr_act(), &style_screen, LV_STATE_DEFAULT);
// Create a meter which can be animated.
meter = lv_meter_create(scr);
lv_obj_center(meter);
lv_obj_set_size(meter, 200, 200);
// Add a scale first
lv_meter_scale_t *scale = lv_meter_add_scale(meter);
lv_meter_set_scale_ticks(meter, scale, 41, 2, 10, lv_palette_main(LV_PALETTE_GREY));
lv_meter_set_scale_major_ticks(meter, scale, 8, 4, 15, lv_color_black(), 10);
lv_meter_indicator_t *indic;
// Add a blue arc to the start
indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_meter_set_indicator_start_value(meter, indic, 0);
lv_meter_set_indicator_end_value(meter, indic, 20);
// Make the tick lines blue at the start of the scale
indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_BLUE), false, 0);
lv_meter_set_indicator_start_value(meter, indic, 0);
lv_meter_set_indicator_end_value(meter, indic, 20);
// Add a red arc to the end
indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_RED), 0);
lv_meter_set_indicator_start_value(meter, indic, 80);
lv_meter_set_indicator_end_value(meter, indic, 100);
// Make the tick lines red at the end of the scale
indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_RED), lv_palette_main(LV_PALETTE_RED), false, 0);
lv_meter_set_indicator_start_value(meter, indic, 80);
lv_meter_set_indicator_end_value(meter, indic, 100);
// Add a needle line indicator
indic = lv_meter_add_needle_line(meter, scale, 4, lv_palette_main(LV_PALETTE_GREY), -10);
// Create an animation to set the value
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, update_meter_value);
lv_anim_set_var(&a, indic);
lv_anim_set_values(&a, 0, 100);
lv_anim_set_time(&a, 2000);
lv_anim_set_repeat_delay(&a, 100);
lv_anim_set_playback_time(&a, 500);
lv_anim_set_playback_delay(&a, 100);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lv_anim_start(&a);
}
void init_tft() {
initialize_spi();
initialize_display();
initialize_lvgl();
ESP_LOGI(TAG, "TFT initialization Successful");
}

18
main/idf_component.yml Normal file
View File

@ -0,0 +1,18 @@
## IDF Component Manager Manifest File
dependencies:
lvgl/lvgl: "8.4"
atanisoft/esp_lcd_ili9488: "^1.0.9"
## Required IDF version
idf:
version: ">=4.1.0"
# # Put list of dependencies here
# # For components maintained by Espressif:
# component: "~1.0.0"
# # For 3rd party components:
# username/component: ">=1.0.0,<2.0.0"
# username2/component2:
# version: "~1.0.0"
# # For transient dependencies `public` flag can be set.
# # `public` flag doesn't have an effect dependencies of the `main` component.
# # All dependencies of `main` are public by default.
# public: true

28
main/main.cpp Executable file
View File

@ -0,0 +1,28 @@
/* Hello World Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "drivers/tft.hpp"
extern "C" void app_main(void)
{
printf("app_main\n");
init_tft();
create_demo_ui();
while (1) {
vTaskDelay(pdMS_TO_TICKS(10));
lv_timer_handler();
}
}

1782
sdkconfig Normal file

File diff suppressed because it is too large Load Diff

0
sdkconfig.ci Executable file
View File