fix uart1 pin bug, delete and update wrong icf files, add vglite support for rt1170 in IAR environment.

This commit is contained in:
Frogrey
2023-09-20 17:00:30 +08:00
committed by guo
parent a7e210d701
commit f941dfcf13
91 changed files with 32890 additions and 236 deletions

View File

@@ -8,6 +8,8 @@
#
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMART is not set
# CONFIG_RT_USING_AMP is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=8
# CONFIG_RT_THREAD_PRIORITY_8 is not set
@@ -30,18 +32,10 @@ CONFIG_IDLE_THREAD_STACK_SIZE=256
# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
# CONFIG_RT_USING_TINY_FFS is not set
# CONFIG_RT_KPRINTF_USING_LONGLONG is not set
CONFIG_RT_DEBUG=y
CONFIG_RT_DEBUG_COLOR=y
# CONFIG_RT_DEBUG_INIT_CONFIG is not set
# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
# CONFIG_RT_DEBUG_IPC_CONFIG is not set
# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
# CONFIG_RT_DEBUG_MEM_CONFIG is not set
# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
CONFIG_RT_USING_DEBUG=y
CONFIG_RT_DEBUGING_COLOR=y
CONFIG_RT_DEBUGING_CONTEXT=y
CONFIG_RT_DEBUGING_INIT=y
#
# Inter-Thread communication
@@ -51,12 +45,12 @@ CONFIG_RT_USING_MUTEX=y
CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MAILBOX=y
CONFIG_RT_USING_MESSAGEQUEUE=y
# CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set
# CONFIG_RT_USING_SIGNALS is not set
#
# Memory Management
#
CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
# CONFIG_RT_USING_SMALL_MEM is not set
# CONFIG_RT_USING_SLAB is not set
@@ -83,13 +77,17 @@ CONFIG_RT_USING_DEVICE=y
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
CONFIG_RT_VER_NUM=0x50000
CONFIG_RT_VER_NUM=0x50001
# CONFIG_RT_USING_STDC_ATOMIC is not set
# CONFIG_RT_USING_CACHE is not set
# CONFIG_RT_USING_HW_ATOMIC is not set
CONFIG_RT_USING_CACHE=y
CONFIG_RT_USING_HW_ATOMIC=y
# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
# CONFIG_RT_USING_CPU_FFS is not set
CONFIG_RT_USING_CPU_FFS=y
CONFIG_ARCH_ARM=y
CONFIG_ARCH_ARM_CORTEX_M=y
CONFIG_ARCH_ARM_CORTEX_FPU=y
CONFIG_ARCH_ARM_CORTEX_M7=y
#
# RT-Thread Components
@@ -114,6 +112,10 @@ CONFIG_FINSH_USING_DESCRIPTION=y
# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_ARG_MAX=10
#
# DFS: device virtual file system
#
# CONFIG_RT_USING_DFS is not set
# CONFIG_RT_USING_FAL is not set
@@ -172,7 +174,19 @@ CONFIG_RT_USBD_THREAD_STACK_SZ=4096
#
# C/C++ and POSIX layer
#
CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# ISO-ANSI C layer
#
#
# Timezone and Daylight Saving Time
#
# CONFIG_RT_LIBC_USING_FULL_TZ_DST is not set
CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y
CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8
CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0
CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
#
# POSIX (Portable Operating System Interface) layer
@@ -219,9 +233,11 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
# CONFIG_RT_USING_VAR_EXPORT is not set
# CONFIG_RT_USING_RESOURCE_ID is not set
# CONFIG_RT_USING_ADT is not set
# CONFIG_RT_USING_RT_LINK is not set
# CONFIG_RT_USING_VBUS is not set
# CONFIG_RT_USING_KTIME is not set
#
# RT-Thread Utestcases
@@ -246,7 +262,6 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_KAWAII_MQTT is not set
# CONFIG_PKG_USING_BC28_MQTT is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_LIBMODBUS is not set
# CONFIG_PKG_USING_FREEMODBUS is not set
# CONFIG_PKG_USING_NANOPB is not set
@@ -264,6 +279,11 @@ CONFIG_NETDEV_IPV6=0
#
# CONFIG_PKG_USING_WLAN_WICED is not set
# CONFIG_PKG_USING_RW007 is not set
#
# CYW43012 WiFi
#
# CONFIG_PKG_USING_WLAN_CYW43012 is not set
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
@@ -325,6 +345,7 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_ZFTP is not set
# CONFIG_PKG_USING_WOL is not set
# CONFIG_PKG_USING_ZEPHYR_POLLING is not set
# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set
#
# security packages
@@ -371,7 +392,6 @@ CONFIG_NETDEV_IPV6=0
# LVGL: powerful and easy-to-use embedded GUI library
#
# CONFIG_PKG_USING_LVGL is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
@@ -398,6 +418,7 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_GUIENGINE is not set
# CONFIG_PKG_USING_PERSIMMON is not set
# CONFIG_PKG_USING_3GPP_AMRNB is not set
#
@@ -446,6 +467,8 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_HASH_MATCH is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
# CONFIG_PKG_USING_VOFA_PLUS is not set
# CONFIG_PKG_USING_RT_TRACE is not set
# CONFIG_PKG_USING_ZDEBUG is not set
#
# system packages
@@ -482,6 +505,8 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_UC_COMMON is not set
# CONFIG_PKG_USING_UC_MODBUS is not set
# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
# CONFIG_PKG_USING_LITEOS_SDK is not set
# CONFIG_PKG_USING_TZ_DATABASE is not set
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_PARTITION is not set
@@ -505,6 +530,7 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_QBOOT is not set
# CONFIG_PKG_USING_PPOOL is not set
# CONFIG_PKG_USING_OPENAMP is not set
# CONFIG_PKG_USING_RPMSG_LITE is not set
# CONFIG_PKG_USING_LPM is not set
# CONFIG_PKG_USING_TLSF is not set
# CONFIG_PKG_USING_EVENT_RECORDER is not set
@@ -517,6 +543,9 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_QPC is not set
# CONFIG_PKG_USING_AGILE_UPGRADE is not set
# CONFIG_PKG_USING_FLASH_BLOB is not set
# CONFIG_PKG_USING_MLIBC is not set
# CONFIG_PKG_USING_TASK_MSG_BUS is not set
# CONFIG_PKG_USING_SFDB is not set
#
# peripheral libraries and drivers
@@ -581,6 +610,7 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_BALANCE is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
# CONFIG_PKG_USING_SHT4X is not set
# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_ADT74XX is not set
# CONFIG_PKG_USING_MAX17048 is not set
@@ -601,6 +631,7 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_FT5426 is not set
# CONFIG_PKG_USING_FT6236 is not set
# CONFIG_PKG_USING_XPT2046_TOUCH is not set
# CONFIG_PKG_USING_CST816X is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ESP_IDF is not set
@@ -613,7 +644,6 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_LKDGUI is not set
# CONFIG_PKG_USING_NRF5X_SDK is not set
# CONFIG_PKG_USING_NRFX is not set
# CONFIG_PKG_USING_WM_LIBRARIES is not set
#
# Kendryte SDK
@@ -671,14 +701,18 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
# CONFIG_PKG_USING_BL_MCU_SDK is not set
# CONFIG_PKG_USING_SOFT_SERIAL is not set
# CONFIG_PKG_USING_MB85RS16 is not set
# CONFIG_PKG_USING_RFM300 is not set
# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
# CONFIG_PKG_USING_AIP650 is not set
# CONFIG_PKG_USING_FINGERPRINT is not set
# CONFIG_PKG_USING_BT_ECB02C is not set
# CONFIG_PKG_USING_UAT is not set
# CONFIG_PKG_USING_ST7789 is not set
# CONFIG_PKG_USING_SPI_TOOLS is not set
#
# AI packages
@@ -697,7 +731,11 @@ CONFIG_NETDEV_IPV6=0
# Signal Processing and Control Algorithm Packages
#
# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_QPID is not set
# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_KISSFFT is not set
# CONFIG_PKG_USING_CMSIS_DSP is not set
#
# miscellaneous packages
@@ -744,7 +782,6 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_DSTR is not set
# CONFIG_PKG_USING_TINYFRAME is not set
# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_UPACKER is not set
# CONFIG_PKG_USING_UPARAM is not set
# CONFIG_PKG_USING_HELLO is not set
@@ -769,8 +806,9 @@ CONFIG_NETDEV_IPV6=0
# CONFIG_PKG_USING_RTDUINO is not set
#
# Projects
# Projects and Demos
#
# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set
# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
@@ -917,14 +955,21 @@ CONFIG_NETDEV_IPV6=0
#
# Display
#
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_GFX_LIBRARY is not set
# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set
# CONFIG_PKG_USING_ARDUINO_TFT_ESPI is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ST7735 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set
# CONFIG_PKG_USING_SEEED_TM1637 is not set
#
# Timing
#
# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set
# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
# CONFIG_PKG_USING_ARDUINO_TICKER is not set
# CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set
#
# Data Processing
@@ -958,7 +1003,6 @@ CONFIG_NETDEV_IPV6=0
#
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set
# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set
#
# Signal IO
@@ -975,6 +1019,7 @@ CONFIG_NETDEV_IPV6=0
#
# Uncategorized
#
CONFIG_SOC_IMXRT1170_SERIES=y
#
# Hardware Drivers Config
@@ -997,6 +1042,7 @@ CONFIG_BSP_USING_LPUART1=y
# CONFIG_BSP_USING_LPUART3 is not set
# CONFIG_BSP_USING_CAN is not set
# CONFIG_BSP_USING_FLEXSPI is not set
# CONFIG_BSP_USING_VGLITE is not set
#
# Onboard Peripheral Drivers

View File

@@ -141,6 +141,42 @@ menu "On-chip Peripheral Drivers"
bool "Enable FLEXSPI2"
default n
endif
menuconfig BSP_USING_VGLITE
bool "Enable VGLITE"
select RT_USING_PIN
default n
if BSP_USING_VGLITE
choice
prompt "Select lcd panel"
default VGLITE_USING_RK055AHD091
config VGLITE_USING_RK055AHD091
bool "RK055AHD091-CTG (RK055HDMIPI4M 720 * 1280)"
config VGLITE_USING_RK055IQH091
bool "RK055IQH091-CTG (540 * 960)"
config VGLITE_USING_RK055MHD091
bool "RK055MHD091A0-CTG (RK055HDMIPI4MA0 720 * 1280)"
endchoice
choice
prompt "Select display controller"
default VGLITE_USING_LCDIFV2
config VGLITE_USING_ELCDIF
bool "ELCDIF"
config VGLITE_USING_LCDIFV2
bool "LCDIFV2"
endchoice
config VGLITE_USING_ELM
bool "Enable Elementary"
default y
endif
endmenu
menu "Onboard Peripheral Drivers"

View File

@@ -258,26 +258,7 @@ void imxrt_uart_pins_init(void)
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_B0_13 is configured as LPUART1_RX */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_24_LPUART1_TXD, /* GPIO_AD_B0_12 PAD functional properties : */
0x10B0u); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: R0/6
Speed Field: medium(100MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_B0_13 PAD functional properties : */
0x10B0u); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: R0/6
Speed Field: medium(100MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
#endif
#ifdef BSP_USING_LPUART2
@@ -1334,6 +1315,25 @@ void imxrt_flexspi_pins_init(void)
}
#endif
#ifdef BSP_USING_VGLITE
void imxrt_lcd_pins_init(void)
{
#ifdef BSP_USING_VGLITE
CLOCK_EnableClock(kCLOCK_Iomuxc); /* LPCG on: LPCG is ON. */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_02_GPIO9_IO01, /* GPIO_AD_02 is configured as GPIO9_IO01 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_30_GPIO9_IO29, /* GPIO_AD_30 is configured as GPIO9_IO29 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_15_GPIO11_IO16, /* GPIO_DISP_B2_15 is configured as GPIO11_IO16 */
0U); /* Software Input On Field: Input Path is determined by functionality */
#endif
}
#endif
void rt_hw_board_init()
{
BOARD_ConfigMPU();
@@ -1378,5 +1378,9 @@ void rt_hw_board_init()
#ifdef BSP_USING_FLEXSPI
imxrt_flexspi_pins_init();
#endif
#ifdef BSP_USING_VGLITE
imxrt_lcd_pins_init();
#endif
}

View File

@@ -1,98 +0,0 @@
/*
** ###################################################################
** Processors: MIMXRT1052CVJ5B
** MIMXRT1052CVL5B
** MIMXRT1052DVJ6B
** MIMXRT1052DVL6B
**
** Compiler: IAR ANSI C/C++ Compiler for ARM
** Reference manual: IMXRT1050RM Rev.1, 03/2018
** Version: rev. 1.0, 2018-09-21
** Build: b180921
**
** Abstract:
** Linker file for the IAR ANSI C/C++ Compiler for ARM
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2018 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
define symbol m_interrupts_start = 0x30002000;
define symbol m_interrupts_end = 0x300023FF;
define symbol m_text_start = 0x30002400;
define symbol m_text_end = 0x30FBFFFF;
define symbol m_data_start = 0x20000000;
define symbol m_data_end = 0x2003FFFF;
define symbol m_data2_start = 0x202C0000;
define symbol m_data2_end = 0x2033FFFF;
define exported symbol __NCACHE_REGION_START = m_data2_start;
define exported symbol __NCACHE_REGION_SIZE = 0x0;
define exported symbol m_boot_hdr_conf_start = 0x30000400;
define symbol m_boot_hdr_ivt_start = 0x30001000;
define symbol m_boot_hdr_boot_data_start = 0x30001020;
define symbol m_boot_hdr_dcd_data_start = 0x30001030;
/* Sizes */
if (isdefinedsymbol(__stack_size__)) {
define symbol __size_cstack__ = __stack_size__;
} else {
define symbol __size_cstack__ = 0x0400;
}
if (isdefinedsymbol(__heap_size__)) {
define symbol __size_heap__ = __heap_size__;
} else {
define symbol __size_heap__ = 0x0400;
}
define exported symbol __VECTOR_TABLE = m_interrupts_start;
define exported symbol __VECTOR_RAM = m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE = 0x0;
define exported symbol __RTT_HEAP_END = m_data2_end;
define memory mem with size = 4G;
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
| mem:[from m_text_start to m_text_end];
define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__];
define region DATA2_region = mem:[from m_data2_start to m_data2_end];
define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end];
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
define block RW { readwrite };
define block ZI { zi };
define block NCACHE_VAR { section NonCacheable , section NonCacheable.init };
initialize by copy { readwrite, section .textrw };
do not initialize { section .noinit };
place at address mem: m_interrupts_start { readonly section .intvec };
place at address mem:m_boot_hdr_conf_start { section .boot_hdr.conf };
place at address mem:m_boot_hdr_ivt_start { section .boot_hdr.ivt };
place at address mem:m_boot_hdr_boot_data_start { readonly section .boot_hdr.boot_data };
place at address mem:m_boot_hdr_dcd_data_start { readonly section .boot_hdr.dcd_data };
keep{ section .boot_hdr.conf, section .boot_hdr.ivt, section .boot_hdr.boot_data, section .boot_hdr.dcd_data };
place in TEXT_region { readonly };
place in DATA_region { block RW };
place in DATA_region { block ZI };
place in DATA_region { last block HEAP };
place in DATA_region { block NCACHE_VAR };
place in CSTACK_region { block CSTACK };

View File

@@ -24,10 +24,10 @@
** ###################################################################
*/
define symbol m_interrupts_start = 0x00002000;
define symbol m_interrupts_end = 0x000023FF;
define symbol m_interrupts_start = 0x00000000;
define symbol m_interrupts_end = 0x000003FF;
define symbol m_text_start = 0x00002400;
define symbol m_text_start = 0x00000400;
define symbol m_text_end = 0x0003FFFF;
define symbol m_data_start = 0x20000000;
@@ -36,8 +36,14 @@ define symbol m_data_end = 0x2003FFFF;
define symbol m_data2_start = 0x202C0000;
define symbol m_data2_end = 0x2033FFFF;
define exported symbol __NCACHE_REGION_START = m_data2_start;
define exported symbol __NCACHE_REGION_SIZE = 0x0;
define symbol m_data3_start = 0x80000000;
define symbol m_data3_end = 0x82FFFFFF;
define symbol m_ncache_start = 0x83000000;
define symbol m_ncache_end = 0x83FFFFFF;
define exported symbol __NCACHE_REGION_START = m_ncache_start;
define exported symbol __NCACHE_REGION_SIZE = m_ncache_end - m_ncache_start + 1;
/* Sizes */
if (isdefinedsymbol(__stack_size__)) {
@@ -55,19 +61,21 @@ if (isdefinedsymbol(__heap_size__)) {
define exported symbol __VECTOR_TABLE = m_interrupts_start;
define exported symbol __VECTOR_RAM = m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE = 0x0;
define exported symbol __RTT_HEAP_END = m_data2_end;
define exported symbol __RTT_HEAP_END = m_data3_end-__size_cstack__;
define memory mem with size = 4G;
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
| mem:[from m_text_start to m_text_end];
define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__];
define region DATA_region = mem:[from m_data_start to m_data_end];
define region DATA2_region = mem:[from m_data2_start to m_data2_end];
define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end];
define region DATA3_region = mem:[from m_data3_start to m_data3_end-__size_cstack__];
define region CSTACK_region = mem:[from m_data3_end-__size_cstack__+1 to m_data3_end];
define region NCACHE_region = mem:[from m_ncache_start to m_ncache_end];
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
define block RW { readwrite };
define block ZI { zi };
define block RW { first readwrite, section m_usb_dma_init_data };
define block ZI with alignment = 32 { first zi, section m_usb_dma_noninit_data };
define block NCACHE_VAR { section NonCacheable , section NonCacheable.init };
define block QACCESS_CODE { section CodeQuickAccess };
define block QACCESS_DATA { section DataQuickAccess };
@@ -78,10 +86,14 @@ do not initialize { section .noinit };
place at address mem: m_interrupts_start { readonly section .intvec };
place in TEXT_region { readonly };
place in DATA_region { block RW };
place in DATA_region { block ZI };
place in DATA_region { last block HEAP };
place in DATA_region { block NCACHE_VAR };
place in DATA3_region { block RW };
place in DATA3_region { block ZI };
if (isdefinedsymbol(__heap_noncacheable__)) {
place in NCACHE_region { last block HEAP };
} else {
place in DATA3_region { last block HEAP };
}
place in NCACHE_region { block NCACHE_VAR };
place in TEXT_region { block QACCESS_CODE };
place in DATA_region { block QACCESS_DATA };
place in CSTACK_region { block CSTACK };

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<fileVersion>3</fileVersion>
<fileVersion>4</fileVersion>
<configuration>
<name>rtthread</name>
<toolchain>
@@ -11,7 +11,7 @@
<name>C-SPY</name>
<archiveVersion>2</archiveVersion>
<data>
<version>32</version>
<version>33</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -36,7 +36,7 @@
</option>
<option>
<name>MacFile</name>
<state></state>
<state>C:\XGW\IARWorkspace\rt-thread-imxrt\bsp\imxrt\imxrt1170-nxp-evk\m7\evkbmimxrt1170_connect_cm7.mac</state>
</option>
<option>
<name>MemOverride</name>
@@ -44,7 +44,7 @@
</option>
<option>
<name>MemFile</name>
<state>$TOOLKIT_DIR$\CONFIG\debugger\NXP\MIMXRT1176xxxA_M7.ddf</state>
<state>$TOOLKIT_DIR$\config\debugger\NXP\MIMXRT1176xxxA_M7.ddf</state>
</option>
<option>
<name>RunToEnable</name>
@@ -84,11 +84,11 @@
</option>
<option>
<name>OCDynDriverList</name>
<state>JLINK_ID</state>
<state>CMSISDAP_ID</state>
</option>
<option>
<name>OCLastSavedByProductVersion</name>
<state>9.30.1.50052</state>
<state>9.40.1.63870</state>
</option>
<option>
<name>UseFlashLoader</name>
@@ -222,6 +222,38 @@
<name>OCTpiuBaseOption</name>
<state>1</state>
</option>
<option>
<name>OCOverrideSlave</name>
<state>0</state>
</option>
<option>
<name>OCOverrideSlavePath</name>
<state></state>
</option>
<option>
<name>C_32_64Device</name>
<state>1</state>
</option>
<option>
<name>AuthEnable</name>
<state>0</state>
</option>
<option>
<name>AuthSdmSelection</name>
<state>1</state>
</option>
<option>
<name>AuthSdmManifest</name>
<state></state>
</option>
<option>
<name>AuthSdmExplicitLib</name>
<state></state>
</option>
<option>
<name>AuthEnforce</name>
<state>0</state>
</option>
</data>
</settings>
<settings>
@@ -296,7 +328,7 @@
<option>
<name>CMSISDAPResetList</name>
<version>1</version>
<state>4</state>
<state>1</state>
</option>
<option>
<name>CMSISDAPHWResetDuration</name>
@@ -381,27 +413,27 @@
</option>
<option>
<name>CatchMMERR</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CatchNOCPERR</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CatchCHKERR</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CatchSTATERR</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CatchBUSERR</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CatchINTERR</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CatchSFERR</name>
@@ -409,7 +441,7 @@
</option>
<option>
<name>CatchHARDERR</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CatchDummy</name>
@@ -457,6 +489,39 @@
</option>
</data>
</settings>
<settings>
<name>E2_ID</name>
<archiveVersion>2</archiveVersion>
<data>
<version>0</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
<name>E2PowerFromProbe</name>
<state>1</state>
</option>
<option>
<name>CE2UsbSerialNo</name>
<state></state>
</option>
<option>
<name>CE2IdCodeEditB</name>
<state>0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF</state>
</option>
<option>
<name>CE2LogFileCheck</name>
<state>0</state>
</option>
<option>
<name>CE2LogFileEditB</name>
<state>$PROJ_DIR$\cspycomm.log</state>
</option>
<option>
<name>OCDriverInfo</name>
<state>1</state>
</option>
</data>
</settings>
<settings>
<name>GDBSERVER_ID</name>
<archiveVersion>2</archiveVersion>
@@ -1072,7 +1137,7 @@
<name>STLINK_ID</name>
<archiveVersion>2</archiveVersion>
<data>
<version>7</version>
<version>8</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -1187,9 +1252,17 @@
</option>
<option>
<name>CCSTLinkProbeList</name>
<version>1</version>
<version>2</version>
<state>2</state>
</option>
<option>
<name>CCSTLinkTargetVccEnable</name>
<state>1</state>
</option>
<option>
<name>CCSTLinkTargetVoltage</name>
<state>3.3</state>
</option>
</data>
</settings>
<settings>
@@ -1417,7 +1490,7 @@
</option>
<option>
<name>CCXds100ResetList</name>
<version>0</version>
<version>1</version>
<state>0</state>
</option>
<option>

View File

@@ -1,5 +1,5 @@
<project>
<fileVersion>3</fileVersion>
<fileVersion>4</fileVersion>
<configuration>
<name>rtthread</name>
<toolchain>
@@ -10,7 +10,7 @@
<name>General</name>
<archiveVersion>3</archiveVersion>
<data>
<version>35</version>
<version>36</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -69,7 +69,7 @@
</option>
<option>
<name>OGLastSavedByProductVersion</name>
<state>9.30.1.50052</state>
<state>9.40.1.63870</state>
</option>
<option>
<name>OGChipSelectEditMenu</name>
@@ -97,7 +97,7 @@
</option>
<option>
<name>GBECoreSlave</name>
<version>32</version>
<version>33</version>
<state>41</state>
</option>
<option>
@@ -114,7 +114,7 @@
</option>
<option>
<name>CoreVariant</name>
<version>32</version>
<version>33</version>
<state>41</state>
</option>
<option>
@@ -137,7 +137,7 @@
</option>
<option>
<name>GFPUCoreSlave2</name>
<version>32</version>
<version>33</version>
<state>41</state>
</option>
<option>
@@ -210,13 +210,18 @@
<name>FPU64</name>
<state>1</state>
</option>
<option>
<name>OG_32_64DeviceCoreSlave</name>
<version>33</version>
<state>41</state>
</option>
</data>
</settings>
<settings>
<name>ICCARM</name>
<archiveVersion>2</archiveVersion>
<data>
<version>37</version>
<version>38</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -237,7 +242,6 @@
<state>XIP_EXTERNAL_FLASH=1</state>
<state>ARM_MATH_CM7</state>
<state>USE_SDRAM</state>
<state>SOC_IMXRT1170_SERIES</state>
<state>ENDIANNESS</state>
<state>USE_RTOS</state>
<state>__RTTHREAD__</state>
@@ -367,8 +371,8 @@
<state>$PROJ_DIR$\..\..\libraries\MIMXRT1170\CMSIS\Include</state>
<state>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\extension\fcntl\octal</state>
<state>$PROJ_DIR$\..\..\..\..\components\drivers\usb\usbhost\include</state>
<state>$PROJ_DIR$\..\..\..\..\components\libc\posix\io\stdio</state>
<state>$PROJ_DIR$\..\..\..\..\components\libc\posix\io\poll</state>
<state>$PROJ_DIR$\..\..\..\..\components\libc\posix\io\epoll</state>
<state>$PROJ_DIR$\..\..\libraries\MIMXRT1170\MIMXRT1176\drivers\cm7</state>
<state>$PROJ_DIR$\..\..\libraries\drivers</state>
<state>$PROJ_DIR$\..\..\..\..\libcpu\arm\cortex-m7</state>
@@ -383,6 +387,7 @@
<state>$PROJ_DIR$\..\..\..\..\components\drivers\usb\usbhost\class</state>
<state>$PROJ_DIR$\board\ports</state>
<state>$PROJ_DIR$\applications</state>
<state>$PROJ_DIR$\..\..\..\..\components\libc\posix\io\eventfd</state>
<state>$PROJ_DIR$\..\..\..\..\include</state>
<state>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\include</state>
<state>$PROJ_DIR$\..\..\..\..\components\libc\posix\ipc</state>
@@ -500,13 +505,21 @@
<name>CCStackProtection</name>
<state>0</state>
</option>
<option>
<name>CCPointerAutentiction</name>
<state>0</state>
</option>
<option>
<name>CCBranchTargetIdentification</name>
<state>0</state>
</option>
</data>
</settings>
<settings>
<name>AARM</name>
<archiveVersion>2</archiveVersion>
<data>
<version>11</version>
<version>12</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -666,6 +679,10 @@
<name>PreInclude</name>
<state />
</option>
<option>
<name>A_32_64Device</name>
<state>1</state>
</option>
</data>
</settings>
<settings>
@@ -704,18 +721,10 @@
<data>
<extensions />
<cmdline />
<hasPrio>208</hasPrio>
<hasPrio>1</hasPrio>
<buildSequence>inputOutputBased</buildSequence>
</data>
</settings>
<settings>
<name>BUILDACTION</name>
<archiveVersion>1</archiveVersion>
<data>
<prebuild />
<postbuild />
</data>
</settings>
<settings>
<name>ILINK</name>
<archiveVersion>0</archiveVersion>
@@ -797,7 +806,7 @@
</option>
<option>
<name>IlinkIcfFile</name>
<state>$PROJ_DIR$\board\linker_scripts\link.icf</state>
<state>$PROJ_DIR$\board\linker_scripts\link_ram.icf</state>
</option>
<option>
<name>IlinkIcfFileSlave</name>
@@ -1111,6 +1120,11 @@
</option>
</data>
</settings>
<settings>
<name>BUILDACTION</name>
<archiveVersion>2</archiveVersion>
<data />
</settings>
</configuration>
<group>
<name>Applications</name>
@@ -1126,9 +1140,6 @@
<file>
<name>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\cctype.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\cstdio.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\cstdlib.c</name>
</file>
@@ -1138,6 +1149,9 @@
<file>
<name>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\ctime.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\cunistd.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\libc\compilers\common\cwchar.c</name>
</file>
@@ -1171,6 +1185,9 @@
</group>
<group>
<name>CPU</name>
<file>
<name>$PROJ_DIR$\..\..\..\..\libcpu\arm\common\atomic_arm.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\libcpu\arm\common\div0.c</name>
</file>
@@ -1189,6 +1206,9 @@
</group>
<group>
<name>DeviceDrivers</name>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\drivers\core\device.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\drivers\ipc\completion.c</name>
</file>
@@ -1285,9 +1305,6 @@
<file>
<name>$PROJ_DIR$\..\..\..\..\src\components.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\src\device.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\src\idle.c</name>
</file>
@@ -1382,10 +1399,10 @@
<group>
<name>SAL</name>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\net\netdev\src\netdev_ipaddr.c</name>
<name>$PROJ_DIR$\..\..\..\..\components\net\netdev\src\netdev.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\..\..\..\components\net\netdev\src\netdev.c</name>
<name>$PROJ_DIR$\..\..\..\..\components\net\netdev\src\netdev_ipaddr.c</name>
</file>
</group>
<group>

View File

