Added LVGL demo.
continuous-integration/drone/push Build is failing Details

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2024-03-16 18:11:27 +08:00
parent 541b76d79a
commit b7171f73d0
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
15 changed files with 530 additions and 30 deletions

3
.gitmodules vendored
View File

@ -10,3 +10,6 @@
[submodule "lib/lvgl"]
path = lib/lvgl
url = https://github.com/lvgl/lvgl.git
[submodule "lib/sensors"]
path = lib/sensors
url = git@git.minori.work:Embedded_Projects/imsensors.git

View File

@ -6,7 +6,7 @@ enable_language(CXX)
enable_language(ASM)
# Different linker scripts
set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/SDK/devices/MIMXRT1021/gcc/MIMXRT1021xxxxx_flexspi_nor.ld")
set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/gcc/MIMXRT1021xxxxx_flexspi_nor.ld")
set(TARGET_LDSCRIPT_RAM "${CMAKE_SOURCE_DIR}/SDK/devices/MIMXRT1021/gcc/MIMXRT1021xxxxx_ram.ld")
set(TARGET_SOURCES
@ -90,7 +90,8 @@ set(TARGET_SOURCES
"board/dcd.c"
"board/peripherals.c"
"board/pin_mux.c"
"src/app_lcd_impl.c"
"src/app_impl_lcd.c"
"src/app_impl_sensors.c"
"src/app_lvgl.c"
"src/main.c"
"xip/fire_rt1021_evk_flexspi_nor_config.c"
@ -103,6 +104,7 @@ set(TARGET_C_DEFINES
"SERIAL_PORT_TYPE_UART"
"__STARTUP_CLEAR_BSS"
"__STARTUP_INITIALIZE_NONCACHEDATA"
"__STARTUP_INITIALIZE_RAMFUNCTION"
)
set(TARGET_C_DEFINES_XIP
@ -128,7 +130,9 @@ set(TARGET_C_INCLUDES
# Shared libraries linked with application
set(TARGET_LIBS
"lvgl"
"lvgl_demos"
"epd-spi"
"imsensors"
"freertos_kernel"
"c"
"m"
@ -166,6 +170,9 @@ add_subdirectory(lib/freertos)
add_subdirectory(lib/lcd)
set(IMSENSORS_FLOAT_SUPPORT ON CACHE BOOL "")
add_subdirectory(lib/sensors)
set(LV_CONF_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include/lv_conf.h" CACHE STRING "")
add_subdirectory(lib/lvgl)

View File

@ -58,8 +58,8 @@
</dependency>
</dependencies>
<pins>
<pin peripheral="LPUART1" signal="RX" pin_num="101" pin_signal="GPIO_AD_B0_07"/>
<pin peripheral="LPUART1" signal="TX" pin_num="105" pin_signal="GPIO_AD_B0_06"/>
<pin peripheral="LPUART1" signal="RX" pin_num="101" pin_signal="GPIO_AD_B0_07"/>
</pins>
</function>
<function name="BOARD_InitLCDSPIPins">
@ -128,8 +128,18 @@
</dependency>
</dependencies>
<pins>
<pin peripheral="LPI2C1" signal="SCL" pin_num="75" pin_signal="GPIO_AD_B1_14"/>
<pin peripheral="LPI2C1" signal="SDA" pin_num="74" pin_signal="GPIO_AD_B1_15"/>
<pin peripheral="LPI2C1" signal="SDA" pin_num="74" pin_signal="GPIO_AD_B1_15">
<pin_features>
<pin_feature name="software_input_on" value="Enable"/>
<pin_feature name="open_drain" value="Enable"/>
</pin_features>
</pin>
<pin peripheral="LPI2C1" signal="SCL" pin_num="75" pin_signal="GPIO_AD_B1_14">
<pin_features>
<pin_feature name="software_input_on" value="Enable"/>
<pin_feature name="open_drain" value="Enable"/>
</pin_features>
</pin>
</pins>
</function>
<function name="BOARD_InitLEDPins">

View File

@ -41,8 +41,8 @@ void BOARD_InitBootPins(void) {
BOARD_InitDbgUARTPins:
- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'}
- pin_list:
- {pin_num: '101', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07}
- {pin_num: '105', peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_06}
- {pin_num: '101', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
@ -100,8 +100,8 @@ void BOARD_InitLCDSPIPins(void) {
BOARD_InitLCDTPPins:
- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'}
- pin_list:
- {pin_num: '75', peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_14}
- {pin_num: '74', peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_15}
- {pin_num: '74', peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_15, software_input_on: Enable, open_drain: Enable}
- {pin_num: '75', peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_14, software_input_on: Enable, open_drain: Enable}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
@ -114,8 +114,10 @@ BOARD_InitLCDTPPins:
void BOARD_InitLCDTPPins(void) {
CLOCK_EnableClock(kCLOCK_Iomuxc);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_LPI2C1_SCL, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_LPI2C1_SDA, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_LPI2C1_SCL, 1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_LPI2C1_SDA, 1U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_14_LPI2C1_SCL, 0x18B0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_15_LPI2C1_SDA, 0x18B0U);
}
/*

View File

@ -0,0 +1,282 @@
/*
** ###################################################################
** Processors: MIMXRT1021CAF4A
** MIMXRT1021CAF4B
** MIMXRT1021CAG4A
** MIMXRT1021CAG4B
** MIMXRT1021DAF5A
** MIMXRT1021DAF5B
** MIMXRT1021DAG5A
** MIMXRT1021DAG5B
**
** Compiler: GNU C Compiler
** Reference manual: IMXRT1020RM Rev.2, 01/2021 | IMXRT102XSRM Rev.0
** Version: rev. 0.1, 2017-06-06
** Build: b230821
**
** Abstract:
** Linker file for the GNU C Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x00000400 : 0;
/* Specify the memory areas */
MEMORY
{
m_flash_config (RX) : ORIGIN = 0x60000000, LENGTH = 0x00001000
m_ivt (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x007FDC00
m_qacode (RX) : ORIGIN = 0x00000000, LENGTH = 0x00010000
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00020000
m_sdram (RW) : ORIGIN = 0x80000000, LENGTH = 0x02000000
}
/* Define output sections */
SECTIONS
{
__NCACHE_REGION_START = ORIGIN(m_data2);
__NCACHE_REGION_SIZE = 0;
.flash_config :
{
. = ALIGN(4);
__FLASH_BASE = .;
KEEP(* (.boot_hdr.conf)) /* flash config section */
. = ALIGN(4);
} > m_flash_config
ivt_begin = ORIGIN(m_flash_config) + LENGTH(m_flash_config);
.ivt : AT(ivt_begin)
{
. = ALIGN(4);
KEEP(* (.boot_hdr.ivt)) /* ivt section */
KEEP(* (.boot_hdr.boot_data)) /* boot section */
KEEP(* (.boot_hdr.dcd_data)) /* dcd section */
. = ALIGN(4);
} > m_ivt
/* The startup code goes first into internal RAM */
.interrupts :
{
__VECTOR_TABLE = .;
__Vectors = .;
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_interrupts
/* The program code and other data goes into internal RAM */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_text
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
.interrupts_ram :
{
. = ALIGN(4);
__VECTOR_RAM__ = .;
__interrupts_ram_start__ = .; /* Create a global symbol at data start */
*(.m_interrupts_ram) /* This is a user defined section */
. += VECTOR_RAM_SIZE;
. = ALIGN(4);
__interrupts_ram_end__ = .; /* Define a global symbol at data end */
} > m_data
__VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts);
__RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0;
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(m_usb_dma_init_data)
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(DataQuickAccess) /* quick access data section */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */
} > m_data
__ram_function_flash_start = __DATA_ROM + (__data_end__ - __data_start__); /* Symbol is used by startup for TCM data initialization */
.ram_function : AT(__ram_function_flash_start)
{
. = ALIGN(32);
__ram_function_start__ = .;
*(CodeQuickAccess)
. = ALIGN(128);
__ram_function_end__ = .;
} > m_qacode
__NDATA_ROM = __ram_function_flash_start + (__ram_function_end__ - __ram_function_start__);
.ncache.init : AT(__NDATA_ROM)
{
__noncachedata_start__ = .; /* create a global symbol at ncache data start */
*(NonCacheable.init)
. = ALIGN(4);
__noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */
} > m_data
. = __noncachedata_init_end__;
.ncache :
{
*(NonCacheable)
. = ALIGN(4);
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
} > m_data
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
text_end = ORIGIN(m_text) + LENGTH(m_text);
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
/* Uninitialized data section */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
. = ALIGN(4);
__START_BSS = .;
__bss_start__ = .;
*(m_usb_dma_noninit_data)
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__END_BSS = .;
} > m_data
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > m_data
.stack :
{
. = ALIGN(8);
. += STACK_SIZE;
} > m_data
.ext_data :
{
. = ALIGN(8);
*(.lvgl_largemem)
*(.lvgl_largemem*)
. = ALIGN(8);
} > m_sdram
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_data) + LENGTH(m_data);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}

View File

@ -65,14 +65,14 @@
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE ((size_t)(32 * 1024))
#define configTOTAL_HEAP_SIZE ((size_t)(48 * 1024))
#define configAPPLICATION_ALLOCATED_HEAP 0
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_MALLOC_FAILED_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
/* Run time and task stats gathering related definitions. */
@ -93,6 +93,9 @@
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)
/* Port specific settings */
#define configUSE_FPU 1
/* Define to trap errors during development. */
#define configASSERT(x) if(( x) == 0) {taskDISABLE_INTERRUPTS(); for (;;);}
@ -113,8 +116,6 @@
#define INCLUDE_xTaskGetHandle 0
#define INCLUDE_xTaskResumeFromISR 1
#if defined(__ICCARM__)||defined(__CC_ARM)||defined(__GNUC__)
/* Clock manager provides in this variable system core clock frequency */
#include <stdint.h>

View File

@ -0,0 +1,11 @@
#ifndef APP_IMPL_SENSORS_H
#define APP_IMPL_SENSORS_H
/* Sensors */
#include "imsensors/common/sensors_common.h"
int app_impl_sensors_init(void);
ims_ret_t app_impl_sensors_i2c_xfer(void *pdev, ims_i2c_xfer_desc_t *xfer);
ims_ret_t app_impl_sensors_delay(void *pdev, uint32_t delay_ms);
#endif // APP_IMPL_SENSORS_H

View File

@ -48,7 +48,7 @@
#define LV_MEM_POOL_EXPAND_SIZE 0
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
#define LV_MEM_ADR 0x20200000 /* SRAM2 */
#define LV_MEM_ADR 0
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
#if LV_MEM_ADR == 0
#undef LV_MEM_POOL_INCLUDE
@ -326,10 +326,10 @@
#define LV_ATTRIBUTE_TICK_INC
/*Define a custom attribute to `lv_timer_handler` function*/
#define LV_ATTRIBUTE_TIMER_HANDLER
#define LV_ATTRIBUTE_TIMER_HANDLER __attribute__((section("CodeQuickAccess")))
/*Define a custom attribute to `lv_display_flush_ready` function*/
#define LV_ATTRIBUTE_FLUSH_READY
#define LV_ATTRIBUTE_FLUSH_READY __attribute__((section("CodeQuickAccess")))
/*Required alignment size for buffers*/
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1
@ -342,7 +342,7 @@
#define LV_ATTRIBUTE_LARGE_CONST
/*Compiler prefix for a big array declaration in RAM*/
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY __attribute__((section(".lvgl_largemem")))
/*Place performance critical functions into a faster memory (e.g RAM)*/
#define LV_ATTRIBUTE_FAST_MEM
@ -355,7 +355,7 @@
#define LV_ATTRIBUTE_EXTERN_DATA
/* Use `float` as `lv_value_precise_t` */
#define LV_USE_FLOAT 0
#define LV_USE_FLOAT 1
/*==================
* FONT USAGE
@ -906,7 +906,7 @@
====================*/
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
#define LV_USE_DEMO_WIDGETS 0
#define LV_USE_DEMO_WIDGETS 1
#if LV_USE_DEMO_WIDGETS
#define LV_DEMO_WIDGETS_SLIDESHOW 0
#endif

@ -1 +1 @@
Subproject commit 9fe29d33414911a8ae6ca0a347d1bd9af05be3b4
Subproject commit 651efeb64848a969657f58171ae1dbab2f7e454d

1
lib/sensors Submodule

@ -0,0 +1 @@
Subproject commit dd9e014464b8ed97765aac2fae750800daef737a

View File

@ -12,7 +12,7 @@
#include "pin_mux.h"
/* LCD */
#include "app_lcd_impl.h"
#include "app_impl_lcd.h"
int app_lcd_impl_init(void *handle) {
CLOCK_EnableClock(kCLOCK_Lpspi4);

76
src/app_impl_sensors.c Normal file
View File

@ -0,0 +1,76 @@
/* FreeRTOS */
#include "FreeRTOS.h"
#include "task.h"
/* SDK drivers */
#include "fsl_lpi2c.h"
/* Board */
#include "board.h"
#include "clock_config.h"
#include "peripherals.h"
#include "pin_mux.h"
/* App */
#include "app_impl_sensors.h"
#define APP_IMPL_I2C_INST LPI2C1
#define APP_IMPL_I2C_CLK kCLOCK_Lpi2c1
int app_impl_sensors_init(void) {
CLOCK_EnableClock(APP_IMPL_I2C_CLK);
lpi2c_master_config_t i2c_cfg;
LPI2C_MasterGetDefaultConfig(&i2c_cfg);
i2c_cfg.baudRate_Hz = 400000; /* Fast mode */
LPI2C_MasterInit(APP_IMPL_I2C_INST, &i2c_cfg, CLOCK_GetClockRootFreq(kCLOCK_Lpi2cClkRoot));
return 0;
}
ims_ret_t app_impl_sensors_i2c_xfer(void *pdev, ims_i2c_xfer_desc_t *xfer) {
status_t ret;
lpi2c_master_transfer_t master_xfer = {
.slaveAddress = (uint32_t)pdev & 0xFFU,
.subaddressSize = 0U,
.flags = kLPI2C_TransferDefaultFlag,
};
if (xfer->tx_data) {
master_xfer.direction = kLPI2C_Write;
master_xfer.data = xfer->tx_data;
master_xfer.dataSize = xfer->tx_size;
ret = LPI2C_MasterTransferBlocking(APP_IMPL_I2C_INST, &master_xfer);
if (ret != kStatus_Success) {
return IMS_FAIL;
}
}
if (xfer->rx_data) {
master_xfer.direction = kLPI2C_Read;
if (xfer->tx_data) {
master_xfer.flags = kLPI2C_TransferRepeatedStartFlag;
}
master_xfer.data = xfer->rx_data;
master_xfer.dataSize = xfer->rx_size;
ret = LPI2C_MasterTransferBlocking(APP_IMPL_I2C_INST, &master_xfer);
if (ret != kStatus_Success) {
return IMS_FAIL;
}
}
return IMS_SUCCESS;
}
ims_ret_t app_impl_sensors_delay(void *pdev, uint32_t delay_ms) {
vTaskDelay(pdMS_TO_TICKS(delay_ms));
return IMS_SUCCESS;
}

View File

@ -5,16 +5,21 @@
#include "task.h"
/* LVGL */
#include "lv_demos.h"
#include "lvgl.h"
/* LCD */
#include "epd-spi/panel/lcd_tk0096f611.h"
/* Sensors */
#include "imsensors/touch/tp_it7259.h"
/* App */
#include "app_lcd_impl.h"
#include "app_impl_lcd.h"
#include "app_impl_sensors.h"
#include "app_lvgl.h"
#define APP_LVGL_LCD_DIR LCD_ST7789_DIR_90
#define APP_LVGL_LCD_DIR (LCD_ST7789_DIR_0)
#define APP_LVGL_LCD_BUF_SIZE (160 * 20)
static lcd_st7789_t s_lcd = {
@ -26,12 +31,22 @@ static lcd_st7789_t s_lcd = {
},
};
static ims_it7259_t s_tp = {
.cb =
{
.i2c_xfer = app_impl_sensors_i2c_xfer,
.delay = app_impl_sensors_delay,
},
.pdev = (void *)0x46U, /* Address */
};
static SemaphoreHandle_t s_lvgl_semphr = NULL;
static uint16_t s_lcd_buffer[APP_LVGL_LCD_BUF_SIZE];
static uint32_t app_lvgl_get_tick_cb(void);
static void app_lvgl_lcd_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map);
static void app_lvgl_tp_read_cb(lv_indev_t *indev, lv_indev_data_t *data);
static void app_lvgl_task(void *arguments);
int app_lvgl_init(void) {
@ -43,12 +58,15 @@ int app_lvgl_init(void) {
xSemaphoreGive(s_lvgl_semphr);
app_lcd_impl_init(NULL);
lcd_st7789_init(&s_lcd, &lcd_tk0096_panel_config);
lcd_st7789_set_direction(&s_lcd, APP_LVGL_LCD_DIR);
lcd_st7789_set_pixel_format(&s_lcd, LCD_ST7789_RGB565);
lcd_st7789_enable_display(&s_lcd, true);
app_impl_sensors_init();
ims_it7259_init(&s_tp);
lv_init();
lv_tick_set_cb(app_lvgl_get_tick_cb);
@ -65,17 +83,40 @@ int app_lvgl_init(void) {
}
lv_display_t *display = lv_display_create(hor_res, ver_res);
if (display == NULL) {
goto deinit_lv_exit;
}
lv_display_set_flush_cb(display, app_lvgl_lcd_flush_cb);
lv_display_set_buffers(display, s_lcd_buffer, NULL, sizeof(s_lcd_buffer), LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_indev_t *indev = lv_indev_create();
if (indev == NULL) {
goto destroy_display_exit;
}
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, app_lvgl_tp_read_cb);
lv_demo_widgets();
if (xTaskCreate(app_lvgl_task, "LVGL", 2048, NULL, 3, NULL) != pdPASS) {
lv_deinit();
vSemaphoreDelete(s_lvgl_semphr);
return -1;
goto destroy_indev_exit;
}
return 0;
destroy_indev_exit:
lv_indev_delete(indev);
destroy_display_exit:
lv_display_delete(display);
deinit_lv_exit:
lv_deinit();
vSemaphoreDelete(s_lvgl_semphr);
return -1;
}
bool app_lvgl_lock(uint32_t timeout_ms) {
@ -109,6 +150,56 @@ static void app_lvgl_lcd_flush_cb(lv_display_t *disp, const lv_area_t *area, uin
lv_display_flush_ready(disp);
}
static void app_lvgl_tp_read_cb(lv_indev_t *indev, lv_indev_data_t *data) {
ims_it7259_point_t touch_points[3];
uint8_t num_points = 3;
bool track_found = false;
ims_ret_t ret = ims_it7259_read_points(&s_tp, &num_points, touch_points);
if (ret != IMS_SUCCESS) {
return;
}
for (uint8_t i = 0; i < num_points; i++) {
if (touch_points[i].id != 0) {
continue;
}
if (touch_points[i].pres < IT7259_PRES_LIGHT) {
continue;
}
track_found = true;
data->state = LV_INDEV_STATE_PRESSED;
switch (s_lcd.direction) {
case LCD_ST7789_DIR_0:
data->point.x = (s_tp.resolution_x - 1) - touch_points->pos_x;
data->point.y = (s_tp.resolution_y - 1) - touch_points->pos_y;
break;
case LCD_ST7789_DIR_90:
data->point.x = (s_tp.resolution_y - 1) - touch_points->pos_y;
data->point.y = touch_points->pos_x;
break;
case LCD_ST7789_DIR_180:
data->point.x = touch_points->pos_x;
data->point.y = touch_points->pos_y;
break;
case LCD_ST7789_DIR_270:
data->point.x = touch_points->pos_y;
data->point.y = (s_tp.resolution_x - 1) - touch_points->pos_x;
break;
default:
break;
}
}
if (!track_found) {
data->state = LV_INDEV_STATE_RELEASED;
}
}
static void app_lvgl_task(void *arguments) {
for (;;) {
if (app_lvgl_lock(portMAX_DELAY)) {

View File

@ -30,7 +30,7 @@ int main(void) {
BOARD_InitDebugConsole();
if (xTaskCreate(app_task_initialization, "Init", 512, NULL, 2, NULL) != pdPASS) {
if (xTaskCreate(app_task_initialization, "Init", 2048, NULL, 2, NULL) != pdPASS) {
goto dead_loop;
}
@ -42,6 +42,22 @@ dead_loop:
}
}
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
printf("Task stack overflow in %s.\r\n", pcTaskName);
for (;;) {
__WFI();
}
}
void vApplicationMallocFailedHook(void) {
printf("Malloc failed.\r\n");
for (;;) {
__WFI();
}
}
static void app_task_initialization(void *arguments) {
app_lvgl_init();