From b7171f73d080c336245bf9c0eb68e5ca0c8e4634 Mon Sep 17 00:00:00 2001 From: Yilin Sun Date: Sat, 16 Mar 2024 18:11:27 +0800 Subject: [PATCH] Added LVGL demo. Signed-off-by: Yilin Sun --- .gitmodules | 3 + CMakeLists.txt | 11 +- MIMXRT1021xxxxx.mex | 16 +- board/pin_mux.c | 12 +- gcc/MIMXRT1021xxxxx_flexspi_nor.ld | 282 +++++++++++++++++++++ include/FreeRTOSConfig.h | 11 +- include/{app_lcd_impl.h => app_impl_lcd.h} | 0 include/app_impl_sensors.h | 11 + include/lv_conf.h | 12 +- lib/lcd | 2 +- lib/sensors | 1 + src/{app_lcd_impl.c => app_impl_lcd.c} | 2 +- src/app_impl_sensors.c | 76 ++++++ src/app_lvgl.c | 103 +++++++- src/main.c | 18 +- 15 files changed, 530 insertions(+), 30 deletions(-) create mode 100644 gcc/MIMXRT1021xxxxx_flexspi_nor.ld rename include/{app_lcd_impl.h => app_impl_lcd.h} (100%) create mode 100644 include/app_impl_sensors.h create mode 160000 lib/sensors rename src/{app_lcd_impl.c => app_impl_lcd.c} (98%) create mode 100644 src/app_impl_sensors.c diff --git a/.gitmodules b/.gitmodules index 4c747fb..285c264 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e115c7..4f30163 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/MIMXRT1021xxxxx.mex b/MIMXRT1021xxxxx.mex index a058b3d..77b1e3b 100644 --- a/MIMXRT1021xxxxx.mex +++ b/MIMXRT1021xxxxx.mex @@ -58,8 +58,8 @@ - + @@ -128,8 +128,18 @@ - - + + + + + + + + + + + + diff --git a/board/pin_mux.c b/board/pin_mux.c index 5a4937a..b7b22b3 100644 --- a/board/pin_mux.c +++ b/board/pin_mux.c @@ -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); } /* diff --git a/gcc/MIMXRT1021xxxxx_flexspi_nor.ld b/gcc/MIMXRT1021xxxxx_flexspi_nor.ld new file mode 100644 index 0000000..b2e31ee --- /dev/null +++ b/gcc/MIMXRT1021xxxxx_flexspi_nor.ld @@ -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") +} diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h index e779be0..b1a1a2f 100644 --- a/include/FreeRTOSConfig.h +++ b/include/FreeRTOSConfig.h @@ -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 diff --git a/include/app_lcd_impl.h b/include/app_impl_lcd.h similarity index 100% rename from include/app_lcd_impl.h rename to include/app_impl_lcd.h diff --git a/include/app_impl_sensors.h b/include/app_impl_sensors.h new file mode 100644 index 0000000..47ece93 --- /dev/null +++ b/include/app_impl_sensors.h @@ -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 diff --git a/include/lv_conf.h b/include/lv_conf.h index 4ecea28..1f7b1d2 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -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 diff --git a/lib/lcd b/lib/lcd index 9fe29d3..651efeb 160000 --- a/lib/lcd +++ b/lib/lcd @@ -1 +1 @@ -Subproject commit 9fe29d33414911a8ae6ca0a347d1bd9af05be3b4 +Subproject commit 651efeb64848a969657f58171ae1dbab2f7e454d diff --git a/lib/sensors b/lib/sensors new file mode 160000 index 0000000..dd9e014 --- /dev/null +++ b/lib/sensors @@ -0,0 +1 @@ +Subproject commit dd9e014464b8ed97765aac2fae750800daef737a diff --git a/src/app_lcd_impl.c b/src/app_impl_lcd.c similarity index 98% rename from src/app_lcd_impl.c rename to src/app_impl_lcd.c index 9e91d40..93320a5 100644 --- a/src/app_lcd_impl.c +++ b/src/app_impl_lcd.c @@ -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); diff --git a/src/app_impl_sensors.c b/src/app_impl_sensors.c new file mode 100644 index 0000000..966ea03 --- /dev/null +++ b/src/app_impl_sensors.c @@ -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; +} \ No newline at end of file diff --git a/src/app_lvgl.c b/src/app_lvgl.c index 2df61f5..8e63e84 100644 --- a/src/app_lvgl.c +++ b/src/app_lvgl.c @@ -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)) { diff --git a/src/main.c b/src/main.c index 4adf98e..d4d3862 100644 --- a/src/main.c +++ b/src/main.c @@ -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();