@@ -20,8 +20,10 @@
/* kservice optimization */
#define RT_DEBUG
#define RT_DEBUG_COLOR
#define RT_USING_DEBUG
#define RT_DEBUGING_COLOR
#define RT_DEBUGING_CONTEXT
#define RT_DEBUGING_INIT
/* Inter-Thread communication */
@@ -33,7 +35,6 @@
/* Memory Management */
#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_MEMHEAP
#define RT_MEMHEAP_FAST_MODE
@@ -47,7 +48,14 @@
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x50000
#define RT_VER_NUM 0x50001
#define RT_USING_CACHE
#define RT_USING_HW_ATOMIC
#define RT_USING_CPU_FFS
#define ARCH_ARM
#define ARCH_ARM_CORTEX_M
#define ARCH_ARM_CORTEX_FPU
#define ARCH_ARM_CORTEX_M7
/* RT-Thread Components */
@@ -69,6 +77,9 @@
#define FINSH_USING_DESCRIPTION
#define FINSH_ARG_MAX 10
/* DFS: device virtual file system */
/* Device Drivers */
#define RT_USING_DEVICE_IPC
@@ -87,7 +98,14 @@
/* C/C++ and POSIX layer */
#define RT_LIBC_DEFAULT_TIMEZONE 8
/* ISO-ANSI C layer */
/* Timezone and Daylight Saving Time */
#define RT_LIBC_USING_LIGHT_TZ_DST
#define RT_LIBC_TZ_DEFAULT_HOUR 8
#define RT_LIBC_TZ_DEFAULT_MIN 0
#define RT_LIBC_TZ_DEFAULT_SEC 0
/* POSIX (Portable Operating System Interface) layer */
@@ -127,6 +145,9 @@
/* Wiced WiFi */
/* CYW43012 WiFi */
/* IoT Cloud */
@@ -196,7 +217,7 @@
/* Arduino libraries */
/* Projects */
/* Projects and Demos */
/* Sensors */
@@ -227,6 +248,8 @@
/* Uncategorized */
#define SOC_IMXRT1170_SERIES
/* Hardware Drivers Config */
#define BSP_USING_QSPIFLASH

View File

@@ -24,7 +24,7 @@ elif CROSS_TOOL == 'keil':
EXEC_PATH = r'C:/Keil_v5'
elif CROSS_TOOL == 'iar':
PLATFORM = 'iccarm'
EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3'
EXEC_PATH = r'C:/Program Files/IAR Systems/Embedded Workbench 9.2'
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
@@ -145,7 +145,7 @@ elif PLATFORM == 'iccarm':
else:
CFLAGS += ' -Oh'
LFLAGS = ' --config "board/linker_scripts/link.icf"'
LFLAGS = ' --config "board/linker_scripts/link_ram.icf"'
LFLAGS += ' --redirect _Printf=_PrintfTiny'
LFLAGS += ' --redirect _Scanf=_ScanfSmall'
LFLAGS += ' --entry __iar_program_start'

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<fileVersion>3</fileVersion>
<fileVersion>4</fileVersion>
<configuration>
<name>rtthread</name>
<toolchain>
@@ -11,7 +11,7 @@
<name>C-SPY</name>
<archiveVersion>2</archiveVersion>
<data>
<version>32</version>
<version>33</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -44,7 +44,7 @@
</option>
<option>
<name>MemFile</name>
<state>$TOOLKIT_DIR$\CONFIG\debugger\NXP\MIMXRT1176xxxA_M7.ddf</state>
<state>$TOOLKIT_DIR$\config\debugger\NXP\MIMXRT1176xxxA_M7.ddf</state>
</option>
<option>
<name>RunToEnable</name>
@@ -88,7 +88,7 @@
</option>
<option>
<name>OCLastSavedByProductVersion</name>
<state>9.30.1.50052</state>
<state>9.40.1.63870</state>
</option>
<option>
<name>UseFlashLoader</name>
@@ -222,6 +222,38 @@
<name>OCTpiuBaseOption</name>
<state>1</state>
</option>
<option>
<name>OCOverrideSlave</name>
<state>0</state>
</option>
<option>
<name>OCOverrideSlavePath</name>
<state></state>
</option>
<option>
<name>C_32_64Device</name>
<state>1</state>
</option>
<option>
<name>AuthEnable</name>
<state>0</state>
</option>
<option>
<name>AuthSdmSelection</name>
<state>1</state>
</option>
<option>
<name>AuthSdmManifest</name>
<state></state>
</option>
<option>
<name>AuthSdmExplicitLib</name>
<state></state>
</option>
<option>
<name>AuthEnforce</name>
<state>0</state>
</option>
</data>
</settings>
<settings>
@@ -457,6 +489,39 @@
</option>
</data>
</settings>
<settings>
<name>E2_ID</name>
<archiveVersion>2</archiveVersion>
<data>
<version>0</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
<name>E2PowerFromProbe</name>
<state>1</state>
</option>
<option>
<name>CE2UsbSerialNo</name>
<state></state>
</option>
<option>
<name>CE2IdCodeEditB</name>
<state>0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF</state>
</option>
<option>
<name>CE2LogFileCheck</name>
<state>0</state>
</option>
<option>
<name>CE2LogFileEditB</name>
<state>$PROJ_DIR$\cspycomm.log</state>
</option>
<option>
<name>OCDriverInfo</name>
<state>1</state>
</option>
</data>
</settings>
<settings>
<name>GDBSERVER_ID</name>
<archiveVersion>2</archiveVersion>
@@ -1072,7 +1137,7 @@
<name>STLINK_ID</name>
<archiveVersion>2</archiveVersion>
<data>
<version>7</version>
<version>8</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -1187,9 +1252,17 @@
</option>
<option>
<name>CCSTLinkProbeList</name>
<version>1</version>
<version>2</version>
<state>2</state>
</option>
<option>
<name>CCSTLinkTargetVccEnable</name>
<state>1</state>
</option>
<option>
<name>CCSTLinkTargetVoltage</name>
<state>###Uninitialized###</state>
</option>
</data>
</settings>
<settings>
@@ -1417,7 +1490,7 @@
</option>
<option>
<name>CCXds100ResetList</name>
<version>0</version>
<version>1</version>
<state>0</state>
</option>
<option>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<fileVersion>3</fileVersion>
<fileVersion>4</fileVersion>
<configuration>
<name>rtthread</name>
<toolchain>
@@ -11,7 +11,7 @@
<name>General</name>
<archiveVersion>3</archiveVersion>
<data>
<version>35</version>
<version>36</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -70,7 +70,7 @@
</option>
<option>
<name>OGLastSavedByProductVersion</name>
<state>9.30.1.50052</state>
<state>9.40.1.63870</state>
</option>
<option>
<name>OGChipSelectEditMenu</name>
@@ -98,7 +98,7 @@
</option>
<option>
<name>GBECoreSlave</name>
<version>32</version>
<version>33</version>
<state>41</state>
</option>
<option>
@@ -115,7 +115,7 @@
</option>
<option>
<name>CoreVariant</name>
<version>32</version>
<version>33</version>
<state>41</state>
</option>
<option>
@@ -138,7 +138,7 @@
</option>
<option>
<name>GFPUCoreSlave2</name>
<version>32</version>
<version>33</version>
<state>41</state>
</option>
<option>
@@ -211,13 +211,18 @@
<name>FPU64</name>
<state>1</state>
</option>
<option>
<name>OG_32_64DeviceCoreSlave</name>
<version>33</version>
<state>41</state>
</option>
</data>
</settings>
<settings>
<name>ICCARM</name>
<archiveVersion>2</archiveVersion>
<data>
<version>37</version>
<version>38</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -459,13 +464,21 @@
<name>CCStackProtection</name>
<state>0</state>
</option>
<option>
<name>CCPointerAutentiction</name>
<state>0</state>
</option>
<option>
<name>CCBranchTargetIdentification</name>
<state>0</state>
</option>
</data>
</settings>
<settings>
<name>AARM</name>
<archiveVersion>2</archiveVersion>
<data>
<version>11</version>
<version>12</version>
<wantNonLocal>1</wantNonLocal>
<debug>1</debug>
<option>
@@ -625,6 +638,10 @@
<name>PreInclude</name>
<state></state>
</option>
<option>
<name>A_32_64Device</name>
<state>1</state>
</option>
</data>
</settings>
<settings>
@@ -663,18 +680,10 @@
<data>
<extensions></extensions>
<cmdline></cmdline>
<hasPrio>208</hasPrio>
<hasPrio>1</hasPrio>
<buildSequence>inputOutputBased</buildSequence>
</data>
</settings>
<settings>
<name>BUILDACTION</name>
<archiveVersion>1</archiveVersion>
<data>
<prebuild></prebuild>
<postbuild></postbuild>
</data>
</settings>
<settings>
<name>ILINK</name>
<archiveVersion>0</archiveVersion>
@@ -756,7 +765,7 @@
</option>
<option>
<name>IlinkIcfFile</name>
<state>$PROJ_DIR$\board\linker_scripts\link.icf</state>
<state>$PROJ_DIR$\board\linker_scripts\link_ram.icf</state>
</option>
<option>
<name>IlinkIcfFileSlave</name>
@@ -1070,5 +1079,10 @@
</option>
</data>
</settings>
<settings>
<name>BUILDACTION</name>
<archiveVersion>2</archiveVersion>
<data />
</settings>
</configuration>
</project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
/****************************************************************************
*
* The MIT License (MIT)
*
* Copyright 2020 NXP
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "buf_reader.h"
#include "stdio.h"
#include "string.h"
#define DBG_TRACE(x) printf x
static int _is_buffered_handle_valid(bufferred_reader_t *fd)
{
if (fd == NULL)
return E_BUF_INVALID_HANDLE;
if ( fd->data_buf == NULL )
return E_BUF_INVALID_HANDLE;
if ( fd->size < 0 )
return E_BUF_INVALID_HANDLE;
if ( fd->index > fd->size )
return E_BUF_INVALID_HANDLE;
return 0;
}
/* Write buffered IO operations */
int bufferred_fopen(bufferred_reader_t *fd, char *buf, int size)
{
if (fd == NULL)
return E_BUF_INVALID_HANDLE;
fd->data_buf = buf;
fd->size = size;
fd->index = 0;
if ( _is_buffered_handle_valid(fd)) {
return E_BUF_INVALID_HANDLE;
}
fd->is_valid = 1;
return 0;
}
int bufferred_ftell(bufferred_reader_t *fd)
{
if ( _is_buffered_handle_valid(fd)) {
return E_BUF_INVALID_HANDLE;
}
return fd->index;
}
int bufferred_fread(
void *ptr,
int size,
int nmemb,
bufferred_reader_t *fd
)
{
int to_copy = 0;
char *data_ptr = NULL;
char *buff = (char *)ptr;
int byte_to_read = size * nmemb;
if ( _is_buffered_handle_valid(fd)) {
return E_BUF_INVALID_HANDLE;
}
if ( buff == NULL ) {
return E_BUF_IO_INVALID_PARAMETERS;
}
if ( byte_to_read < 0 ) {
return E_BUF_IO_INVALID_PARAMETERS;
}
to_copy = (fd->size - fd->index);
data_ptr = fd->data_buf + fd->index;
if ( to_copy > byte_to_read )
to_copy = byte_to_read;
if (to_copy <= 0)
return -1; //EOF
memcpy(buff, data_ptr, to_copy);
fd->index += to_copy;
return 0;
}
int bufferred_fseek(
bufferred_reader_t *fd,
int offset,
int direction
)
{
if ( _is_buffered_handle_valid(fd)) {
return E_BUF_INVALID_HANDLE;
}
switch(direction)
{
case SEEK_SET:
fd->index = offset;
break;
case SEEK_CUR:
fd->index += offset;
break;
case SEEK_END:
fd->index = fd->size - offset;
break;
}
/* Clamp current offset */
if ( fd->index > fd->size ) {
DBG_TRACE(("WARNING: seeking beyond buffer size\n"));
fd->index = fd->size;
}
if ( fd->index < 0 ) {
DBG_TRACE(("WARNING: seeking beyond buffer size\n"));
fd->index = 0;
}
return 0;
}
int bufferred_fclose(bufferred_reader_t *fd)
{
if ( _is_buffered_handle_valid(fd)) {
return E_BUF_INVALID_HANDLE;
}
fd->size = -1;
fd->is_valid = 0;
return 0;
}
char *bufferred_fgets(char* buff, int len, bufferred_reader_t *fd)
{
char *ptr;
int i, j, valid_bytes;
if ( buff == NULL ) {
return NULL;
}
if ( len <= 0 ) {
return NULL;
}
if ( _is_buffered_handle_valid(fd)) {
return NULL;
}
/* Check how many bytes are available to read */
valid_bytes = fd->size - fd->index;
if ( len > 0 )
len -=1; /* fgets read one character less than buffer length */
if ( len > valid_bytes )
len = valid_bytes;
if ( valid_bytes <= 0 )
return NULL;
ptr = fd->data_buf + fd->index;
for(i=0; ptr[i] != '\0' && i < len; i++)
{
if ( ptr[i] == '\n' )
break;
if ( ptr[i] == '\r' )
break;
buff[i] = ptr[i];
}
buff[i] = '\0';
j = i;
/* skip trailing newline from file buffer */
if ( ptr[i] == '\r' )
i++;
if ( ptr[i] == '\n' )
i++;
fd->index += i;
/* Trim trailing spaces from output buffer */
for (i = j-1 ; i>0; i--) {
if (buff[i] == ' ')
buff[i] = '\0';
else
break;
}
return ptr;
}

View File

@@ -0,0 +1,63 @@
/****************************************************************************
*
* The MIT License (MIT)
*
* Copyright 2020 NXP
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
/* Bufferred reader interface */
#ifndef _BUFFERRED_READER_
#define _BUFFERRED_READER_
typedef struct buffered_reader {
char *data_buf;
int size;
int index;
int is_valid;
} bufferred_reader_t;
#define E_BUF_IO_OUT_OF_MEMORY -10
#define E_BUF_IO_READ_ERROR -11
#define E_BUF_INVALID_HANDLE -12
#define E_BUF_IO_INVALID_PARAMETERS -13
int is_buffered_handle_valid(bufferred_reader_t *fd);
int bufferred_fopen(bufferred_reader_t *fd, char *buf, int size);
int bufferred_ftell(bufferred_reader_t *fd);
int bufferred_fread(
void *ptr,
int size,
int nmemb,
bufferred_reader_t *fd
);
int bufferred_fseek(
bufferred_reader_t *fd,
int offset,
int direction
);
int bufferred_fclose(bufferred_reader_t *fd);
char *bufferred_fgets(char* buff, int len, bufferred_reader_t *fd);
#endif //!_BUFFERRED_READER_

View File

@@ -0,0 +1,474 @@
/*
* Copyright 2019-2021, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <rtthread.h>
#include "display_support.h"
#include "fsl_gpio.h"
#include "fsl_mipi_dsi.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*
* The DPHY bit clock must be fast enough to send out the pixels, it should be
* larger than:
*
* (Pixel clock * bit per output pixel) / number of MIPI data lane
*
* Here the desired DPHY bit clock multiplied by ( 9 / 8 = 1.125) to ensure
* it is fast enough.
*/
#define DEMO_MIPI_DPHY_BIT_CLK_ENLARGE(origin) (((origin) / 8) * 9)
/*******************************************************************************
* Prototypes
******************************************************************************/
static void BOARD_PullPanelResetPin(bool pullUp);
static void BOARD_PullPanelPowerPin(bool pullUp);
static void BOARD_InitLcdifClock(void);
static void BOARD_InitMipiDsiClock(void);
static status_t BOARD_DSI_Transfer(dsi_transfer_t *xfer);
/*******************************************************************************
* Variables
******************************************************************************/
static uint32_t mipiDsiTxEscClkFreq_Hz;
static uint32_t mipiDsiDphyBitClkFreq_Hz;
static uint32_t mipiDsiDphyRefClkFreq_Hz;
static uint32_t mipiDsiDpiClkFreq_Hz;
const MIPI_DSI_Type g_mipiDsi = {
.host = DSI_HOST,
.apb = DSI_HOST_APB_PKT_IF,
.dpi = DSI_HOST_DPI_INTFC,
.dphy = DSI_HOST_DPHY_INTFC,
};
#if defined(VGLITE_USING_RK055AHD091)
static mipi_dsi_device_t dsiDevice = {
.virtualChannel = 0,
.xferFunc = BOARD_DSI_Transfer,
};
static const rm68200_resource_t rm68200Resource = {
.dsiDevice = &dsiDevice,
.pullResetPin = BOARD_PullPanelResetPin,
.pullPowerPin = BOARD_PullPanelPowerPin,
};
static display_handle_t rm68200Handle = {
.resource = &rm68200Resource,
.ops = &rm68200_ops,
};
#elif defined(VGLITE_USING_RK055MHD091)
static mipi_dsi_device_t dsiDevice = {
.virtualChannel = 0,
.xferFunc = BOARD_DSI_Transfer,
};
static const hx8394_resource_t hx8394Resource = {
.dsiDevice = &dsiDevice,
.pullResetPin = BOARD_PullPanelResetPin,
.pullPowerPin = BOARD_PullPanelPowerPin,
};
static display_handle_t hx8394Handle = {
.resource = &hx8394Resource,
.ops = &hx8394_ops,
};
#else
static mipi_dsi_device_t dsiDevice = {
.virtualChannel = 0,
.xferFunc = BOARD_DSI_Transfer,
};
static const rm68191_resource_t rm68191Resource = {
.dsiDevice = &dsiDevice,
.pullResetPin = BOARD_PullPanelResetPin,
.pullPowerPin = BOARD_PullPanelPowerPin,
};
static display_handle_t rm68191Handle = {
.resource = &rm68191Resource,
.ops = &rm68191_ops,
};
#endif
#if defined(VGLITE_USING_LCDIFV2)
static dc_fb_lcdifv2_handle_t s_dcFbLcdifv2Handle = {0};
static const dc_fb_lcdifv2_config_t s_dcFbLcdifv2Config = {
.lcdifv2 = DEMO_LCDIF,
.width = LCD_WIDTH,
.height = LCD_HEIGHT,
.hsw = LCD_HSW,
.hfp = LCD_HFP,
.hbp = LCD_HBP,
.vsw = LCD_VSW,
.vfp = LCD_VFP,
.vbp = LCD_VBP,
.polarityFlags = DEMO_LCDIF_POL_FLAGS,
.lineOrder = kLCDIFV2_LineOrderRGB,
/* CM4 is domain 1, CM7 is domain 0. */
#if (__CORTEX_M <= 4)
.domain = 1,
#else
.domain = 0,
#endif
};
const dc_fb_t g_dc = {
.ops = &g_dcFbOpsLcdifv2,
.prvData = &s_dcFbLcdifv2Handle,
.config = &s_dcFbLcdifv2Config,
};
#else
dc_fb_elcdif_handle_t s_dcFbElcdifHandle = {0}; /* The handle must be initialized to 0. */
const dc_fb_elcdif_config_t s_dcFbElcdifConfig = {
.elcdif = DEMO_LCDIF,
.width = LCD_WIDTH,
.height = LCD_HEIGHT,
.hsw = LCD_HSW,
.hfp = LCD_HFP,
.hbp = LCD_HBP,
.vsw = LCD_VSW,
.vfp = LCD_VFP,
.vbp = LCD_VBP,
.polarityFlags = DEMO_LCDIF_POL_FLAGS,
#if (!DEMO_USE_XRGB8888) && (DEMO_USE_LUT8)
.dataBus = kELCDIF_DataBus8Bit,
#else
.dataBus = kELCDIF_DataBus24Bit,
#endif
};
const dc_fb_t g_dc = {
.ops = &g_dcFbOpsElcdif,
.prvData = &s_dcFbElcdifHandle,
.config = &s_dcFbElcdifConfig,
};
#endif
/*******************************************************************************
* Code
******************************************************************************/
static void BOARD_PullPanelResetPin(bool pullUp)
{
if (pullUp)
{
GPIO_PinWrite(BOARD_MIPI_PANEL_RST_GPIO, BOARD_MIPI_PANEL_RST_PIN, 1);
}
else
{
GPIO_PinWrite(BOARD_MIPI_PANEL_RST_GPIO, BOARD_MIPI_PANEL_RST_PIN, 0);
}
}
static void BOARD_PullPanelPowerPin(bool pullUp)
{
if (pullUp)
{
GPIO_PinWrite(BOARD_MIPI_PANEL_POWER_GPIO, BOARD_MIPI_PANEL_POWER_PIN, 1);
}
else
{
GPIO_PinWrite(BOARD_MIPI_PANEL_POWER_GPIO, BOARD_MIPI_PANEL_POWER_PIN, 0);
}
}
static status_t BOARD_DSI_Transfer(dsi_transfer_t *xfer)
{
return DSI_TransferBlocking(DEMO_MIPI_DSI, xfer);
}
static void BOARD_InitLcdifClock(void)
{
/*
* The pixel clock is (height + VSW + VFP + VBP) * (width + HSW + HFP + HBP) * frame rate.
*
* For 60Hz frame rate, the RK055IQH091 pixel clock should be 36MHz.
* the RK055AHD091 pixel clock should be 62MHz.
*/
const clock_root_config_t lcdifClockConfig = {
.clockOff = false,
.mux = 4, /*!< PLL_528. */
#if (defined(VGLITE_USING_RK055AHD091) || defined(VGLITE_USING_RK055MHD091))
.div = 9,
#else
.div = 15,
#endif
};
#if defined(VGLITE_USING_LCDIFV2)
CLOCK_SetRootClock(kCLOCK_Root_Lcdifv2, &lcdifClockConfig);
mipiDsiDpiClkFreq_Hz = CLOCK_GetRootClockFreq(kCLOCK_Root_Lcdifv2);
#else
CLOCK_SetRootClock(kCLOCK_Root_Lcdif, &lcdifClockConfig);
mipiDsiDpiClkFreq_Hz = CLOCK_GetRootClockFreq(kCLOCK_Root_Lcdif);
#endif
}
static void BOARD_InitMipiDsiClock(void)
{
uint32_t mipiDsiEscClkFreq_Hz;
/* RxClkEsc max 60MHz, TxClkEsc 12 to 20MHz. */
/* RxClkEsc = 528MHz / 11 = 48MHz. */
/* TxClkEsc = 528MHz / 11 / 4 = 16MHz. */
const clock_root_config_t mipiEscClockConfig = {
.clockOff = false,
.mux = 4, /*!< PLL_528. */
.div = 11,
};
CLOCK_SetRootClock(kCLOCK_Root_Mipi_Esc, &mipiEscClockConfig);
mipiDsiEscClkFreq_Hz = CLOCK_GetRootClockFreq(kCLOCK_Root_Mipi_Esc);
const clock_group_config_t mipiEscClockGroupConfig = {
.clockOff = false, .resetDiv = 2, .div0 = 2, /* TX esc clock. */
};
CLOCK_SetGroupConfig(kCLOCK_Group_MipiDsi, &mipiEscClockGroupConfig);
mipiDsiTxEscClkFreq_Hz = mipiDsiEscClkFreq_Hz / 3;
/* DPHY reference clock, use OSC 24MHz clock. */
const clock_root_config_t mipiDphyRefClockConfig = {
.clockOff = false,
.mux = 1, /*!< OSC_24M. */
.div = 1,
};
CLOCK_SetRootClock(kCLOCK_Root_Mipi_Ref, &mipiDphyRefClockConfig);
mipiDsiDphyRefClkFreq_Hz = BOARD_XTAL0_CLK_HZ;
}
static status_t BOARD_InitLcdPanel(void)
{
status_t status;
const gpio_pin_config_t pinConfig = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
const display_config_t displayConfig = {
.resolution = FSL_VIDEO_RESOLUTION(LCD_WIDTH, LCD_HEIGHT),
.hsw = LCD_HSW,
.hfp = LCD_HFP,
.hbp = LCD_HBP,
.vsw = LCD_VSW,
.vfp = LCD_VFP,
.vbp = LCD_VBP,
.controlFlags = 0,
.dsiLanes = DEMO_MIPI_DSI_LANE_NUM,
};
GPIO_PinInit(BOARD_MIPI_PANEL_POWER_GPIO, BOARD_MIPI_PANEL_POWER_PIN, &pinConfig);
GPIO_PinInit(BOARD_MIPI_PANEL_BL_GPIO, BOARD_MIPI_PANEL_BL_PIN, &pinConfig);
GPIO_PinInit(BOARD_MIPI_PANEL_RST_GPIO, BOARD_MIPI_PANEL_RST_PIN, &pinConfig);
#if defined(VGLITE_USING_RK055AHD091)
status = RM68200_Init(&rm68200Handle, &displayConfig);
#elif defined(VGLITE_USING_RK055MHD091)
status = HX8394_Init(&hx8394Handle, &displayConfig);
#else
status = RM68191_Init(&rm68191Handle, &displayConfig);
#endif
if (status == kStatus_Success)
{
GPIO_PinWrite(BOARD_MIPI_PANEL_BL_GPIO, BOARD_MIPI_PANEL_BL_PIN, 1);
}
return status;
}
static void BOARD_SetMipiDsiConfig(void)
{
dsi_config_t dsiConfig;
dsi_dphy_config_t dphyConfig;
const dsi_dpi_config_t dpiConfig = {.pixelPayloadSize = LCD_WIDTH,
.dpiColorCoding = kDSI_Dpi24Bit,
.pixelPacket = kDSI_PixelPacket24Bit,
.videoMode = kDSI_DpiBurst,
.bllpMode = kDSI_DpiBllpLowPower,
.polarityFlags = kDSI_DpiVsyncActiveLow | kDSI_DpiHsyncActiveLow,
.hfp = LCD_HFP,
.hbp = LCD_HBP,
.hsw = LCD_HSW,
.vfp = LCD_VFP,
.vbp = LCD_VBP,
.panelHeight = LCD_HEIGHT,
.virtualChannel = 0};
/*
* dsiConfig.numLanes = 4;
* dsiConfig.enableNonContinuousHsClk = false;
* dsiConfig.autoInsertEoTp = true;
* dsiConfig.numExtraEoTp = 0;
* dsiConfig.htxTo_ByteClk = 0;
* dsiConfig.lrxHostTo_ByteClk = 0;
* dsiConfig.btaTo_ByteClk = 0;
*/
DSI_GetDefaultConfig(&dsiConfig);
dsiConfig.numLanes = DEMO_MIPI_DSI_LANE_NUM;
dsiConfig.autoInsertEoTp = true;
/* Init the DSI module. */
DSI_Init(DEMO_MIPI_DSI, &dsiConfig);
/* Init DPHY.
*
* The DPHY bit clock must be fast enough to send out the pixels, it should be
* larger than:
*
* (Pixel clock * bit per output pixel) / number of MIPI data lane
*
* Here the desired DPHY bit clock multiplied by ( 9 / 8 = 1.125) to ensure
* it is fast enough.
*
* Note that the DSI output pixel is 24bit per pixel.
*/
mipiDsiDphyBitClkFreq_Hz = mipiDsiDpiClkFreq_Hz * (24 / DEMO_MIPI_DSI_LANE_NUM);
mipiDsiDphyBitClkFreq_Hz = DEMO_MIPI_DPHY_BIT_CLK_ENLARGE(mipiDsiDphyBitClkFreq_Hz);
DSI_GetDphyDefaultConfig(&dphyConfig, mipiDsiDphyBitClkFreq_Hz, mipiDsiTxEscClkFreq_Hz);
mipiDsiDphyBitClkFreq_Hz = DSI_InitDphy(DEMO_MIPI_DSI, &dphyConfig, mipiDsiDphyRefClkFreq_Hz);
/* Init DPI interface. */
DSI_SetDpiConfig(DEMO_MIPI_DSI, &dpiConfig, DEMO_MIPI_DSI_LANE_NUM, mipiDsiDpiClkFreq_Hz, mipiDsiDphyBitClkFreq_Hz);
}
status_t BOARD_InitDisplayInterface(void)
{
CLOCK_EnableClock(kCLOCK_Video_Mux);
#if defined(VGLITE_USING_LCDIFV2)
/* LCDIF v2 output to MIPI DSI. */
VIDEO_MUX->VID_MUX_CTRL.SET = VIDEO_MUX_VID_MUX_CTRL_MIPI_DSI_SEL_MASK;
#else
/* ELCDIF output to MIPI DSI. */
VIDEO_MUX->VID_MUX_CTRL.CLR = VIDEO_MUX_VID_MUX_CTRL_MIPI_DSI_SEL_MASK;
#endif
/* 1. Power on and isolation off. */
PGMC_BPC4->BPC_POWER_CTRL |= (PGMC_BPC_BPC_POWER_CTRL_PSW_ON_SOFT_MASK | PGMC_BPC_BPC_POWER_CTRL_ISO_OFF_SOFT_MASK);
/* 2. Assert MIPI reset. */
IOMUXC_GPR->GPR62 &=
~(IOMUXC_GPR_GPR62_MIPI_DSI_PCLK_SOFT_RESET_N_MASK | IOMUXC_GPR_GPR62_MIPI_DSI_ESC_SOFT_RESET_N_MASK |
IOMUXC_GPR_GPR62_MIPI_DSI_BYTE_SOFT_RESET_N_MASK | IOMUXC_GPR_GPR62_MIPI_DSI_DPI_SOFT_RESET_N_MASK);
/* 3. Setup clock. */
BOARD_InitMipiDsiClock();
/* 4. Deassert PCLK and ESC reset. */
IOMUXC_GPR->GPR62 |=
(IOMUXC_GPR_GPR62_MIPI_DSI_PCLK_SOFT_RESET_N_MASK | IOMUXC_GPR_GPR62_MIPI_DSI_ESC_SOFT_RESET_N_MASK);
/* 5. Configures peripheral. */
BOARD_SetMipiDsiConfig();
/* 6. Deassert BYTE and DBI reset. */
IOMUXC_GPR->GPR62 |=
(IOMUXC_GPR_GPR62_MIPI_DSI_BYTE_SOFT_RESET_N_MASK | IOMUXC_GPR_GPR62_MIPI_DSI_DPI_SOFT_RESET_N_MASK);
/* 7. Configure the panel. */
return BOARD_InitLcdPanel();
}
#if defined(VGLITE_USING_LCDIFV2)
void LCDIFv2_IRQHandler(void)
{
DC_FB_LCDIFV2_IRQHandler(&g_dc);
}
#else
void eLCDIF_IRQHandler(void)
{
DC_FB_ELCDIF_IRQHandler(&g_dc);
}
#endif
status_t BOARD_VerifyDisplayClockSource(void)
{
status_t status;
uint32_t srcClkFreq;
/*
* In this implementation, the SYSPLL2 (528M) clock is used as the source
* of LCDIFV2 pixel clock and MIPI DSI ESC clock. The OSC24M clock is used
* as the MIPI DSI DPHY PLL reference clock. This function checks the clock
* source are valid. OSC24M is always valid, so only verify the SYSPLL2.
*/
srcClkFreq = CLOCK_GetPllFreq(kCLOCK_PllSys2);
if (528 != (srcClkFreq / 1000000))
{
status = kStatus_Fail;
}
else
{
status = kStatus_Success;
}
return status;
}
status_t BOARD_PrepareDisplayController(void)
{
status_t status;
status = BOARD_VerifyDisplayClockSource();
if (status != kStatus_Success)
{
// PRINTF("Error: Invalid display clock source.\r\n");
return status;
}
BOARD_InitLcdifClock();
status = BOARD_InitDisplayInterface();
if (kStatus_Success == status)
{
#if defined(VGLITE_USING_LCDIFV2)
NVIC_ClearPendingIRQ(LCDIFv2_IRQn);
NVIC_SetPriority(LCDIFv2_IRQn, 3);
EnableIRQ(LCDIFv2_IRQn);
#else
NVIC_ClearPendingIRQ(eLCDIF_IRQn);
NVIC_SetPriority(eLCDIF_IRQn, 3);
EnableIRQ(eLCDIF_IRQn);
#endif
}
return kStatus_Success;
}

View File

@@ -0,0 +1,189 @@
/*
* Copyright 2019-2021, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _DISPLAY_SUPPORT_H_
#define _DISPLAY_SUPPORT_H_
#include <rtthread.h>
#include "fsl_dc_fb.h"
#if defined(VGLITE_USING_RK055AHD091)
#include "fsl_rm68200.h"
#elif defined(VGLITE_USING_RK055IQH091)
#include "fsl_rm68191.h"
#elif defined(VGLITE_USING_RK055MHD091)
#include "fsl_hx8394.h"
#else
#error "Please config lcd panel parameters."
#endif
#include "pin_mux.h"
#include "board.h"
#if defined(VGLITE_USING_LCDIFV2)
#include "fsl_dc_fb_lcdifv2.h"
#else
#include "fsl_dc_fb_elcdif.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/* @TEST_ANCHOR */
#define DEMO_BUFFER_FIXED_ADDRESS 0
#if DEMO_BUFFER_FIXED_ADDRESS
#define DEMO_BUFFER0_ADDR 0x80000000
#define DEMO_BUFFER1_ADDR 0x80200000
#endif
/*
* Use the MIPI dumb panel
*/
/* Definitions for the frame buffer. */
#define DEMO_BUFFER_COUNT 2 /* 2 is enough for DPI interface display. */
#ifndef DEMO_USE_XRGB8888
#define DEMO_USE_XRGB8888 0
#endif
/* Use LCDIF LUT (or named color palette) which is 8-bit per-pixel */
#ifndef DEMO_USE_LUT8
#define DEMO_USE_LUT8 0
#endif
#if DEMO_USE_XRGB8888
#define DEMO_BUFFER_PIXEL_FORMAT kVIDEO_PixelFormatXRGB8888
#define DEMO_BUFFER_BYTE_PER_PIXEL 4
#elif DEMO_USE_LUT8
#define DEMO_BUFFER_PIXEL_FORMAT kVIDEO_PixelFormatLUT8
#define DEMO_BUFFER_BYTE_PER_PIXEL 1
#else
#define DEMO_BUFFER_PIXEL_FORMAT kVIDEO_PixelFormatRGB565
#define DEMO_BUFFER_BYTE_PER_PIXEL 2
#endif
#if (defined(VGLITE_USING_RK055AHD091) || defined(VGLITE_USING_RK055MHD091))
#define LCD_WIDTH (720)
#define LCD_HEIGHT (1280)
#elif defined(VGLITE_USING_RK055IQH091)
#define LCD_WIDTH (540)
#define LCD_HEIGHT (960)
#endif
#define DEMO_BUFFER_WIDTH LCD_WIDTH
#define DEMO_BUFFER_HEIGHT LCD_HEIGHT
/* Where the frame buffer is shown in the screen. */
#define DEMO_BUFFER_START_X 0U
#define DEMO_BUFFER_START_Y 0U
#define DEMO_BUFFER_STRIDE_BYTE (DEMO_BUFFER_WIDTH * DEMO_BUFFER_BYTE_PER_PIXEL)
/* There is not frame buffer aligned requirement, consider the 64-bit AXI data
* bus width and 32-byte cache line size, the frame buffer alignment is set to
* 32 byte.
*/
#define FRAME_BUFFER_ALIGN 32
/*
* MIPI panel pin
*/
#define BOARD_MIPI_PANEL_RST_GPIO GPIO9
#define BOARD_MIPI_PANEL_RST_PIN 1
#define BOARD_MIPI_PANEL_POWER_GPIO GPIO11
#define BOARD_MIPI_PANEL_POWER_PIN 16
/* Back light pin. */
#define BOARD_MIPI_PANEL_BL_GPIO GPIO9
#define BOARD_MIPI_PANEL_BL_PIN 29
/*
* MIPI panel pin for RT-Thread
*/
#define GET_PIN(PORTx, PIN) (32 * (PORTx - 1) + (PIN & 31)) /* PORTx:1,2,3,4,5 */
#define LCD_RST_GPIO_PORT (3U)
#define LCD_RST_GPIO_PIN (1U)
#define LCD_RST_PIN GET_PIN(LCD_RST_GPIO_PORT, LCD_RST_GPIO_PIN)
/* Back light pin. */
#define LCD_BL_GPIO_PORT (3U)
#define LCD_BL_GPIO_PIN (29U)
#define LCD_BL_PIN GET_PIN(LCD_BL_GPIO_PORT, LCD_BL_GPIO_PIN)
/*
* RK055AHD091 panel
*/
#if defined(VGLITE_USING_RK055AHD091)
#define LCD_HSW 8
#define LCD_HFP 32
#define LCD_HBP 32
#define LCD_VSW 2
#define LCD_VFP 16
#define LCD_VBP 14
#elif defined(VGLITE_USING_RK055IQH091)
#define LCD_HSW 2
#define LCD_HFP 32
#define LCD_HBP 30
#define LCD_VSW 2
#define LCD_VFP 16
#define LCD_VBP 14
#elif defined(VGLITE_USING_RK055MHD091)
#define LCD_HSW 6
#define LCD_HFP 12
#define LCD_HBP 24
#define LCD_VSW 2
#define LCD_VFP 16
#define LCD_VBP 14
#endif
#if defined(VGLITE_USING_LCDIFV2)
#define DEMO_LCDIF_POL_FLAGS \
(kLCDIFV2_DataEnableActiveHigh | kLCDIFV2_VsyncActiveLow | kLCDIFV2_HsyncActiveLow | \
kLCDIFV2_DriveDataOnFallingClkEdge)
#define DEMO_LCDIF LCDIFV2
#else
#define DEMO_LCDIF_POL_FLAGS \
(kELCDIF_DataEnableActiveHigh | kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DriveDataOnFallingClkEdge)
#define DEMO_LCDIF LCDIF
#endif
/* Definitions for MIPI. */
#define DEMO_MIPI_DSI (&g_mipiDsi)
#define DEMO_MIPI_DSI_LANE_NUM 2
extern const dc_fb_t g_dc;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
status_t BOARD_PrepareDisplayController(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* _DISPLAY_SUPPORT_H_ */

View File

@@ -0,0 +1,321 @@
/****************************************************************************
*
* Copyright 2012 - 2020 Vivante Corporation, Santa Clara, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "elm_precom.h"
#include "vg_lite.h"
#if !DDRLESS
static vg_lite_buffer_format_t _buffer_format_to_vglite(ELM_BUFFER_FORMAT format)
{
vg_lite_buffer_format_t fmt;
switch (format) {
case ELM_BUFFER_FORMAT_RGBA8888:
fmt = VG_LITE_RGBA8888;
break;
case ELM_BUFFER_FORMAT_RGBX8888:
fmt = VG_LITE_RGBX8888;
break;
case ELM_BUFFER_FORMAT_BGRA8888:
fmt = VG_LITE_BGRA8888;
break;
case ELM_BUFFER_FORMAT_BGRX8888:
fmt = VG_LITE_BGRX8888;
break;
case ELM_BUFFER_FORMAT_RGB565:
fmt = VG_LITE_RGB565;
break;
case ELM_BUFFER_FORMAT_BGR565:
fmt = VG_LITE_BGR565;
break;
case ELM_BUFFER_FORMAT_RGBA4444:
fmt = VG_LITE_RGBA4444;
break;
case ELM_BUFFER_FORMAT_BGRA4444:
fmt = VG_LITE_BGRA4444;
break;
default:
fmt = VG_LITE_RGBA8888;
break;
}
return fmt;
}
#endif
/*!
@abstract Create internal render buffer.
@discussion
This functiois is to create an internal render buffer for Elementary rendering, ussually it's not for direct display.
The buffer which is displayed on pannel is wrapped up by another API, whose address is managed by display controller side.
@param width
The buffer's width.
@param height
The buffer's height.
@param format
The buffer's format, check enumeration of ELM_BUFFER_FORMAT.
@return
The buffer handle.
*/
ElmBuffer ElmCreateBuffer(unsigned int width, unsigned int height, ELM_BUFFER_FORMAT format)
{
#if !DDRLESS
el_Obj_Buffer *buffer_obj;
vg_lite_buffer_t *buffer;
vg_lite_error_t error;
ElmHandle handle = ELM_NULL_HANDLE;
do {
/* Allocate ebo object. */
buffer_obj = (el_Obj_Buffer *)calloc(1,sizeof(el_Obj_Buffer));
if (buffer_obj != NULL) {
buffer_obj->object.type = ELM_OBJECT_TYPE_BUF;
/* Allocate the buffer. */
buffer = &buffer_obj->buffer;
memset(buffer, 0, sizeof(vg_lite_buffer_t));
buffer->width = width;
buffer->height = height;
buffer->format = (vg_lite_buffer_format_t)format;
error = vg_lite_allocate(buffer);
if (error)
goto error_exit;
JUMP_IF_NON_ZERO_VALUE(add_object((el_Object *)buffer_obj), error_exit);
handle = buffer_obj->object.handle;
}
} while(0);
return handle;
error_exit:
vg_lite_free(buffer);
free(buffer_obj);
return ELM_NULL_HANDLE;
#else
return ELM_NULL_HANDLE;
#endif
}
/*!
@abstract Wrap a customized buffer.
@discussion
The application may wrap a user created buffer by giving the information of
the buffer including the size, the memory addresses and format. E.g., the
application can wrap a system framebuffer thus ELM can directly render onto
the screen.
@return
The buffer handle.
*/
ElmBuffer ElmWrapBuffer(int width, int height, int stride,
void *logical, uint32_t physical,
ELM_BUFFER_FORMAT format)
{
#if !DDRLESS
el_Obj_Buffer *buffer_obj;
vg_lite_buffer_t *buffer;
ElmHandle handle = ELM_NULL_HANDLE;
do {
/* open framebuffer. */
buffer_obj = (el_Obj_Buffer *)elm_alloc(1, sizeof(el_Obj_Buffer));
if (buffer_obj != NULL) {
buffer_obj->object.type = ELM_OBJECT_TYPE_BUF;
buffer = &buffer_obj->buffer;
buffer->width = width;
buffer->height = height;
buffer->stride = stride;
buffer->memory = logical;
buffer->handle = NULL;
buffer->address = physical;
buffer->format = _buffer_format_to_vglite(format);
buffer->tiled = VG_LITE_LINEAR;
JUMP_IF_NON_ZERO_VALUE(add_object((el_Object *)buffer_obj), error_exit);
handle = buffer_obj->object.handle;
}
} while(0);
return handle;
error_exit:
free(buffer_obj);
return ELM_NULL_HANDLE;
#else
return ELM_NULL_HANDLE;
#endif
}
/*!
@abstract Get buffer address.
@discussion
The function is to get the address of ElmBuffer.
@return
The buffer address.
*/
uint32_t ElmGetBufferAddress(ElmBuffer buffer)
{
#if !DDRLESS
el_Obj_Buffer *buff_obj;
buff_obj = (el_Obj_Buffer *)get_object(buffer);
if (buff_obj == NULL)
{
return 0;
}
else
{
return buff_obj->buffer.address;
}
#else
return 0;
#endif
}
/*!
@abstract Destroy a render buffer.
@discussion
This function is to release all internal resource inside Elementary libary belonging to this buffer.
Applicatoin need make sure the buffer is not being used by elmentary library any more when calling this function.
@param buffer
The render buffer handle
@return
If destroying is completed successfully.
*/
BOOL ElmDestroyBuffer(ElmBuffer buffer)
{
#if !DDRLESS
/* Find the object. */
el_Obj_Buffer *buff = (el_Obj_Buffer *)get_object(buffer);
/* If found, delete the vg_lite_buffer object. Otherwise, return FALSE. */
if (buff != NULL) {
if (buff->buffer.handle != NULL) {
/* Free the buffer memory. */
vg_lite_free(&buff->buffer);
}
remove_object((el_Object*)buff);
elm_free(buff);
return TRUE;
}
else {
return FALSE;
}
#else
return TRUE;
#endif
}
BOOL ElmSaveBuffer(ElmBuffer buffer, const char *name)
{
#if !DDRLESS
el_Obj_Buffer *buff = (el_Obj_Buffer *)get_object(buffer);
/* If found, delete the vg_lite_buffer object. Otherwise, return FALSE. */
if (buff != NULL) {
#if !RTOS
/*
"vg_lite_save_png" function does not exist (anymore). Probably a left
over from an older driver.
*/
if (buff->buffer.memory != NULL) {
vg_lite_save_png(name, &buff->buffer);
}
#endif
return TRUE;
}
else {
return FALSE;
}
#else
return TRUE;
#endif
}
/*!
@abstract Convert vglite format to elm format.
*/
ELM_BUFFER_FORMAT _buffer_format_to_Elm(vg_lite_buffer_format_t format)
{
switch (format)
{
case VG_LITE_RGB565:
return ELM_BUFFER_FORMAT_RGB565;
break;
case VG_LITE_BGR565:
return ELM_BUFFER_FORMAT_BGR565;
break;
default:
return ELM_BUFFER_FORMAT_RGBA8888;
break;
}
}
/*!
@abstract Get handle of the framebuffer.
*/
ElmBuffer ElmGetBuffer(vg_lite_buffer_t *buffer)
{
elm_tls_t* elm_tls;
elm_tls = (elm_tls_t *) elm_os_get_tls();
if (elm_tls == NULL)
return ELM_NULL_HANDLE;
for (int i = 0; i < APP_BUFFER_COUNT; i++) {
if (elm_tls->gContext.elmFB[i].buffer == NULL) {
elm_tls->gContext.elmFB[i].buffer = buffer;
elm_tls->gContext.elmFB[i].handle = ElmWrapBuffer(buffer->width, buffer->height, buffer->stride, buffer->memory,
buffer->address, _buffer_format_to_Elm(buffer->format));
vg_lite_clear(buffer, NULL, 0x0);
return elm_tls->gContext.elmFB[i].handle;
}
if (elm_tls->gContext.elmFB[i].buffer == buffer)
return elm_tls->gContext.elmFB[i].handle;
}
return 0;
}

View File

@@ -0,0 +1,483 @@
/****************************************************************************
*
* Copyright 2012 - 2020 Vivante Corporation, Santa Clara, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "elm_precom.h"
#if (VG_RENDER_TEXT==1)
#include "elm_text.h"
#endif /* VG_RENDER_TEXT */
static void multiply(vg_lite_matrix_t * matrix, vg_lite_matrix_t * mult)
{
vg_lite_matrix_t temp;
int row, column;
/* Process all rows. */
for (row = 0; row < 3; row++) {
/* Process all columns. */
for (column = 0; column < 3; column++) {
/* Compute matrix entry. */
temp.m[row][column] = (matrix->m[row][0] * mult->m[0][column])
+ (matrix->m[row][1] * mult->m[1][column])
+ (matrix->m[row][2] * mult->m[2][column]);
}
}
memcpy(matrix, &temp, sizeof(temp));
}
static vg_lite_filter_t quality_to_filter(ELM_QUALITY quality)
{
switch (quality) {
case ELM_QULIATY_HI:
return VG_LITE_FILTER_BI_LINEAR;
break;
case ELM_QUALITY_MED:
return VG_LITE_FILTER_LINEAR;
break;
case ELM_QUALITY_LOW:
default:
return VG_LITE_FILTER_POINT;
break;
}
}
static vg_lite_pattern_mode_t pat_to_pad(ELM_PATTERN_MODE mode)
{
switch (mode) {
case ELM_PATTERN_MODE_PAD:
return VG_LITE_PATTERN_PAD;
break;
default:
return VG_LITE_PATTERN_COLOR;
break;
}
}
static vg_lite_error_t draw_evo_pattern(el_Obj_Buffer *buff, el_Obj_Group *ego,int * index)
{
el_Obj_EVO *evo;
vg_lite_error_t error = VG_LITE_INVALID_ARGUMENT;
vg_lite_color_t color;
vg_lite_filter_t filter;
vg_lite_blend_t blend;
vg_lite_fill_t rule;
vg_lite_buffer_t *buffer;
vg_lite_matrix_t mat;
vg_lite_pattern_mode_t pat_mode;
int width = 0;
int height = 0;
int start = *index;
int i = start;
evo = &ego->group.objects[i];
width = (int)(evo->data.path.bounding_box[2] - evo->data.path.bounding_box[0]);
height = (int)(evo->data.path.bounding_box[3] - evo->data.path.bounding_box[1]);
buffer = (vg_lite_buffer_t *)malloc(sizeof(vg_lite_buffer_t));
memset(buffer,0,sizeof(vg_lite_buffer_t));
buffer->width = width;
buffer->height = height;
buffer->format = VG_LITE_RGBA8888;
error = vg_lite_allocate(buffer);
vg_lite_clear(buffer,NULL,0xffffffff);
i++;
evo = &ego->group.objects[i];
while(evo->is_pattern)
{
blend = (vg_lite_blend_t)evo->attribute.blend;
rule = (vg_lite_fill_t)evo->attribute.fill_rule;
color = (vg_lite_color_t)evo->attribute.paint.color;
memcpy(&mat, &(evo->attribute.transform.matrix), sizeof(mat));
error = vg_lite_draw(buffer, &evo->data.path,
rule,
&mat,
blend,
color);
if(error)
return error;
i++;
evo = &ego->group.objects[i];
}
*index = i - 1;
evo = &ego->group.objects[start];
blend = (vg_lite_blend_t)evo->attribute.blend;
rule = (vg_lite_fill_t)evo->attribute.fill_rule;
color = (vg_lite_color_t)evo->attribute.paint.color;
memcpy(&mat, &(evo->attribute.transform.matrix), sizeof(mat));
filter = VG_LITE_FILTER_POINT;
pat_mode = VG_LITE_PATTERN_COLOR;
error = vg_lite_draw_pattern(&buff->buffer, &evo->data.path,
rule,
&mat,
buffer,
&mat,
blend,
pat_mode,
color,
filter);
vg_lite_finish();
vg_lite_free(buffer);
free(buffer);
return error;
}
static vg_lite_error_t draw_evo(el_Obj_Buffer *buff, el_Obj_EVO *evo, vg_lite_matrix_t *mat)
{
el_Obj_EBO *pattern;
vg_lite_error_t error = VG_LITE_INVALID_ARGUMENT;
vg_lite_color_t color;
vg_lite_filter_t filter;
vg_lite_matrix_t mat_pattern;
ELM_PAINT_TYPE paint_type = evo->attribute.paint.type;
vg_lite_blend_t blend = (vg_lite_blend_t)evo->attribute.blend;
vg_lite_fill_t rule = (vg_lite_fill_t)evo->attribute.fill_rule;
vg_lite_pattern_mode_t pat_mode = pat_to_pad(evo->attribute.paint.pattern.mode);
switch (paint_type) {
case ELM_PAINT_GRADIENT:
memcpy(&evo->attribute.paint.grad->data.grad.matrix,
&evo->attribute.paint.grad->data.transform.matrix,
sizeof(evo->attribute.paint.grad->data.transform.matrix));
#if !DDRLESS
error = vg_lite_draw_gradient(&buff->buffer, &evo->data.path,
rule,
mat,
&evo->attribute.paint.grad->data.grad,
blend);
#else
error = vg_lite_draw_gradient(NULL, &evo->data.path,
rule,
mat,
&evo->attribute.paint.grad->data.grad,
blend);
#endif
break;
case ELM_PAINT_RADIAL_GRADIENT:
memcpy(&evo->attribute.paint.radgrad->data.rad_grad.matrix,
&evo->attribute.paint.radgrad->data.transform.matrix,
sizeof(evo->attribute.paint.radgrad->data.transform.matrix));
error = vg_lite_draw_radial_gradient(&buff->buffer, &evo->data.path,
rule,
mat,
&evo->attribute.paint.radgrad->data.rad_grad,
0,
blend,
VG_LITE_FILTER_LINEAR);
break;
case ELM_PAINT_COLOR:
color = (vg_lite_color_t)evo->attribute.paint.color;
#if !DDRLESS
error = vg_lite_draw(&buff->buffer, &evo->data.path,
rule,
mat,
blend,
color);
#else
error = vg_lite_draw(NULL, &evo->data.path,
rule,
mat,
blend,
color);
#endif
break;
case ELM_PAINT_PATTERN:
pattern = (el_Obj_EBO *)(evo->attribute.paint.pattern.pattern);
blend = (vg_lite_blend_t)(pattern->attribute.blend);
filter = quality_to_filter(evo->attribute.quality);
color = (vg_lite_color_t)pattern->attribute.paint.color;
memcpy(&mat_pattern, &pattern->attribute.transform.matrix,
sizeof(pattern->attribute.transform.matrix));
#if !DDRLESS
error = vg_lite_draw_pattern(&buff->buffer, &evo->data.path, rule, mat,
&pattern->data.buffer, &mat_pattern, blend,
pat_mode, color, filter);
#else
error = vg_lite_draw_pattern(NULL, &evo->data.path, rule, mat,
&pattern->data.buffer, &mat_pattern, blend,
pat_mode, color, filter);
#endif
break;
case ELM_PAINT_TEXT:
#if (VG_RENDER_TEXT==1)
error = draw_text(buff, evo, mat);
#endif /* VG_RENDER_TEXT */
break;
}
return error;
}
static vg_lite_error_t draw_ebo(el_Obj_Buffer *buff, el_Obj_EBO *ebo, vg_lite_matrix_t *mat)
{
vg_lite_error_t error;
vg_lite_buffer_t *image_buffer = &ebo->data.buffer;
vg_lite_blend_t blend = (vg_lite_blend_t)ebo->attribute.blend;
vg_lite_color_t color = ebo->attribute.paint.color;
vg_lite_filter_t filter = quality_to_filter(ebo->attribute.quality);
if (image_buffer->format >= VG_LITE_INDEX_1 && image_buffer->format <= VG_LITE_INDEX_8)
{
vg_lite_set_CLUT(ebo->clut_count, ebo->clut);
}
image_buffer->image_mode = VG_LITE_NORMAL_IMAGE_MODE;
#if !DDRLESS
error = vg_lite_blit(&buff->buffer, image_buffer, mat, blend, color, filter);
#else
error = vg_lite_blit(NULL, image_buffer, mat, blend, color, filter);
#endif
return error;
}
/*!
@abstract Clear a render buffer with specified color and dimension.
@discussion
This function is called to clear full or partial of the buffer. If the rectangle is out of buffer space, the intersect portion will be cleared.
@param buffer
A render buffer handle.
@param color
Clear color value.
@param x
x origin of partical clear rectangle.
@param y
y origin of partial clear rectangle.
@param width
width of partical clear rectangle.
@param height
height of partical clear rectangle.
@param full
Flag to indicate a full buffer clear. If true, the dimension parameters will be ignored.
@return bool
Indicate the clear operation is set up correctly.
*/
BOOL ElmClear(ElmBuffer buffer, uint32_t color, uint32_t x, uint32_t y, uint32_t width, uint32_t height, BOOL full)
{
#if !DDRLESS
vg_lite_error_t error = VG_LITE_SUCCESS;
el_Obj_Buffer *buff = (el_Obj_Buffer *)get_object(buffer);
vg_lite_rectangle_t rectangle;
rectangle.x = x;
rectangle.y = y;
rectangle.width = width;
rectangle.height = height;
if (full == 1)
{
error = vg_lite_clear(&buff->buffer, NULL, color);
}
else
{
error = vg_lite_clear(&buff->buffer, &rectangle, color);
}
return ((error == VG_LITE_SUCCESS) ? TRUE : FALSE);
#else
return TRUE;
#endif
}
/*!
@abstract Finish all rendering on GPU issued before this call.
@discussion
This function tells the engine that it has finished the frame data and GPU can draw it now. It's blocked until GPU rendering done.
@return
If the opeartion is successfully done or not.
*/
BOOL ElmFinish()
{
vg_lite_finish();
return TRUE;
}
/*!
@abstract Flush all rendering command to GPU issued before this call.
@discussion
This function tells the engine to start kicking off command to GPU side, it will return immediately after firing off GPU.
@return
If the opeartion is successfully done or not.
*/
BOOL ElmFlush()
{
vg_lite_flush();
return TRUE;
}
/*!
@abstract Draw a graphics object onto current render target
@discussion
This is an enssentail function to do the real job, it takes all current setting of the elementary object and
render into theb buffer target.
@param buffer
The render target that an elmentary object will be rendered into.
@param obj
The elmentary object will be draw into render target.
@return bool
The draw operation for this elmentary object is sucessful.
*/
BOOL ElmDraw(ElmBuffer buffer, ElmHandle object)
{
BOOL status = TRUE;
el_Object *elm;
el_Obj_Buffer *buff;
vg_lite_error_t error;
vg_lite_matrix_t mat;
elm = get_object(object);
if (!elm)
{
return FALSE;
}
#if !DDRLESS
buff = (el_Obj_Buffer *)get_object(buffer);
if (buff == NULL)
{
return FALSE;
}
#else
buff = NULL;
#endif
if (elm->type == ELM_OBJECT_TYPE_EGO)
{
el_Obj_EVO *evo;
el_Obj_Group *ego = (el_Obj_Group *)elm;
vg_lite_matrix_t mat_group, res_mat;
if (ego->group.count > 0)
{
int i;
memcpy(&mat_group, &(ego->transform.matrix), sizeof(ego->transform.matrix));
for (i = 0; i < ego->group.count; i++)
{
evo = &ego->group.objects[i];
/* Font objects may generate empty objects */
if (evo->object.handle == ELM_NULL_HANDLE)
continue;
if(evo->is_image)
{
ElmHandle ebo_handle;
el_Object *elm_ebo;
el_Obj_EBO *ebo;
ebo_handle = ElmCreateObjectFromFile(ELM_OBJECT_TYPE_EBO, evo->eboname);
elm_ebo = get_object(ebo_handle);
ebo = (el_Obj_EBO *)elm_ebo;
memcpy(&mat, &evo->defaultAttrib.transform.matrix, sizeof(mat));
error = draw_ebo(buff, ebo, &mat);
if (error)
{
status = FALSE;
}
continue;
}
memcpy(&mat, &(evo->attribute.transform.matrix), sizeof(mat));
memcpy(&res_mat, &mat_group, sizeof(mat_group));
multiply(&res_mat, &mat);
if(evo->has_pattern)
error = draw_evo_pattern(buff,ego,&i);
else
error = draw_evo(buff, evo, &res_mat);
if (error)
{
status = FALSE;
break;
}
}
}
}
else if (elm->type == ELM_OBJECT_TYPE_EVO)
{
el_Obj_EVO *evo = (el_Obj_EVO *)elm;
memcpy(&mat, &(evo->attribute.transform.matrix), sizeof(mat));
error = draw_evo(buff, evo, &mat);
if (error)
{
status = FALSE;
}
}
else if (elm->type == ELM_OBJECT_TYPE_EBO)
{
el_Obj_EBO *ebo = (el_Obj_EBO *)elm;
memcpy(&mat, &(ebo->attribute.transform.matrix), sizeof(mat));
error = draw_ebo(buff, ebo, &mat);
if (error)
{
status = FALSE;
}
}
else if (elm->type == ELM_OBJECT_TYPE_BUF)
{
el_Obj_Buffer *src = (el_Obj_Buffer *)elm;
vg_lite_identity(&mat);
#if !DDRLESS
if (VG_LITE_SUCCESS !=
vg_lite_blit(&buff->buffer, &src->buffer, &mat, VG_LITE_BLEND_NONE, 0,
VG_LITE_FILTER_BI_LINEAR)
)
#else
if (VG_LITE_SUCCESS !=
vg_lite_blit(NULL, &src->buffer, &mat, VG_LITE_BLEND_NONE, 0,
VG_LITE_FILTER_BI_LINEAR)
)
#endif
{
status = FALSE;
}
}
return status;
}

View File

@@ -0,0 +1,158 @@
/****************************************************************************
*
* Copyright 2021 Vivante Corporation, Santa Clara, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef __ELM_HEADERS_H__
#define __ELM_HEADERS_H__
#define ATTR_PACKED __attribute__((packed, aligned(4)))
typedef struct {
vg_lite_matrix_t matrix;
uint32_t reserved;
uint32_t stop_count;
uint32_t stop_offset;
uint32_t color_offset;
} el_EVO_GradData;
typedef struct {
vg_lite_radial_gradient_parameter_t params;
vg_lite_radial_gradient_spreadmode_t spread_mode;
} el_EVO_RadGradDataExt;
struct el_PaintType_t {
uint32_t paint:28;
uint32_t flags:1;
uint32_t is_image:1;
uint32_t is_pattern:1;
uint32_t has_pattern:1;
};
typedef struct ATTR_PACKED {
uint32_t type;
vg_lite_float_t min_x, min_y, max_x, max_y;
uint32_t format;
uint32_t length:31;
uint32_t arc_flag:1;
uint32_t offset;
vg_lite_matrix_t matrix;
uint32_t reserved;
uint32_t quality;
uint32_t fill_rule;
uint32_t blend;
union {
uint32_t paint_data;
struct el_PaintType_t paint_type;
};
vg_lite_color_t color;
el_EVO_GradData grad;
} el_EVO_Polygon;
typedef struct ATTR_PACKED {
uint32_t type;
uint32_t namelength;
char eboname[76];
union {
uint32_t paint_data;
struct el_PaintType_t paint_type;
};
vg_lite_matrix_t matrix;
uint32_t width;
uint32_t height;
} el_EVO_Image;
typedef struct ATTR_PACKED {
union {
el_EVO_Polygon polygon;
el_EVO_Image image;
};
} el_EVO_Header;
typedef struct ATTR_PACKED {
uint32_t type;
uint32_t size_font_block;
uint32_t num_ttf_fonts;
uint32_t num_vector_fonts;
uint32_t num_text_fonts;
uint32_t ttf_fonts_block_offset;
uint32_t ttf_fonts_block_length;
uint32_t vector_fonts_block_offset;
uint32_t vector_fonts_block_length;
uint32_t text_fonts_block_offset;
uint32_t text_fonts_block_length;
uint32_t property_block_offset;
uint32_t property_block_length;
} el_Font_Header;
struct el_TextFlags_t {
uint32_t flags1:1;
uint32_t text_anchor:2;
uint32_t flags2:29;
};
typedef struct ATTR_PACKED {
uint32_t type;
uint32_t size_text_block;
uint32_t tspan_has_dx_dy;
float x_pos;
float y_pos;
float font_size;
uint32_t font_id;
uint32_t color;
union {
uint32_t flags_data;
struct el_TextFlags_t text_flags;
};
vg_lite_matrix_t matrix;
uint32_t reserved;
uint16_t data_length;
} el_Text_Header;
typedef struct ATTR_PACKED {
uint32_t type;
uint32_t width;
uint32_t height;
uint32_t stride;
uint32_t tiled;
uint32_t format;
uint32_t data_offset;
} el_EBO_Header;
typedef struct ATTR_PACKED {
uint32_t clut_count;
uint32_t clut_data_offset;
} el_EBO_Palette;
typedef struct ATTR_PACKED {
uint32_t type;
vg_lite_matrix_t matrix;
uint32_t count;
} el_EGO_Header;
#endif /* __ELM_HEADERS_H__ */

View File

@@ -0,0 +1,160 @@
/****************************************************************************
*
* Copyright 2012 - 2020 Vivante Corporation, Santa Clara, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "elm_precom.h"
#include "elm_os.h"
#include "vg_lite_os.h"
#if (VG_RENDER_TEXT==1)
#include "elm_text.h"
#endif /* VG_RENDER_TEXT */
/* Prototypes */
static int _initialize_elm(uint32_t width, uint32_t height);
/* Initialize vg_lite related. */
static int _initialize_vglite(int32_t width, int32_t height)
{
vg_lite_error_t error = VG_LITE_SUCCESS;
error = vg_lite_init(width, height);
return (error == VG_LITE_SUCCESS);
}
/* Initialize elm global objects. */
static int _initialize_elm(uint32_t width, uint32_t height)
{
vg_lite_error_t error;
elm_tls_t* elm_tls;
elm_tls = (elm_tls_t *)elm_os_get_tls();
if (elm_tls == NULL) {
elm_tls = (elm_tls_t *)vg_lite_os_malloc(sizeof(elm_tls_t));
error = elm_os_set_tls((void *) elm_tls);
if(error != VG_LITE_SUCCESS)
return error;
}
int i;
elm_tls->gContext.version = VERSION;
elm_tls->gContext.currentHandle = (ELM_NULL_HANDLE + 1); /* Reserve handle 0 for error */
elm_tls->gContext.objectCount = 0;
elm_tls->gContext.tessellation_width = width;
elm_tls->gContext.tessellation_height = height;
elm_tls->gContext.vector_id = -1;
for (i = 0; i < SLOT_COUNT; i++) {
elm_tls->gContext.object_slots[i] = NULL;
}
#if (RTOS && DDRLESS) || BAREMETAL
for (i = 0; i < sizeof(elm_tls->gContext.objmap_ebo) / 4; i++) {
elm_tls->gContext.objmap_ebo[i] = 0;
}
for (i = 0; i < sizeof(elm_tls->gContext.objmap_evo) / 4; i++) {
elm_tls->gContext.objmap_evo[i] = 0;
}
for (i = 0; i < sizeof(elm_tls->gContext.objmap_group) / 4; i++) {
elm_tls->gContext.objmap_group[i] = 0;
}
for (i = 0; i < sizeof(elm_tls->gContext.objmap_grad) / 4; i++) {
elm_tls->gContext.objmap_grad[i] = 0;
}
elm_tls->gContext.objcounter_grad = 0;
elm_tls->gContext.objcounter_evo = 0;
elm_tls->gContext.objcounter_ebo = 0;
elm_tls->gContext.objcounter_group = 0;
#endif
return 1;
}
/* Terminate vg_lite related. */
static void _terminate_vglite(void)
{
vg_lite_close();
}
/* Terminate elm global objects. */
static void _terminate_elm(void)
{
#if (VG_RENDER_TEXT==1)
_release_default_text_parameters();
#endif
elm_os_reset_tls();
}
/*!
@abstract Initialize Elementary context.
@discussion
It should be called as the first function of Elemenatary libary, which initializes the library. Currently
Elementary library doesn't support context concept, neigher multi-threading. Elementary library defines
origin of coordinate system is at top-left.
@param none
@return none
*/
BOOL ElmInitialize(uint32_t width, uint32_t height)
{
BOOL result = TRUE;
do {
result = _initialize_vglite((int32_t)width, (int32_t)height);
if (!result)
break;
result = _initialize_elm(width, height);
if (!result)
break;
}
while (0);
#if (VG_RENDER_TEXT==1)
initialize_elm_text();
#endif /* VG_RENDER_TEXT */
return result;
}
/*!
@abstract Terminate Elementary context.
@discussion
This should be called when an app exits. It frees all the resource.
@param none
@return none
*/
void ElmTerminate(void)
{
_terminate_elm();
_terminate_vglite();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
#include "elm_os.h"
#include "rtthread.h"
vg_lite_error_t elm_os_set_tls(void* tls)
{
if(tls == NULL)
return VG_LITE_INVALID_ARGUMENT;
rt_thread_t rt_TCB;
rt_TCB = rt_thread_self();
RT_ASSERT( rt_TCB != NULL );
rt_uint32_t * tls_ptr = (rt_uint32_t *)rt_TCB->user_data;
*(tls_ptr + 1) = (rt_uint32_t) tls;
return VG_LITE_SUCCESS;
}
void * elm_os_get_tls(void)
{
rt_thread_t rt_TCB;
void * pvReturn = NULL;
rt_TCB = rt_thread_self();
rt_uint32_t * tls_ptr = (rt_uint32_t *)rt_TCB->user_data;
pvReturn = (void *) *(tls_ptr + 1);
return pvReturn;
}
void elm_os_reset_tls(void)
{
rt_thread_t rt_TCB;
rt_TCB = rt_thread_self();
RT_ASSERT( rt_TCB != NULL );
rt_uint32_t * tls_ptr = (rt_uint32_t *)rt_TCB->user_data;
*(tls_ptr + 1) = NULL;
}

View File

@@ -0,0 +1,13 @@
#ifndef ELM_OS_H_
#define ELM_OS_H_
#include<stdlib.h>
#include"vg_lite.h"
vg_lite_error_t elm_os_set_tls(void* tls);
void * elm_os_get_tls(void);
void elm_os_reset_tls(void);
#endif

View File

@@ -0,0 +1,55 @@
/****************************************************************************
*
* Copyright 2012 - 2021 Vivante Corporation, Santa Clara, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef elm_precom_h
#define elm_precom_h
/* System headers. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* VGLite hdaders. */
#include "vg_lite.h"
/* Project headers. */
#include "Elm.h"
#include "velm.h"
#include "elm_os.h"
#define JUMP_IF_NON_ZERO_VALUE(x, label) { int ret = x; if ( (ret) != 1 ) { goto label; } }
#define JUMP_IF_NULL(x, label) { if (x == NULL) { goto label;} }
#define JUMP_IF_LOWER(x, y, label) {if (x < y) {goto label;} }
#define JUMP_IF_GREATER(x, y, label) {if (x > y) {goto label;} }
#define JUMP_IF_EQUAL(x, y, label) {if (x == y) {goto label;} }
#define JUMP_IF_LOWER_OR_EQUAL(x, y, label) {if (x <= y) {goto label;} }
#define JUMP_IF_GREATER_OR_EQUAL(x, y, label) {if (x => y) {goto label;} }
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif /* elm_precom_h */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,207 @@
/****************************************************************************
*
* The MIT License (MIT)
*
* Copyright 2020 NXP
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "Elm.h"
#include "velm.h"
#ifndef _elm_text_h_
#define _elm_text_h_
#ifdef __cplusplus
extern "C" {
#endif
typedef enum eElemType {
eElemTypeLinearGradient = 0,
eElemTypePath = 1,
eElemTypeGroup = 2,
eElemTypeText = 3,
eElemTypeTspan = 4,
eElemTypeFont = 5,
eElemTypeTtfFont = 6,
eElemTypeVectorFont = 7,
eElemTypeTextFont = 8,
} eElemType_t;
typedef enum eFontVariant {
eFontVariantNormal = 1,
eFontVariantSmallCaps = 2,
eFontVariantInherit = 3,
} eFontVariant_t;
typedef enum eDisplayAlign {
eDisplayAlignBefore = 1,
eDisplayAlignCenter = 2,
eDisplayAlignAfter = 3,
eDisplayAlignAuto = 1,
} eDisplayAlign_t;
typedef enum eFontFields {
HORIZ_ADV_X = 0,
HORIZ_ORIGIN_X = 1,
ASCENT = 2,
ALPHABETIC = 3,
BBOX = 4,
CAP_HEIGHT = 5,
DESCENT = 6,
FONT_FAMILY = 7,
FONT_SIZE = 8,
FONT_STRETCH = 9,
FONT_STYLE = 10,
FONT_TYPE = 11,
FONT_VARIANT = 12,
FONT_WEIGHT = 13,
SLOPE = 14,
UNICODE_RANGE = 15,
UNITS_PER_EM = 16,
X_HEIGHT = 17,
TEXT_ANCHOR = 18,
MAX_FONT_ATTRIBUTES = 19,
} eFontFields_t;
typedef struct glyph {
uint8_t glyph_name;
uint8_t unicode;
uint32_t horiz_adv_x;
uint32_t path_data_length;
void *path_data;
} glyph_t;
typedef struct glyph_table {
uint32_t offset;
uint32_t size;
} glyph_table_t;
typedef union value_type {
uint32_t i_value;
float f_value;
char *data;
} value_type_t;
typedef struct font_field_info {
value_type_t value;
eFontFields_t eName;
} font_field_info_t;
typedef struct font_fields {
font_field_info_t info;
uint32_t offset;
uint32_t size;
unsigned char *data;
} font_fields_t;
typedef struct vector_font {
uint32_t id;
eElemType_t type;
uint32_t num_fields;
font_fields_t *fields;
glyph_table_t *glyph_table;
glyph_t *glyph_offset;
} vector_font_t;
typedef struct ttf_font {
uint32_t id;
eElemType_t type;
uint32_t num_fields;
font_fields_t *fields;
} ttf_font_t;
typedef struct font_prop {
uint32_t num_props;
font_fields_t *prop_values;
} font_prop_t;
typedef struct font_block {
uint32_t size;
eElemType_t type;
uint32_t num_ttf_fonts;
uint32_t num_vector_fonts;
uint32_t num_text_fonts;
uint32_t ttf_fonts_block_offset;
uint32_t ttf_fonts_block_length;
uint32_t vector_fonts_block_offset;
uint32_t vector_fonts_block_length;
uint32_t text_fonts_block_offset;
uint32_t text_fonts_block_length;
uint32_t property_block_offset;
uint32_t property_block_length;
font_prop_t *font_prop;
unsigned int *sizes_of_ttf_data;
unsigned int *offsets_of_ttf_data;
ttf_font_t *ttf_fonts;
unsigned int *sizes_of_vector_data;
unsigned int *offsets_of_vector_data;
vector_font_t *vector_fonts;
unsigned int *sizes_of_text_font_data;
unsigned int *offsets_of_text_font_data;
ttf_font_t *text_fonts;
} font_block_t;
typedef struct {
el_Object object;
el_Attribute attribute;
el_Attribute defaultAttrib;
uint32_t tspan_has_dx_dy;
uint32_t text_anchor;
uint32_t font_size;
uint32_t font_id;
uint32_t x_pos;
uint32_t y_pos;
unsigned char *msg;
} el_Obj_TEXT;
typedef enum eAppProperties {
eFontNameProperty,
eFontHeightProperty,
eFontWeightProperty,
eFontStretchProperty,
eFontStyleProperty,
eTextColorProperty,
eTextAlignProperty,
eMaxFontProperties,
} eAppProperties_t;
vg_lite_error_t draw_text(el_Obj_Buffer *buff,
el_Obj_EVO *evo, vg_lite_matrix_t *mat);
extern font_block_t *fontblockobj;
int _load_font_data(uint8_t *data);
ElmHandle _load_text_data(uint8_t *data, el_Obj_EVO *evo);
void _unload_text(el_Obj_EVO *evo);
void _init_transform(el_Transform *transform);
void initialize_elm_text(void);
void destroy_font_data();
void _release_default_text_parameters(void);
#ifdef __cplusplus
}
#endif
#endif /* _elm_text_h_ */

View File

@@ -0,0 +1,30 @@
/****************************************************************************
*
* The MIT License (MIT)
*
* Copyright 2020 NXP
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#define ABS_ARY(x) (void *)x, sizeof(x), 0

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_DC_FB_H_
#define _FSL_DC_FB_H_
#include "fsl_video_common.h"
/*!
* @addtogroup dc_fb
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief frame buffer information. */
typedef struct _dc_fb_info
{
uint16_t startX; /*!< The start position in the panel. */
uint16_t startY; /*!< The start position in the panel. */
uint16_t width; /*!< How many pixels in one line of the frame buffer.*/
uint16_t height; /*!< How many lines in one frame buffer. */
uint16_t strideBytes; /*!< Stride of the frame buffer */
video_pixel_format_t pixelFormat; /*!< Pixel format of the frame buffer */
} dc_fb_info_t;
/*! @brief Display controller frame callback. */
typedef void (*dc_fb_callback_t)(void *param, void *inactiveBuffer);
/*! @brief Display controller. */
typedef struct _dc_fb dc_fb_t;
/*! @brief Display controller operations. */
typedef struct _dc_fb_ops
{
status_t (*init)(const dc_fb_t *dc);
status_t (*deinit)(const dc_fb_t *dc);
status_t (*enableLayer)(const dc_fb_t *dc, uint8_t layer);
status_t (*disableLayer)(const dc_fb_t *dc, uint8_t layer);
status_t (*setLayerConfig)(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo);
status_t (*getLayerDefaultConfig)(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo);
status_t (*setFrameBuffer)(const dc_fb_t *dc, uint8_t layer, void *frameBuffer);
uint32_t (*getProperty)(const dc_fb_t *dc);
void (*setCallback)(const dc_fb_t *dc, uint8_t layer, dc_fb_callback_t callback, void *param);
} dc_fb_ops_t;
/*! @brief Display controller property. */
enum _dc_fb_property
{
kDC_FB_ReserveFrameBuffer = (1 << 0), /*< One frame buffer is always used as the DC active buffer. */
kDC_FB_TwoDimensionMemoryWrite = (1 << 1), /*< Support writing memory to device in two dimension way. */
};
/*! @brief Display controller driver handle. */
struct _dc_fb
{
const dc_fb_ops_t *ops; /* Display controller operations. */
void *prvData; /* Private data for the display controller. */
const void *config; /* Configuration for the display controller. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_DC_FB_H_ */

View File

@@ -0,0 +1,264 @@
/*
* Copyright 2019-2020, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_dc_fb_elcdif.h"
/*******************************************************************************
* Definitions
******************************************************************************/
const dc_fb_ops_t g_dcFbOpsElcdif = {
.init = DC_FB_ELCDIF_Init,
.deinit = DC_FB_ELCDIF_Deinit,
.enableLayer = DC_FB_ELCDIF_EnableLayer,
.disableLayer = DC_FB_ELCDIF_DisableLayer,
.setLayerConfig = DC_FB_ELCDIF_SetLayerConfig,
.getLayerDefaultConfig = DC_FB_ELCDIF_GetLayerDefaultConfig,
.setFrameBuffer = DC_FB_ELCDIF_SetFrameBuffer,
.getProperty = DC_FB_ELCDIF_GetProperty,
.setCallback = DC_FB_ELCDIF_SetCallback,
};
typedef struct
{
video_pixel_format_t videoFormat;
elcdif_pixel_format_t elcdifFormat;
} dc_fb_elcdif_pixel_foramt_map_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
static status_t DC_FB_ELCDIF_GetPixelFormat(video_pixel_format_t input, elcdif_pixel_format_t *output);
/*******************************************************************************
* Variables
******************************************************************************/
static const dc_fb_elcdif_pixel_foramt_map_t s_elcdifPixelFormatMap[] = {
{kVIDEO_PixelFormatLUT8, kELCDIF_PixelFormatRAW8},
{kVIDEO_PixelFormatRGB565, kELCDIF_PixelFormatRGB565},
{
kVIDEO_PixelFormatXRGB8888,
kELCDIF_PixelFormatXRGB8888,
},
{
kVIDEO_PixelFormatRGB888,
kELCDIF_PixelFormatRGB888,
}};
/*******************************************************************************
* Code
******************************************************************************/
static status_t DC_FB_ELCDIF_GetPixelFormat(video_pixel_format_t input, elcdif_pixel_format_t *output)
{
uint8_t i;
for (i = 0; i < ARRAY_SIZE(s_elcdifPixelFormatMap); i++)
{
if (s_elcdifPixelFormatMap[i].videoFormat == input)
{
*output = s_elcdifPixelFormatMap[i].elcdifFormat;
return kStatus_Success;
}
}
return kStatus_InvalidArgument;
}
status_t DC_FB_ELCDIF_Init(const dc_fb_t *dc)
{
const dc_fb_elcdif_config_t *dcConfig;
elcdif_rgb_mode_config_t elcdifConfig = {0};
dc_fb_elcdif_handle_t *dcHandle = dc->prvData;
if (0U == dcHandle->initTimes++)
{
dcConfig = (const dc_fb_elcdif_config_t *)(dc->config);
elcdifConfig.panelWidth = dcConfig->width;
elcdifConfig.panelHeight = dcConfig->height;
elcdifConfig.hsw = (uint8_t)dcConfig->hsw;
elcdifConfig.hfp = (uint8_t)dcConfig->hfp;
elcdifConfig.hbp = (uint8_t)dcConfig->hbp;
elcdifConfig.vsw = (uint8_t)dcConfig->vsw;
elcdifConfig.vfp = (uint8_t)dcConfig->vfp;
elcdifConfig.vbp = (uint8_t)dcConfig->vbp;
elcdifConfig.bufferAddr = 0;
elcdifConfig.dataBus = dcConfig->dataBus;
elcdifConfig.pixelFormat = DC_FB_ELCDIF_DEFAULT_PIXEL_FORMAT_ELCDIF;
elcdifConfig.polarityFlags = dcConfig->polarityFlags;
dcHandle->height = dcConfig->height;
dcHandle->width = dcConfig->width;
dcHandle->elcdif = dcConfig->elcdif;
ELCDIF_RgbModeInit(dcHandle->elcdif, &elcdifConfig);
}
return kStatus_Success;
}
status_t DC_FB_ELCDIF_Deinit(const dc_fb_t *dc)
{
dc_fb_elcdif_handle_t *dcHandle = dc->prvData;
if (dcHandle->initTimes > 0U)
{
if ((--dcHandle->initTimes) == 0U)
{
ELCDIF_Deinit(dcHandle->elcdif);
}
}
return kStatus_Success;
}
status_t DC_FB_ELCDIF_EnableLayer(const dc_fb_t *dc, uint8_t layer)
{
assert(layer < DC_FB_ELCDIF_MAX_LAYER);
status_t status = kStatus_Success;
dc_fb_elcdif_handle_t *dcHandle = dc->prvData;
/* If the layer is already started. */
if (!dcHandle->layers[layer].enabled)
{
/* Must have valid frame buffer to show. */
if (dcHandle->layers[layer].activeBuffer == NULL)
{
status = kStatus_Fail;
}
else
{
ELCDIF_RgbModeStart(dcHandle->elcdif);
dcHandle->layers[layer].enabled = true;
ELCDIF_EnableInterrupts(dcHandle->elcdif, (uint32_t)kELCDIF_CurFrameDoneInterruptEnable);
}
}
return status;
}
status_t DC_FB_ELCDIF_DisableLayer(const dc_fb_t *dc, uint8_t layer)
{
assert(layer < DC_FB_ELCDIF_MAX_LAYER);
dc_fb_elcdif_handle_t *dcHandle = dc->prvData;
if (dcHandle->layers[layer].enabled)
{
ELCDIF_RgbModeStop(dcHandle->elcdif);
dcHandle->layers[layer].enabled = false;
ELCDIF_DisableInterrupts(dcHandle->elcdif, (uint32_t)kELCDIF_CurFrameDoneInterruptEnable);
}
return kStatus_Success;
}
status_t DC_FB_ELCDIF_SetLayerConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
{
assert(layer < DC_FB_ELCDIF_MAX_LAYER);
elcdif_pixel_format_t pixelFormat;
status_t status;
dc_fb_elcdif_handle_t *dcHandle = (dc_fb_elcdif_handle_t *)(dc->prvData);
assert(fbInfo->startX == 0U);
assert(fbInfo->startY == 0U);
assert(fbInfo->width == dcHandle->width);
assert(fbInfo->height == dcHandle->height);
assert(fbInfo->strideBytes == VIDEO_GetPixelSizeBits(fbInfo->pixelFormat) * dcHandle->width / 8U);
status = DC_FB_ELCDIF_GetPixelFormat(fbInfo->pixelFormat, &pixelFormat);
if (kStatus_Success != status)
{
return status;
}
ELCDIF_RgbModeSetPixelFormat(dcHandle->elcdif, pixelFormat);
return kStatus_Success;
}
status_t DC_FB_ELCDIF_GetLayerDefaultConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
{
assert(layer < DC_FB_ELCDIF_MAX_LAYER);
dc_fb_elcdif_handle_t *dcHandle = (dc_fb_elcdif_handle_t *)(dc->prvData);
fbInfo->startX = 0;
fbInfo->startY = 0;
fbInfo->width = dcHandle->width;
fbInfo->height = dcHandle->height;
fbInfo->strideBytes = 2U * dcHandle->width;
fbInfo->pixelFormat = DC_FB_ELCDIF_DEFAULT_PIXEL_FORMAT;
return kStatus_Success;
}
status_t DC_FB_ELCDIF_SetFrameBuffer(const dc_fb_t *dc, uint8_t layer, void *frameBuffer)
{
assert(layer < DC_FB_ELCDIF_MAX_LAYER);
dc_fb_elcdif_handle_t *dcHandle = dc->prvData;
ELCDIF_SetNextBufferAddr(dcHandle->elcdif, (uint32_t)(uint8_t *)frameBuffer);
dcHandle->layers[layer].inactiveBuffer = frameBuffer;
/*
* If the layer is not started, set the current buffer and next buffer to
* new frame buffer, there is not pending frame.
* If the layer already started, only set the next buffer, and the new frameBuffer
* is pending until current buffer switched out.
*/
if (!dcHandle->layers[layer].enabled)
{
dcHandle->elcdif->CUR_BUF = ELCDIF_ADDR_CPU_2_IP((uint32_t)(uint8_t *)frameBuffer);
dcHandle->layers[layer].activeBuffer = frameBuffer;
}
else
{
dcHandle->layers[layer].framePending = true;
}
return kStatus_Success;
}
void DC_FB_ELCDIF_SetCallback(const dc_fb_t *dc, uint8_t layer, dc_fb_callback_t callback, void *param)
{
assert(layer < DC_FB_ELCDIF_MAX_LAYER);
dc_fb_elcdif_handle_t *dcHandle = dc->prvData;
dcHandle->layers[layer].callback = callback;
dcHandle->layers[layer].cbParam = param;
}
uint32_t DC_FB_ELCDIF_GetProperty(const dc_fb_t *dc)
{
return (uint32_t)kDC_FB_ReserveFrameBuffer;
}
void DC_FB_ELCDIF_IRQHandler(const dc_fb_t *dc)
{
dc_fb_elcdif_handle_t *dcHandle = dc->prvData;
dc_fb_elcdif_layer_t *layer;
void *oldActiveBuffer;
ELCDIF_ClearInterruptStatus(dcHandle->elcdif, (uint32_t)kELCDIF_CurFrameDone);
for (uint8_t i = 0; i < DC_FB_ELCDIF_MAX_LAYER; i++)
{
if (dcHandle->layers[i].framePending)
{
layer = &dcHandle->layers[i];
oldActiveBuffer = layer->activeBuffer;
layer->activeBuffer = layer->inactiveBuffer;
dcHandle->layers[i].framePending = false;
layer->callback(layer->cbParam, oldActiveBuffer);
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_DC_FB_ELCDIF_H_
#define _FSL_DC_FB_ELCDIF_H_
#include "fsl_dc_fb.h"
#include "fsl_elcdif.h"
/*
* Change log:
*
* 1.0.1
* - Fixed MISRA-C 2012 issues.
*
* 1.0.0
* - Initial version
*/
/*!
* @addtogroup dc_fb_elcdif
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define DC_FB_ELCDIF_MAX_LAYER 1U /* Only support one layer currently. */
#define DC_FB_ELCDIF_DEFAULT_PIXEL_FORMAT kVIDEO_PixelFormatRGB565
#define DC_FB_ELCDIF_DEFAULT_PIXEL_FORMAT_ELCDIF kELCDIF_PixelFormatRGB565
/*! @brief Data for ELCDIF display controller layer. */
typedef struct _dc_fb_elcdif_layer
{
bool enabled; /*!< The layer is enabled. */
volatile bool framePending; /*!< New frame pending. */
void *activeBuffer; /*!< The frame buffer which is shown. */
void *inactiveBuffer; /*!< The frame buffer which will be shown. */
dc_fb_callback_t callback; /*!< Callback for buffer switch off. */
void *cbParam; /*!< Callback parameter. */
} dc_fb_elcdif_layer_t;
/*! @brief Data for ELCDIF display controller driver handle. */
typedef struct _dc_fb_elcdif_handle
{
LCDIF_Type *elcdif; /*!< eLCDIF peripheral. */
uint8_t initTimes; /*!< How many times the DC is initialized. */
uint16_t height; /*!< Panel height. */
uint16_t width; /*!< Panel width. */
dc_fb_elcdif_layer_t layers[DC_FB_ELCDIF_MAX_LAYER]; /*!< Information of the layer. */
} dc_fb_elcdif_handle_t;
/*! @brief Configuration for ELCDIF display controller driver handle. */
typedef struct _dc_fb_elcdif_config
{
LCDIF_Type *elcdif; /*!< ELCDIF peripheral. */
uint16_t width; /*!< Width of the panel. */
uint16_t height; /*!< Height of the panel. */
uint16_t hsw; /*!< HSYNC pulse width. */
uint16_t hfp; /*!< Horizontal front porch. */
uint16_t hbp; /*!< Horizontal back porch. */
uint16_t vsw; /*!< VSYNC pulse width. */
uint16_t vfp; /*!< Vertical front porch. */
uint16_t vbp; /*!< Vertical back porch. */
uint32_t polarityFlags; /*!< Control flags, OR'ed value of @ref _elcdif_polarity_flags. */
elcdif_lcd_data_bus_t dataBus; /*!< LCD data bus. */
} dc_fb_elcdif_config_t;
extern const dc_fb_ops_t g_dcFbOpsElcdif;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
status_t DC_FB_ELCDIF_Init(const dc_fb_t *dc);
status_t DC_FB_ELCDIF_Deinit(const dc_fb_t *dc);
status_t DC_FB_ELCDIF_EnableLayer(const dc_fb_t *dc, uint8_t layer);
status_t DC_FB_ELCDIF_DisableLayer(const dc_fb_t *dc, uint8_t layer);
status_t DC_FB_ELCDIF_SetLayerConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo);
status_t DC_FB_ELCDIF_GetLayerDefaultConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo);
status_t DC_FB_ELCDIF_SetFrameBuffer(const dc_fb_t *dc, uint8_t layer, void *frameBuffer);
uint32_t DC_FB_ELCDIF_GetProperty(const dc_fb_t *dc);
void DC_FB_ELCDIF_SetCallback(const dc_fb_t *dc, uint8_t layer, dc_fb_callback_t callback, void *param);
void DC_FB_ELCDIF_IRQHandler(const dc_fb_t *dc);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_DC_FB_ELCDIF_H_ */

View File

@@ -0,0 +1,288 @@
/*
* Copyright (c) 2019-2020, 2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_dc_fb_lcdifv2.h"
#if defined(SDK_OS_RTOS)
#include "rtthread.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
const dc_fb_ops_t g_dcFbOpsLcdifv2 = {
.init = DC_FB_LCDIFV2_Init,
.deinit = DC_FB_LCDIFV2_Deinit,
.enableLayer = DC_FB_LCDIFV2_EnableLayer,
.disableLayer = DC_FB_LCDIFV2_DisableLayer,
.setLayerConfig = DC_FB_LCDIFV2_SetLayerConfig,
.getLayerDefaultConfig = DC_FB_LCDIFV2_GetLayerDefaultConfig,
.setFrameBuffer = DC_FB_LCDIFV2_SetFrameBuffer,
.getProperty = DC_FB_LCDIFV2_GetProperty,
.setCallback = DC_FB_LCDIFV2_SetCallback,
};
typedef struct
{
video_pixel_format_t videoFormat;
lcdifv2_pixel_format_t lcdifv2Format;
} dc_fb_lcdifv2_pixel_foramt_map_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
static status_t DC_FB_LCDIFV2_GetPixelFormat(video_pixel_format_t input, lcdifv2_pixel_format_t *output);
/*******************************************************************************
* Variables
******************************************************************************/
static const dc_fb_lcdifv2_pixel_foramt_map_t s_lcdifv2PixelFormatMap[] = {
{kVIDEO_PixelFormatRGB565, kLCDIFV2_PixelFormatRGB565},
{kVIDEO_PixelFormatRGB888, kLCDIFV2_PixelFormatRGB888},
{kVIDEO_PixelFormatXRGB8888, kLCDIFV2_PixelFormatARGB8888},
{kVIDEO_PixelFormatXBGR8888, kLCDIFV2_PixelFormatABGR8888},
{kVIDEO_PixelFormatLUT8, kLCDIFV2_PixelFormatIndex8BPP},
{kVIDEO_PixelFormatXRGB4444, kLCDIFV2_PixelFormatARGB4444},
{kVIDEO_PixelFormatXRGB1555, kLCDIFV2_PixelFormatARGB1555}};
/*******************************************************************************
* Code
******************************************************************************/
static status_t DC_FB_LCDIFV2_GetPixelFormat(video_pixel_format_t input, lcdifv2_pixel_format_t *output)
{
uint8_t i;
for (i = 0; i < ARRAY_SIZE(s_lcdifv2PixelFormatMap); i++)
{
if (s_lcdifv2PixelFormatMap[i].videoFormat == input)
{
*output = s_lcdifv2PixelFormatMap[i].lcdifv2Format;
return kStatus_Success;
}
}
return kStatus_InvalidArgument;
}
status_t DC_FB_LCDIFV2_Init(const dc_fb_t *dc)
{
status_t status = kStatus_Success;
const dc_fb_lcdifv2_config_t *dcConfig;
lcdifv2_display_config_t lcdifv2Config = {0};
dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;
if (0U == dcHandle->initTimes++)
{
dcConfig = (const dc_fb_lcdifv2_config_t *)(dc->config);
LCDIFV2_DisplayGetDefaultConfig(&lcdifv2Config);
lcdifv2Config.panelWidth = dcConfig->width;
lcdifv2Config.panelHeight = dcConfig->height;
lcdifv2Config.hsw = (uint8_t)dcConfig->hsw;
lcdifv2Config.hfp = (uint8_t)dcConfig->hfp;
lcdifv2Config.hbp = (uint8_t)dcConfig->hbp;
lcdifv2Config.vsw = (uint8_t)dcConfig->vsw;
lcdifv2Config.vfp = (uint8_t)dcConfig->vfp;
lcdifv2Config.vbp = (uint8_t)dcConfig->vbp;
lcdifv2Config.polarityFlags = dcConfig->polarityFlags;
lcdifv2Config.lineOrder = dcConfig->lineOrder;
dcHandle->height = dcConfig->height;
dcHandle->width = dcConfig->width;
dcHandle->lcdifv2 = dcConfig->lcdifv2;
dcHandle->domain = dcConfig->domain;
LCDIFV2_Init(dcHandle->lcdifv2);
LCDIFV2_SetDisplayConfig(dcHandle->lcdifv2, &lcdifv2Config);
LCDIFV2_EnableInterrupts(dcHandle->lcdifv2, dcHandle->domain, (uint32_t)kLCDIFV2_VerticalBlankingInterrupt);
LCDIFV2_EnableDisplay(dcHandle->lcdifv2, true);
}
return status;
}
status_t DC_FB_LCDIFV2_Deinit(const dc_fb_t *dc)
{
dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;
if (dcHandle->initTimes > 0U)
{
if (--dcHandle->initTimes == 0U)
{
LCDIFV2_DisableInterrupts(dcHandle->lcdifv2, dcHandle->domain,
(uint32_t)kLCDIFV2_VerticalBlankingInterrupt);
LCDIFV2_Deinit(dcHandle->lcdifv2);
}
}
return kStatus_Success;
}
status_t DC_FB_LCDIFV2_EnableLayer(const dc_fb_t *dc, uint8_t layer)
{
assert(layer < DC_FB_LCDIFV2_MAX_LAYER);
status_t status = kStatus_Success;
dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;
/* If the layer is not started. */
if (!dcHandle->layers[layer].enabled)
{
LCDIFV2_SetLayerBackGroundColor(dcHandle->lcdifv2, layer, 0U);
LCDIFV2_EnableLayer(dcHandle->lcdifv2, layer, true);
LCDIFV2_TriggerLayerShadowLoad(dcHandle->lcdifv2, layer);
dcHandle->layers[layer].shadowLoadPending = true;
while (true == dcHandle->layers[layer].shadowLoadPending)
{
#if defined(SDK_OS_RTOS)
rt_thread_delay(1);
#endif
}
dcHandle->layers[layer].activeBuffer = dcHandle->layers[layer].inactiveBuffer;
dcHandle->layers[layer].enabled = true;
}
return status;
}
status_t DC_FB_LCDIFV2_DisableLayer(const dc_fb_t *dc, uint8_t layer)
{
assert(layer < DC_FB_LCDIFV2_MAX_LAYER);
dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;
if (dcHandle->layers[layer].enabled)
{
LCDIFV2_EnableLayer(dcHandle->lcdifv2, layer, false);
LCDIFV2_TriggerLayerShadowLoad(dcHandle->lcdifv2, layer);
dcHandle->layers[layer].enabled = false;
}
return kStatus_Success;
}
status_t DC_FB_LCDIFV2_SetLayerConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
{
assert(layer < DC_FB_LCDIFV2_MAX_LAYER);
lcdifv2_buffer_config_t bufferConfig = {0};
lcdifv2_pixel_format_t pixelFormat;
LCDIFV2_Type *lcdifv2;
status_t status;
dc_fb_lcdifv2_handle_t *dcHandle = (dc_fb_lcdifv2_handle_t *)(dc->prvData);
lcdifv2 = dcHandle->lcdifv2;
status = DC_FB_LCDIFV2_GetPixelFormat(fbInfo->pixelFormat, &pixelFormat);
if (kStatus_Success != status)
{
return status;
}
LCDIFV2_SetLayerSize(lcdifv2, layer, fbInfo->width, fbInfo->height);
LCDIFV2_SetLayerOffset(lcdifv2, layer, fbInfo->startX, fbInfo->startY);
bufferConfig.strideBytes = fbInfo->strideBytes;
bufferConfig.pixelFormat = pixelFormat;
LCDIFV2_SetLayerBufferConfig(lcdifv2, layer, &bufferConfig);
return kStatus_Success;
}
status_t DC_FB_LCDIFV2_GetLayerDefaultConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
{
assert(layer < DC_FB_LCDIFV2_MAX_LAYER);
dc_fb_lcdifv2_handle_t *dcHandle = (dc_fb_lcdifv2_handle_t *)(dc->prvData);
fbInfo->startX = 0;
fbInfo->startY = 0;
fbInfo->width = dcHandle->width;
fbInfo->height = dcHandle->height;
fbInfo->strideBytes = DC_FB_LCDIFV2_DEFAULT_BYTE_PER_PIXEL * dcHandle->width;
fbInfo->pixelFormat = DC_FB_LCDIFV2_DEFAULT_PIXEL_FORMAT;
return kStatus_Success;
}
status_t DC_FB_LCDIFV2_SetFrameBuffer(const dc_fb_t *dc, uint8_t layer, void *frameBuffer)
{
assert(layer < DC_FB_LCDIFV2_MAX_LAYER);
dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;
LCDIFV2_SetLayerBufferAddr(dcHandle->lcdifv2, layer, (uint32_t)(uint8_t *)frameBuffer);
dcHandle->layers[layer].inactiveBuffer = frameBuffer;
if (dcHandle->layers[layer].enabled)
{
LCDIFV2_TriggerLayerShadowLoad(dcHandle->lcdifv2, layer);
dcHandle->layers[layer].shadowLoadPending = true;
dcHandle->layers[layer].framePending = true;
}
else
{
}
return kStatus_Success;
}
void DC_FB_LCDIFV2_SetCallback(const dc_fb_t *dc, uint8_t layer, dc_fb_callback_t callback, void *param)
{
assert(layer < DC_FB_LCDIFV2_MAX_LAYER);
dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;
dcHandle->layers[layer].callback = callback;
dcHandle->layers[layer].cbParam = param;
}
uint32_t DC_FB_LCDIFV2_GetProperty(const dc_fb_t *dc)
{
return (uint32_t)kDC_FB_ReserveFrameBuffer;
}
void DC_FB_LCDIFV2_IRQHandler(const dc_fb_t *dc)
{
uint32_t intStatus;
dc_fb_lcdifv2_handle_t *dcHandle = dc->prvData;
dc_fb_lcdifv2_layer_t *layer;
void *oldActiveBuffer;
intStatus = LCDIFV2_GetInterruptStatus(dcHandle->lcdifv2, dcHandle->domain);
LCDIFV2_ClearInterruptStatus(dcHandle->lcdifv2, dcHandle->domain, intStatus);
if (0U == (intStatus & (uint32_t)kLCDIFV2_VerticalBlankingInterrupt))
{
return;
}
for (uint8_t i = 0; i < DC_FB_LCDIFV2_MAX_LAYER; i++)
{
if (dcHandle->layers[i].shadowLoadPending)
{
dcHandle->layers[i].shadowLoadPending = false;
}
if (dcHandle->layers[i].framePending)
{
layer = &dcHandle->layers[i];
oldActiveBuffer = layer->activeBuffer;
layer->activeBuffer = layer->inactiveBuffer;
dcHandle->layers[i].framePending = false;
layer->callback(layer->cbParam, oldActiveBuffer);
}
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2019-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_DC_FB_LCDIFV2_H_
#define _FSL_DC_FB_LCDIFV2_H_
#include "fsl_dc_fb.h"
#include "fsl_lcdifv2.h"
/*
* Change log:
*
* 1.0.2
* - Add more pixel format support.
*
* 1.0.1
* - Fix MISRA-C 2012 issues.
*
* 1.0.0
* - Initial version
*/
/*!
* @addtogroup dc_fb_lcdifv2
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define DC_FB_LCDIFV2_MAX_LAYER ((uint32_t)LCDIFV2_LAYER_COUNT)
#define DC_FB_LCDIFV2_DEFAULT_BUF_PER_LAYER 3U
#define DC_FB_LCDIFV2_DEFAULT_PIXEL_FORMAT kVIDEO_PixelFormatRGB565
#define DC_FB_LCDIFV2_DEFAULT_PIXEL_FORMAT_LCDIFV2 kLCDIFV2_PixelFormatRGB565
#define DC_FB_LCDIFV2_DEFAULT_BYTE_PER_PIXEL 2U
/*! @brief Data for LCDIFV2 display controller layer. */
typedef struct _dc_fb_lcdifv2_layer
{
bool enabled; /*!< The layer is enabled. */
volatile bool framePending; /*!< New frame pending. */
volatile bool shadowLoadPending; /*!< Shadow load pending. */
void *activeBuffer; /*!< The frame buffer which is shown. */
void *inactiveBuffer; /*!< The frame buffer which will be shown. */
dc_fb_callback_t callback; /*!< Callback for buffer switch off. */
void *cbParam; /*!< Callback parameter. */
} dc_fb_lcdifv2_layer_t;
/*! @brief Data for LCDIFV2 display controller driver handle. */
typedef struct _dc_fb_lcdifv2_handle
{
LCDIFV2_Type *lcdifv2; /*!< LCDIFV2 peripheral. */
uint8_t initTimes; /*!< How many times the DC is initialized. */
uint16_t height; /*!< Panel height. */
uint16_t width; /*!< Panel width. */
uint8_t domain; /*!< Domain used for interrupt. */
dc_fb_lcdifv2_layer_t layers[DC_FB_LCDIFV2_MAX_LAYER]; /*!< Information of the layer. */
} dc_fb_lcdifv2_handle_t;
/*! @brief Configuration for LCDIFV2 display controller driver handle. */
typedef struct _dc_fb_lcdifv2_config
{
LCDIFV2_Type *lcdifv2; /*!< LCDIFV2 peripheral. */
uint16_t width; /*!< Width of the panel. */
uint16_t height; /*!< Height of the panel. */
uint16_t hsw; /*!< HSYNC pulse width. */
uint16_t hfp; /*!< Horizontal front porch. */
uint16_t hbp; /*!< Horizontal back porch. */
uint16_t vsw; /*!< VSYNC pulse width. */
uint16_t vfp; /*!< Vertical front porch. */
uint16_t vbp; /*!< Vertical back porch. */
uint32_t polarityFlags; /*!< Control flags, OR'ed value of @ref _lcdifv2_polarity_flags. */
lcdifv2_line_order_t lineOrder; /*!< Line order. */
uint8_t domain; /*!< Domain used to for interrupt. */
} dc_fb_lcdifv2_config_t;
extern const dc_fb_ops_t g_dcFbOpsLcdifv2;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
status_t DC_FB_LCDIFV2_Init(const dc_fb_t *dc);
status_t DC_FB_LCDIFV2_Deinit(const dc_fb_t *dc);
status_t DC_FB_LCDIFV2_EnableLayer(const dc_fb_t *dc, uint8_t layer);
status_t DC_FB_LCDIFV2_DisableLayer(const dc_fb_t *dc, uint8_t layer);
status_t DC_FB_LCDIFV2_SetLayerConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo);
status_t DC_FB_LCDIFV2_GetLayerDefaultConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo);
status_t DC_FB_LCDIFV2_SetFrameBuffer(const dc_fb_t *dc, uint8_t layer, void *frameBuffer);
uint32_t DC_FB_LCDIFV2_GetProperty(const dc_fb_t *dc);
void DC_FB_LCDIFV2_SetCallback(const dc_fb_t *dc, uint8_t layer, dc_fb_callback_t callback, void *param);
void DC_FB_LCDIFV2_IRQHandler(const dc_fb_t *dc);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_DC_FB_LCDIFV2_H_ */

View File

@@ -0,0 +1,140 @@
/*
* Copyright 2017-2018 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_DISPLAY_H_
#define _FSL_DISPLAY_H_
#include "fsl_video_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Display common configuration. */
typedef struct _display_common_cfg_t
{
uint16_t width;
uint16_t height;
uint16_t hsw; /*!< HSYNC pulse width. */
uint16_t hfp; /*!< Horizontal front porch. */
uint16_t hbp; /*!< Horizontal back porch. */
uint16_t vsw; /*!< VSYNC pulse width. */
uint16_t vfp; /*!< Vrtical front porch. */
uint16_t vbp; /*!< Vertical back porch. */
uint32_t clock; /* !< pixecl clock in kHz>. */
} display_common_cfg;
/*! @brief Display control flags. */
enum _display_flags
{
kDISPLAY_VsyncActiveLow = 0U, /*!< VSYNC active low. */
kDISPLAY_VsyncActiveHigh = (1U << 0U), /*!< VSYNC active high. */
kDISPLAY_HsyncActiveLow = 0U, /*!< HSYNC active low. */
kDISPLAY_HsyncActiveHigh = (1U << 1U), /*!< HSYNC active high. */
kDISPLAY_DataEnableActiveHigh = 0U, /*!< Data enable line active high. */
kDISPLAY_DataEnableActiveLow = (1U << 2U), /*!< Data enable line active low. */
kDISPLAY_DataLatchOnRisingEdge = 0U, /*!< Latch data on rising clock edge. */
kDISPLAY_DataLatchOnFallingEdge = (1U << 3U), /*!< Latch data on falling clock edge. */
};
/*! @brief Display configuration. */
typedef struct _display_config
{
uint32_t resolution; /*!< Resolution, see @ref video_resolution_t and @ref FSL_VIDEO_RESOLUTION. */
uint16_t hsw; /*!< HSYNC pulse width. */
uint16_t hfp; /*!< Horizontal front porch. */
uint16_t hbp; /*!< Horizontal back porch. */
uint16_t vsw; /*!< VSYNC pulse width. */
uint16_t vfp; /*!< Vrtical front porch. */
uint16_t vbp; /*!< Vertical back porch. */
uint32_t controlFlags; /*!< Control flags, OR'ed value of @ref _display_flags. */
uint8_t dsiLanes; /*!< MIPI DSI data lanes number. */
uint32_t pixelClock_Hz; /*!< Pixel clock in Hz. */
video_pixel_format_t pixelFormat; /*!< Pixel format. */
} display_config_t;
typedef struct _display_handle display_handle_t;
/*! @brief Display device operations. */
typedef struct _display_operations
{
status_t (*init)(display_handle_t *handle, const display_config_t *config); /*!< Init the device. */
status_t (*deinit)(display_handle_t *handle); /*!< Deinit the device. */
status_t (*start)(display_handle_t *handle); /*!< Start the device. */
status_t (*stop)(display_handle_t *handle); /*!< Stop the device. */
} display_operations_t;
/*! @brief Display handle. */
struct _display_handle
{
const void *resource;
const display_operations_t *ops;
uint16_t width;
uint16_t height;
video_pixel_format_t pixelFormat;
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initializes the display device with user defined configuration.
*
* @param handle Display device handle.
* @param config Pointer to the user-defined configuration structure.
* @return Returns @ref kStatus_Success if initialize success, otherwise returns
* error code.
*/
static inline status_t DISPLAY_Init(display_handle_t *handle, const display_config_t *config)
{
return handle->ops->init(handle, config);
}
/*!
* @brief Deinitialize the display device.
*
* @param handle Display device handle.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
static inline status_t DISPLAY_Deinit(display_handle_t *handle)
{
return handle->ops->deinit(handle);
}
/*!
* @brief Start the display device.
*
* @param handle Display device handle.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
static inline status_t DISPLAY_Start(display_handle_t *handle)
{
return handle->ops->start(handle);
}
/*!
* @brief Stop the display device.
*
* @param handle Display device handle.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
static inline status_t DISPLAY_Stop(display_handle_t *handle)
{
return handle->ops->stop(handle);
}
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_DISPLAY_H_ */

View File

@@ -0,0 +1,243 @@
/*
* Copyright 2019-2021, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_fbdev.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static void FBDEV_BufferSwitchOffCallback(void *param, void *switchOffBuffer);
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
status_t FBDEV_Open(fbdev_t *fbdev, const dc_fb_t *dc, uint8_t layer)
{
status_t status;
assert(NULL != fbdev);
(void)memset(fbdev, 0, sizeof(fbdev_t));
fbdev->dc = dc;
(void)VIDEO_STACK_Init(&fbdev->fbManager, fbdev->buffers, FBDEV_MAX_FRAME_BUFFER);
/* Initialize the display controller. */
status = dc->ops->init(dc);
if (kStatus_Success != status)
{
return status;
}
fbdev->layer = layer;
/* Initializes the dc_fb_info_t to the display controller default setting. */
status = dc->ops->getLayerDefaultConfig(dc, layer, &fbdev->fbInfo.bufInfo);
if (kStatus_Success != status)
{
return status;
}
fbdev->semaFramePending = rt_sem_create("fsfp", 0, RT_IPC_FLAG_PRIO);
if (NULL == fbdev->semaFramePending)
{
return kStatus_Fail;
}
/* No frame pending. */
(void)rt_sem_release(fbdev->semaFramePending);
dc->ops->setCallback(dc, layer, FBDEV_BufferSwitchOffCallback, (void *)fbdev);
return kStatus_Success;
}
status_t FBDEV_Close(fbdev_t *fbdev)
{
const dc_fb_t *dc = fbdev->dc;
(void)dc->ops->deinit(dc);
if (NULL != fbdev->semaFbManager)
{
rt_sem_delete(fbdev->semaFbManager);
fbdev->semaFbManager = NULL;
}
if (NULL != fbdev->semaFramePending)
{
rt_sem_delete(fbdev->semaFramePending);
fbdev->semaFramePending = NULL;
}
return kStatus_Success;
}
status_t FBDEV_Enable(fbdev_t *fbdev)
{
status_t status = kStatus_Success;
const dc_fb_t *dc = fbdev->dc;
if (!fbdev->enabled)
{
/* Wait for frame buffer sent to display controller video memory. */
if ((dc->ops->getProperty(dc) & (uint32_t)kDC_FB_ReserveFrameBuffer) == 0U)
{
if (RT_EOK != rt_sem_take(fbdev->semaFramePending, RT_WAITING_FOREVER))
{
status = kStatus_Fail;
}
}
if (kStatus_Success == status)
{
/* No frame is pending. */
(void)rt_sem_release(fbdev->semaFramePending);
status = dc->ops->enableLayer(dc, fbdev->layer);
if (kStatus_Success == status)
{
fbdev->enabled = true;
}
}
}
return status;
}
status_t FBDEV_Disable(fbdev_t *fbdev)
{
status_t status = kStatus_Success;
const dc_fb_t *dc = fbdev->dc;
if (!fbdev->enabled)
{
/* Wait until no frame pending. */
if (RT_EOK != rt_sem_take(fbdev->semaFramePending, RT_WAITING_FOREVER))
{
status = kStatus_Fail;
}
if (kStatus_Success == status)
{
(void)rt_sem_release(fbdev->semaFramePending);
(void)dc->ops->disableLayer(dc, fbdev->layer);
fbdev->enabled = false;
}
}
return status;
}
void FBDEV_GetFrameBufferInfo(fbdev_t *fbdev, fbdev_fb_info_t *info)
{
*info = fbdev->fbInfo;
}
status_t FBDEV_SetFrameBufferInfo(fbdev_t *fbdev, fbdev_fb_info_t *info)
{
status_t status;
const dc_fb_t *dc = fbdev->dc;
/* Should only change the frame buffer setting before enabling the fbdev. */
if (fbdev->enabled)
{
return kStatus_Fail;
}
fbdev->fbInfo = *info;
status = dc->ops->setLayerConfig(dc, fbdev->layer, &fbdev->fbInfo.bufInfo);
if (kStatus_Success != status)
{
return status;
}
fbdev->semaFbManager = rt_sem_create("fsfm", 0, RT_IPC_FLAG_PRIO);
if (NULL == fbdev->semaFbManager)
{
return kStatus_Fail;
}
for (uint8_t i = 0; i < info->bufferCount; i++)
{
/* Don't need to disable interrupt for the FB stack operation, because
the fbdev is not working, this is the only function to access FB stack.
*/
(void)VIDEO_STACK_Push(&fbdev->fbManager, info->buffers[i]);
(void)rt_sem_release(fbdev->semaFbManager);
}
return kStatus_Success;
}
void *FBDEV_GetFrameBuffer(fbdev_t *fbdev, uint32_t flags)
{
rt_uint32_t tick;
void *fb;
tick = ((flags & (uint32_t)kFBDEV_NoWait) != 0U) ? 0U : RT_WAITING_FOREVER;
if (RT_EOK == rt_sem_take(fbdev->semaFbManager, tick))
{
/* Disable interrupt to protect the FB stack. */
rt_enter_critical();
(void)VIDEO_STACK_Pop(&fbdev->fbManager, &fb);
rt_exit_critical();
}
else
{
fb = NULL;
}
return fb;
}
status_t FBDEV_SetFrameBuffer(fbdev_t *fbdev, void *frameBuffer, uint32_t flags)
{
rt_uint32_t tick;
const dc_fb_t *dc = fbdev->dc;
tick = ((flags & (uint32_t)kFBDEV_NoWait) != 0U) ? 0U : RT_WAITING_FOREVER;
if (RT_EOK == rt_sem_take(fbdev->semaFramePending, tick))
{
return dc->ops->setFrameBuffer(dc, fbdev->layer, frameBuffer);
}
else
{
return kStatus_Fail;
}
}
static void FBDEV_BufferSwitchOffCallback(void *param, void *switchOffBuffer)
{
fbdev_t *fbdev = (fbdev_t *)param;
/* This function should only be called in ISR, so don't need to protect the FB stack */
(void)VIDEO_STACK_Push(&fbdev->fbManager, switchOffBuffer);
rt_sem_release(fbdev->semaFbManager);
rt_sem_release(fbdev->semaFramePending);
}

View File

@@ -0,0 +1,227 @@
/*
* Copyright 2019-2021, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_FBDEV_H_
#define _FSL_FBDEV_H_
#include "fsl_video_common.h"
#include "fsl_dc_fb.h"
#include "rtthread.h"
/*
* Change Log:
*
* 1.0.3:
* - Bug Fixes:
* - Fixed the issue that frame buffer content changed when saved
* to free frame buffer list.
*
* 1.0.2:
* - Bug Fixes:
* - Fixed MISRA 2012 issues.
*
* 1.0.1:
* - Bug Fixes:
* - Fixed coverity warnings that return values unchedked.
*
* 1.0.0:
* - Initial version.
*/
/*!
* @addtogroup fbdev
* @{
*
* To use the fbdev, follow the workflow:
*
@code
uint8_t layer = 0;
fbdev_t fbdev;
fbdev_fb_info_t fbInfo;
extern const dc_fb_t dc;
FBDEV_Open(&fbdev, &dc, layer);
fbInfo.bufInfo.pixelFormat = DEMO_BUFFER_PIXEL_FORMAT;
fbInfo.bufInfo.width = DEMO_BUFFER_WIDTH;
fbInfo.bufInfo.height = DEMO_BUFFER_HEIGHT;
fbInfo.bufInfo.strideBytes = DEMO_BUFFER_STRIDE_BYTE;
fbInfo.buffers[0] = DEMO_BUFFER0_ADDR;
fbInfo.buffers[1] = DEMO_BUFFER1_ADDR;
FBDEV_SetFrameBufferInfo(&fbdev, &fbInfo);
buffer = FBDEV_GetFrameBuffer(&fbdev, 0);
fill the buffer here.
FBDEV_SetFrameBuffer(&fbdev, buffer, 0);
FBDEV_Enable(&fbdev);
buffer = FBDEV_GetFrameBuffer(&fbdev, 0);
fill the buffer here.
FBDEV_SetFrameBuffer(&fbdev, buffer, 0);
...
@endcode
*
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief How many frame buffers used in each fbdev. */
#ifndef FBDEV_MAX_FRAME_BUFFER
#define FBDEV_MAX_FRAME_BUFFER 3
#endif
#define FBDEV_DEFAULT_FRAME_BUFFER 2
/*! @brief Frame buffer information. */
typedef struct _fbdev_fb_info
{
uint8_t bufferCount; /*!< How many frame buffers used. */
void *buffers[FBDEV_MAX_FRAME_BUFFER]; /*!< Address of the frame buffers */
dc_fb_info_t bufInfo; /*!< Frame buffers information */
} fbdev_fb_info_t;
/*! @brief FBDEV handle, user should not touch the members directly. */
typedef struct _fbdev
{
fbdev_fb_info_t fbInfo; /*!< Frame buffer information. */
video_stack_t fbManager; /*!< Manage the framebuffers used by this device. */
void *buffers[FBDEV_MAX_FRAME_BUFFER]; /*!< Memory used by @ref fbManager, to save the free frame buffers. */
const dc_fb_t *dc; /*!< Display controller handle. */
uint8_t layer; /*!< Layer in the display controller. */
bool enabled; /*!< The fbdev is enabled or not by @ref FBDEV_Enable. */
rt_sem_t semaFbManager; /*!< Semaphore for the @ref fbManager. */
rt_sem_t semaFramePending; /*!< Semaphore for the @ref framePending. */
} fbdev_t;
/*! @brief Flags used for FBDEV operations. */
enum _fbdev_flag
{
kFBDEV_NoWait = (1 << 0), /*!< Don't wait until available, but return directly. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Open the FBDEV.
*
* @param fbdev The FBDEV handle.
* @param dc The display controller used.
* @param layer The layer in the display controller.
* @return Returns @ref kStatus_Success if success, otherwise returns
* error code.
*/
status_t FBDEV_Open(fbdev_t *fbdev, const dc_fb_t *dc, uint8_t layer);
/*!
* @brief Close the FBDEV.
*
* @param fbdev The FBDEV handle.
* @return Returns @ref kStatus_Success if success, otherwise returns
* error code.
*/
status_t FBDEV_Close(fbdev_t *fbdev);
/*!
* @brief Enable the FBDEV.
*
* After enabled, the FBDEV will be shown in the panel. This function should be
* called after @ref FBDEV_SetFrameBufferInfo.
*
* @param fbdev The FBDEV handle.
* @return Returns @ref kStatus_Success if success, otherwise returns
* error code.
*/
status_t FBDEV_Enable(fbdev_t *fbdev);
/*!
* @brief Disable the FBDEV.
*
* After disabled, the FBDEV will not be shown in the panel. Don't call
* @ref FBDEV_SetFrameBuffer when the FBDEV is disabled.
*
* @param fbdev The FBDEV handle.
* @return Returns @ref kStatus_Success if success, otherwise returns
* error code.
*/
status_t FBDEV_Disable(fbdev_t *fbdev);
/*!
* @brief Get the frame buffer information of the FBDEV.
*
* @param fbdev The FBDEV handle.
* @param info Pointer to the frame buffer information.
*/
void FBDEV_GetFrameBufferInfo(fbdev_t *fbdev, fbdev_fb_info_t *info);
/*!
* @brief Set the frame buffer information of the FBDEV.
*
* This function could be used to configure the FRDEV, including set witdh, height,
* pixel format, frame buffers, and so on. This function should only be called once
* after @ref FBDEV_Open and before @ref FBDEV_Enable.
*
* @param fbdev The FBDEV handle.
* @param info Pointer to the frame buffer information.
* @return Returns @ref kStatus_Success if success, otherwise returns
* error code.
*/
status_t FBDEV_SetFrameBufferInfo(fbdev_t *fbdev, fbdev_fb_info_t *info);
/*!
* @brief Get available frame buffer from the FBDEV.
*
* Upper layer could call this function to get an available frame buffer from
* the FBDEV, render send to show.
*
* @param fbdev The FBDEV handle.
* @param flags OR'ed value of @ref _fbdev_flag. If @ref kFBDEV_NoWait is used,
* the function returns NULL immediately if no available buffer. If @ref kFBDEV_NoWait
* is not used, this function waits until available.
*
* @return Returns the address of the frame buffer. If no available, returns NULL.
*/
void *FBDEV_GetFrameBuffer(fbdev_t *fbdev, uint32_t flags);
/*!
* @brief Send frame buffer to the FBDEV.
*
* Upper layer could call this function to send a frame buffer to the FBDEV. This
* function should only be used when the FBDEV is enabled.
*
* @param fbdev The FBDEV handle.
* @param flags OR'ed value of @ref _fbdev_flag. If @ref kFBDEV_NoWait is used,
* the function returns NULL immediately if the previous frame buffer is pending.
* If @ref kFBDEV_NoWait is not used, this function waits until previous frame
* buffer not pending.
*
* @return Returns @ref kStatus_Success if success, otherwise returns
* error code.
*/
status_t FBDEV_SetFrameBuffer(fbdev_t *fbdev, void *frameBuffer, uint32_t flags);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_FBDEV_H_ */

View File

@@ -0,0 +1,187 @@
/*
* Copyright 2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_display.h"
#include "fsl_hx8394.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define HX8394_DelayMs VIDEO_DelayMs
typedef struct
{
const uint8_t *cmd;
uint8_t cmdLen;
} hx8394_cmd_t;
/*******************************************************************************
* Variables
******************************************************************************/
const display_operations_t hx8394_ops = {
.init = HX8394_Init,
.deinit = HX8394_Deinit,
.start = HX8394_Start,
.stop = HX8394_Stop,
};
static const hx8394_cmd_t s_hx8394Cmds[] = {
{(const uint8_t[]){0x36U, 0x02U}, 2U},
{(const uint8_t[]){0xB1U, 0x48U, 0x12U, 0x72U, 0x09U, 0x32U, 0x54U, 0x71U, 0x71U, 0x57U, 0x47U}, 11U},
{(const uint8_t[]){0xB2U, 0x00U, 0x80U, 0x64U, 0x0CU, 0x0DU, 0x2FU}, 7U},
{(const uint8_t[]){0xB4U, 0x73U, 0x74U, 0x73U, 0x74U, 0x73U, 0x74U, 0x01U, 0x0CU, 0x86U, /* 10 */
0x75U, 0x00U, 0x3FU, 0x73U, 0x74U, 0x73U, 0x74U, 0x73U, 0x74U, 0x01U, /* 20 */
0x0CU, 0x86U},
22U},
{(const uint8_t[]){0xD3U, 0x00U, 0x00U, 0x07U, 0x07U, 0x40U, 0x07U, 0x0CU, 0x00U, 0x08U, /* 10 */
0x10U, 0x08U, 0x00U, 0x08U, 0x54U, 0x15U, 0x0AU, 0x05U, 0x0AU, 0x02U, /* 20 */
0x15U, 0x06U, 0x05U, 0x06U, 0x47U, 0x44U, 0x0AU, 0x0AU, 0x4BU, 0x10U, /* 30 */
0x07U, 0x07U, 0x0CU, 0x40U},
34U},
{(const uint8_t[]){0xD5U, 0x1CU, 0x1CU, 0x1DU, 0x1DU, 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, /* 10 */
0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0AU, 0x0BU, 0x24U, 0x25U, 0x18U, /* 20 */
0x18U, 0x26U, 0x27U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, /* 30 */
0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x20U, /* 40 */
0x21U, 0x18U, 0x18U, 0x18U, 0x18U},
45U},
{(const uint8_t[]){0xD6U, 0x1CU, 0x1CU, 0x1DU, 0x1DU, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, /* 10 */
0x02U, 0x01U, 0x00U, 0x0BU, 0x0AU, 0x09U, 0x08U, 0x21U, 0x20U, 0x18U, /* 20 */
0x18U, 0x27U, 0x26U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, /* 30 */
0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x18U, 0x25U, /* 40 */
0x24U, 0x18U, 0x18U, 0x18U, 0x18U},
45U},
{(const uint8_t[]){0xB6U, 0x92U, 0x92U}, 3U},
{(const uint8_t[]){0xE0U, 0x00U, 0x0AU, 0x15U, 0x1BU, 0x1EU, 0x21U, 0x24U, 0x22U, 0x47U, /* 10 */
0x56U, 0x65U, 0x66U, 0x6EU, 0x82U, 0x88U, 0x8BU, 0x9AU, 0x9DU, 0x98U, /* 20 */
0xA8U, 0xB9U, 0x5DU, 0x5CU, 0x61U, 0x66U, 0x6AU, 0x6FU, 0x7FU, 0x7FU, /* 30 */
0x00U, 0x0AU, 0x15U, 0x1BU, 0x1EU, 0x21U, 0x24U, 0x22U, 0x47U, 0x56U, /* 40 */
0x65U, 0x65U, 0x6EU, 0x81U, 0x87U, 0x8BU, 0x98U, 0x9DU, 0x99U, 0xA8U, /* 50 */
0xBAU, 0x5DU, 0x5DU, 0x62U, 0x67U, 0x6BU, 0x72U, 0x7FU, 0x7FU},
59U},
{(const uint8_t[]){0xC0U, 0x1FU, 0x31U}, 3U},
{(const uint8_t[]){0xCCU, 0x03U}, 2U},
{(const uint8_t[]){0xD4U, 0x02U}, 2U},
{(const uint8_t[]){0xBDU, 0x02U}, 2U},
{(const uint8_t[]){0xD8U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, /* 10 */
0xFFU, 0xFFU, 0xFFU},
13U},
{(const uint8_t[]){0xBDU, 0x00U}, 2U},
{(const uint8_t[]){0xBDU, 0x01U}, 2U},
{(const uint8_t[]){0xB1U, 0x00U}, 2U},
{(const uint8_t[]){0xBDU, 0x00U}, 2U},
{(const uint8_t[]){0xBFU, 0x40U, 0x81U, 0x50U, 0x00U, 0x1AU, 0xFCU, 0x01}, 8U},
{(const uint8_t[]){0xC6U, 0xEDU}, 2U},
{(const uint8_t[]){0x35U, 0x00U}, 2U},
};
/*******************************************************************************
* Code
******************************************************************************/
status_t HX8394_Init(display_handle_t *handle, const display_config_t *config)
{
uint8_t i;
status_t status = kStatus_Success;
const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
uint8_t setmipi[7] = {0xBAU, 0x60U, 0x03U, 0x68U, 0x6BU, 0xB2U, 0xC0U};
/* Only support 720 * 1280 */
if (config->resolution != FSL_VIDEO_RESOLUTION(720, 1280))
{
return kStatus_InvalidArgument;
}
/* Power on. */
resource->pullPowerPin(true);
HX8394_DelayMs(1);
/* Perform reset. */
resource->pullResetPin(false);
HX8394_DelayMs(1);
resource->pullResetPin(true);
HX8394_DelayMs(50U);
status = MIPI_DSI_GenericWrite(dsiDevice, (const uint8_t[]){0xB9U, 0xFFU, 0x83U, 0x94U}, 4);
setmipi[1] |= (config->dsiLanes - 1U);
if (kStatus_Success == status)
{
status = MIPI_DSI_GenericWrite(dsiDevice, setmipi, 7);
}
if (kStatus_Success == status)
{
for (i = 0; i < ARRAY_SIZE(s_hx8394Cmds); i++)
{
status = MIPI_DSI_GenericWrite(dsiDevice, s_hx8394Cmds[i].cmd, (int32_t)s_hx8394Cmds[i].cmdLen);
if (kStatus_Success != status)
{
break;
}
}
}
if (kStatus_Success == status)
{
status = MIPI_DSI_DCS_EnterSleepMode(dsiDevice, false);
}
if (kStatus_Success == status)
{
HX8394_DelayMs(120U);
status = MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
}
return status;
}
status_t HX8394_Deinit(display_handle_t *handle)
{
const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
(void)MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
resource->pullResetPin(false);
resource->pullPowerPin(false);
return kStatus_Success;
}
status_t HX8394_Start(display_handle_t *handle)
{
const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
}
status_t HX8394_Stop(display_handle_t *handle)
{
const hx8394_resource_t *resource = (const hx8394_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_HX8394_H_
#define _FSL_HX8394_H_
#include "fsl_display.h"
#include "fsl_mipi_dsi_cmd.h"
/*
* Change log:
*
* 1.0.0
* - Initial version
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @brief HX8394 resource.
*/
typedef struct _hx8394_resource
{
mipi_dsi_device_t *dsiDevice; /*!< MIPI DSI device. */
void (*pullResetPin)(bool pullUp); /*!< Function to pull reset pin high or low. */
void (*pullPowerPin)(bool pullUp); /*!< Function to pull power pin high or low. */
} hx8394_resource_t;
extern const display_operations_t hx8394_ops;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
status_t HX8394_Init(display_handle_t *handle, const display_config_t *config);
status_t HX8394_Deinit(display_handle_t *handle);
status_t HX8394_Start(display_handle_t *handle);
status_t HX8394_Stop(display_handle_t *handle);
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_HX8394_H_ */

View File

@@ -0,0 +1,351 @@
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_mipi_dsi_cmd.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
status_t MIPI_DSI_DCS_SoftReset(mipi_dsi_device_t *device)
{
dsi_transfer_t dsiXfer = {0};
uint8_t txData = (uint8_t)kMIPI_DCS_SoftReset;
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
dsiXfer.txDataSize = 1;
dsiXfer.txData = &txData;
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_SetDisplayOn(mipi_dsi_device_t *device, bool on)
{
dsi_transfer_t dsiXfer = {0};
uint8_t txData;
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
dsiXfer.txDataSize = 1;
dsiXfer.txData = &txData;
if (on)
{
txData = (uint8_t)kMIPI_DCS_SetDisplayOn;
}
else
{
txData = (uint8_t)kMIPI_DCS_SetDisplayOff;
}
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_SetPixelFormat(mipi_dsi_device_t *device,
mipi_dsc_pixel_format_t dbiFormat,
mipi_dsc_pixel_format_t dpiFormat)
{
dsi_transfer_t dsiXfer = {0};
uint8_t txData[2];
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsShortWrOneParam;
dsiXfer.txDataSize = 2;
dsiXfer.txData = txData;
txData[0] = (uint8_t)kMIPI_DCS_SetPixelFormat;
txData[1] = ((uint8_t)dbiFormat << 0U) | ((uint8_t)dpiFormat << 4U);
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_EnterSleepMode(mipi_dsi_device_t *device, bool enter)
{
dsi_transfer_t dsiXfer = {0};
uint8_t txData;
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
dsiXfer.txDataSize = 1;
dsiXfer.txData = &txData;
if (enter)
{
txData = (uint8_t)kMIPI_DCS_EnterSleepMode;
}
else
{
txData = (uint8_t)kMIPI_DCS_ExitSleepMode;
}
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_EnterPartialMode(mipi_dsi_device_t *device, bool enter)
{
dsi_transfer_t dsiXfer = {0};
uint8_t txData;
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
dsiXfer.txDataSize = 1;
dsiXfer.txData = &txData;
if (enter)
{
txData = (uint8_t)kMIPI_DCS_EnterPartialMode;
}
else
{
txData = (uint8_t)kMIPI_DCS_EnterNormalMode;
}
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_EnterInvertMode(mipi_dsi_device_t *device, bool enter)
{
dsi_transfer_t dsiXfer = {0};
uint8_t txData;
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
dsiXfer.txDataSize = 1;
dsiXfer.txData = &txData;
if (enter)
{
txData = (uint8_t)kMIPI_DCS_EnterInvertMode;
}
else
{
txData = (uint8_t)kMIPI_DCS_ExitInvertMode;
}
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_EnterIdleMode(mipi_dsi_device_t *device, bool enter)
{
dsi_transfer_t dsiXfer = {0};
uint8_t txData;
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
dsiXfer.txDataSize = 1;
dsiXfer.txData = &txData;
if (enter)
{
txData = (uint8_t)kMIPI_DCS_EnterIdleMode;
}
else
{
txData = (uint8_t)kMIPI_DCS_ExitIdleMode;
}
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_Write(mipi_dsi_device_t *device, const uint8_t *txData, int32_t txDataSize)
{
dsi_transfer_t dsiXfer = {0};
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataSize = (uint16_t)txDataSize;
dsiXfer.txData = txData;
if (0 == txDataSize)
{
/* For DSC command, the data size should not be 0. */
return kStatus_InvalidArgument;
}
else if (1 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
}
else if (2 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataDcsShortWrOneParam;
}
else
{
dsiXfer.txDataType = kDSI_TxDataDcsLongWr;
}
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_GenericWrite(mipi_dsi_device_t *device, const uint8_t *txData, int32_t txDataSize)
{
dsi_transfer_t dsiXfer = {0};
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataSize = (uint16_t)txDataSize;
dsiXfer.txData = txData;
if (0 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataGenShortWrNoParam;
}
else if (1 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataGenShortWrOneParam;
}
else if (2 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataGenShortWrTwoParam;
}
else
{
dsiXfer.txDataType = kDSI_TxDataGenLongWr;
}
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_DCS_SetMaxReturnPktSize(mipi_dsi_device_t *device, uint16_t sizeBytes)
{
dsi_transfer_t dsiXfer = {0};
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataSetMaxReturnPktSize;
dsiXfer.txDataSize = 2;
dsiXfer.txData = (uint8_t *)&sizeBytes;
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_GenericRead(
mipi_dsi_device_t *device, const uint8_t *txData, int32_t txDataSize, uint8_t *rxData, int32_t *rxDataSize)
{
status_t status;
dsi_transfer_t dsiXfer = {0};
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataSize = (uint16_t)txDataSize;
dsiXfer.txData = txData;
dsiXfer.rxDataSize = (uint16_t)*rxDataSize;
dsiXfer.rxData = rxData;
*rxDataSize = 0;
if (0 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataGenShortRdNoParam;
}
else if (1 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataGenShortRdOneParam;
}
else if (2 == txDataSize)
{
dsiXfer.txDataType = kDSI_TxDataGenShortRdTwoParam;
}
else
{
return kStatus_InvalidArgument;
}
status = device->xferFunc(&dsiXfer);
/* Return actual received size. */
*rxDataSize = (int32_t)dsiXfer.rxDataSize;
return status;
}
status_t MIPI_DSI_ReadCMD(mipi_dsi_device_t *device, enum _mipi_dcs dcsCmd, uint8_t *rxData, int32_t *rxDataSize)
{
uint8_t txData[2];
status_t status = kStatus_Fail;
txData[0] = (uint8_t)dcsCmd;
if (kStatus_Success == MIPI_DSI_DCS_SetMaxReturnPktSize(device, (uint16_t)*rxDataSize))
{
status = MIPI_DSI_GenericRead(device, txData, 1, rxData, rxDataSize);
}
return status;
}
status_t MIPI_DSI_SelectArea(mipi_dsi_device_t *device, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY)
{
status_t status;
dsi_transfer_t dsiXfer = {0};
uint8_t txData[4];
dsiXfer.virtualChannel = device->virtualChannel;
dsiXfer.txDataType = kDSI_TxDataDcsLongWr;
dsiXfer.txDataSize = 4;
dsiXfer.txData = txData;
dsiXfer.sendDscCmd = true;
dsiXfer.dscCmd = (uint8_t)kMIPI_DCS_SetColumnAddress;
txData[0] = (uint8_t)((startX >> 8U) & 0xFFU);
txData[1] = (uint8_t)(startX & 0xFFU);
txData[2] = (uint8_t)((endX >> 8U) & 0xFFU);
txData[3] = (uint8_t)(endX & 0xFFU);
status = device->xferFunc(&dsiXfer);
if (kStatus_Success != status)
{
return status;
}
dsiXfer.dscCmd = (uint8_t)kMIPI_DCS_SetPageAddress;
txData[0] = (uint8_t)((startY >> 8U) & 0xFFU);
txData[1] = (uint8_t)(startY & 0xFFU);
txData[2] = (uint8_t)((endY >> 8U) & 0xFFU);
txData[3] = (uint8_t)(endY & 0xFFU);
return device->xferFunc(&dsiXfer);
}
status_t MIPI_DSI_WriteMemory(mipi_dsi_device_t *device, const uint8_t *data, uint32_t length)
{
return device->memWriteFunc(device->virtualChannel, data, length);
}
status_t MIPI_DSI_WriteMemory2D(
mipi_dsi_device_t *device, const uint8_t *data, uint32_t minorLoop, uint32_t minorLoopOffset, uint32_t majorLoop)
{
if (device->memWriteFunc2D != NULL)
{
return device->memWriteFunc2D(device->virtualChannel, data, minorLoop, minorLoopOffset, majorLoop);
}
else
{
return kStatus_Fail;
}
}
void MIPI_DSI_SetMemoryDoneCallback(mipi_dsi_device_t *device, mipi_dsi_mem_done_callback_t callback, void *userData)
{
device->callback = callback;
device->userData = userData;
}
void MIPI_DSI_MemoryDoneDriverCallback(status_t status, void *userData)
{
mipi_dsi_device_t *device = (mipi_dsi_device_t *)userData;
if (NULL != device->callback)
{
device->callback(status, device->userData);
}
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_MIPI_DSI_CMD_H_
#define _FSL_MIPI_DSI_CMD_H_
#include "fsl_common.h"
#include "fsl_mipi_dsi.h"
/*
* Change log:
*
* 1.0.2
* - Fix MISRA-C 2012 issues.
*
* 1.0.1
* - Add more functions for panel works in command mode.
*
* 1.0.0
* - Initial version
*/
/*******************************************************************************
* Definitions
******************************************************************************/
enum _mipi_dcs
{
kMIPI_DCS_Nop = 0x00,
kMIPI_DCS_SoftReset = 0x01,
kMIPI_DCS_GetRedChannel = 0x06,
kMIPI_DCS_GetGreenChannel = 0x07,
kMIPI_DCS_GetBlueChannel = 0x08,
kMIPI_DCS_GetPowerMode = 0x0A,
kMIPI_DCS_GetAddressMode = 0x0B,
kMIPI_DCS_GetPixelFormat = 0x0C,
kMIPI_DCS_GetDisplayMode = 0x0D,
kMIPI_DCS_GetSignalMode = 0x0E,
kMIPI_DCS_GetDiagnosticResult = 0x0F,
kMIPI_DCS_EnterSleepMode = 0x10,
kMIPI_DCS_ExitSleepMode = 0x11,
kMIPI_DCS_EnterPartialMode = 0x12,
kMIPI_DCS_EnterNormalMode = 0x13,
kMIPI_DCS_ExitInvertMode = 0x20,
kMIPI_DCS_EnterInvertMode = 0x21,
kMIPI_DCS_SetGammaCurve = 0x26,
kMIPI_DCS_SetDisplayOff = 0x28,
kMIPI_DCS_SetDisplayOn = 0x29,
kMIPI_DCS_SetColumnAddress = 0x2a,
kMIPI_DCS_SetPageAddress = 0x2b,
kMIPI_DCS_WriteMemoryStart = 0x2C,
kMIPI_DCS_WriteLUT = 0x2D,
kMIPI_DCS_ReadMemoryStart = 0x2E,
kMIPI_DCS_SetPartialRows = 0x30,
kMIPI_DCS_SetPartialColumns = 0x31,
kMIPI_DCS_SetScrollArea = 0x33,
kMIPI_DCS_SetTearOff = 0x34,
kMIPI_DCS_SetTearOn = 0x35,
kMIPI_DCS_SetAddressMode = 0x36,
kMIPI_DCS_SetScrollStart = 0x37,
kMIPI_DCS_ExitIdleMode = 0x38,
kMIPI_DCS_EnterIdleMode = 0x39,
kMIPI_DCS_SetPixelFormat = 0x3A,
kMIPI_DCS_WriteMemoryContinue = 0x3C,
kMIPI_DCS_Set3DControl = 0x3D,
kMIPI_DCS_ReadMemoryContinue = 0x3E,
kMIPI_DCS_Get3DControl = 0x3F,
kMIPI_DCS_SetVsyncTiming = 0x40,
kMIPI_DCS_SetTearScanline = 0x44,
kMIPI_DCS_GetScanline = 0x45,
kMIPI_DCS_SetDisplayBrightness = 0x51,
kMIPI_DCS_GetDisplayBrightness = 0x52,
kMIPI_DCS_WriteControlDisplay = 0x53,
kMIPI_DCS_GetControlDisplay = 0x54,
kMIPI_DCS_WritePowerSave = 0x55,
kMIPI_DCS_GetPowerSave = 0x56,
kMIPI_DCS_SetCABCMinBrightness = 0x5E,
kMIPI_DCS_GetCABCMinBrightness = 0x5F,
kMIPI_DCS_ReadDDBStart = 0xA1,
kMIPI_DCS_ReadDDBContinue = 0xA8,
};
/*!
* @brief Pixel format used by DSC command.
*/
typedef enum _mipi_dsc_pixel_format
{
kMIPI_DCS_Pixel3Bits = 1U, /*!< 3-bit per pixel. */
kMIPI_DCS_Pixel8Bits = 2U, /*!< 8-bit per pixel. */
kMIPI_DCS_Pixel12Bits = 3U, /*!< 12-bit per pixel. */
kMIPI_DCS_Pixel16Bits = 5U, /*!< 16-bit per pixel. */
kMIPI_DCS_Pixel18Bits = 6U, /*!< 18-bit per pixel. */
kMIPI_DCS_Pixel24Bits = 7U, /*!< 24-bit per pixel. */
} mipi_dsc_pixel_format_t;
/*!
* @brief Callback function when the write memory finished.
*
* If transfer done successfully, the @p status is kStatus_Success.
*/
typedef void (*mipi_dsi_mem_done_callback_t)(status_t status, void *userData);
/*! @brief MIPI DSI transfer function. */
typedef status_t (*mipi_dsi_transfer_func_t)(dsi_transfer_t *xfer);
/*! @brief MIPI DSI memory write function. */
typedef status_t (*mipi_dsi_mem_write_func_t)(uint8_t virtualChannel, const uint8_t *data, uint32_t length);
/*! @brief MIPI DSI memory write function using 2-dimensional way. */
typedef status_t (*mipi_dsi_mem_write_func_2D_t)(
uint8_t virtualChannel, const uint8_t *data, uint32_t minorLoop, uint32_t minorLoopOffset, uint32_t majorLoop);
/*! @brief MIPI DSI device. */
typedef struct _mipi_dsi_device
{
uint8_t virtualChannel;
mipi_dsi_transfer_func_t xferFunc;
mipi_dsi_mem_write_func_t memWriteFunc; /*!< Function to write display memory,
it should be non-blocking function and
notify upper layer using callback when finished.
Not used when panel works in video mode. */
mipi_dsi_mem_write_func_2D_t memWriteFunc2D; /*!< Function to write display memory using 2-dimensional way,
it should be non-blocking function and
notify upper layer using callback when finished.
Not used when panel works in video mode. */
mipi_dsi_mem_done_callback_t callback; /*!< The callback function to notify upper layer
that memory write done. Not used when panel
works in video mode. */
void *userData; /*!< Parameter for the memory write done callback.
not used when panel works in video mode. */
} mipi_dsi_device_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Send software reset to MIPI DSI device.
*
* @param device The MIPI DSI device.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_SoftReset(mipi_dsi_device_t *device);
/*!
* @brief Set display on or off.
*
* @param device The MIPI DSI device.
* @param on Set true to turn on, false to turn off.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_SetDisplayOn(mipi_dsi_device_t *device, bool on);
/*!
* @brief Enter or exit sleep mode.
*
* @param device The MIPI DSI device.
* @param enter Set true to enter sleep mode, false to exit.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_EnterSleepMode(mipi_dsi_device_t *device, bool enter);
/*!
* @brief Enter or exit partial mode.
*
* @param device The MIPI DSI device.
* @param enter Set true to enter partial mode, false to exit.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_EnterPartialMode(mipi_dsi_device_t *device, bool enter);
/*!
* @brief Enter or exit invert mode.
*
* @param device The MIPI DSI device.
* @param enter Set true to enter invert mode, false to exit.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_EnterInvertMode(mipi_dsi_device_t *device, bool enter);
/*!
* @brief Enter or exit idle mode.
*
* @param device The MIPI DSI device.
* @param enter Set true to enter idle mode, false to exit.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_EnterIdleMode(mipi_dsi_device_t *device, bool enter);
/*!
* @brief Send DCS command.
*
* @param device The MIPI DSI device.
* @param txData The data to send.
* @param txDataSize Size of the data to send (in bytes).
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_Write(mipi_dsi_device_t *device, const uint8_t *txData, int32_t txDataSize);
/*!
* @brief Send generic data.
*
* @param device The MIPI DSI device.
* @param txData The data to send.
* @param txDataSize Size of the data to send (in bytes).
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_GenericWrite(mipi_dsi_device_t *device, const uint8_t *txData, int32_t txDataSize);
/*!
* @brief Set the maximum return data length.
*
* @param device The MIPI DSI device.
* @param sizeBytes Maximum return data length.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_SetMaxReturnPktSize(mipi_dsi_device_t *device, uint16_t sizeBytes);
/*!
* @brief Generic read.
*
* @param device The MIPI DSI device.
* @param txData The data to send before read.
* @param txDataSize Size of the data to send (in bytes).
* @param rxData The data to read.
* @param rxDataSize Size of the data to read (in bytes), after this function returns,
* it is the actual read length.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_GenericRead(
mipi_dsi_device_t *device, const uint8_t *txData, int32_t txDataSize, uint8_t *rxData, int32_t *rxDataSize);
/*!
* @brief Read DCS command(read type command, such as: Get Display ID).
*
* @param device The MIPI DSI device.
* @param dcsCmd The command to send before read.
* @param rxData The data to read.
* @param rxDataSize Size of the data to read (in bytes), after this function returns,
* it is the actual read length.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_ReadCMD(mipi_dsi_device_t *device, enum _mipi_dcs dcsCmd, uint8_t *rxData, int32_t *rxDataSize);
/*!
* @brief Set the panel pixel format.
*
* @param device The MIPI DSI device.
* @param dbiFormat The DBI interface pixel format.
* @param dpiFormat The DPI interface pixel format.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_DCS_SetPixelFormat(mipi_dsi_device_t *device,
mipi_dsc_pixel_format_t dbiFormat,
mipi_dsc_pixel_format_t dpiFormat);
/*!
* @brief Select area to write or read pixels.
*
* @param device The MIPI DSI device.
* @param startX Start point X coordination.
* @param startY Start point Y coordination.
* @param endX End point X coordination.
* @param endY End point Y coordination.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_SelectArea(mipi_dsi_device_t *device, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY);
/*!
* @brief Send pixel data to the display controller's frame memory.
*
* The pixels will be shown in the region selected by @ref MIPI_DSI_SelectArea.
* This function is non-blocking function, user should install callback function
* using @ref MIPI_DSI_SetMemoryDoneCallback to get informed when write finished.
*
* @param device The MIPI DSI device.
* @param data The pixel data to send.
* @param length Length of the data in byte.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_WriteMemory(mipi_dsi_device_t *device, const uint8_t *data, uint32_t length);
/*!
* @brief Send pixel data to the display controller's frame memory in 2-dinmensional way.
*
* The pixels will be shown in the region selected by @ref MIPI_DSI_SelectArea.
* This function is non-blocking function, user should install callback function
* using @ref MIPI_DSI_SetMemoryDoneCallback to get informed when write finished.
*
* @verbatim
* +---------------------------------------------------+
* | |
* | data |
* | +-------------------+ |
* | | minorLoop | |
* | | | |
* | | | majorLoop |
* | | | |
* | | | |
* | +-------------------+ |
* | |
* | minorLoop + minorLoopOffset |
* +---------------------------------------------------+
* @endverbatim
*
* @param device The MIPI DSI device.
* @param data The pixel data to send.
* @param minorLoop Count of the data in one line in byte.
* @param minorLoopOffset The offset between line stride and the count of one line in byte.
* @param majorLoop Count of the lines in byte.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
status_t MIPI_DSI_WriteMemory2D(
mipi_dsi_device_t *device, const uint8_t *data, uint32_t minorLoop, uint32_t minorLoopOffset, uint32_t majorLoop);
/*!
* @brief Install the callback called when write memory finished.
*
* Upper layer should install callback function using this function to
* get memory write done notification.
*
* @param device The MIPI DSI device.
* @param callback The callback function to inform upper layer that memory write done.
* @param userData Parameter used by the callback.
* @return Returns @ref kStatus_Success if success, otherwise returns error code.
*/
void MIPI_DSI_SetMemoryDoneCallback(mipi_dsi_device_t *device, mipi_dsi_mem_done_callback_t callback, void *userData);
/*!
* @brief The callback function lower layer should call when write memory finished.
*
* When implement the @ref mipi_dsi_device_t, this function should be called when
* the memory writing finished. The parameter @p userData should be pointer to the
* @ref mipi_dsi_device_t.
*
* @param status The memory writing result. @ref kStatus_Success if success.
* @param userData Must be pointer to the @ref mipi_dsi_device_t instance.
*/
void MIPI_DSI_MemoryDoneDriverCallback(status_t status, void *userData);
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_MIPI_DSI_CMD_H_ */

View File

@@ -0,0 +1,251 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_display.h"
#include "fsl_rm68191.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define RM68191_DelayMs VIDEO_DelayMs
typedef struct _rm68191_setting
{
const uint8_t *value;
uint8_t len;
} rm68191_setting_t;
#define RM68191_MAKE_SETTING_ITEM(setting) \
{ \
(setting), (uint8_t)sizeof(setting) \
}
/*******************************************************************************
* Variables
******************************************************************************/
static const uint8_t s_rm68191Cmd0[] = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x03};
static const uint8_t s_rm68191Cmd1[] = {0x90, 0x05, 0x16, 0x09, 0x03, 0xCD, 0x00, 0x00, 0x00, 0x00};
static const uint8_t s_rm68191Cmd2[] = {0x91, 0x05, 0x16, 0x0B, 0x03, 0xCF, 0x00, 0x00, 0x00, 0x00};
static const uint8_t s_rm68191Cmd3[] = {0x92, 0x40, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x8F, 0x00, 0x00, 0x04, 0x08};
static const uint8_t s_rm68191Cmd4[] = {0x94, 0x00, 0x08, 0x0C, 0x03, 0xD1, 0x03, 0xD2, 0x0C};
static const uint8_t s_rm68191Cmd5[] = {0x95, 0x40, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13,
0x00, 0x8F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08};
static const uint8_t s_rm68191Cmd6[] = {0x99, 0x00, 0x00};
static const uint8_t s_rm68191Cmd7[] = {0x9A, 0x80, 0x10, 0x03, 0xD5, 0x03, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x50};
static const uint8_t s_rm68191Cmd8[] = {0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t s_rm68191Cmd9[] = {0x9C, 0x00, 0x00};
static const uint8_t s_rm68191Cmd10[] = {0x9D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00};
static const uint8_t s_rm68191Cmd11[] = {0x9E, 0x00, 0x00};
static const uint8_t s_rm68191Cmd12[] = {0xA0, 0x84, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x08, 0x1F, 0x0A, 0x1F};
static const uint8_t s_rm68191Cmd13[] = {0xA1, 0x1F, 0x1F, 0x1F, 0x1F, 0x0C, 0x1F, 0x0E, 0x1F, 0x1F, 0x1F};
static const uint8_t s_rm68191Cmd14[] = {0xA2, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x02, 0x1F, 0x06, 0x1F};
static const uint8_t s_rm68191Cmd15[] = {0xA3, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
static const uint8_t s_rm68191Cmd16[] = {0xA4, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x07, 0x1F, 0x03, 0x1F, 0x0F};
static const uint8_t s_rm68191Cmd17[] = {0xA5, 0x1F, 0x0D, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0B, 0x1F, 0x09};
static const uint8_t s_rm68191Cmd18[] = {0xA6, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x01, 0x05};
static const uint8_t s_rm68191Cmd19[] = {0xA7, 0x03, 0x07, 0x1F, 0x1F, 0x1F, 0x1F, 0x0B, 0x1F, 0x09, 0x1F};
static const uint8_t s_rm68191Cmd20[] = {0xA8, 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x1F, 0x0D, 0x1F, 0x1F, 0x1F};
static const uint8_t s_rm68191Cmd21[] = {0xA9, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x1F, 0x01, 0x1F};
static const uint8_t s_rm68191Cmd22[] = {0xAA, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
static const uint8_t s_rm68191Cmd23[] = {0xAB, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x1F, 0x04, 0x1F, 0x0C};
static const uint8_t s_rm68191Cmd24[] = {0xAC, 0x1F, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x08, 0x1F, 0x0A};
static const uint8_t s_rm68191Cmd25[] = {0xAD, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x06, 0x02};
static const uint8_t s_rm68191Cmd26[] = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x02};
static const uint8_t s_rm68191Cmd27[] = {0xEA, 0x7D};
static const uint8_t s_rm68191Cmd28[] = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00};
static const uint8_t s_rm68191Cmd29[] = {0xBC, 0x00, 0x00, 0x00};
static const uint8_t s_rm68191Cmd30[] = {0xB8, 0x01, 0xAF, 0x8F, 0x8F};
static const uint8_t s_rm68191Cmd31[] = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01};
static const uint8_t s_rm68191Cmd32[] = {0xD1, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
static const uint8_t s_rm68191Cmd33[] = {0xD2, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
static const uint8_t s_rm68191Cmd34[] = {0xD3, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
static const uint8_t s_rm68191Cmd35[] = {0xD4, 0x03, 0xE5, 0x03, 0xFF};
static const uint8_t s_rm68191Cmd36[] = {0xD5, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
static const uint8_t s_rm68191Cmd37[] = {0xD6, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
static const uint8_t s_rm68191Cmd38[] = {0xD7, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
static const uint8_t s_rm68191Cmd39[] = {0xD8, 0x03, 0xE5, 0x03, 0xFF};
static const uint8_t s_rm68191Cmd40[] = {0xD9, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
static const uint8_t s_rm68191Cmd41[] = {0xDD, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
static const uint8_t s_rm68191Cmd42[] = {0xDE, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
static const uint8_t s_rm68191Cmd43[] = {0xDF, 0x03, 0xE5, 0x03, 0xFF};
static const uint8_t s_rm68191Cmd44[] = {0xE0, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
static const uint8_t s_rm68191Cmd45[] = {0xE1, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
static const uint8_t s_rm68191Cmd46[] = {0xE2, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
static const uint8_t s_rm68191Cmd47[] = {0xE3, 0x03, 0xE5, 0x03, 0xFF};
static const uint8_t s_rm68191Cmd48[] = {0xE4, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
static const uint8_t s_rm68191Cmd49[] = {0xE5, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
static const uint8_t s_rm68191Cmd50[] = {0xE6, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
static const uint8_t s_rm68191Cmd51[] = {0xE7, 0x03, 0xE5, 0x03, 0xFF};
static const uint8_t s_rm68191Cmd52[] = {0xE8, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
static const uint8_t s_rm68191Cmd53[] = {0xE9, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
static const uint8_t s_rm68191Cmd54[] = {0xEA, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
static const uint8_t s_rm68191Cmd55[] = {0xEB, 0x03, 0xE5, 0x03, 0xFF};
static const uint8_t s_rm68191Cmd56[] = {0xB0, 0x07, 0x07, 0x07};
static const uint8_t s_rm68191Cmd57[] = {0xB1, 0x07, 0x07, 0x07};
static const uint8_t s_rm68191Cmd58[] = {0xB3, 0x11, 0x11, 0x11};
static const uint8_t s_rm68191Cmd59[] = {0xB4, 0x09, 0x09, 0x09};
static const uint8_t s_rm68191Cmd60[] = {0xB6, 0x44, 0x44, 0x44};
static const uint8_t s_rm68191Cmd61[] = {0xB7, 0x34, 0x34, 0x34};
static const uint8_t s_rm68191Cmd62[] = {0xB9, 0x34, 0x34, 0x34};
static const uint8_t s_rm68191Cmd63[] = {0xBA, 0x14, 0x14, 0x14};
static const uint8_t s_rm68191Cmd64[] = {0xBC, 0x00, 0x98, 0x00};
static const uint8_t s_rm68191Cmd65[] = {0xBD, 0x00, 0x98, 0x00};
static const uint8_t s_rm68191Cmd66[] = {0xBE, 0x1D};
static const uint8_t s_rm68191Cmd67[] = {0x35, 0x00};
static const rm68191_setting_t s_rm68191InitSetting[] = {
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd0), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd1),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd2), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd3),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd4), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd5),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd6), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd7),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd8), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd9),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd10), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd11),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd12), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd13),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd14), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd15),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd16), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd17),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd18), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd19),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd20), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd21),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd22), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd23),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd24), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd25),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd26), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd27),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd28), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd29),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd30), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd31),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd32), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd33),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd34), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd35),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd36), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd37),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd38), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd39),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd40), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd41),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd42), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd43),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd44), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd45),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd46), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd47),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd48), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd49),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd50), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd51),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd52), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd53),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd54), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd55),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd56), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd57),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd58), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd59),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd60), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd61),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd62), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd63),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd64), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd65),
RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd66), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd67),
};
const display_operations_t rm68191_ops = {
.init = RM68191_Init,
.deinit = RM68191_Deinit,
.start = RM68191_Start,
.stop = RM68191_Stop,
};
/*******************************************************************************
* Code
******************************************************************************/
status_t RM68191_Init(display_handle_t *handle, const display_config_t *config)
{
uint32_t i;
status_t status = kStatus_Success;
const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
/* Only support 540 * 960 */
if (config->resolution != FSL_VIDEO_RESOLUTION(540, 960))
{
return kStatus_InvalidArgument;
}
/* Power on. */
resource->pullPowerPin(true);
RM68191_DelayMs(1);
/* Perform reset. */
resource->pullResetPin(false);
RM68191_DelayMs(1);
resource->pullResetPin(true);
RM68191_DelayMs(5);
/* Set the LCM init settings. */
for (i = 0; i < ARRAY_SIZE(s_rm68191InitSetting); i++)
{
status = MIPI_DSI_DCS_Write(dsiDevice, s_rm68191InitSetting[i].value, (int32_t)s_rm68191InitSetting[i].len);
if (kStatus_Success != status)
{
return status;
}
}
/* Exit sleep mode */
status = MIPI_DSI_DCS_EnterSleepMode(dsiDevice, false);
if (kStatus_Success != status)
{
return status;
}
RM68191_DelayMs(200);
/* Set display on. */
status = MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
if (kStatus_Success != status)
{
return status;
}
RM68191_DelayMs(200);
return kStatus_Success;
}
status_t RM68191_Deinit(display_handle_t *handle)
{
const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
(void)MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
resource->pullResetPin(false);
resource->pullPowerPin(false);
return kStatus_Success;
}
status_t RM68191_Start(display_handle_t *handle)
{
const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
}
status_t RM68191_Stop(display_handle_t *handle)
{
const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2019-2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_RM68191_H_
#define _FSL_RM68191_H_
#include "fsl_display.h"
#include "fsl_mipi_dsi_cmd.h"
/*
* Change log:
*
* 1.1.0
* - Fix MISRA-C 2012 issues.
* - Change rm68191_resource_t structure.
*
* 1.0.0
* - Initial version
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @brief RM68191 resource.
*/
typedef struct _rm68191_resource
{
mipi_dsi_device_t *dsiDevice; /*!< MIPI DSI device. */
void (*pullResetPin)(bool pullUp); /*!< Function to pull reset pin high or low. */
void (*pullPowerPin)(bool pullUp); /*!< Function to pull power pin high or low. */
} rm68191_resource_t;
extern const display_operations_t rm68191_ops;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
status_t RM68191_Init(display_handle_t *handle, const display_config_t *config);
status_t RM68191_Deinit(display_handle_t *handle);
status_t RM68191_Start(display_handle_t *handle);
status_t RM68191_Stop(display_handle_t *handle);
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_RM68191_H_ */

View File

@@ -0,0 +1,409 @@
/*
* Copyright 2019-2021 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_display.h"
#include "fsl_rm68200.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define RM68200_DelayMs VIDEO_DelayMs
/*******************************************************************************
* Variables
******************************************************************************/
uint8_t RM68200_DDB_START[5] = {0x00, 0x00, 0x00, 0x00, 0xff};
static const uint8_t lcmInitPage0Setting[][2] = {
{0xFE, 0x01}, {0x24, 0xC0}, {0x25, 0x53}, {0x26, 0x00}, {0x2B, 0xE5}, {0x27, 0x0A},
{0x29, 0x0A}, {0x16, 0x52}, {0x2F, 0x53}, {0x34, 0x5A}, {0x1B, 0x00}, {0x12, 0x0A},
{0x1A, 0x06}, {0x46, 0x56}, {0x52, 0xA0}, {0x53, 0x00}, {0x54, 0xA0}, {0x55, 0x00},
};
static const uint8_t lcmInitSetting[][2] = {
{0xFE, 0x03},
{0x00, 0x05},
{0x02, 0x0B},
{0x03, 0x0F},
{0x04, 0x7D},
{0x05, 0x00},
{0x06, 0x50},
{0x07, 0x05},
{0x08, 0x16},
{0x09, 0x0D},
{0x0A, 0x11},
{0x0B, 0x7D},
{0x0C, 0x00},
{0x0D, 0x50},
{0x0E, 0x07},
{0x0F, 0x08},
{0x10, 0x01},
{0x11, 0x02},
{0x12, 0x00},
{0x13, 0x7D},
{0x14, 0x00},
{0x15, 0x85},
{0x16, 0x08},
{0x17, 0x03},
{0x18, 0x04},
{0x19, 0x05},
{0x1A, 0x06},
{0x1B, 0x00},
{0x1C, 0x7D},
{0x1D, 0x00},
{0x1E, 0x85},
{0x1F, 0x08},
{0x20, 0x00},
{0x21, 0x00},
{0x22, 0x00},
{0x23, 0x00},
{0x24, 0x00},
{0x25, 0x00},
{0x26, 0x00},
{0x27, 0x00},
{0x28, 0x00},
{0x29, 0x00},
{0x2A, 0x07},
{0x2B, 0x08},
{0x2D, 0x01},
{0x2F, 0x02},
{0x30, 0x00},
{0x31, 0x40},
{0x32, 0x05},
{0x33, 0x08},
{0x34, 0x54},
{0x35, 0x7D},
{0x36, 0x00},
{0x37, 0x03},
{0x38, 0x04},
{0x39, 0x05},
{0x3A, 0x06},
{0x3B, 0x00},
{0x3D, 0x40},
{0x3F, 0x05},
{0x40, 0x08},
{0x41, 0x54},
{0x42, 0x7D},
{0x43, 0x00},
{0x44, 0x00},
{0x45, 0x00},
{0x46, 0x00},
{0x47, 0x00},
{0x48, 0x00},
{0x49, 0x00},
{0x4A, 0x00},
{0x4B, 0x00},
{0x4C, 0x00},
{0x4D, 0x00},
{0x4E, 0x00},
{0x4F, 0x00},
{0x50, 0x00},
{0x51, 0x00},
{0x52, 0x00},
{0x53, 0x00},
{0x54, 0x00},
{0x55, 0x00},
{0x56, 0x00},
{0x58, 0x00},
{0x59, 0x00},
{0x5A, 0x00},
{0x5B, 0x00},
{0x5C, 0x00},
{0x5D, 0x00},
{0x5E, 0x00},
{0x5F, 0x00},
{0x60, 0x00},
{0x61, 0x00},
{0x62, 0x00},
{0x63, 0x00},
{0x64, 0x00},
{0x65, 0x00},
{0x66, 0x00},
{0x67, 0x00},
{0x68, 0x00},
{0x69, 0x00},
{0x6A, 0x00},
{0x6B, 0x00},
{0x6C, 0x00},
{0x6D, 0x00},
{0x6E, 0x00},
{0x6F, 0x00},
{0x70, 0x00},
{0x71, 0x00},
{0x72, 0x20},
{0x73, 0x00},
{0x74, 0x08},
{0x75, 0x08},
{0x76, 0x08},
{0x77, 0x08},
{0x78, 0x08},
{0x79, 0x08},
{0x7A, 0x00},
{0x7B, 0x00},
{0x7C, 0x00},
{0x7D, 0x00},
{0x7E, 0xBF},
{0x7F, 0x02},
{0x80, 0x06},
{0x81, 0x14},
{0x82, 0x10},
{0x83, 0x16},
{0x84, 0x12},
{0x85, 0x08},
{0x86, 0x3F},
{0x87, 0x3F},
{0x88, 0x3F},
{0x89, 0x3F},
{0x8A, 0x3F},
{0x8B, 0x0C},
{0x8C, 0x0A},
{0x8D, 0x0E},
{0x8E, 0x3F},
{0x8F, 0x3F},
{0x90, 0x00},
{0x91, 0x04},
{0x92, 0x3F},
{0x93, 0x3F},
{0x94, 0x3F},
{0x95, 0x3F},
{0x96, 0x05},
{0x97, 0x01},
{0x98, 0x3F},
{0x99, 0x3F},
{0x9A, 0x0F},
{0x9B, 0x0B},
{0x9C, 0x0D},
{0x9D, 0x3F},
{0x9E, 0x3F},
{0x9F, 0x3F},
{0xA0, 0x3F},
{0xA2, 0x3F},
{0xA3, 0x09},
{0xA4, 0x13},
{0xA5, 0x17},
{0xA6, 0x11},
{0xA7, 0x15},
{0xA9, 0x07},
{0xAA, 0x03},
{0xAB, 0x3F},
{0xAC, 0x3F},
{0xAD, 0x05},
{0xAE, 0x01},
{0xAF, 0x17},
{0xB0, 0x13},
{0xB1, 0x15},
{0xB2, 0x11},
{0xB3, 0x0F},
{0xB4, 0x3F},
{0xB5, 0x3F},
{0xB6, 0x3F},
{0xB7, 0x3F},
{0xB8, 0x3F},
{0xB9, 0x0B},
{0xBA, 0x0D},
{0xBB, 0x09},
{0xBC, 0x3F},
{0xBD, 0x3F},
{0xBE, 0x07},
{0xBF, 0x03},
{0xC0, 0x3F},
{0xC1, 0x3F},
{0xC2, 0x3F},
{0xC3, 0x3F},
{0xC4, 0x02},
{0xC5, 0x06},
{0xC6, 0x3F},
{0xC7, 0x3F},
{0xC8, 0x08},
{0xC9, 0x0C},
{0xCA, 0x0A},
{0xCB, 0x3F},
{0xCC, 0x3F},
{0xCD, 0x3F},
{0xCE, 0x3F},
{0xCF, 0x3F},
{0xD0, 0x0E},
{0xD1, 0x10},
{0xD2, 0x14},
{0xD3, 0x12},
{0xD4, 0x16},
{0xD5, 0x00},
{0xD6, 0x04},
{0xD7, 0x3F},
{0xDC, 0x02},
{0xDE, 0x12},
{0xFE, 0x0E},
{0x01, 0x75},
/* Gamma Settings */
{0xFE, 0x04},
{0x60, 0x00},
{0x61, 0x0C},
{0x62, 0x12},
{0x63, 0x0E},
{0x64, 0x06},
{0x65, 0x12},
{0x66, 0x0E},
{0x67, 0x0B},
{0x68, 0x15},
{0x69, 0x0B},
{0x6A, 0x10},
{0x6B, 0x07},
{0x6C, 0x0F},
{0x6D, 0x12},
{0x6E, 0x0C},
{0x6F, 0x00},
{0x70, 0x00},
{0x71, 0x0C},
{0x72, 0x12},
{0x73, 0x0E},
{0x74, 0x06},
{0x75, 0x12},
{0x76, 0x0E},
{0x77, 0x0B},
{0x78, 0x15},
{0x79, 0x0B},
{0x7A, 0x10},
{0x7B, 0x07},
{0x7C, 0x0F},
{0x7D, 0x12},
{0x7E, 0x0C},
{0x7F, 0x00},
/* Page 0. */
{0xFE, 0x00},
{0x11, 0x00},
};
const display_operations_t rm68200_ops = {
.init = RM68200_Init,
.deinit = RM68200_Deinit,
.start = RM68200_Start,
.stop = RM68200_Stop,
};
/*******************************************************************************
* Code
******************************************************************************/
status_t RM68200_Init(display_handle_t *handle, const display_config_t *config)
{
uint32_t i;
uint8_t param[2];
status_t status = kStatus_Success;
const rm68200_resource_t *resource = (const rm68200_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
/* Only support 720 * 1280 */
if (config->resolution != FSL_VIDEO_RESOLUTION(720, 1280))
{
return kStatus_InvalidArgument;
}
/* Power on. */
resource->pullPowerPin(true);
RM68200_DelayMs(1);
/* Perform reset. */
resource->pullResetPin(false);
RM68200_DelayMs(1);
resource->pullResetPin(true);
RM68200_DelayMs(5);
/* Set the LCM page0 init settings. */
for (i = 0; i < ARRAY_SIZE(lcmInitPage0Setting); i++)
{
status = MIPI_DSI_GenericWrite(dsiDevice, lcmInitPage0Setting[i], 2);
if (kStatus_Success != status)
{
return status;
}
}
/* Data lane number selection. */
param[0] = 0x5FU;
param[1] = 0x10U | (config->dsiLanes - 1U);
status = MIPI_DSI_GenericWrite(dsiDevice, param, 2);
if (kStatus_Success != status)
{
return status;
}
/* Set the LCM init settings. */
for (i = 0; i < ARRAY_SIZE(lcmInitSetting); i++)
{
status = MIPI_DSI_GenericWrite(dsiDevice, lcmInitSetting[i], 2);
if (kStatus_Success != status)
{
return status;
}
}
RM68200_DelayMs(200);
param[0] = 0x29;
param[1] = 0x00;
status = MIPI_DSI_GenericWrite(dsiDevice, param, 2);
if (kStatus_Success != status)
{
return status;
}
RM68200_DelayMs(100);
param[0] = 0x2c;
status = MIPI_DSI_GenericWrite(dsiDevice, param, 1);
if (kStatus_Success != status)
{
return status;
}
param[0] = 0x35;
param[1] = 0x00;
status = MIPI_DSI_GenericWrite(dsiDevice, param, 2);
if (kStatus_Success != status)
{
return status;
}
RM68200_DelayMs(200);
return kStatus_Success;
}
status_t RM68200_Deinit(display_handle_t *handle)
{
const rm68200_resource_t *resource = (const rm68200_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
(void)MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
resource->pullResetPin(false);
resource->pullPowerPin(false);
return kStatus_Success;
}
status_t RM68200_Start(display_handle_t *handle)
{
const rm68200_resource_t *resource = (const rm68200_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
}
status_t RM68200_Stop(display_handle_t *handle)
{
const rm68200_resource_t *resource = (const rm68200_resource_t *)(handle->resource);
mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2019-2021 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_RM68200_H_
#define _FSL_RM68200_H_
#include "fsl_display.h"
#include "fsl_mipi_dsi_cmd.h"
/*
* Change log:
*
* 1.1.1
* - Support 1 lane to 4 lanes, previously only support 2 lanes.
*
* 1.1.0
* - Fix MISRA-C 2012 issues.
* - Change rm68200_resource_t structure.
*
* 1.0.0
* - Initial version
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*!
* @brief RM68200 resource.
*/
typedef struct _rm68200_resource
{
mipi_dsi_device_t *dsiDevice; /*!< MIPI DSI device. */
void (*pullResetPin)(bool pullUp); /*!< Function to pull reset pin high or low. */
void (*pullPowerPin)(bool pullUp); /*!< Function to pull power pin high or low. */
} rm68200_resource_t;
extern const display_operations_t rm68200_ops;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
extern uint8_t RM68200_DDB_START[5];
status_t RM68200_Init(display_handle_t *handle, const display_config_t *config);
status_t RM68200_Deinit(display_handle_t *handle);
status_t RM68200_Start(display_handle_t *handle);
status_t RM68200_Stop(display_handle_t *handle);
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_RM68200_H_ */

View File

@@ -0,0 +1,301 @@
/*
* Copyright 2017, 2020-2021, 2023 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_video_common.h"
#if defined(SDK_OS_RTOS)
#include "rtthread.h"
#endif
/*******************************************************************************
* Code
******************************************************************************/
bool VIDEO_IsYUV(video_pixel_format_t format)
{
if ((kVIDEO_PixelFormatYUYV == format) || (kVIDEO_PixelFormatYVYU == format) ||
(kVIDEO_PixelFormatUYVY == format) || (kVIDEO_PixelFormatVYUY == format) ||
(kVIDEO_PixelFormatXYVU == format) || (kVIDEO_PixelFormatXYUV == format))
{
return true;
}
else
{
return false;
}
}
void VIDEO_DelayMs(uint32_t ms)
{
#if defined(SDK_OS_RTOS)
rt_thread_mdelay(ms);
#else
while (0U != (ms--))
{
SDK_DelayAtLeastUs(1000U, SystemCoreClock);
}
#endif
}
uint8_t VIDEO_GetPixelSizeBits(video_pixel_format_t pixelFormat)
{
uint8_t ret;
switch (pixelFormat)
{
case kVIDEO_PixelFormatXRGB8888:
case kVIDEO_PixelFormatRGBX8888:
case kVIDEO_PixelFormatXBGR8888:
case kVIDEO_PixelFormatBGRX8888:
case kVIDEO_PixelFormatXYUV:
case kVIDEO_PixelFormatXYVU:
ret = 32;
break;
case kVIDEO_PixelFormatRGB888:
case kVIDEO_PixelFormatBGR888:
ret = 24;
break;
case kVIDEO_PixelFormatRGB565:
case kVIDEO_PixelFormatBGR565:
case kVIDEO_PixelFormatXRGB1555:
case kVIDEO_PixelFormatRGBX5551:
case kVIDEO_PixelFormatXBGR1555:
case kVIDEO_PixelFormatBGRX5551:
case kVIDEO_PixelFormatXRGB4444:
case kVIDEO_PixelFormatRGBX4444:
case kVIDEO_PixelFormatXBGR4444:
case kVIDEO_PixelFormatBGRX4444:
case kVIDEO_PixelFormatYUYV:
case kVIDEO_PixelFormatYVYU:
case kVIDEO_PixelFormatUYVY:
case kVIDEO_PixelFormatVYUY:
ret = 16;
break;
case kVIDEO_PixelFormatRAW8:
case kVIDEO_PixelFormatLUT8:
ret = 8;
break;
default:
ret = 0;
break;
}
return ret;
}
status_t VIDEO_RINGBUF_Init(video_ringbuf_t *ringbuf, void **buf, uint32_t size)
{
assert(ringbuf != NULL);
ringbuf->rear = 0;
ringbuf->front = 0;
ringbuf->size = size;
ringbuf->buf = buf;
return kStatus_Success;
}
status_t VIDEO_RINGBUF_Get(video_ringbuf_t *ringbuf, void **item)
{
uint32_t front_next;
/* To fix IAR Pa082 warning. */
uint32_t rear = ringbuf->rear;
uint32_t front = ringbuf->front;
if (rear != front)
{
*item = ringbuf->buf[ringbuf->front];
/*
* Here don't use ringbuf->front = (ringbuf->front + 1) % ringbuf->size,
* because mod operation might be slow.
*/
front_next = (ringbuf->front + 1U);
/* Use two steps to make sure ringbuf->front is always a valid value. */
ringbuf->front = (front_next == ringbuf->size) ? 0UL : front_next;
return kStatus_Success;
}
else
{
return kStatus_Fail;
}
}
status_t VIDEO_RINGBUF_Put(video_ringbuf_t *ringbuf, void *item)
{
/*
* Here don't use ringbuf->rear = (ringbuf->rear + 1) % ringbuf->size,
* because mod operation might be slow.
*/
uint32_t rear_next = ringbuf->rear + 1U;
rear_next = (rear_next == ringbuf->size) ? 0U : rear_next;
if (rear_next != ringbuf->front)
{
ringbuf->buf[ringbuf->rear] = item;
ringbuf->rear = rear_next;
return kStatus_Success;
}
/* No room. */
else
{
return kStatus_Fail;
}
}
uint32_t VIDEO_RINGBUF_GetLength(video_ringbuf_t *ringbuf)
{
uint32_t ret;
/* To fix IAR Pa082 warning. */
uint32_t rear = ringbuf->rear;
uint32_t front = ringbuf->front;
ret = (rear + ringbuf->size) - front;
if (ret >= ringbuf->size)
{
ret -= ringbuf->size;
}
return ret;
}
bool VIDEO_RINGBUF_IsEmpty(video_ringbuf_t *ringbuf)
{
/* To fix IAR Pa082 warning. */
uint32_t rear = ringbuf->rear;
uint32_t front = ringbuf->front;
if (rear == front)
{
return true;
}
else
{
return false;
}
}
bool VIDEO_RINGBUF_IsFull(video_ringbuf_t *ringbuf)
{
uint32_t rear = ringbuf->rear;
uint32_t front = ringbuf->front;
rear++;
if (rear >= ringbuf->size)
{
rear = 0;
}
if (rear == front)
{
return true;
}
else
{
return false;
}
}
status_t VIDEO_MEMPOOL_Init(video_mempool_t *mempool, void *initMem, uint32_t size, uint32_t count)
{
(void)memset(mempool, 0, sizeof(video_mempool_t));
while (0U != (count--))
{
VIDEO_MEMPOOL_Put(mempool, initMem);
initMem = &((uint8_t *)initMem)[size];
}
return kStatus_Success;
}
void VIDEO_MEMPOOL_InitEmpty(video_mempool_t *mempool)
{
mempool->pool = NULL;
mempool->cnt = 0;
}
void VIDEO_MEMPOOL_Put(video_mempool_t *mempool, void *mem)
{
*(void **)mem = mempool->pool;
mempool->pool = mem;
mempool->cnt++;
}
void *VIDEO_MEMPOOL_Get(video_mempool_t *mempool)
{
void *mem = mempool->pool;
if (NULL != mem)
{
mempool->cnt--;
mempool->pool = *(void **)mem;
}
return mem;
}
uint32_t VIDEO_MEMPOOL_GetCount(video_mempool_t *mempool)
{
return mempool->cnt;
}
status_t VIDEO_STACK_Init(video_stack_t *stack, void **buf, uint32_t size)
{
stack->buf = buf;
stack->maxCount = size;
stack->top = 0U;
return kStatus_Success;
}
status_t VIDEO_STACK_Pop(video_stack_t *stack, void **item)
{
status_t status;
if (stack->top > 0U)
{
*item = stack->buf[--stack->top];
status = kStatus_Success;
}
else
{
*item = NULL;
status = kStatus_Fail;
}
return status;
}
status_t VIDEO_STACK_Push(video_stack_t *stack, void *item)
{
status_t status;
if (stack->top < (stack->maxCount))
{
stack->buf[stack->top++] = item;
status = kStatus_Success;
}
else
{
status = kStatus_Fail;
}
return status;
}

View File

@@ -0,0 +1,364 @@
/*
* Copyright 2017, 2020-2021, 2023 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_VIDEO_COMMON_H_
#define _FSL_VIDEO_COMMON_H_
#include "fsl_common.h"
/*
* Change log:
*
* 1.1.0
* - Add stack function which supports LIFO item management.
*
* 1.0.5
* - Fix IAR Pa082 warning.
*
* 1.0.4
* - Add LUT8 definition.
*
* 1.0.3
* - Add RAW8 definition.
*
* 1.0.2
* - Fixed MISRA-C 2012 issues.
*
* 1.0.1
* - Update the VIDEO_DelayMs for bare metal.
*
* 1.0.0
* - Initial version
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Pixel format FOURCC. */
#define FSL_VIDEO_FOURCC(a, b, c, d) \
((uint32_t)(a) | ((uint32_t)(b) << 8U) | ((uint32_t)(c) << 16U) | ((uint32_t)(d) << 24U))
/*! @brief Macro to define resolution. */
#define FSL_VIDEO_RESOLUTION(width, height) ((uint32_t)(width) | ((uint32_t)(height) << 16U))
#define FSL_VIDEO_EXTRACT_WIDTH(resolution) ((uint16_t)((resolution)&0xFFFFU))
#define FSL_VIDEO_EXTRACT_HEIGHT(resolution) ((uint16_t)((resolution) >> 16U))
/*! @brief Pixel format definition. */
typedef enum _video_pixel_format
{
/* RAW */
kVIDEO_PixelFormatRAW8 = FSL_VIDEO_FOURCC('G', 'R', 'B', 'G'), /*!< RAW8, GRBG. */
/* LUT/palette */
kVIDEO_PixelFormatLUT8 = FSL_VIDEO_FOURCC('L', 'U', 'T', '8'), /*!< 8-bit Indexed Color. */
/* RGB */
kVIDEO_PixelFormatXRGB8888 = FSL_VIDEO_FOURCC('X', 'R', '2', '4'), /*!< 32-bit XRGB8888. */
kVIDEO_PixelFormatRGBX8888 = FSL_VIDEO_FOURCC('R', 'X', '2', '4'), /*!< 32-bit RGBX8888. */
kVIDEO_PixelFormatXBGR8888 = FSL_VIDEO_FOURCC('X', 'B', '2', '4'), /*!< 32-bit XBGR8888. */
kVIDEO_PixelFormatBGRX8888 = FSL_VIDEO_FOURCC('B', 'X', '2', '4'), /*!< 32-bit BGRX8888. */
kVIDEO_PixelFormatRGB888 = FSL_VIDEO_FOURCC('R', 'G', '2', '4'), /*!< 24-bit RGB888. */
kVIDEO_PixelFormatBGR888 = FSL_VIDEO_FOURCC('B', 'G', '2', '4'), /*!< 24-bit BGR888. */
kVIDEO_PixelFormatRGB565 = FSL_VIDEO_FOURCC('R', 'G', '1', '6'), /*!< 16-bit RGB565. */
kVIDEO_PixelFormatBGR565 = FSL_VIDEO_FOURCC('B', 'G', '1', '6'), /*!< 16-bit BGR565. */
kVIDEO_PixelFormatXRGB1555 = FSL_VIDEO_FOURCC('X', 'R', '1', '5'), /*!< 16-bit XRGB1555. */
kVIDEO_PixelFormatRGBX5551 = FSL_VIDEO_FOURCC('R', 'X', '1', '5'), /*!< 16-bit RGBX5551. */
kVIDEO_PixelFormatXBGR1555 = FSL_VIDEO_FOURCC('X', 'B', '1', '5'), /*!< 16-bit XBGR1555. */
kVIDEO_PixelFormatBGRX5551 = FSL_VIDEO_FOURCC('B', 'X', '1', '5'), /*!< 16-bit BGRX5551. */
kVIDEO_PixelFormatXRGB4444 = FSL_VIDEO_FOURCC('X', 'R', '1', '2'), /*!< 16-bit XRGB4444. */
kVIDEO_PixelFormatRGBX4444 = FSL_VIDEO_FOURCC('R', 'X', '1', '2'), /*!< 16-bit RGBX4444. */
kVIDEO_PixelFormatXBGR4444 = FSL_VIDEO_FOURCC('X', 'B', '1', '2'), /*!< 16-bit XBGR4444. */
kVIDEO_PixelFormatBGRX4444 = FSL_VIDEO_FOURCC('B', 'X', '1', '2'), /*!< 16-bit BGRX4444. */
/* YUV. */
kVIDEO_PixelFormatYUYV = FSL_VIDEO_FOURCC('Y', 'U', 'Y', 'V'), /*!< YUV422, Y-U-Y-V. */
kVIDEO_PixelFormatYVYU = FSL_VIDEO_FOURCC('Y', 'V', 'Y', 'U'), /*!< YUV422, Y-V-Y-U. */
kVIDEO_PixelFormatUYVY = FSL_VIDEO_FOURCC('U', 'Y', 'V', 'Y'), /*!< YUV422, U-Y-V-Y. */
kVIDEO_PixelFormatVYUY = FSL_VIDEO_FOURCC('V', 'Y', 'U', 'Y'), /*!< YUV422, V-Y-U-Y. */
kVIDEO_PixelFormatXYUV = FSL_VIDEO_FOURCC('X', 'Y', 'U', 'V'), /*!< YUV444, X-Y-U-V. */
kVIDEO_PixelFormatXYVU = FSL_VIDEO_FOURCC('X', 'Y', 'V', 'U'), /*!< YUV444, X-Y-V-U. */
} video_pixel_format_t;
/*! @brief Resolution definition. */
typedef enum _video_resolution
{
kVIDEO_ResolutionVGA = FSL_VIDEO_RESOLUTION(640, 480), /*!< VGA, 640 * 480 */
kVIDEO_ResolutionQVGA = FSL_VIDEO_RESOLUTION(320, 240), /*!< QVGA, 320 * 240 */
kVIDEO_ResolutionQQVGA = FSL_VIDEO_RESOLUTION(160, 120), /*!< QQVGA, 160 * 120 */
kVIDEO_ResolutionCIF = FSL_VIDEO_RESOLUTION(352, 288), /*!< CIF, 352 * 288 */
kVIDEO_ResolutionQCIF = FSL_VIDEO_RESOLUTION(176, 144), /*!< QCIF, 176 * 144 */
kVIDEO_ResolutionQQCIF = FSL_VIDEO_RESOLUTION(88, 72), /*!< QQCIF, 88 * 72 */
kVIDEO_Resolution720P = FSL_VIDEO_RESOLUTION(1280, 720), /*!< 720P, 1280 * 720 */
kVIDEO_Resolution1080P = FSL_VIDEO_RESOLUTION(1920, 1080), /*!< 1080P, 1920 * 1280*/
kVIDEO_ResolutionWXGA = FSL_VIDEO_RESOLUTION(1280, 800), /*!< WXGA, 1280 * 800 */
} video_resolution_t;
/*!
* @brief Ring buffer structure.
*
* There is one empty room reserved in the ring buffer, used to distinguish
* whether the ring buffer is full or empty. When rear equals front, it is empty;
* when rear+1 equals front, it is full.
*/
typedef struct
{
volatile uint32_t rear; /*!< Pointer to save the incoming item. */
volatile uint32_t front; /*!< Pointer to read out the item. */
void *volatile *buf; /*!< Memory to the ring buffer. */
uint32_t size; /*!< Ring buffer total size. */
} video_ringbuf_t;
/*!
* @brief Memory pool structure.
*/
typedef struct
{
void *volatile pool; /*!< Pointer to the pool. */
volatile uint32_t cnt; /*!< Count of memory blocks in the pool. */
} video_mempool_t;
/*!
* @brief Stack structure.
*/
typedef struct
{
void **buf; /*!< Pointer to the memory to store the items. */
volatile uint32_t top; /*!< Current top stack top. */
uint32_t maxCount; /*!< Maximal count of items can be stored in the stack. */
} video_stack_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Common
* @{
*/
/*!
* @brief Check the pixel format is YUV or not.
*
* @param format Pixel format.
*/
bool VIDEO_IsYUV(video_pixel_format_t format);
/*!
* @brief Delay the specific time.
*
* @param ms How many milli-second to delay.
*/
void VIDEO_DelayMs(uint32_t ms);
/*!
* @brief Get the pixel size in bits.
*
* @param pixelFormat The pixel format.
* @return Bits per pixel.
*/
uint8_t VIDEO_GetPixelSizeBits(video_pixel_format_t pixelFormat);
/* @} */
/*!
* @name Ring buffer.
* @{
*/
/*!
* @brief Initializes ring buffer.
*
* @param ringbuf Pointer to the ring buffer handle.
* @param buf Memory to save the items.
* @param size Size of the @p buf.
* @return Returns @ref kStatus_Success if initialize success, otherwise returns
* error code.
*/
status_t VIDEO_RINGBUF_Init(video_ringbuf_t *ringbuf, void **buf, uint32_t size);
/*!
* @brief Get one item from the ring buffer.
*
* @param ringbuf Pointer to the ring buffer handle.
* @param item Memory to save the item.
* @return Returns @ref kStatus_Success if get success, otherwise returns
* error code.
*/
status_t VIDEO_RINGBUF_Get(video_ringbuf_t *ringbuf, void **item);
/*!
* @brief Put one item to the ring buffer.
*
* @param ringbuf Pointer to the ring buffer handle.
* @param item The new item to save.
* @return Returns @ref kStatus_Success if put success, otherwise returns
* error code.
*/
status_t VIDEO_RINGBUF_Put(video_ringbuf_t *ringbuf, void *item);
/*!
* @brief Get current count of items in the ring buffer.
*
* @param ringbuf Pointer to the ring buffer handle.
* @return Returns the item count.
*/
uint32_t VIDEO_RINGBUF_GetLength(video_ringbuf_t *ringbuf);
/*!
* @brief Check whether the ring buffer is empty.
*
* @param ringbuf Pointer to the ring buffer handle.
* @return Returns true if the ring buffer is empty, otherwise returns false.
*/
bool VIDEO_RINGBUF_IsEmpty(video_ringbuf_t *ringbuf);
/*!
* @brief Check whether the ring buffer is full.
*
* @param ringbuf Pointer to the ring buffer handle.
* @return Returns true if the ring buffer is full, otherwise returns false.
*/
bool VIDEO_RINGBUF_IsFull(video_ringbuf_t *ringbuf);
/* @} */
/*!
* @name Memory Pool
*
* User can put memory block to the pool, or get memory block from the pool.
* There is no count limitation to put memory block in to the pool. The memory
* content in the pool might be modified.
*
* The memory block should be 4-byte aligned, and the dividable by 4-byte.
*
* @{
*/
/*!
* @brief Initializes memory pool.
*
* Initializes memory pool. Initial memory blocks in the memory pool is optional.
* If initial blocks are used, user should specify the initial block size and count.
*
* @param mempool Pointer to the memory pool handle.
* @param initMem Initial memory blocks to saved in the pool.
* @param size Every memory block's size (bytes) in the @p initMem.
* @param count Number of memory blocks @p initMem.
* @return Returns @ref kStatus_Success if initialize success, otherwise returns
* error code.
*/
status_t VIDEO_MEMPOOL_Init(video_mempool_t *mempool, void *initMem, uint32_t size, uint32_t count);
/*!
* @brief Create an empty memory pool.
*
* @param mempool Pointer to the memory pool handle.
*/
void VIDEO_MEMPOOL_InitEmpty(video_mempool_t *mempool);
/*!
* @brief Put memory block in the pool.
*
* @param mempool Pointer to the memory pool handle.
* @param mem Pointer to the memory block.
*/
void VIDEO_MEMPOOL_Put(video_mempool_t *mempool, void *mem);
/*!
* @brief Get memory block in the pool.
*
* @param mempool Pointer to the memory pool handle.
* @return The memory block get from pool. If the pool is empty, returns NULL.
*/
void *VIDEO_MEMPOOL_Get(video_mempool_t *mempool);
/*!
* @brief How many memory blocks in the pool.
*
* @param mempool Pointer to the memory pool handle.
* @return The memory block count in the pool
*/
uint32_t VIDEO_MEMPOOL_GetCount(video_mempool_t *mempool);
/* @} */
/*!
* @name Stack which supports LIFO item management.
* @{
*/
/*!
* @brief Initializes stack.
*
* @param stack Pointer to the stack handle.
* @param buf Memory to save the items.
* @param size Size of the @p buf.
* @return Returns @ref kStatus_Success if initialize success, otherwise returns
* error code.
*/
status_t VIDEO_STACK_Init(video_stack_t *stack, void **buf, uint32_t size);
/*!
* @brief Pop one item from the stack.
*
* @param stack Pointer to the stack handle.
* @param item Memory to save the item.
* @return Returns @ref kStatus_Success if get success, returns
* kStatus_Fail if the stack is empty.
*/
status_t VIDEO_STACK_Pop(video_stack_t *stack, void **item);
/*!
* @brief Put one item to the stack.
*
* @param stack Pointer to the stack handle.
* @param item The new item to save.
* @return Returns @ref kStatus_Success if put success, returns
* kStatus_Fail if the stack is full.
*/
status_t VIDEO_STACK_Push(video_stack_t *stack, void *item);
/*!
* @brief Get current count of items in the stack.
*
* @param stack Pointer to the stack handle.
* @return Returns the item count.
*/
static inline uint32_t VIDEO_STACK_GetCount(video_stack_t *stack)
{
return stack->top;
}
/*!
* @brief Get maxiumal count of items in the stack.
*
* @param stack Pointer to the stack handle.
* @return Returns the maxiumal count of items in the stack.
*/
static inline uint32_t VIDEO_STACK_GetMaxCount(video_stack_t *stack)
{
return stack->maxCount;
}
/* @} */
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_VIDEO_COMMON_H_ */

View File

@@ -0,0 +1,14 @@
/* Tiny library for rendering compressed bitmap fonts on microcontrollers. */
#ifndef _MCUFONT_H_
#define _MCUFONT_H_
#include "mf_config.h"
#include "mf_encoding.h"
#include "mf_justify.h"
#include "mf_kerning.h"
#include "mf_rlefont.h"
#include "mf_scaledfont.h"
#include "mf_wordwrap.h"
#endif

View File

@@ -0,0 +1,134 @@
#include "mf_bwfont.h"
#include <stdbool.h>
/* Find the character range and index that contains a given glyph.. */
static const struct mf_bwfont_char_range_s *find_char_range(
const struct mf_bwfont_s *font, uint16_t character, uint16_t *index_ret)
{
unsigned i, index;
const struct mf_bwfont_char_range_s *range;
for (i = 0; i < font->char_range_count; i++)
{
range = &font->char_ranges[i];
index = character - range->first_char;
if (character >= range->first_char && index < range->char_count)
{
*index_ret = index;
return range;
}
}
return 0;
}
static uint8_t get_width(const struct mf_bwfont_char_range_s *r, uint16_t index)
{
if (r->width)
{
return r->width + r->offset_x;
}
else
{
return r->glyph_widths[index];
}
}
static uint8_t render_char(const struct mf_bwfont_char_range_s *r,
int16_t x0, int16_t y0, uint16_t index,
mf_pixel_callback_t callback,
void *state)
{
const uint8_t *data, *p;
uint8_t stride, runlen;
uint8_t x, y, height, num_cols;
uint8_t bit, byte, mask;
bool oldstate, newstate;
if (r->width)
{
data = r->glyph_data + r->width * index * r->height_bytes;
num_cols = r->width;
}
else
{
data = r->glyph_data + r->glyph_offsets[index] * r->height_bytes;
num_cols = r->glyph_offsets[index + 1] - r->glyph_offsets[index];
}
stride = r->height_bytes;
height = r->height_pixels;
y0 += r->offset_y;
x0 += r->offset_x;
bit = 0;
byte = 0;
for (y = 0; y < height; y++)
{
mask = (1 << bit);
oldstate = false;
runlen = 0;
p = data + byte;
for (x = 0; x < num_cols; x++, p += stride)
{
newstate = pgm_read_byte(p) & mask;
if (newstate != oldstate)
{
if (oldstate && runlen)
{
callback(x0 + x - runlen, y0 + y, runlen, 255, state);
}
oldstate = newstate;
runlen = 0;
}
runlen++;
}
if (oldstate && runlen)
{
callback(x0 + x - runlen, y0 + y, runlen, 255, state);
}
bit++;
if (bit > 7)
{
bit = 0;
byte++;
}
}
return get_width(r, index);
}
uint8_t mf_bwfont_render_character(const struct mf_font_s *font,
int16_t x0, int16_t y0,
uint16_t character,
mf_pixel_callback_t callback,
void *state)
{
const struct mf_bwfont_s *bwfont = (const struct mf_bwfont_s*)font;
const struct mf_bwfont_char_range_s *range;
uint16_t index;
range = find_char_range(bwfont, character, &index);
if (!range)
return 0;
return render_char(range, x0, y0, index, callback, state);
}
uint8_t mf_bwfont_character_width(const struct mf_font_s *font,
uint16_t character)
{
const struct mf_bwfont_s *bwfont = (const struct mf_bwfont_s*)font;
const struct mf_bwfont_char_range_s *range;
uint16_t index;
range = find_char_range(bwfont, character, &index);
if (!range)
return 0;
return get_width(range, index);
}

View File

@@ -0,0 +1,77 @@
/* Uncompressed font format for storing black & white fonts. Very efficient
* to decode and works well for small font sizes.
*/
#ifndef _MF_BWFONT_H_
#define _MF_BWFONT_H_
#include "mf_font.h"
/* Versions of the BW font format that are supported. */
#define MF_BWFONT_VERSION_4_SUPPORTED 1
/* Structure for a range of characters. */
struct mf_bwfont_char_range_s
{
/* The number of the first character in this range. */
uint16_t first_char;
/* The total count of characters in this range. */
uint16_t char_count;
/* The left and top skips of the characters in this range.
* This is the number of empty rows at left and at top. */
uint8_t offset_x;
uint8_t offset_y;
/* Column height for glyphs in this range, in bytes and pixels. */
uint8_t height_bytes;
uint8_t height_pixels;
/* Positive value if the width of all glyphs in this range is the
* same, or zero if it is not. */
uint8_t width;
/* Lookup table for the character widths. NULL if width is specified. */
uint8_t *glyph_widths;
/* Lookup table for the character offsets. Multiply by height_bytes
* to get the byte offset. Also allows lookup of the number of columns.
* NULL if width is specified. */
uint16_t *glyph_offsets;
/* Table for the glyph data.
* The data for each glyph is column-by-column, with N bytes per each
* column. The LSB of the first byte is the top left pixel.
*/
uint8_t *glyph_data;
};
/* Structure for the font */
struct mf_bwfont_s
{
struct mf_font_s font;
/* Version of the font format. */
uint8_t version;
/* Number of character ranges. */
uint8_t char_range_count;
/* Array of the character ranges */
struct mf_bwfont_char_range_s *char_ranges;
};
#ifdef MF_BWFONT_INTERNALS
/* Internal functions, don't use these directly. */
MF_EXTERN uint8_t mf_bwfont_render_character(const struct mf_font_s *font,
int16_t x0, int16_t y0,
mf_char character,
mf_pixel_callback_t callback,
void *state);
MF_EXTERN uint8_t mf_bwfont_character_width(const struct mf_font_s *font,
mf_char character);
#endif
#endif

View File

@@ -0,0 +1,144 @@
/* Configuration constants for mcufont. */
#ifndef _MF_CONFIG_H_
#define _MF_CONFIG_H_
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
#include <pgmspace.h>
#else
#include <stdint.h>
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const uint16_t *)(addr))
#endif /* __AVR__ */
/*******************************************************
* Configuration settings related to build environment *
*******************************************************/
/* Name of the file that contains all the included fonts. */
#ifndef MF_FONT_FILE_NAME
#define MF_FONT_FILE_NAME "fonts.h"
#endif
/*****************************************
* Configuration settings related to API *
*****************************************/
/* Encoding for the input data.
* With the unicode encodings, the library supports the range of unicode
* characters 0x0000-0xFFFF (the Basic Multilingual Plane).
*
* ASCII: Plain ascii (somewhat works with ISO8859-1 also)
* UTF8: UTF8 encoding (variable number of bytes)
* UTF16: UTF16 encoding (2 bytes per character, compatible with UCS-2)
* WCHAR: Use compiler's wchar_t (usually same as UTF16)
*/
#define MF_ENCODING_ASCII 0
#define MF_ENCODING_UTF8 1
#define MF_ENCODING_UTF16 2
#define MF_ENCODING_WCHAR 3
#ifndef MF_ENCODING
#define MF_ENCODING MF_ENCODING_UTF8
#endif
/************************************************************************
* Configuration settings related to visual appearance of rendered text *
************************************************************************/
/* Minimum space between characters, in percents of the glyph width.
* Increasing this causes the kerning module to leave more space between
* characters.
*/
#ifndef MF_KERNING_SPACE_PERCENT
#define MF_KERNING_SPACE_PERCENT 15
#endif
/* Minimum space between characters, in pixels. Added to the percentual
* spacing. This pixel-based value guarantees enough space even with small
* fonts.
*/
#ifndef MF_KERNING_SPACE_PIXELS
#define MF_KERNING_SPACE_PIXELS 3
#endif
/* Maximum adjustment done by the kerning algorithm, as percent of the
* glyph width.
*/
#ifndef MF_KERNING_LIMIT
#define MF_KERNING_LIMIT 20
#endif
/* Spacing of tabulator stops. The value is multiplied by the width of the
* 'm' character in the current font.
*/
#ifndef MF_TABSIZE
#define MF_TABSIZE 8
#endif
/*************************************************************************
* Configuration settings to strip down library to reduce resource usage *
*************************************************************************/
/* Enable or disable the kerning module.
* Disabling it saves some code size and run time, but causes the spacing
* between characters to be less consistent.
*/
#ifndef MF_USE_KERNING
#define MF_USE_KERNING 1
#endif
/* Enable or disable the advanced word wrap algorithm.
* If disabled, uses a simpler algorithm.
*/
#ifndef MF_USE_ADVANCED_WORDWRAP
#define MF_USE_ADVANCED_WORDWRAP 1
#endif
/* Enable of disable the justification algorithm.
* If disabled, mf_render_justified renders just left-aligned.
*/
#ifndef MF_USE_JUSTIFY
#define MF_USE_JUSTIFY 1
#endif
/* Enable or disable the center and right alignment code.
* If disabled, any alignment results in MF_ALIGN_LEFT.
*/
#ifndef MF_USE_ALIGN
#define MF_USE_ALIGN 1
#endif
/* Enable or disable the support for tab alignment.
* If disabled, tabs will be rendered as regular space character.
*/
#ifndef MF_USE_TABS
#define MF_USE_TABS 1
#endif
/* Number of vertical zones to use when computing kerning.
* Larger values give more accurate kerning, but are slower and use somewhat
* more memory. There is no point to increase this beyond the height of the
* font.
*/
#ifndef MF_KERNING_ZONES
#define MF_KERNING_ZONES 16
#endif
/* Add extern "C" when used from C++. */
#ifdef __cplusplus
#define MF_EXTERN extern "C"
#else
#define MF_EXTERN extern
#endif
#endif

View File

@@ -0,0 +1,84 @@
#include "mf_encoding.h"
#if MF_ENCODING == MF_ENCODING_UTF8
mf_char mf_getchar(mf_str *str)
{
uint8_t c;
uint8_t tmp, seqlen;
uint16_t result;
c = **str;
if (!c)
return 0;
(*str)++;
if ((c & 0x80) == 0)
{
/* Just normal ASCII character. */
return c;
}
else if ((c & 0xC0) == 0x80)
{
/* Dangling piece of corrupted multibyte sequence.
* Did you cut the string in the wrong place?
*/
return c;
}
else if ((**str & 0xC0) == 0xC0)
{
/* Start of multibyte sequence without any following bytes.
* Silly. Maybe you are using the wrong encoding.
*/
return c;
}
else
{
/* Beginning of a multi-byte sequence.
* Find out how many characters and combine them.
*/
seqlen = 2;
tmp = 0x20;
result = 0;
while ((c & tmp) && (seqlen < 5))
{
seqlen++;
tmp >>= 1;
result = (result << 6) | (**str & 0x3F);
(*str)++;
}
result = (result << 6) | (**str & 0x3F);
(*str)++;
result |= (c & (tmp - 1)) << ((seqlen - 1) * 6);
return result;
}
}
void mf_rewind(mf_str *str)
{
(*str)--;
while ((**str & 0x80) != 0x00 && (**str & 0xC0) != 0xC0)
(*str)--;
}
#else
mf_char mf_getchar(mf_str *str)
{
if (!(**str))
return 0;
else
return *(*str)++;
}
void mf_rewind(mf_str *str)
{
(*str)--;
}
#endif

Some files were not shown because too many files have changed in this diff Show More