Implement LVGL with SDL for simulator (#16)
* Implemented LVGL with SDL for simulator * cleanup * added SDL to build * build fix * mutex fixes * sim app cleanup and improvements * docs updated * fix for sdl? * fix for SDL cmake setup
This commit is contained in:
parent
18a5c5aa45
commit
d6baf40d0b
8
.github/workflows/pc.yml
vendored
8
.github/workflows/pc.yml
vendored
@ -8,9 +8,17 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: libsdl-org/setup-sdl@main
|
||||
id: sdl
|
||||
with:
|
||||
install-linux-dependencies: true
|
||||
version: 2-latest
|
||||
version-sdl-image: 2-latest
|
||||
- name: Configure Project
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
- name: Prepare Project
|
||||
run: cmake -S ./ -B build
|
||||
- name: Build Project
|
||||
env:
|
||||
USE_SDL_WITH_NAMESPACE: true
|
||||
run: cmake --build build
|
||||
|
||||
@ -36,8 +36,73 @@ add_subdirectory(tactility)
|
||||
add_subdirectory(tactility-core)
|
||||
|
||||
if (NOT ESP_PLATFORM)
|
||||
add_subdirectory(libs/lvgl) # Added as idf component for ESP and as library for other targets
|
||||
add_subdirectory(libs/freertos-kernel)
|
||||
add_subdirectory(libs/mbedtls)
|
||||
add_subdirectory(app-sim)
|
||||
|
||||
# region LVGL
|
||||
|
||||
add_subdirectory(libs/lvgl) # Added as idf component for ESP and as library for other targets
|
||||
add_subdirectory(libs/lv_drivers)
|
||||
|
||||
option(LV_USE_DRAW_SDL "Use SDL draw unit" OFF)
|
||||
option(LV_USE_LIBPNG "Use libpng to decode PNG" OFF)
|
||||
option(LV_USE_LIBJPEG_TURBO "Use libjpeg turbo to decode JPEG" OFF)
|
||||
option(LV_USE_FFMPEG "Use libffmpeg to display video using lv_ffmpeg" OFF)
|
||||
option(LV_USE_FREETYPE "Use freetype lib" OFF)
|
||||
|
||||
set(CMAKE_C_STANDARD 99) # C99 # lvgl officially support C99 and above
|
||||
set(CMAKE_CXX_STANDARD 17) # C17
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
||||
|
||||
find_package(SDL2 REQUIRED CONFIG)
|
||||
|
||||
add_compile_definitions($<$<BOOL:${LV_USE_DRAW_SDL}>:LV_USE_DRAW_SDL=1>)
|
||||
add_compile_definitions($<$<BOOL:${LV_USE_LIBPNG}>:LV_USE_LIBPNG=1>)
|
||||
add_compile_definitions($<$<BOOL:${LV_USE_LIBJPEG_TURBO}>:LV_USE_LIBJPEG_TURBO=1>)
|
||||
add_compile_definitions($<$<BOOL:${LV_USE_FFMPEG}>:LV_USE_FFMPEG=1>)
|
||||
|
||||
target_include_directories(lvgl
|
||||
PUBLIC ${SDL2_INCLUDE_DIRS}
|
||||
PUBLIC app-sim/src # for lv_conf.h and lv_drv_conf.h
|
||||
)
|
||||
|
||||
if (LV_USE_DRAW_SDL)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
# Need to install libsdl2-image-dev
|
||||
# `sudo apt install libsdl2-image-dev`
|
||||
# `brew install sdl2_image`
|
||||
find_package(SDL2_image REQUIRED)
|
||||
target_include_directories(lvgl PUBLIC ${SDL2_IMAGE_INCLUDE_DIRS})
|
||||
target_link_libraries(app-sim ${SDL2_IMAGE_LIBRARIES})
|
||||
endif(LV_USE_DRAW_SDL)
|
||||
|
||||
if (LV_USE_LIBPNG)
|
||||
find_package(PNG REQUIRED)
|
||||
target_include_directories(lvgl PUBLIC ${PNG_INCLUDE_DIR})
|
||||
target_link_libraries(app-sim ${PNG_LIBRARY})
|
||||
endif(LV_USE_LIBPNG)
|
||||
|
||||
if (LV_USE_LIBJPEG_TURBO)
|
||||
# Need to install libjpeg-turbo8-dev
|
||||
# `sudo apt install libjpeg-turbo8-dev`
|
||||
# `brew install libjpeg-turbo`
|
||||
find_package(JPEG REQUIRED)
|
||||
target_include_directories(lvgl PUBLIC ${JPEG_INCLUDE_DIRS})
|
||||
target_link_libraries(app-sim ${JPEG_LIBRARIES})
|
||||
endif(LV_USE_LIBJPEG_TURBO)
|
||||
|
||||
if (LV_USE_FFMPEG)
|
||||
target_link_libraries(main avformat avcodec avutil swscale)
|
||||
endif(LV_USE_FFMPEG)
|
||||
|
||||
if (LV_USE_FREETYPE)
|
||||
find_package(Freetype REQUIRED)
|
||||
target_link_libraries(app-sim ${FREETYPE_LIBRARIES})
|
||||
target_include_directories(lvgl PUBLIC ${FREETYPE_INCLUDE_DIRS})
|
||||
endif(LV_USE_FREETYPE)
|
||||
|
||||
#endregion
|
||||
endif()
|
||||
|
||||
@ -3,15 +3,17 @@
|
||||
Tactility is a front-end application platform for ESP32. It is mainly intended for touchscreen devices.
|
||||
It provides an application framework that is based on code from the [Flipper Zero](https://github.com/flipperdevices/flipperzero-firmware/) project.
|
||||
|
||||
Tactility provides:
|
||||

|
||||
|
||||
Tactility features:
|
||||
- A hardware abstraction layer
|
||||
- UI capabilities (via LVGL)
|
||||
- An application platform that can run apps and services
|
||||
- PC app support to speed up development for ESP32 apps
|
||||
|
||||
Requirements:
|
||||
- ESP32 (any?)
|
||||
- ESP32 (any?) with a display (connected via SPI or I2C)
|
||||
- [esp-idf 5.1.2](https://docs.espressif.com/projects/esp-idf/en/v5.1.2/esp32/get-started/index.html) or a newer v5.1.x
|
||||
- a display (connected via SPI or I2C)
|
||||
|
||||
**Status: Alpha**
|
||||
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
file(GLOB SOURCES "src/*.c")
|
||||
file(GLOB_RECURSE SOURCES "src/*.c")
|
||||
add_executable(app-sim ${SOURCES})
|
||||
target_link_libraries(app-sim PRIVATE tactility)
|
||||
target_link_libraries(app-sim PRIVATE tactility-core)
|
||||
target_link_libraries(app-sim
|
||||
PRIVATE tactility
|
||||
PRIVATE tactility-core
|
||||
PRIVATE lvgl
|
||||
PRIVATE lv_drivers
|
||||
)
|
||||
|
||||
find_package(SDL2 REQUIRED CONFIG)
|
||||
target_link_libraries(app-sim PRIVATE ${SDL2_LIBRARIES})
|
||||
include_directories(${SDL2_INCLUDE_DIRS})
|
||||
|
||||
add_definitions(-D_Nullable=)
|
||||
add_definitions(-D_Nonnull=)
|
||||
|
||||
|
||||
65
app-sim/src/freertos.c
Normal file
65
app-sim/src/freertos.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include "tactility.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#define TAG "freertos"
|
||||
|
||||
#define mainQUEUE_RECEIVE_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
|
||||
|
||||
_Noreturn void app_main();
|
||||
|
||||
bool lvgl_is_ready();
|
||||
void lvgl_task(void*);
|
||||
|
||||
void app_main_task(TT_UNUSED void* parameter) {
|
||||
while (!lvgl_is_ready()) {
|
||||
TT_LOG_I(TAG, "waiting for lvgl task");
|
||||
vTaskDelay(50);
|
||||
}
|
||||
|
||||
app_main();
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create the main app loop, like ESP-IDF
|
||||
xTaskCreate(
|
||||
lvgl_task,
|
||||
"lvgl",
|
||||
8192,
|
||||
NULL,
|
||||
mainQUEUE_RECEIVE_TASK_PRIORITY + 2,
|
||||
NULL
|
||||
);
|
||||
|
||||
xTaskCreate(
|
||||
app_main_task,
|
||||
"app_main",
|
||||
8192,
|
||||
NULL,
|
||||
mainQUEUE_RECEIVE_TASK_PRIORITY + 1,
|
||||
NULL
|
||||
);
|
||||
|
||||
// Blocks forever
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert implementation as defined in the FreeRTOSConfig.h
|
||||
* It allows you to set breakpoints and debug asserts.
|
||||
*/
|
||||
void vAssertCalled(TT_UNUSED unsigned long line, TT_UNUSED const char* const file) {
|
||||
static portBASE_TYPE xPrinted = pdFALSE;
|
||||
volatile uint32_t set_to_nonzero_in_debugger_to_continue = 0;
|
||||
|
||||
TT_LOG_E(TAG, "assert triggered");
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
// Step out by attaching a debugger and setting set_to_nonzero_in_debugger_to_continue
|
||||
while (set_to_nonzero_in_debugger_to_continue == 0) {
|
||||
// NO-OP
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
22
app-sim/src/hello_world/hello_world.c
Normal file
22
app-sim/src/hello_world/hello_world.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include "hello_world.h"
|
||||
#include "services/gui/gui.h"
|
||||
#include "services/loader/loader.h"
|
||||
|
||||
static void app_show(TT_UNUSED App app, lv_obj_t* parent) {
|
||||
lv_obj_t* label = lv_label_create(parent);
|
||||
lv_label_set_recolor(label, true);
|
||||
lv_obj_set_width(label, 200);
|
||||
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
|
||||
lv_label_set_text(label, "Hello, world!");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
}
|
||||
|
||||
const AppManifest hello_world_app = {
|
||||
.id = "helloworld",
|
||||
.name = "Hello World",
|
||||
.icon = NULL,
|
||||
.type = AppTypeUser,
|
||||
.on_start = NULL,
|
||||
.on_stop = NULL,
|
||||
.on_show = &app_show
|
||||
};
|
||||
5
app-sim/src/hello_world/hello_world.h
Normal file
5
app-sim/src/hello_world/hello_world.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "app_manifest.h"
|
||||
|
||||
extern const AppManifest hello_world_app;
|
||||
700
app-sim/src/lv_conf.h
Normal file
700
app-sim/src/lv_conf.h
Normal file
@ -0,0 +1,700 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
* Configuration file for v8.2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copy this file as `lv_conf.h`
|
||||
* 1. simply next to the `lvgl` folder
|
||||
* 2. or any other places and
|
||||
* - define `LV_CONF_INCLUDE_SIMPLE`
|
||||
* - add the path as include path
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
#if 1 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*====================
|
||||
COLOR SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
|
||||
#define LV_COLOR_DEPTH 32
|
||||
|
||||
/*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
|
||||
/*Enable more complex drawing routines to manage screens transparency.
|
||||
*Can be used if the UI is above another layer, e.g. an OSD menu or video player.
|
||||
*Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
|
||||
/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently.
|
||||
* 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */
|
||||
#define LV_COLOR_MIX_ROUND_OFS (LV_COLOR_DEPTH == 32 ? 0: 128)
|
||||
|
||||
/*Images pixels with this color will not be drawn if they are chroma keyed)*/
|
||||
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*pure green*/
|
||||
|
||||
/*=========================
|
||||
MEMORY SETTINGS
|
||||
*=========================*/
|
||||
|
||||
/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
|
||||
#define LV_MEM_SIZE (128 * 1024U) /*[bytes]*/
|
||||
|
||||
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
|
||||
#define LV_MEM_ADR 0 /*0: unused*/
|
||||
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
|
||||
#if LV_MEM_ADR == 0
|
||||
//#define LV_MEM_POOL_INCLUDE your_alloc_library /* Uncomment if using an external allocator*/
|
||||
//#define LV_MEM_POOL_ALLOC your_alloc /* Uncomment if using an external allocator*/
|
||||
#endif
|
||||
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
#define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
#define LV_MEM_CUSTOM_ALLOC malloc
|
||||
#define LV_MEM_CUSTOM_FREE free
|
||||
#define LV_MEM_CUSTOM_REALLOC realloc
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/*Number of the intermediate memory buffer used during rendering and other internal processing mechanisms.
|
||||
*You will see an error log message if there wasn't enough buffers. */
|
||||
#define LV_MEM_BUF_MAX_NUM 16
|
||||
|
||||
/*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/
|
||||
#define LV_MEMCPY_MEMSET_STD 0
|
||||
|
||||
/*====================
|
||||
HAL SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*Default display refresh period. LVG will redraw changed areas with this period time*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 17 /*[ms]*/
|
||||
|
||||
/*Input device read period in milliseconds*/
|
||||
#define LV_INDEV_DEF_READ_PERIOD 17 /*[ms]*/
|
||||
|
||||
/*Use a custom tick source that tells the elapsed time in milliseconds.
|
||||
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
|
||||
#define LV_TICK_CUSTOM 1
|
||||
#if LV_TICK_CUSTOM
|
||||
#define LV_TICK_CUSTOM_INCLUDE "SDL2/SDL.h" /*Header for the system time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (SDL_GetTicks()) /*Expression evaluating to current system time in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
|
||||
*(Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI_DEF 130 /*[px/inch]*/
|
||||
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
|
||||
/*-------------
|
||||
* Drawing
|
||||
*-----------*/
|
||||
|
||||
/*Enable complex draw engine.
|
||||
*Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
|
||||
#define LV_DRAW_COMPLEX 1
|
||||
#if LV_DRAW_COMPLEX != 0
|
||||
|
||||
/*Allow buffering some shadow calculation.
|
||||
*LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
|
||||
*Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/
|
||||
#define LV_SHADOW_CACHE_SIZE 0
|
||||
|
||||
/* Set number of maximally cached circle data.
|
||||
* The circumference of 1/4 circle are saved for anti-aliasing
|
||||
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
|
||||
* 0: to disable caching */
|
||||
#define LV_CIRCLE_CACHE_SIZE 4
|
||||
#endif /*LV_DRAW_COMPLEX*/
|
||||
|
||||
/*Default image cache size. Image caching keeps the images opened.
|
||||
*If only the built-in image formats are used there is no real advantage of caching. (I.e. if no new image decoder is added)
|
||||
*With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
||||
*However the opened images might consume additional RAM.
|
||||
*0: to disable caching*/
|
||||
#define LV_IMG_CACHE_DEF_SIZE 8
|
||||
|
||||
/*Number of stops allowed per gradient. Increase this to allow more stops.
|
||||
*This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
|
||||
#define LV_GRADIENT_MAX_STOPS 2
|
||||
|
||||
/*Default gradient buffer size.
|
||||
*When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
|
||||
*LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes.
|
||||
*If the cache is too small the map will be allocated only while it's required for the drawing.
|
||||
*0 mean no caching.*/
|
||||
#define LV_GRAD_CACHE_DEF_SIZE 8*1024
|
||||
|
||||
/*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
|
||||
*LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
|
||||
*The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
|
||||
#define LV_DITHER_GRADIENT 1
|
||||
#if LV_DITHER_GRADIENT
|
||||
/*Add support for error diffusion dithering.
|
||||
*Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
|
||||
*The increase in memory consumption is (24 bits * object's width)*/
|
||||
#define LV_DITHER_ERROR_DIFFUSION 1
|
||||
#endif
|
||||
|
||||
/*Maximum buffer size to allocate for rotation.
|
||||
*Only used if software rotation is enabled in the display driver.*/
|
||||
#define LV_DISP_ROT_MAX_BUF (32*1024)
|
||||
|
||||
/*-------------
|
||||
* GPU
|
||||
*-----------*/
|
||||
|
||||
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
||||
#define LV_USE_GPU_STM32_DMA2D 0
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
/*Must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
#endif
|
||||
|
||||
/*Use NXP's PXP GPU iMX RTxxx platforms*/
|
||||
#define LV_USE_GPU_NXP_PXP 0
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
|
||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
|
||||
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
||||
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
||||
*/
|
||||
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
|
||||
#endif
|
||||
|
||||
/*Use NXP's VG-Lite GPU iMX RTxxx platforms*/
|
||||
#define LV_USE_GPU_NXP_VG_LITE 0
|
||||
|
||||
/*Use SDL renderer API*/
|
||||
#define LV_USE_GPU_SDL 0
|
||||
#if LV_USE_GPU_SDL
|
||||
#define LV_GPU_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
/*Texture cache size, 8MB by default*/
|
||||
#define LV_GPU_SDL_LRU_SIZE (1024 * 1024 * 8)
|
||||
/*Custom blend mode for mask drawing, disable if you need to link with older SDL2 lib*/
|
||||
#define LV_GPU_SDL_CUSTOM_BLEND_MODE (SDL_VERSION_ATLEAST(2, 0, 6))
|
||||
#endif
|
||||
|
||||
/*-------------
|
||||
* Logging
|
||||
*-----------*/
|
||||
|
||||
/*Enable the log module*/
|
||||
#define LV_USE_LOG 1
|
||||
#if LV_USE_LOG
|
||||
|
||||
/*How important log should be added:
|
||||
*LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
*LV_LOG_LEVEL_INFO Log important events
|
||||
*LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
/*1: Print the log with 'printf';
|
||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
||||
#define LV_LOG_PRINTF 1
|
||||
|
||||
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
|
||||
#define LV_LOG_TRACE_MEM 1
|
||||
#define LV_LOG_TRACE_TIMER 1
|
||||
#define LV_LOG_TRACE_INDEV 1
|
||||
#define LV_LOG_TRACE_DISP_REFR 1
|
||||
#define LV_LOG_TRACE_EVENT 1
|
||||
#define LV_LOG_TRACE_OBJ_CREATE 1
|
||||
#define LV_LOG_TRACE_LAYOUT 1
|
||||
#define LV_LOG_TRACE_ANIM 1
|
||||
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*-------------
|
||||
* Asserts
|
||||
*-----------*/
|
||||
|
||||
/*Enable asserts if an operation is failed or an invalid data is found.
|
||||
*If LV_USE_LOG is enabled an error message will be printed on failure*/
|
||||
#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_STYLE 1 /*Check if the styles are properly initialized. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_MEM_INTEGRITY 1 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
|
||||
#define LV_USE_ASSERT_OBJ 1 /*Check the object's type and existence (e.g. not deleted). (Slow)*/
|
||||
|
||||
/*Add a custom handler when assert happens e.g. to restart the MCU*/
|
||||
#define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
|
||||
#define LV_ASSERT_HANDLER while(1); /*Halt by default*/
|
||||
|
||||
/*-------------
|
||||
* Others
|
||||
*-----------*/
|
||||
|
||||
/*1: Show CPU usage and FPS count*/
|
||||
#define LV_USE_PERF_MONITOR 1
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
|
||||
#endif
|
||||
|
||||
/*1: Show the used memory and the memory fragmentation
|
||||
* Requires LV_MEM_CUSTOM = 0*/
|
||||
#define LV_USE_MEM_MONITOR 1
|
||||
#if LV_USE_MEM_MONITOR
|
||||
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
|
||||
#endif
|
||||
|
||||
/*1: Draw random colored rectangles over the redrawn areas*/
|
||||
#define LV_USE_REFR_DEBUG 0
|
||||
|
||||
/*Change the built in (v)snprintf functions*/
|
||||
#define LV_SPRINTF_CUSTOM 0
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
#define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
#define lv_snprintf snprintf
|
||||
#define lv_vsnprintf vsnprintf
|
||||
#else /*LV_SPRINTF_CUSTOM*/
|
||||
#define LV_SPRINTF_USE_FLOAT 0
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
#define LV_USE_USER_DATA 1
|
||||
|
||||
/*Garbage Collector settings
|
||||
*Used if lvgl is bound to higher level language and the memory is managed by that language*/
|
||||
#define LV_ENABLE_GC 0
|
||||
#if LV_ENABLE_GC != 0
|
||||
#define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
#endif /*LV_ENABLE_GC*/
|
||||
|
||||
/*=====================
|
||||
* COMPILER SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*For big endian systems set to 1*/
|
||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
||||
|
||||
/*Define a custom attribute to `lv_tick_inc` function*/
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
/*Define a custom attribute to `lv_timer_handler` function*/
|
||||
#define LV_ATTRIBUTE_TIMER_HANDLER
|
||||
|
||||
/*Define a custom attribute to `lv_disp_flush_ready` function*/
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
|
||||
/*Required alignment size for buffers*/
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1
|
||||
|
||||
/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default).
|
||||
* E.g. __attribute__((aligned(4)))*/
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
||||
/*Attribute to mark large constant arrays for example font's bitmaps*/
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
|
||||
/*Compiler prefix for a big array declaration in RAM*/
|
||||
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
|
||||
|
||||
/*Place performance critical functions into a faster memory (e.g RAM)*/
|
||||
#define LV_ATTRIBUTE_FAST_MEM
|
||||
|
||||
/*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/
|
||||
#define LV_ATTRIBUTE_DMA
|
||||
|
||||
/*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
|
||||
*should also appear on LVGL binding API such as Micropython.*/
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/
|
||||
|
||||
/*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/
|
||||
#define LV_USE_LARGE_COORD 0
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
|
||||
*https://fonts.google.com/specimen/Montserrat*/
|
||||
#define LV_FONT_MONTSERRAT_8 1
|
||||
#define LV_FONT_MONTSERRAT_10 1
|
||||
#define LV_FONT_MONTSERRAT_12 1
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_16 1
|
||||
#define LV_FONT_MONTSERRAT_18 1
|
||||
#define LV_FONT_MONTSERRAT_20 1
|
||||
#define LV_FONT_MONTSERRAT_22 1
|
||||
#define LV_FONT_MONTSERRAT_24 1
|
||||
#define LV_FONT_MONTSERRAT_26 1
|
||||
#define LV_FONT_MONTSERRAT_28 1
|
||||
#define LV_FONT_MONTSERRAT_30 1
|
||||
#define LV_FONT_MONTSERRAT_32 1
|
||||
#define LV_FONT_MONTSERRAT_34 1
|
||||
#define LV_FONT_MONTSERRAT_36 1
|
||||
#define LV_FONT_MONTSERRAT_38 1
|
||||
#define LV_FONT_MONTSERRAT_40 1
|
||||
#define LV_FONT_MONTSERRAT_42 1
|
||||
#define LV_FONT_MONTSERRAT_44 1
|
||||
#define LV_FONT_MONTSERRAT_46 1
|
||||
#define LV_FONT_MONTSERRAT_48 1
|
||||
|
||||
/*Demonstrate special features*/
|
||||
#define LV_FONT_MONTSERRAT_12_SUBPX 1
|
||||
#define LV_FONT_MONTSERRAT_28_COMPRESSED 1 /*bpp = 3*/
|
||||
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1 /*Hebrew, Arabic, Persian letters and all their forms*/
|
||||
#define LV_FONT_SIMSUN_16_CJK 1 /*1000 most common CJK radicals*/
|
||||
|
||||
/*Pixel perfect monospace fonts*/
|
||||
#define LV_FONT_UNSCII_8 1
|
||||
#define LV_FONT_UNSCII_16 1
|
||||
|
||||
/*Optionally declare custom fonts here.
|
||||
*You can use these fonts as default font too and they will be available globally.
|
||||
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
|
||||
/*Always set a default font*/
|
||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||
|
||||
/*Enable handling large font and/or fonts with a lot of characters.
|
||||
*The limit depends on the font size, font face and bpp.
|
||||
*Compiler error will be triggered if a font needs it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 1
|
||||
|
||||
/*Enables/disables support for compressed fonts.*/
|
||||
#define LV_USE_FONT_COMPRESSED 1
|
||||
|
||||
/*Enable subpixel rendering*/
|
||||
#define LV_USE_FONT_SUBPX 1
|
||||
#if LV_USE_FONT_SUBPX
|
||||
/*Set the pixel order of the display. Physical order of RGB channels. Doesn't matter with "normal" fonts.*/
|
||||
#define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1:BGR order*/
|
||||
#endif
|
||||
|
||||
/*=================
|
||||
* TEXT SETTINGS
|
||||
*=================*/
|
||||
|
||||
/**
|
||||
* Select a character encoding for strings.
|
||||
* Your IDE or editor should have the same character encoding
|
||||
* - LV_TXT_ENC_UTF8
|
||||
* - LV_TXT_ENC_ASCII
|
||||
*/
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
|
||||
/*If a word is at least this long, will break wherever "prettiest"
|
||||
*To disable, set to a value <= 0*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 0
|
||||
|
||||
/*Minimum number of characters in a long word to put on a line before a break.
|
||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||
|
||||
/*Minimum number of characters in a long word to put on a line after a break.
|
||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||
|
||||
/*The control character to use for signalling text recoloring.*/
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
|
||||
/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts.
|
||||
*The direction will be processed according to the Unicode Bidirectional Algorithm:
|
||||
*https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||
#define LV_USE_BIDI 1
|
||||
#if LV_USE_BIDI
|
||||
/*Set the default direction. Supported values:
|
||||
*`LV_BASE_DIR_LTR` Left-to-Right
|
||||
*`LV_BASE_DIR_RTL` Right-to-Left
|
||||
*`LV_BASE_DIR_AUTO` detect texts base direction*/
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
|
||||
#endif
|
||||
|
||||
/*Enable Arabic/Persian processing
|
||||
*In these languages characters should be replaced with an other form based on their position in the text*/
|
||||
#define LV_USE_ARABIC_PERSIAN_CHARS 1
|
||||
|
||||
/*==================
|
||||
* WIDGET USAGE
|
||||
*================*/
|
||||
|
||||
/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/
|
||||
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
#define LV_USE_ANIMIMG 1
|
||||
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
#define LV_USE_BTN 1
|
||||
|
||||
#define LV_USE_BTNMATRIX 1
|
||||
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
#define LV_USE_CHECKBOX 1
|
||||
|
||||
#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_IMG 1 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL
|
||||
#define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/
|
||||
#define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_LINE 1
|
||||
|
||||
#define LV_USE_ROLLER 1 /*Requires: lv_label*/
|
||||
#if LV_USE_ROLLER
|
||||
#define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/
|
||||
|
||||
#define LV_USE_SWITCH 1
|
||||
|
||||
#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/
|
||||
#if LV_USE_TEXTAREA != 0
|
||||
#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_TABLE 1
|
||||
|
||||
/*==================
|
||||
* EXTRA COMPONENTS
|
||||
*==================*/
|
||||
|
||||
/*-----------
|
||||
* Widgets
|
||||
*----------*/
|
||||
#define LV_USE_CALENDAR 1
|
||||
#if LV_USE_CALENDAR
|
||||
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||
#if LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
|
||||
#else
|
||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"}
|
||||
#endif
|
||||
|
||||
#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
|
||||
#define LV_USE_CALENDAR_HEADER_ARROW 1
|
||||
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
|
||||
#endif /*LV_USE_CALENDAR*/
|
||||
|
||||
#define LV_USE_CHART 1
|
||||
|
||||
#define LV_USE_COLORWHEEL 1
|
||||
|
||||
#define LV_USE_IMGBTN 1
|
||||
|
||||
#define LV_USE_KEYBOARD 1
|
||||
|
||||
#define LV_USE_LED 1
|
||||
|
||||
#define LV_USE_LIST 1
|
||||
|
||||
#define LV_USE_MENU 1
|
||||
|
||||
#define LV_USE_METER 1
|
||||
|
||||
#define LV_USE_MSGBOX 1
|
||||
|
||||
#define LV_USE_SPINBOX 1
|
||||
|
||||
#define LV_USE_SPINNER 1
|
||||
|
||||
#define LV_USE_TABVIEW 1
|
||||
|
||||
#define LV_USE_TILEVIEW 1
|
||||
|
||||
#define LV_USE_WIN 1
|
||||
|
||||
#define LV_USE_SPAN 1
|
||||
#if LV_USE_SPAN
|
||||
/*A line text can contain maximum num of span descriptor */
|
||||
#define LV_SPAN_SNIPPET_STACK_SIZE 64
|
||||
#endif
|
||||
|
||||
/*-----------
|
||||
* Themes
|
||||
*----------*/
|
||||
|
||||
/*A simple, impressive and very complete theme*/
|
||||
#define LV_USE_THEME_DEFAULT 1
|
||||
#if LV_USE_THEME_DEFAULT
|
||||
|
||||
/*0: Light mode; 1: Dark mode*/
|
||||
#define LV_THEME_DEFAULT_DARK 0
|
||||
|
||||
/*1: Enable grow on press*/
|
||||
#define LV_THEME_DEFAULT_GROW 1
|
||||
|
||||
/*Default transition time in [ms]*/
|
||||
#define LV_THEME_DEFAULT_TRANSITION_TIME 80
|
||||
#endif /*LV_USE_THEME_DEFAULT*/
|
||||
|
||||
/*A very simple theme that is a good starting point for a custom theme*/
|
||||
#define LV_USE_THEME_BASIC 1
|
||||
|
||||
/*A theme designed for monochrome displays*/
|
||||
#define LV_USE_THEME_MONO 1
|
||||
|
||||
/*-----------
|
||||
* Layouts
|
||||
*----------*/
|
||||
|
||||
/*A layout similar to Flexbox in CSS.*/
|
||||
#define LV_USE_FLEX 1
|
||||
|
||||
/*A layout similar to Grid in CSS.*/
|
||||
#define LV_USE_GRID 1
|
||||
|
||||
/*---------------------
|
||||
* 3rd party libraries
|
||||
*--------------------*/
|
||||
|
||||
/*File system interfaces for common APIs */
|
||||
|
||||
/*API for fopen, fread, etc*/
|
||||
#define LV_USE_FS_STDIO 1
|
||||
#if LV_USE_FS_STDIO
|
||||
#define LV_FS_STDIO_LETTER 'A' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
||||
#define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*API for open, read, etc*/
|
||||
#define LV_USE_FS_POSIX 0
|
||||
#if LV_USE_FS_POSIX
|
||||
#define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
||||
#define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*API for CreateFile, ReadFile, etc*/
|
||||
#define LV_USE_FS_WIN32 0
|
||||
#if LV_USE_FS_WIN32
|
||||
#define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
||||
#define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
|
||||
#define LV_USE_FS_FATFS 0
|
||||
#if LV_USE_FS_FATFS
|
||||
#define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*PNG decoder library*/
|
||||
#define LV_USE_PNG 1
|
||||
|
||||
/*BMP decoder library*/
|
||||
#define LV_USE_BMP 1
|
||||
|
||||
/* JPG + split JPG decoder library.
|
||||
* Split JPG is a custom format optimized for embedded systems. */
|
||||
#define LV_USE_SJPG 1
|
||||
|
||||
/*GIF decoder library*/
|
||||
#define LV_USE_GIF 1
|
||||
|
||||
/*QR code library*/
|
||||
#define LV_USE_QRCODE 1
|
||||
|
||||
/*FreeType library*/
|
||||
#define LV_USE_FREETYPE 0
|
||||
#if LV_USE_FREETYPE
|
||||
/*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
|
||||
#define LV_FREETYPE_CACHE_SIZE (16 * 1024)
|
||||
#if LV_FREETYPE_CACHE_SIZE >= 0
|
||||
/* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
|
||||
/* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
|
||||
/* if font size >= 256, must be configured as image cache */
|
||||
#define LV_FREETYPE_SBIT_CACHE 0
|
||||
/* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
|
||||
/* (0:use system defaults) */
|
||||
#define LV_FREETYPE_CACHE_FT_FACES 0
|
||||
#define LV_FREETYPE_CACHE_FT_SIZES 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Rlottie library*/
|
||||
#define LV_USE_RLOTTIE 0
|
||||
|
||||
/*FFmpeg library for image decoding and playing videos
|
||||
*Supports all major image formats so do not enable other image decoder with it*/
|
||||
#define LV_USE_FFMPEG 0
|
||||
#if LV_USE_FFMPEG
|
||||
/*Dump input information to stderr*/
|
||||
#define LV_FFMPEG_AV_DUMP_FORMAT 0
|
||||
#endif
|
||||
|
||||
/*-----------
|
||||
* Others
|
||||
*----------*/
|
||||
|
||||
/*1: Enable API to take snapshot for object*/
|
||||
#define LV_USE_SNAPSHOT 1
|
||||
|
||||
/*1: Enable Monkey test*/
|
||||
#define LV_USE_MONKEY 1
|
||||
|
||||
/*1: Enable grid navigation*/
|
||||
#define LV_USE_GRIDNAV 1
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
/*Enable the examples to be built with the library*/
|
||||
#define LV_BUILD_EXAMPLES 1
|
||||
|
||||
/*===================
|
||||
* DEMO USAGE
|
||||
====================*/
|
||||
|
||||
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
|
||||
#define LV_USE_DEMO_WIDGETS 1
|
||||
#if LV_USE_DEMO_WIDGETS
|
||||
#define LV_DEMO_WIDGETS_SLIDESHOW 0
|
||||
#endif
|
||||
|
||||
/*Demonstrate the usage of encoder and keyboard*/
|
||||
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
|
||||
|
||||
/*Benchmark your system*/
|
||||
#define LV_USE_DEMO_BENCHMARK 0
|
||||
|
||||
/*Stress test for LVGL*/
|
||||
#define LV_USE_DEMO_STRESS 0
|
||||
|
||||
/*Music player demo*/
|
||||
#define LV_USE_DEMO_MUSIC 0
|
||||
#if LV_USE_DEMO_MUSIC
|
||||
# define LV_DEMO_MUSIC_SQUARE 0
|
||||
# define LV_DEMO_MUSIC_LANDSCAPE 0
|
||||
# define LV_DEMO_MUSIC_ROUND 0
|
||||
# define LV_DEMO_MUSIC_LARGE 0
|
||||
# define LV_DEMO_MUSIC_AUTO_PLAY 0
|
||||
#endif
|
||||
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
||||
496
app-sim/src/lv_drv_conf.h
Normal file
496
app-sim/src/lv_drv_conf.h
Normal file
@ -0,0 +1,496 @@
|
||||
/**
|
||||
* @file lv_drv_conf.h
|
||||
* Configuration file for v8.3.0-dev
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPY THIS FILE AS lv_drv_conf.h
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
#if 1 /*Set it to "1" to enable the content*/
|
||||
|
||||
#ifndef LV_DRV_CONF_H
|
||||
#define LV_DRV_CONF_H
|
||||
|
||||
#include "lv_conf.h"
|
||||
|
||||
/*********************
|
||||
* DELAY INTERFACE
|
||||
*********************/
|
||||
#define LV_DRV_DELAY_INCLUDE <stdint.h> /*Dummy include by default*/
|
||||
#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/
|
||||
#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/
|
||||
|
||||
/*********************
|
||||
* DISPLAY INTERFACE
|
||||
*********************/
|
||||
|
||||
/*------------
|
||||
* Common
|
||||
*------------*/
|
||||
#define LV_DRV_DISP_INCLUDE <stdint.h> /*Dummy include by default*/
|
||||
#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/
|
||||
#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
|
||||
|
||||
/*---------
|
||||
* SPI
|
||||
*---------*/
|
||||
#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
|
||||
#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/
|
||||
#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/
|
||||
|
||||
/*------------------
|
||||
* Parallel port
|
||||
*-----------------*/
|
||||
#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/
|
||||
#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/
|
||||
#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/
|
||||
#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/
|
||||
#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/
|
||||
|
||||
/***************************
|
||||
* INPUT DEVICE INTERFACE
|
||||
***************************/
|
||||
|
||||
/*----------
|
||||
* Common
|
||||
*----------*/
|
||||
#define LV_DRV_INDEV_INCLUDE <stdint.h> /*Dummy include by default*/
|
||||
#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
|
||||
#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/
|
||||
|
||||
/*---------
|
||||
* SPI
|
||||
*---------*/
|
||||
#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
|
||||
#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/
|
||||
|
||||
/*---------
|
||||
* I2C
|
||||
*---------*/
|
||||
#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/
|
||||
#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/
|
||||
#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/
|
||||
#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/
|
||||
#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/
|
||||
|
||||
|
||||
/*********************
|
||||
* DISPLAY DRIVERS
|
||||
*********************/
|
||||
|
||||
/*-------------------
|
||||
* SDL
|
||||
*-------------------*/
|
||||
|
||||
/* SDL based drivers for display, mouse, mousewheel and keyboard*/
|
||||
#ifndef USE_SDL
|
||||
# define USE_SDL 1
|
||||
#endif
|
||||
|
||||
/* Hardware accelerated SDL driver */
|
||||
#ifndef USE_SDL_GPU
|
||||
# define USE_SDL_GPU 0
|
||||
#endif
|
||||
|
||||
#define SDL_WINDOW_NAME "Tactility"
|
||||
|
||||
#if USE_SDL || USE_SDL_GPU
|
||||
# define SDL_HOR_RES 320
|
||||
# define SDL_VER_RES 240
|
||||
|
||||
/* Scale window by this factor (useful when simulating small screens) */
|
||||
# define SDL_ZOOM 1
|
||||
|
||||
/* Used to test true double buffering with only address changing.
|
||||
* Use 2 draw buffers, bith with SDL_HOR_RES x SDL_VER_RES size*/
|
||||
# define SDL_DOUBLE_BUFFERED 0
|
||||
|
||||
/*Eclipse: <SDL2/SDL.h> Visual Studio: <SDL.h>*/
|
||||
# define SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
|
||||
/*Open two windows to test multi display support*/
|
||||
# define SDL_DUAL_DISPLAY 0
|
||||
#endif
|
||||
|
||||
/*-------------------
|
||||
* Monitor of PC
|
||||
*-------------------*/
|
||||
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_MONITOR
|
||||
# define USE_MONITOR 0
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR
|
||||
# define MONITOR_HOR_RES 480
|
||||
# define MONITOR_VER_RES 320
|
||||
|
||||
/* Scale window by this factor (useful when simulating small screens) */
|
||||
# define MONITOR_ZOOM 1
|
||||
|
||||
/* Used to test true double buffering with only address changing.
|
||||
* Use 2 draw buffers, bith with MONITOR_HOR_RES x MONITOR_VER_RES size*/
|
||||
# define MONITOR_DOUBLE_BUFFERED 0
|
||||
|
||||
/*Eclipse: <SDL2/SDL.h> Visual Studio: <SDL.h>*/
|
||||
# define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
|
||||
/*Open two windows to test multi display support*/
|
||||
# define MONITOR_DUAL 0
|
||||
#endif
|
||||
|
||||
/*-----------------------------------
|
||||
* Native Windows (including mouse)
|
||||
*----------------------------------*/
|
||||
#ifndef USE_WINDOWS
|
||||
# define USE_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if USE_WINDOWS
|
||||
# define WINDOW_HOR_RES 480
|
||||
# define WINDOW_VER_RES 320
|
||||
#endif
|
||||
|
||||
/*----------------------------
|
||||
* Native Windows (win32drv)
|
||||
*---------------------------*/
|
||||
#ifndef USE_WIN32DRV
|
||||
# define USE_WIN32DRV 0
|
||||
#endif
|
||||
|
||||
#if USE_WIN32DRV
|
||||
/* Scale window by this factor (useful when simulating small screens) */
|
||||
# define WIN32DRV_MONITOR_ZOOM 1
|
||||
#endif
|
||||
|
||||
/*----------------------------------------
|
||||
* GTK drivers (monitor, mouse, keyboard
|
||||
*---------------------------------------*/
|
||||
#ifndef USE_GTK
|
||||
# define USE_GTK 0
|
||||
#endif
|
||||
|
||||
/*----------------------------------------
|
||||
* Wayland drivers (monitor, mouse, keyboard, touchscreen)
|
||||
*---------------------------------------*/
|
||||
#ifndef USE_WAYLAND
|
||||
# define USE_WAYLAND 0
|
||||
#endif
|
||||
|
||||
#if USE_WAYLAND
|
||||
/* Support for client-side decorations */
|
||||
# ifndef LV_WAYLAND_CLIENT_SIDE_DECORATIONS
|
||||
# define LV_WAYLAND_CLIENT_SIDE_DECORATIONS 1
|
||||
# endif
|
||||
/* Support for (deprecated) wl-shell protocol */
|
||||
# ifndef LV_WAYLAND_WL_SHELL
|
||||
# define LV_WAYLAND_WL_SHELL 1
|
||||
# endif
|
||||
/* Support for xdg-shell protocol */
|
||||
# ifndef LV_WAYLAND_XDG_SHELL
|
||||
# define LV_WAYLAND_XDG_SHELL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------
|
||||
* SSD1963
|
||||
*--------------*/
|
||||
#ifndef USE_SSD1963
|
||||
# define USE_SSD1963 0
|
||||
#endif
|
||||
|
||||
#if USE_SSD1963
|
||||
# define SSD1963_HOR_RES LV_HOR_RES
|
||||
# define SSD1963_VER_RES LV_VER_RES
|
||||
# define SSD1963_HT 531
|
||||
# define SSD1963_HPS 43
|
||||
# define SSD1963_LPS 8
|
||||
# define SSD1963_HPW 10
|
||||
# define SSD1963_VT 288
|
||||
# define SSD1963_VPS 12
|
||||
# define SSD1963_FPS 4
|
||||
# define SSD1963_VPW 10
|
||||
# define SSD1963_HS_NEG 0 /*Negative hsync*/
|
||||
# define SSD1963_VS_NEG 0 /*Negative vsync*/
|
||||
# define SSD1963_ORI 0 /*0, 90, 180, 270*/
|
||||
# define SSD1963_COLOR_DEPTH 16
|
||||
#endif
|
||||
|
||||
/*----------------
|
||||
* R61581
|
||||
*--------------*/
|
||||
#ifndef USE_R61581
|
||||
# define USE_R61581 0
|
||||
#endif
|
||||
|
||||
#if USE_R61581
|
||||
# define R61581_HOR_RES LV_HOR_RES
|
||||
# define R61581_VER_RES LV_VER_RES
|
||||
# define R61581_HSPL 0 /*HSYNC signal polarity*/
|
||||
# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/
|
||||
# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/
|
||||
# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */
|
||||
# define R61581_VSPL 0 /*VSYNC signal polarity*/
|
||||
# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/
|
||||
# define R61581_VFP 8 /*Vertical Front poarch*/
|
||||
# define R61581_VBP 8 /*Vertical Back poarch */
|
||||
# define R61581_DPL 0 /*DCLK signal polarity*/
|
||||
# define R61581_EPL 1 /*ENABLE signal polarity*/
|
||||
# define R61581_ORI 0 /*0, 180*/
|
||||
# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/
|
||||
#endif
|
||||
|
||||
/*------------------------------
|
||||
* ST7565 (Monochrome, low res.)
|
||||
*-----------------------------*/
|
||||
#ifndef USE_ST7565
|
||||
# define USE_ST7565 0
|
||||
#endif
|
||||
|
||||
#if USE_ST7565
|
||||
/*No settings*/
|
||||
#endif /*USE_ST7565*/
|
||||
|
||||
/*------------------------------
|
||||
* GC9A01 (color, low res.)
|
||||
*-----------------------------*/
|
||||
#ifndef USE_GC9A01
|
||||
# define USE_GC9A01 0
|
||||
#endif
|
||||
|
||||
#if USE_GC9A01
|
||||
/*No settings*/
|
||||
#endif /*USE_GC9A01*/
|
||||
|
||||
/*------------------------------------------
|
||||
* UC1610 (4 gray 160*[104|128])
|
||||
* (EA DOGXL160 160x104 tested)
|
||||
*-----------------------------------------*/
|
||||
#ifndef USE_UC1610
|
||||
# define USE_UC1610 0
|
||||
#endif
|
||||
|
||||
#if USE_UC1610
|
||||
# define UC1610_HOR_RES LV_HOR_RES
|
||||
# define UC1610_VER_RES LV_VER_RES
|
||||
# define UC1610_INIT_CONTRAST 33 /* init contrast, values in [%] */
|
||||
# define UC1610_INIT_HARD_RST 0 /* 1 : hardware reset at init, 0 : software reset */
|
||||
# define UC1610_TOP_VIEW 0 /* 0 : Bottom View, 1 : Top View */
|
||||
#endif /*USE_UC1610*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* SHARP memory in pixel monochrome display series
|
||||
* LS012B7DD01 (184x38 pixels.)
|
||||
* LS013B7DH03 (128x128 pixels.)
|
||||
* LS013B7DH05 (144x168 pixels.)
|
||||
* LS027B7DH01 (400x240 pixels.) (tested)
|
||||
* LS032B7DD02 (336x536 pixels.)
|
||||
* LS044Q7DH01 (320x240 pixels.)
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_SHARP_MIP
|
||||
# define USE_SHARP_MIP 0
|
||||
#endif
|
||||
|
||||
#if USE_SHARP_MIP
|
||||
# define SHARP_MIP_HOR_RES LV_HOR_RES
|
||||
# define SHARP_MIP_VER_RES LV_VER_RES
|
||||
# define SHARP_MIP_SOFT_COM_INVERSION 0
|
||||
# define SHARP_MIP_REV_BYTE(b) /*((uint8_t) __REV(__RBIT(b)))*/ /*Architecture / compiler dependent byte bits order reverse*/
|
||||
#endif /*USE_SHARP_MIP*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* ILI9341 240X320 TFT LCD
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_ILI9341
|
||||
# define USE_ILI9341 0
|
||||
#endif
|
||||
|
||||
#if USE_ILI9341
|
||||
# define ILI9341_HOR_RES LV_HOR_RES
|
||||
# define ILI9341_VER_RES LV_VER_RES
|
||||
# define ILI9341_GAMMA 1
|
||||
# define ILI9341_TEARING 0
|
||||
#endif /*USE_ILI9341*/
|
||||
|
||||
/*-----------------------------------------
|
||||
* Linux frame buffer device (/dev/fbx)
|
||||
*-----------------------------------------*/
|
||||
#ifndef USE_FBDEV
|
||||
# define USE_FBDEV 0
|
||||
#endif
|
||||
|
||||
#if USE_FBDEV
|
||||
# define FBDEV_PATH "/dev/fb0"
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------
|
||||
* FreeBSD frame buffer device (/dev/fbx)
|
||||
*.........................................*/
|
||||
#ifndef USE_BSD_FBDEV
|
||||
# define USE_BSD_FBDEV 0
|
||||
#endif
|
||||
|
||||
#if USE_BSD_FBDEV
|
||||
# define FBDEV_PATH "/dev/fb0"
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------
|
||||
* DRM/KMS device (/dev/dri/cardX)
|
||||
*-----------------------------------------*/
|
||||
#ifndef USE_DRM
|
||||
# define USE_DRM 0
|
||||
#endif
|
||||
|
||||
#if USE_DRM
|
||||
# define DRM_CARD "/dev/dri/card0"
|
||||
# define DRM_CONNECTOR_ID -1 /* -1 for the first connected one */
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INPUT DEVICES
|
||||
*********************/
|
||||
|
||||
/*--------------
|
||||
* XPT2046
|
||||
*--------------*/
|
||||
#ifndef USE_XPT2046
|
||||
# define USE_XPT2046 0
|
||||
#endif
|
||||
|
||||
#if USE_XPT2046
|
||||
# define XPT2046_HOR_RES 480
|
||||
# define XPT2046_VER_RES 320
|
||||
# define XPT2046_X_MIN 200
|
||||
# define XPT2046_Y_MIN 200
|
||||
# define XPT2046_X_MAX 3800
|
||||
# define XPT2046_Y_MAX 3800
|
||||
# define XPT2046_AVG 4
|
||||
# define XPT2046_X_INV 0
|
||||
# define XPT2046_Y_INV 0
|
||||
# define XPT2046_XY_SWAP 0
|
||||
#endif
|
||||
|
||||
/*-----------------
|
||||
* FT5406EE8
|
||||
*-----------------*/
|
||||
#ifndef USE_FT5406EE8
|
||||
# define USE_FT5406EE8 0
|
||||
#endif
|
||||
|
||||
#if USE_FT5406EE8
|
||||
# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/
|
||||
#endif
|
||||
|
||||
/*---------------
|
||||
* AD TOUCH
|
||||
*--------------*/
|
||||
#ifndef USE_AD_TOUCH
|
||||
# define USE_AD_TOUCH 0
|
||||
#endif
|
||||
|
||||
#if USE_AD_TOUCH
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------
|
||||
* Mouse or touchpad on PC (using SDL)
|
||||
*-------------------------------------*/
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_MOUSE
|
||||
# define USE_MOUSE 0
|
||||
#endif
|
||||
|
||||
#if USE_MOUSE
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------
|
||||
* Mousewheel as encoder on PC (using SDL)
|
||||
*------------------------------------------*/
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_MOUSEWHEEL
|
||||
# define USE_MOUSEWHEEL 0
|
||||
#endif
|
||||
|
||||
#if USE_MOUSEWHEEL
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------
|
||||
* Touchscreen, mouse/touchpad or keyboard as libinput interface (for Linux based systems)
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_LIBINPUT
|
||||
# define USE_LIBINPUT 0
|
||||
#endif
|
||||
|
||||
#ifndef USE_BSD_LIBINPUT
|
||||
# define USE_BSD_LIBINPUT 0
|
||||
#endif
|
||||
|
||||
#if USE_LIBINPUT || USE_BSD_LIBINPUT
|
||||
/*If only a single device of the same type is connected, you can also auto detect it, e.g.:
|
||||
*#define LIBINPUT_NAME libinput_find_dev(LIBINPUT_CAPABILITY_TOUCH, false)*/
|
||||
# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/
|
||||
|
||||
#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* Mouse or touchpad as evdev interface (for Linux based systems)
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_EVDEV
|
||||
# define USE_EVDEV 0
|
||||
#endif
|
||||
|
||||
#ifndef USE_BSD_EVDEV
|
||||
# define USE_BSD_EVDEV 0
|
||||
#endif
|
||||
|
||||
#if USE_EVDEV || USE_BSD_EVDEV
|
||||
# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/
|
||||
# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/
|
||||
|
||||
# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/
|
||||
|
||||
# if EVDEV_CALIBRATE
|
||||
# define EVDEV_HOR_MIN 0 /*to invert axis swap EVDEV_XXX_MIN by EVDEV_XXX_MAX*/
|
||||
# define EVDEV_HOR_MAX 4096 /*"evtest" Linux tool can help to get the correct calibraion values>*/
|
||||
# define EVDEV_VER_MIN 0
|
||||
# define EVDEV_VER_MAX 4096
|
||||
# endif /*EVDEV_CALIBRATE*/
|
||||
#endif /*USE_EVDEV*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* Full keyboard support for evdev and libinput interface
|
||||
*------------------------------------------------*/
|
||||
# ifndef USE_XKB
|
||||
# define USE_XKB 0
|
||||
# endif
|
||||
|
||||
#if USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV
|
||||
# if USE_XKB
|
||||
# define XKB_KEY_MAP { .rules = NULL, \
|
||||
.model = "pc101", \
|
||||
.layout = "us", \
|
||||
.variant = NULL, \
|
||||
.options = NULL } /*"setxkbmap -query" can help find the right values for your keyboard*/
|
||||
# endif /*USE_XKB*/
|
||||
#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV*/
|
||||
|
||||
/*-------------------------------
|
||||
* Keyboard of a PC (using SDL)
|
||||
*------------------------------*/
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_KEYBOARD
|
||||
# define USE_KEYBOARD 0
|
||||
#endif
|
||||
|
||||
#if USE_KEYBOARD
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
||||
75
app-sim/src/lvgl_hal.c
Normal file
75
app-sim/src/lvgl_hal.c
Normal file
@ -0,0 +1,75 @@
|
||||
#include "lvgl_hal.h"
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "tactility_core.h"
|
||||
#include <sdl/sdl.h>
|
||||
|
||||
#define TAG "lvgl_hal"
|
||||
|
||||
#define BUFFER_SIZE (SDL_HOR_RES * SDL_VER_RES * 3)
|
||||
|
||||
static lv_disp_t* hal_init() {
|
||||
/* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/
|
||||
sdl_init();
|
||||
|
||||
/*Create a display buffer*/
|
||||
static lv_disp_draw_buf_t disp_buf1;
|
||||
static lv_color_t buf1_1[BUFFER_SIZE];
|
||||
lv_disp_draw_buf_init(&disp_buf1, buf1_1, NULL, BUFFER_SIZE);
|
||||
|
||||
/*Create a display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.draw_buf = &disp_buf1;
|
||||
disp_drv.flush_cb = sdl_display_flush;
|
||||
disp_drv.hor_res = SDL_HOR_RES;
|
||||
disp_drv.ver_res = SDL_VER_RES;
|
||||
|
||||
lv_disp_t* disp = lv_disp_drv_register(&disp_drv);
|
||||
|
||||
lv_theme_t* th = lv_theme_default_init(
|
||||
disp,
|
||||
lv_palette_main(LV_PALETTE_BLUE),
|
||||
lv_palette_main(LV_PALETTE_RED),
|
||||
LV_THEME_DEFAULT_DARK,
|
||||
LV_FONT_DEFAULT
|
||||
);
|
||||
|
||||
lv_disp_set_theme(disp, th);
|
||||
|
||||
lv_group_t* g = lv_group_create();
|
||||
lv_group_set_default(g);
|
||||
|
||||
/* Add the mouse as input device
|
||||
* Use the 'mouse' driver which reads the PC's mouse*/
|
||||
static lv_indev_drv_t indev_drv_1;
|
||||
lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
|
||||
indev_drv_1.type = LV_INDEV_TYPE_POINTER;
|
||||
|
||||
/*This function will be called periodically (by the library) to get the mouse position and state*/
|
||||
indev_drv_1.read_cb = sdl_mouse_read;
|
||||
lv_indev_t* mouse_indev = lv_indev_drv_register(&indev_drv_1);
|
||||
|
||||
static lv_indev_drv_t indev_drv_2;
|
||||
lv_indev_drv_init(&indev_drv_2); /*Basic initialization*/
|
||||
indev_drv_2.type = LV_INDEV_TYPE_KEYPAD;
|
||||
indev_drv_2.read_cb = sdl_keyboard_read;
|
||||
lv_indev_t* kb_indev = lv_indev_drv_register(&indev_drv_2);
|
||||
lv_indev_set_group(kb_indev, g);
|
||||
|
||||
static lv_indev_drv_t indev_drv_3;
|
||||
lv_indev_drv_init(&indev_drv_3); /*Basic initialization*/
|
||||
indev_drv_3.type = LV_INDEV_TYPE_ENCODER;
|
||||
indev_drv_3.read_cb = sdl_mousewheel_read;
|
||||
lv_indev_t* enc_indev = lv_indev_drv_register(&indev_drv_3);
|
||||
lv_indev_set_group(enc_indev, g);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lvgl_hal_init() {
|
||||
TT_LOG_I(TAG, "init: started");
|
||||
lv_init();
|
||||
hal_init();
|
||||
TT_LOG_I(TAG, "init: complete");
|
||||
}
|
||||
14
app-sim/src/lvgl_hal.h
Normal file
14
app-sim/src/lvgl_hal.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lvgl_hal_init();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
115
app-sim/src/lvgl_task.c
Normal file
115
app-sim/src/lvgl_task.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include "lvgl_task.h"
|
||||
|
||||
#include "lvgl_hal.h"
|
||||
#include "tactility_core.h"
|
||||
#include "thread.h"
|
||||
#include "ui/lvgl_sync.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define TAG "lvgl_task"
|
||||
|
||||
// Mutex for LVGL drawing
|
||||
static QueueHandle_t lvgl_mutex = NULL;
|
||||
static uint32_t task_max_sleep_ms = 10;
|
||||
// Mutex for LVGL task state (to modify task_running state)
|
||||
static QueueHandle_t task_mutex = NULL;
|
||||
static bool task_running = false;
|
||||
|
||||
static bool task_lock(int timeout_ticks) {
|
||||
assert(task_mutex != NULL);
|
||||
return xSemaphoreTakeRecursive(task_mutex, timeout_ticks) == pdTRUE;
|
||||
}
|
||||
|
||||
static void task_unlock() {
|
||||
assert(task_mutex != NULL);
|
||||
xSemaphoreGiveRecursive(task_mutex);
|
||||
}
|
||||
|
||||
static void task_set_running(bool running) {
|
||||
assert(task_lock(configTICK_RATE_HZ / 100));
|
||||
task_running = running;
|
||||
task_unlock();
|
||||
}
|
||||
|
||||
static bool task_is_running() {
|
||||
assert(task_lock(configTICK_RATE_HZ / 100));
|
||||
bool result = task_running;
|
||||
task_unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool lvgl_lock(int timeout_ticks) {
|
||||
assert(lvgl_mutex != NULL);
|
||||
return xSemaphoreTakeRecursive(lvgl_mutex, timeout_ticks) == pdTRUE;
|
||||
}
|
||||
|
||||
static void lvgl_unlock() {
|
||||
assert(lvgl_mutex != NULL);
|
||||
xSemaphoreGiveRecursive(lvgl_mutex);
|
||||
}
|
||||
|
||||
static void lvgl_task_init() {
|
||||
if (lvgl_mutex == NULL) {
|
||||
TT_LOG_D(TAG, "init: creating lvgl mutex");
|
||||
lvgl_mutex = xSemaphoreCreateRecursiveMutex();
|
||||
}
|
||||
|
||||
if (task_mutex == NULL) {
|
||||
TT_LOG_D(TAG, "init: creating task mutex");
|
||||
task_mutex = xSemaphoreCreateRecursiveMutex();
|
||||
}
|
||||
|
||||
tt_lvgl_sync_set(&lvgl_lock, &lvgl_unlock);
|
||||
}
|
||||
|
||||
static void lvgl_task_deinit() {
|
||||
if (lvgl_mutex) {
|
||||
vSemaphoreDelete(lvgl_mutex);
|
||||
lvgl_mutex = NULL;
|
||||
}
|
||||
if (task_mutex) {
|
||||
vSemaphoreDelete(task_mutex);
|
||||
task_mutex = NULL;
|
||||
}
|
||||
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
|
||||
lv_deinit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void lvgl_task(TT_UNUSED void* arg) {
|
||||
lvgl_hal_init();
|
||||
lvgl_task_init();
|
||||
|
||||
uint32_t task_delay_ms = task_max_sleep_ms;
|
||||
|
||||
task_set_running(true);
|
||||
|
||||
while (task_is_running()) {
|
||||
if (lvgl_lock(0)) {
|
||||
task_delay_ms = lv_timer_handler();
|
||||
lvgl_unlock();
|
||||
}
|
||||
if ((task_delay_ms > task_max_sleep_ms) || (1 == task_delay_ms)) {
|
||||
task_delay_ms = task_max_sleep_ms;
|
||||
} else if (task_delay_ms < 1) {
|
||||
task_delay_ms = 1;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(task_delay_ms));
|
||||
}
|
||||
|
||||
lvgl_task_deinit();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
bool lvgl_is_ready() {
|
||||
return task_running;
|
||||
}
|
||||
|
||||
void lvgl_interrupt() {
|
||||
tt_check(lvgl_lock(TtWaitForever));
|
||||
task_set_running(false); // interrupt task with boolean as flag
|
||||
lvgl_unlock();
|
||||
}
|
||||
14
app-sim/src/lvgl_task.h
Normal file
14
app-sim/src/lvgl_task.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool lvgl_is_ready();
|
||||
void lvgl_interrupt();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -1,32 +1,27 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "log.h"
|
||||
#include "portmacro.h"
|
||||
#include "hello_world/hello_world.h"
|
||||
#include "lvgl_hal.h"
|
||||
#include "tactility.h"
|
||||
#include "ui/lvgl_sync.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
void vAssertCalled(TT_UNUSED unsigned long line, TT_UNUSED const char* const file) {
|
||||
static portBASE_TYPE xPrinted = pdFALSE;
|
||||
volatile uint32_t set_to_nonzero_in_debugger_to_continue = 0;
|
||||
#define TAG "main"
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
// Step out by attaching a debugger and setting set_to_nonzero_in_debugger_to_continue
|
||||
while (set_to_nonzero_in_debugger_to_continue == 0) { /* NO-OP */
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
_Noreturn void app_main() {
|
||||
static const Config config = {
|
||||
.apps = {
|
||||
&hello_world_app
|
||||
},
|
||||
.services = {},
|
||||
.auto_start_app_id = NULL
|
||||
};
|
||||
|
||||
int main() {
|
||||
// static const Config config = {
|
||||
// .apps = {
|
||||
// &hello_world_app
|
||||
// },
|
||||
// .services = { },
|
||||
// .auto_start_app_id = NULL
|
||||
// };
|
||||
//
|
||||
// tactility_start(&config);
|
||||
TT_LOG_I("app", "Hello, world!");
|
||||
return 0;
|
||||
|
||||
tt_init(&config);
|
||||
|
||||
while (true) {
|
||||
vTaskDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
6
docs/ideas.md
Normal file
6
docs/ideas.md
Normal file
@ -0,0 +1,6 @@
|
||||
# App Ideas
|
||||
- Chip 8 emulator
|
||||
- Discord bot
|
||||
- BadUSB
|
||||
- GPIO status viewer
|
||||
|
||||
BIN
docs/pics/tactility-showcase.jpg
Normal file
BIN
docs/pics/tactility-showcase.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
12
libs/lv_drivers/.github/auto-comment.yml
vendored
Normal file
12
libs/lv_drivers/.github/auto-comment.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# Comment to a new issue.
|
||||
pullRequestOpened: |
|
||||
Thank you for raising your pull request.
|
||||
|
||||
To ensure that all licensing criteria is met all repositories of the LVGL project apply a process called DCO (Developer's Certificate of Origin).
|
||||
|
||||
The text of DCO can be read here: https://developercertificate.org/
|
||||
For a more detailed description see the [Documentation](https://docs.lvgl.io/latest/en/html/contributing/index.html#developer-certification-of-origin-dco) site.
|
||||
|
||||
By contributing to any repositories of the LVGL project you state that your contribution corresponds with the DCO.
|
||||
|
||||
No further action is required if your contribution fulfills the DCO. If you are not sure about it feel free to ask us in a comment.
|
||||
17
libs/lv_drivers/.github/stale.yml
vendored
Normal file
17
libs/lv_drivers/.github/stale.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 21
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- architecture
|
||||
- pinned
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue or pull request has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
2
libs/lv_drivers/.gitignore
vendored
Normal file
2
libs/lv_drivers/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
**/*.o
|
||||
**/*.d
|
||||
58
libs/lv_drivers/CMakeLists.txt
Normal file
58
libs/lv_drivers/CMakeLists.txt
Normal file
@ -0,0 +1,58 @@
|
||||
cmake_minimum_required(VERSION 3.12.4)
|
||||
|
||||
project(lv_drivers HOMEPAGE_URL https://github.com/lvgl/lv_drivers/)
|
||||
|
||||
# Option to build as shared library (as opposed to static), default: OFF
|
||||
option(BUILD_SHARED_LIBS "Build shared as library (as opposed to static)" OFF)
|
||||
|
||||
file(GLOB_RECURSE SOURCES ./*.c)
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
add_library(lv_drivers SHARED ${SOURCES})
|
||||
else()
|
||||
add_library(lv_drivers STATIC ${SOURCES})
|
||||
endif()
|
||||
|
||||
add_library(lvgl_drivers ALIAS lv_drivers)
|
||||
add_library(lvgl::drivers ALIAS lv_drivers)
|
||||
|
||||
target_include_directories(lv_drivers SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PKG_WAYLAND wayland-client wayland-cursor wayland-protocols xkbcommon)
|
||||
target_link_libraries(lv_drivers PUBLIC lvgl ${PKG_WAYLAND_LIBRARIES})
|
||||
|
||||
if("${LIB_INSTALL_DIR}" STREQUAL "")
|
||||
set(LIB_INSTALL_DIR "lib")
|
||||
endif()
|
||||
|
||||
if("${INC_INSTALL_DIR}" STREQUAL "")
|
||||
set(INC_INSTALL_DIR "include/lvgl/lv_drivers")
|
||||
endif()
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/"
|
||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INC_INSTALL_DIR}/"
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN ".git*" EXCLUDE
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN "docs" EXCLUDE
|
||||
PATTERN "lib" EXCLUDE)
|
||||
|
||||
file(GLOB LV_DRIVERS_PUBLIC_HEADERS "${CMAKE_SOURCE_DIR}/lv_drv_conf.h")
|
||||
|
||||
set_target_properties(
|
||||
lv_drivers
|
||||
PROPERTIES OUTPUT_NAME lv_drivers
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
PUBLIC_HEADER "${LV_DRIVERS_PUBLIC_HEADERS}")
|
||||
|
||||
install(
|
||||
TARGETS lv_drivers
|
||||
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
|
||||
LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
|
||||
RUNTIME DESTINATION "${LIB_INSTALL_DIR}"
|
||||
PUBLIC_HEADER DESTINATION "${INC_INSTALL_DIR}")
|
||||
21
libs/lv_drivers/LICENSE
Normal file
21
libs/lv_drivers/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 LittlevGL
|
||||
|
||||
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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
7
libs/lv_drivers/README.md
Normal file
7
libs/lv_drivers/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Display and Touch pad drivers
|
||||
|
||||
Display controller and touchpad driver to can be directly used with [LittlevGL](https://littlevgl.com).
|
||||
|
||||
To learn more about using drivers in LittlevGL visit the [Porting guide](https://docs.lvgl.io/latest/en/html/porting/index.html).
|
||||
|
||||
If you used a new display or touchpad driver with LittlevGL please share it with other people!
|
||||
597
libs/lv_drivers/display/GC9A01.c
Normal file
597
libs/lv_drivers/display/GC9A01.c
Normal file
@ -0,0 +1,597 @@
|
||||
/**
|
||||
* @file GC9A01.c
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "GC9A01.h"
|
||||
#if USE_GC9A01
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include LV_DRV_DISP_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef GC9A01_XSTART
|
||||
#define GC9A01_XSTART 0
|
||||
#endif
|
||||
#ifndef GC9A01_YSTART
|
||||
#define GC9A01_YSTART 0
|
||||
#endif
|
||||
|
||||
#define GC9A01_CMD_MODE 0
|
||||
#define GC9A01_DATA_MODE 1
|
||||
|
||||
#define GC9A01_HOR_RES 240
|
||||
#define GC9A01_VER_RES 240
|
||||
|
||||
/* GC9A01 Commands that we know of. Limited documentation */
|
||||
#define GC9A01_INVOFF 0x20
|
||||
#define GC9A01_INVON 0x21
|
||||
#define GC9A01_DISPON 0x29
|
||||
#define GC9A01_CASET 0x2A
|
||||
#define GC9A01_RASET 0x2B
|
||||
#define GC9A01_RAMWR 0x2C
|
||||
#define GC9A01_COLMOD 0x3A
|
||||
#define GC9A01_MADCTL 0x36
|
||||
#define GC9A01_MADCTL_MY 0x80
|
||||
#define GC9A01_MADCTL_MX 0x40
|
||||
#define GC9A01_MADCTL_MV 0x20
|
||||
#define GC9A01_MADCTL_RGB 0x00
|
||||
#define GC9A01_DISFNCTRL 0xB6
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/* Init script function */
|
||||
struct GC9A01_function {
|
||||
uint16_t cmd;
|
||||
uint16_t data;
|
||||
};
|
||||
|
||||
/* Init script commands */
|
||||
enum GC9A01_cmd {
|
||||
GC9A01_START,
|
||||
GC9A01_END,
|
||||
GC9A01_CMD,
|
||||
GC9A01_DATA,
|
||||
GC9A01_DELAY
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void GC9A01_command(uint8_t cmd);
|
||||
static void GC9A01_data(uint8_t data);
|
||||
static void GC9A01_set_addr_win(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
// Documentation on op codes for GC9A01 are very hard to find.
|
||||
// Will document should they be found.
|
||||
static struct GC9A01_function GC9A01_cfg_script[] = {
|
||||
{ GC9A01_START, GC9A01_START},
|
||||
{ GC9A01_CMD, 0xEF},
|
||||
|
||||
{ GC9A01_CMD, 0xEB},
|
||||
{ GC9A01_DATA, 0x14},
|
||||
|
||||
{ GC9A01_CMD, 0xFE}, // Inter Register Enable1
|
||||
{ GC9A01_CMD, 0xEF}, // Inter Register Enable2
|
||||
|
||||
{ GC9A01_CMD, 0xEB},
|
||||
{ GC9A01_DATA, 0x14},
|
||||
|
||||
{ GC9A01_CMD, 0x84},
|
||||
{ GC9A01_DATA, 0x40},
|
||||
|
||||
{ GC9A01_CMD, 0x85},
|
||||
{ GC9A01_DATA, 0xFF},
|
||||
|
||||
{ GC9A01_CMD, 0x86},
|
||||
{ GC9A01_DATA, 0xFF},
|
||||
|
||||
{ GC9A01_CMD, 0x87},
|
||||
{ GC9A01_DATA, 0xFF},
|
||||
|
||||
{ GC9A01_CMD, 0x88},
|
||||
{ GC9A01_DATA, 0x0A},
|
||||
|
||||
{ GC9A01_CMD, 0x89},
|
||||
{ GC9A01_DATA, 0x21},
|
||||
|
||||
{ GC9A01_CMD, 0x8A},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
|
||||
{ GC9A01_CMD, 0x8B},
|
||||
{ GC9A01_DATA, 0x80},
|
||||
|
||||
{ GC9A01_CMD, 0x8C},
|
||||
{ GC9A01_DATA, 0x01},
|
||||
|
||||
{ GC9A01_CMD, 0x8D},
|
||||
{ GC9A01_DATA, 0x01},
|
||||
|
||||
{ GC9A01_CMD, 0x8E},
|
||||
{ GC9A01_DATA, 0xFF},
|
||||
|
||||
{ GC9A01_CMD, 0x8F},
|
||||
{ GC9A01_DATA, 0xFF},
|
||||
|
||||
{ GC9A01_CMD, GC9A01_DISFNCTRL}, // Display Function Control
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
|
||||
{ GC9A01_CMD, GC9A01_MADCTL}, // Memory Access Control
|
||||
{ GC9A01_DATA, 0x48}, // Set the display direction 0,1,2,3 four directions
|
||||
|
||||
{ GC9A01_CMD, GC9A01_COLMOD}, // COLMOD: Pixel Format Set
|
||||
{ GC9A01_DATA, 0x05}, // 16 Bits per pixel
|
||||
|
||||
{ GC9A01_CMD, 0x90},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
|
||||
{ GC9A01_CMD, 0xBD},
|
||||
{ GC9A01_DATA, 0x06},
|
||||
|
||||
{ GC9A01_CMD, 0xBC},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
|
||||
{ GC9A01_CMD, 0xFF},
|
||||
{ GC9A01_DATA, 0x60},
|
||||
{ GC9A01_DATA, 0x01},
|
||||
{ GC9A01_DATA, 0x04},
|
||||
|
||||
{ GC9A01_CMD, 0xC3}, // Power Control 2
|
||||
{ GC9A01_DATA, 0x13},
|
||||
{ GC9A01_CMD, 0xC4}, // Power Control 3
|
||||
{ GC9A01_DATA, 0x13},
|
||||
|
||||
{ GC9A01_CMD, 0xC9}, // Power Control 4
|
||||
{ GC9A01_DATA, 0x22},
|
||||
|
||||
{ GC9A01_CMD, 0xBE},
|
||||
{ GC9A01_DATA, 0x11},
|
||||
|
||||
{ GC9A01_CMD, 0xE1},
|
||||
{ GC9A01_DATA, 0x10},
|
||||
{ GC9A01_DATA, 0x0E},
|
||||
|
||||
{ GC9A01_CMD, 0xDF},
|
||||
{ GC9A01_DATA, 0x21},
|
||||
{ GC9A01_DATA, 0x0C},
|
||||
{ GC9A01_DATA, 0x02},
|
||||
|
||||
{ GC9A01_CMD, 0xF0}, // SET_GAMMA1
|
||||
{ GC9A01_DATA, 0x45},
|
||||
{ GC9A01_DATA, 0x09},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x26},
|
||||
{ GC9A01_DATA, 0x2A},
|
||||
|
||||
{ GC9A01_CMD, 0xF1}, // SET_GAMMA2
|
||||
{ GC9A01_DATA, 0x43},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x72},
|
||||
{ GC9A01_DATA, 0x36},
|
||||
{ GC9A01_DATA, 0x37},
|
||||
{ GC9A01_DATA, 0x6F},
|
||||
|
||||
{ GC9A01_CMD, 0xF2}, // SET_GAMMA3
|
||||
{ GC9A01_DATA, 0x45},
|
||||
{ GC9A01_DATA, 0x09},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x26},
|
||||
{ GC9A01_DATA, 0x2A},
|
||||
|
||||
{ GC9A01_CMD, 0xF3}, // SET_GAMMA4
|
||||
{ GC9A01_DATA, 0x43},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x72},
|
||||
{ GC9A01_DATA, 0x36},
|
||||
{ GC9A01_DATA, 0x37},
|
||||
{ GC9A01_DATA, 0x6F},
|
||||
|
||||
{ GC9A01_CMD, 0xED},
|
||||
{ GC9A01_DATA, 0x1B},
|
||||
{ GC9A01_DATA, 0x0B},
|
||||
|
||||
{ GC9A01_CMD, 0xAE},
|
||||
{ GC9A01_DATA, 0x77},
|
||||
|
||||
{ GC9A01_CMD, 0xCD},
|
||||
{ GC9A01_DATA, 0x63},
|
||||
|
||||
{ GC9A01_CMD, 0x70},
|
||||
{ GC9A01_DATA, 0x07},
|
||||
{ GC9A01_DATA, 0x07},
|
||||
{ GC9A01_DATA, 0x04},
|
||||
{ GC9A01_DATA, 0x0E},
|
||||
{ GC9A01_DATA, 0x0F},
|
||||
{ GC9A01_DATA, 0x09},
|
||||
{ GC9A01_DATA, 0x07},
|
||||
{ GC9A01_DATA, 0x08},
|
||||
{ GC9A01_DATA, 0x03},
|
||||
|
||||
{ GC9A01_CMD, 0xE8},
|
||||
{ GC9A01_DATA, 0x34},
|
||||
|
||||
{ GC9A01_CMD, 0x62},
|
||||
{ GC9A01_DATA, 0x18},
|
||||
{ GC9A01_DATA, 0x0D},
|
||||
{ GC9A01_DATA, 0x71},
|
||||
{ GC9A01_DATA, 0xED},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x18},
|
||||
{ GC9A01_DATA, 0x0F},
|
||||
{ GC9A01_DATA, 0x71},
|
||||
{ GC9A01_DATA, 0xEF},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
|
||||
{ GC9A01_CMD, 0x63},
|
||||
{ GC9A01_DATA, 0x18},
|
||||
{ GC9A01_DATA, 0x11},
|
||||
{ GC9A01_DATA, 0x71},
|
||||
{ GC9A01_DATA, 0xF1},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x18},
|
||||
{ GC9A01_DATA, 0x13},
|
||||
{ GC9A01_DATA, 0x71},
|
||||
{ GC9A01_DATA, 0xF3},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
{ GC9A01_DATA, 0x70},
|
||||
|
||||
{ GC9A01_CMD, 0x64},
|
||||
{ GC9A01_DATA, 0x28},
|
||||
{ GC9A01_DATA, 0x29},
|
||||
{ GC9A01_DATA, 0xF1},
|
||||
{ GC9A01_DATA, 0x01},
|
||||
{ GC9A01_DATA, 0xF1},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x07},
|
||||
|
||||
{ GC9A01_CMD, 0x66},
|
||||
{ GC9A01_DATA, 0x3C},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0xCD},
|
||||
{ GC9A01_DATA, 0x67},
|
||||
{ GC9A01_DATA, 0x45},
|
||||
{ GC9A01_DATA, 0x45},
|
||||
{ GC9A01_DATA, 0x10},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
|
||||
{ GC9A01_CMD, 0x67},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x3C},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x01},
|
||||
{ GC9A01_DATA, 0x54},
|
||||
{ GC9A01_DATA, 0x10},
|
||||
{ GC9A01_DATA, 0x32},
|
||||
{ GC9A01_DATA, 0x98},
|
||||
|
||||
{ GC9A01_CMD, 0x74},
|
||||
{ GC9A01_DATA, 0x10},
|
||||
{ GC9A01_DATA, 0x85},
|
||||
{ GC9A01_DATA, 0x80},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
{ GC9A01_DATA, 0x4E},
|
||||
{ GC9A01_DATA, 0x00},
|
||||
|
||||
{ GC9A01_CMD, 0x98},
|
||||
{ GC9A01_DATA, 0x3E},
|
||||
{ GC9A01_DATA, 0x07},
|
||||
|
||||
{ GC9A01_CMD, 0x35}, // Tearing Effect Line ON
|
||||
{ GC9A01_CMD, 0x21}, // Display Inversion ON
|
||||
|
||||
{ GC9A01_CMD, 0x11}, // Sleep Out Mode
|
||||
{ GC9A01_DELAY, 120},
|
||||
{ GC9A01_CMD, GC9A01_DISPON}, // Display ON
|
||||
{ GC9A01_DELAY, 255},
|
||||
{ GC9A01_END, GC9A01_END},
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Write a command to the GC9A01
|
||||
* @param cmd the command
|
||||
*/
|
||||
static void GC9A01_command(uint8_t cmd)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(GC9A01_CMD_MODE);
|
||||
LV_DRV_DISP_SPI_WR_BYTE(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to the GC9A01
|
||||
* @param data the data
|
||||
*/
|
||||
static void GC9A01_data(uint8_t data)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(GC9A01_DATA_MODE);
|
||||
LV_DRV_DISP_SPI_WR_BYTE(data);
|
||||
}
|
||||
|
||||
static int GC9A01_data_array(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
uint8_t *pt = buf;
|
||||
|
||||
for (uint32_t lp = 0; lp < len; lp++, pt++)
|
||||
{
|
||||
LV_DRV_DISP_SPI_WR_BYTE(*pt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GC9A01_databuf(uint32_t len, uint8_t *buf)
|
||||
{
|
||||
uint32_t byte_left = len;
|
||||
uint8_t *pt = buf;
|
||||
|
||||
while (byte_left)
|
||||
{
|
||||
if (byte_left > 64)
|
||||
{
|
||||
LV_DRV_DISP_SPI_WR_ARRAY((char*)pt, 64);
|
||||
byte_left = byte_left - 64;
|
||||
pt = pt + 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
LV_DRV_DISP_SPI_WR_ARRAY((char*)pt, byte_left);
|
||||
byte_left=0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// hard reset of the tft controller
|
||||
// ----------------------------------------------------------
|
||||
static void GC9A01_hard_reset( void )
|
||||
{
|
||||
LV_DRV_DISP_SPI_CS(0); // Low to listen to us
|
||||
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
LV_DRV_DISP_RST(0);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
}
|
||||
|
||||
// Configuration of the tft controller
|
||||
// ----------------------------------------------------------
|
||||
static void GC9A01_run_cfg_script(void)
|
||||
{
|
||||
int i = 0;
|
||||
int end_script = 0;
|
||||
|
||||
do {
|
||||
switch (GC9A01_cfg_script[i].cmd)
|
||||
{
|
||||
case GC9A01_START:
|
||||
break;
|
||||
case GC9A01_CMD:
|
||||
GC9A01_command( GC9A01_cfg_script[i].data & 0xFF );
|
||||
break;
|
||||
case GC9A01_DATA:
|
||||
GC9A01_data( GC9A01_cfg_script[i].data & 0xFF );
|
||||
break;
|
||||
case GC9A01_DELAY:
|
||||
LV_DRV_DELAY_MS(GC9A01_cfg_script[i].data);
|
||||
break;
|
||||
case GC9A01_END:
|
||||
end_script = 1;
|
||||
}
|
||||
i++;
|
||||
} while (!end_script);
|
||||
}
|
||||
|
||||
void GC9A01_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
|
||||
// Rudimentary clipping
|
||||
if((x >= GC9A01_HOR_RES) || (y >= GC9A01_VER_RES)) return;
|
||||
if((y+h-1) >= GC9A01_VER_RES) h = GC9A01_VER_RES - y;
|
||||
|
||||
LV_DRV_DISP_SPI_CS(0); // Listen to us
|
||||
|
||||
GC9A01_set_addr_win(x, y, x, y + h - 1);
|
||||
|
||||
uint8_t hi = color >> 8, lo = color;
|
||||
|
||||
while (h--) {
|
||||
GC9A01_data(hi);
|
||||
GC9A01_data(lo);
|
||||
}
|
||||
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
}
|
||||
|
||||
void GC9A01_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
|
||||
// Rudimentary clipping
|
||||
if((x >= GC9A01_HOR_RES) || (y >= GC9A01_VER_RES)) return;
|
||||
if((x+w-1) >= GC9A01_HOR_RES) w = GC9A01_HOR_RES - x;
|
||||
|
||||
LV_DRV_DISP_SPI_CS(0); // Listen to us
|
||||
|
||||
GC9A01_set_addr_win(x, y, x + w - 1, y);
|
||||
|
||||
uint8_t hi = color >> 8, lo = color;
|
||||
|
||||
while (w--) {
|
||||
GC9A01_data(hi);
|
||||
GC9A01_data(lo);
|
||||
}
|
||||
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
}
|
||||
|
||||
|
||||
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
|
||||
uint16_t GC9A01_Color565(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||
}
|
||||
|
||||
void GC9A01_invertDisplay(bool i)
|
||||
{
|
||||
GC9A01_command(i ? GC9A01_INVON : GC9A01_INVOFF);
|
||||
}
|
||||
|
||||
void GC9A01_drawPixel(int16_t x, int16_t y, uint16_t color)
|
||||
{
|
||||
if((x < 0) ||(x >= GC9A01_HOR_RES) || (y < 0) || (y >= GC9A01_VER_RES)) return;
|
||||
|
||||
LV_DRV_DISP_SPI_CS(0); // Listen to us
|
||||
GC9A01_set_addr_win(x, y, x, y);
|
||||
|
||||
uint8_t hi = color >> 8, lo = color;
|
||||
|
||||
GC9A01_data(hi);
|
||||
GC9A01_data(lo);
|
||||
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
}
|
||||
|
||||
void GC9A01_fillScreen(uint16_t color) {
|
||||
GC9A01_fillRect(0, 0, GC9A01_HOR_RES, GC9A01_VER_RES, color);
|
||||
}
|
||||
|
||||
// fill a rectangle
|
||||
void GC9A01_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
|
||||
// rudimentary clipping (drawChar w/big text requires this)
|
||||
if((x >= GC9A01_HOR_RES) || (y >= GC9A01_VER_RES)) return;
|
||||
if((x + w - 1) >= GC9A01_HOR_RES) w = GC9A01_HOR_RES - x;
|
||||
if((y + h - 1) >= GC9A01_VER_RES) h = GC9A01_VER_RES - y;
|
||||
|
||||
LV_DRV_DISP_SPI_CS(0); // Listen to us
|
||||
|
||||
GC9A01_set_addr_win(x, y, x + w - 1, y + h - 1);
|
||||
|
||||
uint8_t hi = color >> 8, lo = color;
|
||||
|
||||
for (y = h; y > 0; y--)
|
||||
{
|
||||
for (x = w; x > 0; x--)
|
||||
{
|
||||
GC9A01_data(hi);
|
||||
GC9A01_data(lo);
|
||||
}
|
||||
}
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
}
|
||||
|
||||
void GC9A01_setRotation(uint8_t m) {
|
||||
|
||||
GC9A01_command(GC9A01_MADCTL);
|
||||
m %= 4; // can't be higher than 3
|
||||
switch (m) {
|
||||
case 0:
|
||||
GC9A01_data(GC9A01_MADCTL_MX | GC9A01_MADCTL_MY | GC9A01_MADCTL_RGB);
|
||||
|
||||
// _xstart = _colstart;
|
||||
// _ystart = _rowstart;
|
||||
break;
|
||||
case 1:
|
||||
GC9A01_data(GC9A01_MADCTL_MY | GC9A01_MADCTL_MV | GC9A01_MADCTL_RGB);
|
||||
|
||||
// _ystart = _colstart;
|
||||
// _xstart = _rowstart;
|
||||
break;
|
||||
case 2:
|
||||
GC9A01_data(GC9A01_MADCTL_RGB);
|
||||
|
||||
// _xstart = _colstart;
|
||||
// _ystart = _rowstart;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
GC9A01_data(GC9A01_MADCTL_MX | GC9A01_MADCTL_MV | GC9A01_MADCTL_RGB);
|
||||
|
||||
// _ystart = _colstart;
|
||||
// _xstart = _rowstart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the GC9A01
|
||||
*/
|
||||
int GC9A01_init(void)
|
||||
{
|
||||
GC9A01_hard_reset();
|
||||
GC9A01_run_cfg_script();
|
||||
|
||||
// GC9A01_fillScreen(0x0000); // Black
|
||||
// GC9A01_fillScreen(0xFFFF); // White
|
||||
GC9A01_fillScreen(0xAAAA); // ?
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void GC9A01_set_addr_win(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
|
||||
{
|
||||
uint16_t x_start = x0 + GC9A01_XSTART, x_end = x1 + GC9A01_XSTART;
|
||||
uint16_t y_start = y0 + GC9A01_YSTART, y_end = y1 + GC9A01_YSTART;
|
||||
|
||||
GC9A01_command(GC9A01_CASET); // Column addr set
|
||||
GC9A01_data(x_start >> 8);
|
||||
GC9A01_data(x_start & 0xFF); // XSTART
|
||||
GC9A01_data(x_end >> 8);
|
||||
GC9A01_data(x_end & 0xFF); // XEND
|
||||
|
||||
GC9A01_command(GC9A01_RASET); // Row addr set
|
||||
GC9A01_data(y_start >> 8);
|
||||
GC9A01_data(y_start & 0xFF); // YSTART
|
||||
GC9A01_data(y_end >> 8);
|
||||
GC9A01_data(y_end & 0xFF); // YEND
|
||||
|
||||
GC9A01_command(GC9A01_RAMWR);
|
||||
}
|
||||
|
||||
void GC9A01_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t *color_p)
|
||||
{
|
||||
LV_DRV_DISP_SPI_CS(0); // Listen to us
|
||||
|
||||
GC9A01_set_addr_win(area->x1, area->y1, area->x2, area->y2);
|
||||
int32_t len = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1) * 2;
|
||||
|
||||
LV_DRV_DISP_CMD_DATA(GC9A01_DATA_MODE);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY((char*)color_p, len);
|
||||
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
lv_disp_flush_ready(disp_drv); /* Indicate you are ready with the flushing*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
76
libs/lv_drivers/display/GC9A01.h
Normal file
76
libs/lv_drivers/display/GC9A01.h
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file GC9A01.h
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef GC9A01_H
|
||||
#define GC9A01_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_GC9A01
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH != 16
|
||||
#error "GC9A01 currently supports 'LV_COLOR_DEPTH == 16'. Set it in lv_conf.h"
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_16_SWAP != 1
|
||||
#error "GC9A01 SPI requires LV_COLOR_16_SWAP == 1. Set it in lv_conf.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
int GC9A01_init(void);
|
||||
void GC9A01_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void GC9A01_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
|
||||
void GC9A01_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t * color_p);
|
||||
void GC9A01_setRotation(uint8_t m);
|
||||
void GC9A01_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||
void GC9A01_fillScreen(uint16_t color);
|
||||
uint16_t GC9A01_Color565(uint8_t r, uint8_t g, uint8_t b);
|
||||
void GC9A01_invertDisplay(bool i);
|
||||
void GC9A01_drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void GC9A01_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
void GC9A01_drawFastVLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_GC9A01 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* GC9A01_H */
|
||||
|
||||
432
libs/lv_drivers/display/ILI9341.c
Normal file
432
libs/lv_drivers/display/ILI9341.c
Normal file
@ -0,0 +1,432 @@
|
||||
/**
|
||||
* @file ILI9341.c
|
||||
*
|
||||
* ILI9341.pdf [ILI9341_DS_V1.13_20110805]
|
||||
*
|
||||
* [references]
|
||||
* - https://www.newhavendisplay.com/app_notes/ILI9341.pdf
|
||||
* - Linux Source [v5.9-rc4] "drivers/staging/fbtft/fb_ili9341.c"
|
||||
* - https://github.com/adafruit/Adafruit_ILI9341/blob/master/Adafruit_ILI9341.cpp
|
||||
* - https://os.mbed.com/users/dreschpe/code/SPI_TFT_ILI9341
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "ILI9341.h"
|
||||
#if USE_ILI9341 != 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include LV_DRV_DISP_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ILI9341_CMD_MODE 0
|
||||
#define ILI9341_DATA_MODE 1
|
||||
|
||||
#define ILI9341_TFTWIDTH 240
|
||||
#define ILI9341_TFTHEIGHT 320
|
||||
|
||||
/* Level 1 Commands -------------- [section] Description */
|
||||
|
||||
#define ILI9341_NOP 0x00 /* [8.2.1 ] No Operation / Terminate Frame Memory Write */
|
||||
#define ILI9341_SWRESET 0x01 /* [8.2.2 ] Software Reset */
|
||||
#define ILI9341_RDDIDIF 0x04 /* [8.2.3 ] Read Display Identification Information */
|
||||
#define ILI9341_RDDST 0x09 /* [8.2.4 ] Read Display Status */
|
||||
#define ILI9341_RDDPM 0x0A /* [8.2.5 ] Read Display Power Mode */
|
||||
#define ILI9341_RDDMADCTL 0x0B /* [8.2.6 ] Read Display MADCTL */
|
||||
#define ILI9341_RDDCOLMOD 0x0C /* [8.2.7 ] Read Display Pixel Format */
|
||||
#define ILI9341_RDDIM 0x0D /* [8.2.8 ] Read Display Image Mode */
|
||||
#define ILI9341_RDDSM 0x0E /* [8.2.9 ] Read Display Signal Mode */
|
||||
#define ILI9341_RDDSDR 0x0F /* [8.2.10] Read Display Self-Diagnostic Result */
|
||||
#define ILI9341_SLPIN 0x10 /* [8.2.11] Enter Sleep Mode */
|
||||
#define ILI9341_SLPOUT 0x11 /* [8.2.12] Leave Sleep Mode */
|
||||
#define ILI9341_PTLON 0x12 /* [8.2.13] Partial Display Mode ON */
|
||||
#define ILI9341_NORON 0x13 /* [8.2.14] Normal Display Mode ON */
|
||||
#define ILI9341_DINVOFF 0x20 /* [8.2.15] Display Inversion OFF */
|
||||
#define ILI9341_DINVON 0x21 /* [8.2.16] Display Inversion ON */
|
||||
#define ILI9341_GAMSET 0x26 /* [8.2.17] Gamma Set */
|
||||
#define ILI9341_DISPOFF 0x28 /* [8.2.18] Display OFF*/
|
||||
#define ILI9341_DISPON 0x29 /* [8.2.19] Display ON*/
|
||||
#define ILI9341_CASET 0x2A /* [8.2.20] Column Address Set */
|
||||
#define ILI9341_PASET 0x2B /* [8.2.21] Page Address Set */
|
||||
#define ILI9341_RAMWR 0x2C /* [8.2.22] Memory Write */
|
||||
#define ILI9341_RGBSET 0x2D /* [8.2.23] Color Set (LUT for 16-bit to 18-bit color depth conversion) */
|
||||
#define ILI9341_RAMRD 0x2E /* [8.2.24] Memory Read */
|
||||
#define ILI9341_PTLAR 0x30 /* [8.2.25] Partial Area */
|
||||
#define ILI9341_VSCRDEF 0x33 /* [8.2.26] Veritcal Scrolling Definition */
|
||||
#define ILI9341_TEOFF 0x34 /* [8.2.27] Tearing Effect Line OFF */
|
||||
#define ILI9341_TEON 0x35 /* [8.2.28] Tearing Effect Line ON */
|
||||
#define ILI9341_MADCTL 0x36 /* [8.2.29] Memory Access Control */
|
||||
#define MADCTL_MY 0x80 /* MY row address order */
|
||||
#define MADCTL_MX 0x40 /* MX column address order */
|
||||
#define MADCTL_MV 0x20 /* MV row / column exchange */
|
||||
#define MADCTL_ML 0x10 /* ML vertical refresh order */
|
||||
#define MADCTL_MH 0x04 /* MH horizontal refresh order */
|
||||
#define MADCTL_RGB 0x00 /* RGB Order [default] */
|
||||
#define MADCTL_BGR 0x08 /* BGR Order */
|
||||
#define ILI9341_VSCRSADD 0x37 /* [8.2.30] Vertical Scrolling Start Address */
|
||||
#define ILI9341_IDMOFF 0x38 /* [8.2.31] Idle Mode OFF */
|
||||
#define ILI9341_IDMON 0x39 /* [8.2.32] Idle Mode ON */
|
||||
#define ILI9341_PIXSET 0x3A /* [8.2.33] Pixel Format Set */
|
||||
#define ILI9341_WRMEMCONT 0x3C /* [8.2.34] Write Memory Continue */
|
||||
#define ILI9341_RDMEMCONT 0x3E /* [8.2.35] Read Memory Continue */
|
||||
#define ILI9341_SETSCANTE 0x44 /* [8.2.36] Set Tear Scanline */
|
||||
#define ILI9341_GETSCAN 0x45 /* [8.2.37] Get Scanline */
|
||||
#define ILI9341_WRDISBV 0x51 /* [8.2.38] Write Display Brightness Value */
|
||||
#define ILI9341_RDDISBV 0x52 /* [8.2.39] Read Display Brightness Value */
|
||||
#define ILI9341_WRCTRLD 0x53 /* [8.2.40] Write Control Display */
|
||||
#define ILI9341_RDCTRLD 0x54 /* [8.2.41] Read Control Display */
|
||||
#define ILI9341_WRCABC 0x55 /* [8.2.42] Write Content Adaptive Brightness Control Value */
|
||||
#define ILI9341_RDCABC 0x56 /* [8.2.43] Read Content Adaptive Brightness Control Value */
|
||||
#define ILI9341_WRCABCMIN 0x5E /* [8.2.44] Write CABC Minimum Brightness */
|
||||
#define ILI9341_RDCABCMIN 0x5F /* [8.2.45] Read CABC Minimum Brightness */
|
||||
#define ILI9341_RDID1 0xDA /* [8.2.46] Read ID1 - Manufacturer ID (user) */
|
||||
#define ILI9341_RDID2 0xDB /* [8.2.47] Read ID2 - Module/Driver version (supplier) */
|
||||
#define ILI9341_RDID3 0xDC /* [8.2.48] Read ID3 - Module/Driver version (user) */
|
||||
|
||||
/* Level 2 Commands -------------- [section] Description */
|
||||
|
||||
#define ILI9341_IFMODE 0xB0 /* [8.3.1 ] Interface Mode Control */
|
||||
#define ILI9341_FRMCTR1 0xB1 /* [8.3.2 ] Frame Rate Control (In Normal Mode/Full Colors) */
|
||||
#define ILI9341_FRMCTR2 0xB2 /* [8.3.3 ] Frame Rate Control (In Idle Mode/8 colors) */
|
||||
#define ILI9341_FRMCTR3 0xB3 /* [8.3.4 ] Frame Rate control (In Partial Mode/Full Colors) */
|
||||
#define ILI9341_INVTR 0xB4 /* [8.3.5 ] Display Inversion Control */
|
||||
#define ILI9341_PRCTR 0xB5 /* [8.3.6 ] Blanking Porch Control */
|
||||
#define ILI9341_DISCTRL 0xB6 /* [8.3.7 ] Display Function Control */
|
||||
#define ILI9341_ETMOD 0xB7 /* [8.3.8 ] Entry Mode Set */
|
||||
#define ILI9341_BLCTRL1 0xB8 /* [8.3.9 ] Backlight Control 1 - Grayscale Histogram UI mode */
|
||||
#define ILI9341_BLCTRL2 0xB9 /* [8.3.10] Backlight Control 2 - Grayscale Histogram still picture mode */
|
||||
#define ILI9341_BLCTRL3 0xBA /* [8.3.11] Backlight Control 3 - Grayscale Thresholds UI mode */
|
||||
#define ILI9341_BLCTRL4 0xBB /* [8.3.12] Backlight Control 4 - Grayscale Thresholds still picture mode */
|
||||
#define ILI9341_BLCTRL5 0xBC /* [8.3.13] Backlight Control 5 - Brightness Transition time */
|
||||
#define ILI9341_BLCTRL7 0xBE /* [8.3.14] Backlight Control 7 - PWM Frequency */
|
||||
#define ILI9341_BLCTRL8 0xBF /* [8.3.15] Backlight Control 8 - ON/OFF + PWM Polarity*/
|
||||
#define ILI9341_PWCTRL1 0xC0 /* [8.3.16] Power Control 1 - GVDD */
|
||||
#define ILI9341_PWCTRL2 0xC1 /* [8.3.17] Power Control 2 - step-up factor for operating voltage */
|
||||
#define ILI9341_VMCTRL1 0xC5 /* [8.3.18] VCOM Control 1 - Set VCOMH and VCOML */
|
||||
#define ILI9341_VMCTRL2 0xC7 /* [8.3.19] VCOM Control 2 - VCOM offset voltage */
|
||||
#define ILI9341_NVMWR 0xD0 /* [8.3.20] NV Memory Write */
|
||||
#define ILI9341_NVMPKEY 0xD1 /* [8.3.21] NV Memory Protection Key */
|
||||
#define ILI9341_RDNVM 0xD2 /* [8.3.22] NV Memory Status Read */
|
||||
#define ILI9341_RDID4 0xD3 /* [8.3.23] Read ID4 - IC Device Code */
|
||||
#define ILI9341_PGAMCTRL 0xE0 /* [8.3.24] Positive Gamma Control */
|
||||
#define ILI9341_NGAMCTRL 0xE1 /* [8.3.25] Negative Gamma Correction */
|
||||
#define ILI9341_DGAMCTRL1 0xE2 /* [8.3.26] Digital Gamma Control 1 */
|
||||
#define ILI9341_DGAMCTRL2 0xE3 /* [8.3.27] Digital Gamma Control 2 */
|
||||
#define ILI9341_IFCTL 0xF6 /* [8.3.28] 16bits Data Format Selection */
|
||||
|
||||
/* Extended Commands --------------- [section] Description*/
|
||||
|
||||
#define ILI9341_PWCTRLA 0xCB /* [8.4.1] Power control A */
|
||||
#define ILI9341_PWCTRLB 0xCF /* [8.4.2] Power control B */
|
||||
#define ILI9341_TIMECTRLA_INT 0xE8 /* [8.4.3] Internal Clock Driver timing control A */
|
||||
#define ILI9341_TIMECTRLA_EXT 0xE9 /* [8.4.4] External Clock Driver timing control A */
|
||||
#define ILI9341_TIMECTRLB 0xEA /* [8.4.5] Driver timing control B (gate driver timing control) */
|
||||
#define ILI9341_PWSEQCTRL 0xED /* [8.4.6] Power on sequence control */
|
||||
#define ILI9341_GAM3CTRL 0xF2 /* [8.4.7] Enable 3 gamma control */
|
||||
#define ILI9341_PUMPRATIO 0xF7 /* [8.4.8] Pump ratio control */
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static inline void ili9341_write(int mode, uint8_t data);
|
||||
static inline void ili9341_write_array(int mode, uint8_t *data, uint16_t len);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the ILI9341 display controller
|
||||
*/
|
||||
void ili9341_init(void)
|
||||
{
|
||||
uint8_t data[15];
|
||||
|
||||
/* hardware reset */
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
LV_DRV_DISP_CMD_DATA(ILI9341_DATA_MODE);
|
||||
LV_DRV_DISP_RST(0);
|
||||
LV_DRV_DELAY_US(50);
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(5);
|
||||
|
||||
/* software reset */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_SWRESET);
|
||||
LV_DRV_DELAY_MS(5);
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_DISPOFF);
|
||||
|
||||
/* startup sequence */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PWCTRLB);
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x83;
|
||||
data[2] = 0x30;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 3);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PWSEQCTRL);
|
||||
data[0] = 0x64;
|
||||
data[1] = 0x03;
|
||||
data[2] = 0x12;
|
||||
data[3] = 0x81;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 4);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_TIMECTRLA_INT);
|
||||
data[0] = 0x85;
|
||||
data[1] = 0x01;
|
||||
data[2] = 0x79;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 3);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PWCTRLA);
|
||||
data[0] = 0x39;
|
||||
data[1] = 0x2c;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x34;
|
||||
data[4] = 0x02;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 5);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PUMPRATIO);
|
||||
ili9341_write(ILI9341_DATA_MODE, 0x20);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_TIMECTRLB);
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 2);
|
||||
|
||||
/* power control */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PWCTRL1);
|
||||
ili9341_write(ILI9341_DATA_MODE, 0x26);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PWCTRL2);
|
||||
ili9341_write(ILI9341_DATA_MODE, 0x11);
|
||||
|
||||
/* VCOM */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_VMCTRL1);
|
||||
data[0] = 0x35;
|
||||
data[1] = 0x3e;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 2);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_VMCTRL2);
|
||||
ili9341_write(ILI9341_DATA_MODE, 0xbe);
|
||||
|
||||
/* set orientation */
|
||||
ili9341_rotate(0, ILI9341_BGR);
|
||||
|
||||
/* 16 bit pixel */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PIXSET);
|
||||
ili9341_write(ILI9341_DATA_MODE, 0x55);
|
||||
|
||||
/* frame rate */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_FRMCTR1);
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x1b;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 2);
|
||||
|
||||
#if ILI9341_GAMMA
|
||||
/* gamma curve set */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_GAMSET);
|
||||
ili9341_write(ILI9341_DATA_MODE, 0x01);
|
||||
|
||||
/* positive gamma correction */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PGAMCTRL);
|
||||
data[0] = 0x1f;
|
||||
data[1] = 0x1a;
|
||||
data[2] = 0x18;
|
||||
data[3] = 0x0a;
|
||||
data[4] = 0x0f;
|
||||
data[5] = 0x06;
|
||||
data[6] = 0x45;
|
||||
data[7] = 0x87;
|
||||
data[8] = 0x32;
|
||||
data[9] = 0x0a;
|
||||
data[10] = 0x07;
|
||||
data[11] = 0x02;
|
||||
data[12] = 0x07;
|
||||
data[13] = 0x05;
|
||||
data[14] = 0x00;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 15);
|
||||
|
||||
/* negative gamma correction */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_NGAMCTRL);
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x25;
|
||||
data[2] = 0x27;
|
||||
data[3] = 0x05;
|
||||
data[4] = 0x10;
|
||||
data[5] = 0x09;
|
||||
data[6] = 0x3a;
|
||||
data[7] = 0x78;
|
||||
data[8] = 0x4d;
|
||||
data[9] = 0x05;
|
||||
data[10] = 0x18;
|
||||
data[11] = 0x0d;
|
||||
data[12] = 0x38;
|
||||
data[13] = 0x3a;
|
||||
data[14] = 0x1f;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 15);
|
||||
#endif
|
||||
|
||||
/* window horizontal */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_CASET);
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = (ILI9341_HOR_RES - 1) >> 8;
|
||||
data[3] = (ILI9341_HOR_RES - 1);
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 4);
|
||||
|
||||
/* window vertical */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PASET);
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = (ILI9341_VER_RES - 1) >> 8;
|
||||
data[3] = (ILI9341_VER_RES - 1);
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 4);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_RAMWR);
|
||||
|
||||
#if ILI9341_TEARING
|
||||
/* tearing effect off */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_TEOFF);
|
||||
|
||||
/* tearing effect on */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_TEON);
|
||||
#endif
|
||||
|
||||
/* entry mode set */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_ETMOD);
|
||||
ili9341_write(ILI9341_DATA_MODE, 0x07);
|
||||
|
||||
/* display function control */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_DISCTRL);
|
||||
data[0] = 0x0a;
|
||||
data[1] = 0x82;
|
||||
data[2] = 0x27;
|
||||
data[3] = 0x00;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 4);
|
||||
|
||||
/* exit sleep mode */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_SLPOUT);
|
||||
|
||||
LV_DRV_DELAY_MS(100);
|
||||
|
||||
/* display on */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_DISPON);
|
||||
|
||||
LV_DRV_DELAY_MS(20);
|
||||
}
|
||||
|
||||
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
if(area->x2 < 0 || area->y2 < 0 || area->x1 > (ILI9341_HOR_RES - 1) || area->y1 > (ILI9341_VER_RES - 1)) {
|
||||
lv_disp_flush_ready(drv);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Truncate the area to the screen */
|
||||
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
|
||||
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
|
||||
int32_t act_x2 = area->x2 > ILI9341_HOR_RES - 1 ? ILI9341_HOR_RES - 1 : area->x2;
|
||||
int32_t act_y2 = area->y2 > ILI9341_VER_RES - 1 ? ILI9341_VER_RES - 1 : area->y2;
|
||||
|
||||
int32_t y;
|
||||
uint8_t data[4];
|
||||
int32_t len = len = (act_x2 - act_x1 + 1) * 2;
|
||||
lv_coord_t w = (area->x2 - area->x1) + 1;
|
||||
|
||||
/* window horizontal */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_CASET);
|
||||
data[0] = act_x1 >> 8;
|
||||
data[1] = act_x1;
|
||||
data[2] = act_x2 >> 8;
|
||||
data[3] = act_x2;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 4);
|
||||
|
||||
/* window vertical */
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_PASET);
|
||||
data[0] = act_y1 >> 8;
|
||||
data[1] = act_y1;
|
||||
data[2] = act_y2 >> 8;
|
||||
data[3] = act_y2;
|
||||
ili9341_write_array(ILI9341_DATA_MODE, data, 4);
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_RAMWR);
|
||||
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
ili9341_write_array(ILI9341_DATA_MODE, (uint8_t *)color_p, len);
|
||||
color_p += w;
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(drv);
|
||||
}
|
||||
|
||||
void ili9341_rotate(int degrees, bool bgr)
|
||||
{
|
||||
uint8_t color_order = MADCTL_RGB;
|
||||
|
||||
if(bgr)
|
||||
color_order = MADCTL_BGR;
|
||||
|
||||
ili9341_write(ILI9341_CMD_MODE, ILI9341_MADCTL);
|
||||
|
||||
switch(degrees) {
|
||||
case 270:
|
||||
ili9341_write(ILI9341_DATA_MODE, MADCTL_MV | color_order);
|
||||
break;
|
||||
case 180:
|
||||
ili9341_write(ILI9341_DATA_MODE, MADCTL_MY | color_order);
|
||||
break;
|
||||
case 90:
|
||||
ili9341_write(ILI9341_DATA_MODE, MADCTL_MX | MADCTL_MY | MADCTL_MV | color_order);
|
||||
break;
|
||||
case 0:
|
||||
/* fall-through */
|
||||
default:
|
||||
ili9341_write(ILI9341_DATA_MODE, MADCTL_MX | color_order);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Write byte
|
||||
* @param mode sets command or data mode for write
|
||||
* @param byte the byte to write
|
||||
*/
|
||||
static inline void ili9341_write(int mode, uint8_t data)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(mode);
|
||||
LV_DRV_DISP_SPI_WR_BYTE(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write byte array
|
||||
* @param mode sets command or data mode for write
|
||||
* @param data the byte array to write
|
||||
* @param len the length of the byte array
|
||||
*/
|
||||
static inline void ili9341_write_array(int mode, uint8_t *data, uint16_t len)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(mode);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY(data, len);
|
||||
}
|
||||
|
||||
#endif
|
||||
67
libs/lv_drivers/display/ILI9341.h
Normal file
67
libs/lv_drivers/display/ILI9341.h
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file ILI9341.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILI9341_H
|
||||
#define ILI9341_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdbool.h>
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_ILI9341
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH != 16
|
||||
#error "ILI9341 currently supports 'LV_COLOR_DEPTH == 16'. Set it in lv_conf.h"
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_16_SWAP != 1
|
||||
#error "ILI9341 SPI requires LV_COLOR_16_SWAP == 1. Set it in lv_conf.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ILI9341_BGR true
|
||||
#define ILI9341_RGB false
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void ili9341_init(void);
|
||||
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void ili9341_rotate(int degrees, bool bgr);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_ILI9341 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* ILI9341_H */
|
||||
425
libs/lv_drivers/display/R61581.c
Normal file
425
libs/lv_drivers/display/R61581.c
Normal file
@ -0,0 +1,425 @@
|
||||
/**
|
||||
* @file R61581.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "R61581.h"
|
||||
#if USE_R61581 != 0
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "lvgl/lv_core/lv_vdb.h"
|
||||
#include LV_DRV_DISP_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define R61581_CMD_MODE 0
|
||||
#define R61581_DATA_MODE 1
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void r61581_io_init(void);
|
||||
static void r61581_reset(void);
|
||||
static void r61581_set_tft_spec(void);
|
||||
static inline void r61581_cmd_mode(void);
|
||||
static inline void r61581_data_mode(void);
|
||||
static inline void r61581_cmd(uint8_t cmd);
|
||||
static inline void r61581_data(uint8_t data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static bool cmd_mode = true;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the R61581 display controller
|
||||
* @return HW_RES_OK or any error from hw_res_t enum
|
||||
*/
|
||||
void r61581_init(void)
|
||||
{
|
||||
r61581_io_init();
|
||||
|
||||
/*Slow mode until the PLL is not started in the display controller*/
|
||||
LV_DRV_DISP_PAR_SLOW;
|
||||
|
||||
r61581_reset();
|
||||
|
||||
r61581_set_tft_spec();
|
||||
|
||||
r61581_cmd(0x13); //SET display on
|
||||
|
||||
r61581_cmd(0x29); //SET display on
|
||||
LV_DRV_DELAY_MS(30);
|
||||
|
||||
/*Parallel to max speed*/
|
||||
LV_DRV_DISP_PAR_FAST;
|
||||
}
|
||||
|
||||
void r61581_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
{
|
||||
/*Return if the area is out the screen*/
|
||||
if(x2 < 0) return;
|
||||
if(y2 < 0) return;
|
||||
if(x1 > R61581_HOR_RES - 1) return;
|
||||
if(y1 > R61581_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = x1 < 0 ? 0 : x1;
|
||||
int32_t act_y1 = y1 < 0 ? 0 : y1;
|
||||
int32_t act_x2 = x2 > R61581_HOR_RES - 1 ? R61581_HOR_RES - 1 : x2;
|
||||
int32_t act_y2 = y2 > R61581_VER_RES - 1 ? R61581_VER_RES - 1 : y2;
|
||||
|
||||
|
||||
//Set the rectangular area
|
||||
r61581_cmd(0x002A);
|
||||
r61581_data(act_x1 >> 8);
|
||||
r61581_data(0x00FF & act_x1);
|
||||
r61581_data(act_x2 >> 8);
|
||||
r61581_data(0x00FF & act_x2);
|
||||
|
||||
r61581_cmd(0x002B);
|
||||
r61581_data(act_y1 >> 8);
|
||||
r61581_data(0x00FF & act_y1);
|
||||
r61581_data(act_y2 >> 8);
|
||||
r61581_data(0x00FF & act_y2);
|
||||
|
||||
r61581_cmd(0x2c);
|
||||
|
||||
int16_t i;
|
||||
uint16_t full_w = x2 - x1 + 1;
|
||||
|
||||
r61581_data_mode();
|
||||
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
uint16_t act_w = act_x2 - act_x1 + 1;
|
||||
for(i = act_y1; i <= act_y2; i++) {
|
||||
LV_DRV_DISP_PAR_WR_ARRAY((uint16_t *)color_p, act_w);
|
||||
color_p += full_w;
|
||||
}
|
||||
#else
|
||||
int16_t j;
|
||||
for(i = act_y1; i <= act_y2; i++) {
|
||||
for(j = 0; j <= act_x2 - act_x1 + 1; j++) {
|
||||
LV_DRV_DISP_PAR_WR_WORD(lv_color_to16(color_p[j]));
|
||||
color_p += full_w;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_flush_ready();
|
||||
}
|
||||
|
||||
void r61581_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
|
||||
{
|
||||
/*Return if the area is out the screen*/
|
||||
if(x2 < 0) return;
|
||||
if(y2 < 0) return;
|
||||
if(x1 > R61581_HOR_RES - 1) return;
|
||||
if(y1 > R61581_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = x1 < 0 ? 0 : x1;
|
||||
int32_t act_y1 = y1 < 0 ? 0 : y1;
|
||||
int32_t act_x2 = x2 > R61581_HOR_RES - 1 ? R61581_HOR_RES - 1 : x2;
|
||||
int32_t act_y2 = y2 > R61581_VER_RES - 1 ? R61581_VER_RES - 1 : y2;
|
||||
|
||||
//Set the rectangular area
|
||||
r61581_cmd(0x002A);
|
||||
r61581_data(act_x1 >> 8);
|
||||
r61581_data(0x00FF & act_x1);
|
||||
r61581_data(act_x2 >> 8);
|
||||
r61581_data(0x00FF & act_x2);
|
||||
|
||||
r61581_cmd(0x002B);
|
||||
r61581_data(act_y1 >> 8);
|
||||
r61581_data(0x00FF & act_y1);
|
||||
r61581_data(act_y2 >> 8);
|
||||
r61581_data(0x00FF & act_y2);
|
||||
|
||||
r61581_cmd(0x2c);
|
||||
|
||||
r61581_data_mode();
|
||||
|
||||
uint16_t color16 = lv_color_to16(color);
|
||||
uint32_t size = (act_x2 - act_x1 + 1) * (act_y2 - act_y1 + 1);
|
||||
uint32_t i;
|
||||
for(i = 0; i < size; i++) {
|
||||
LV_DRV_DISP_PAR_WR_WORD(color16);
|
||||
}
|
||||
}
|
||||
|
||||
void r61581_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
{
|
||||
/*Return if the area is out the screen*/
|
||||
if(x2 < 0) return;
|
||||
if(y2 < 0) return;
|
||||
if(x1 > R61581_HOR_RES - 1) return;
|
||||
if(y1 > R61581_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = x1 < 0 ? 0 : x1;
|
||||
int32_t act_y1 = y1 < 0 ? 0 : y1;
|
||||
int32_t act_x2 = x2 > R61581_HOR_RES - 1 ? R61581_HOR_RES - 1 : x2;
|
||||
int32_t act_y2 = y2 > R61581_VER_RES - 1 ? R61581_VER_RES - 1 : y2;
|
||||
|
||||
|
||||
//Set the rectangular area
|
||||
r61581_cmd(0x002A);
|
||||
r61581_data(act_x1 >> 8);
|
||||
r61581_data(0x00FF & act_x1);
|
||||
r61581_data(act_x2 >> 8);
|
||||
r61581_data(0x00FF & act_x2);
|
||||
|
||||
r61581_cmd(0x002B);
|
||||
r61581_data(act_y1 >> 8);
|
||||
r61581_data(0x00FF & act_y1);
|
||||
r61581_data(act_y2 >> 8);
|
||||
r61581_data(0x00FF & act_y2);
|
||||
|
||||
r61581_cmd(0x2c);
|
||||
|
||||
int16_t i;
|
||||
uint16_t full_w = x2 - x1 + 1;
|
||||
|
||||
r61581_data_mode();
|
||||
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
uint16_t act_w = act_x2 - act_x1 + 1;
|
||||
for(i = act_y1; i <= act_y2; i++) {
|
||||
LV_DRV_DISP_PAR_WR_ARRAY((uint16_t *)color_p, act_w);
|
||||
color_p += full_w;
|
||||
}
|
||||
#else
|
||||
int16_t j;
|
||||
for(i = act_y1; i <= act_y2; i++) {
|
||||
for(j = 0; j <= act_x2 - act_x1 + 1; j++) {
|
||||
LV_DRV_DISP_PAR_WR_WORD(lv_color_to16(color_p[j]));
|
||||
color_p += full_w;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Io init
|
||||
*/
|
||||
static void r61581_io_init(void)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(R61581_CMD_MODE)
|
||||
cmd_mode = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset
|
||||
*/
|
||||
static void r61581_reset(void)
|
||||
{
|
||||
/*Hardware reset*/
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
LV_DRV_DISP_RST(0);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
|
||||
/*Chip enable*/
|
||||
LV_DRV_DISP_PAR_CS(1);
|
||||
LV_DRV_DELAY_MS(10);
|
||||
LV_DRV_DISP_PAR_CS(0);
|
||||
LV_DRV_DELAY_MS(5);
|
||||
|
||||
/*Software reset*/
|
||||
r61581_cmd(0x01);
|
||||
LV_DRV_DELAY_MS(20);
|
||||
|
||||
r61581_cmd(0x01);
|
||||
LV_DRV_DELAY_MS(20);
|
||||
|
||||
r61581_cmd(0x01);
|
||||
LV_DRV_DELAY_MS(20);
|
||||
}
|
||||
|
||||
/**
|
||||
* TFT specific initialization
|
||||
*/
|
||||
static void r61581_set_tft_spec(void)
|
||||
{
|
||||
r61581_cmd(0xB0);
|
||||
r61581_data(0x00);
|
||||
|
||||
r61581_cmd(0xB3);
|
||||
r61581_data(0x02);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x10);
|
||||
|
||||
r61581_cmd(0xB4);
|
||||
r61581_data(0x00);//0X10
|
||||
|
||||
r61581_cmd(0xB9); //PWM
|
||||
r61581_data(0x01);
|
||||
r61581_data(0xFF); //FF brightness
|
||||
r61581_data(0xFF);
|
||||
r61581_data(0x18);
|
||||
|
||||
/*Panel Driving Setting*/
|
||||
r61581_cmd(0xC0);
|
||||
r61581_data(0x02);
|
||||
r61581_data(0x3B);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x01);
|
||||
r61581_data(0x00);//NW
|
||||
r61581_data(0x43);
|
||||
|
||||
/*Display Timing Setting for Normal Mode */
|
||||
r61581_cmd(0xC1);
|
||||
r61581_data(0x08);
|
||||
r61581_data(0x15); //CLOCK
|
||||
r61581_data(R61581_VFP);
|
||||
r61581_data(R61581_VBP);
|
||||
|
||||
/*Source/VCOM/Gate Driving Timing Setting*/
|
||||
r61581_cmd(0xC4);
|
||||
r61581_data(0x15);
|
||||
r61581_data(0x03);
|
||||
r61581_data(0x03);
|
||||
r61581_data(0x01);
|
||||
|
||||
/*Interface Setting*/
|
||||
r61581_cmd(0xC6);
|
||||
r61581_data((R61581_DPL << 0) |
|
||||
(R61581_EPL << 1) |
|
||||
(R61581_HSPL << 4) |
|
||||
(R61581_VSPL << 5));
|
||||
|
||||
/*Gamma Set*/
|
||||
r61581_cmd(0xC8);
|
||||
r61581_data(0x0c);
|
||||
r61581_data(0x05);
|
||||
r61581_data(0x0A);
|
||||
r61581_data(0x6B);
|
||||
r61581_data(0x04);
|
||||
r61581_data(0x06);
|
||||
r61581_data(0x15);
|
||||
r61581_data(0x10);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x31);
|
||||
|
||||
|
||||
r61581_cmd(0x36);
|
||||
if(R61581_ORI == 0) r61581_data(0xE0);
|
||||
else r61581_data(0x20);
|
||||
|
||||
r61581_cmd(0x0C);
|
||||
r61581_data(0x55);
|
||||
|
||||
r61581_cmd(0x3A);
|
||||
r61581_data(0x55);
|
||||
|
||||
r61581_cmd(0x38);
|
||||
|
||||
r61581_cmd(0xD0);
|
||||
r61581_data(0x07);
|
||||
r61581_data(0x07);
|
||||
r61581_data(0x14);
|
||||
r61581_data(0xA2);
|
||||
|
||||
r61581_cmd(0xD1);
|
||||
r61581_data(0x03);
|
||||
r61581_data(0x5A);
|
||||
r61581_data(0x10);
|
||||
|
||||
r61581_cmd(0xD2);
|
||||
r61581_data(0x03);
|
||||
r61581_data(0x04);
|
||||
r61581_data(0x04);
|
||||
|
||||
r61581_cmd(0x11);
|
||||
LV_DRV_DELAY_MS(10);
|
||||
|
||||
r61581_cmd(0x2A);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x00);
|
||||
r61581_data(((R61581_HOR_RES - 1) >> 8) & 0XFF);
|
||||
r61581_data((R61581_HOR_RES - 1) & 0XFF);
|
||||
|
||||
r61581_cmd(0x2B);
|
||||
r61581_data(0x00);
|
||||
r61581_data(0x00);
|
||||
r61581_data(((R61581_VER_RES - 1) >> 8) & 0XFF);
|
||||
r61581_data((R61581_VER_RES - 1) & 0XFF);
|
||||
|
||||
LV_DRV_DELAY_MS(10);
|
||||
|
||||
r61581_cmd(0x29);
|
||||
LV_DRV_DELAY_MS(5);
|
||||
|
||||
r61581_cmd(0x2C);
|
||||
LV_DRV_DELAY_MS(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Command mode
|
||||
*/
|
||||
static inline void r61581_cmd_mode(void)
|
||||
{
|
||||
if(cmd_mode == false) {
|
||||
LV_DRV_DISP_CMD_DATA(R61581_CMD_MODE)
|
||||
cmd_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data mode
|
||||
*/
|
||||
static inline void r61581_data_mode(void)
|
||||
{
|
||||
if(cmd_mode != false) {
|
||||
LV_DRV_DISP_CMD_DATA(R61581_DATA_MODE);
|
||||
cmd_mode = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write command
|
||||
* @param cmd the command
|
||||
*/
|
||||
static inline void r61581_cmd(uint8_t cmd)
|
||||
{
|
||||
r61581_cmd_mode();
|
||||
LV_DRV_DISP_PAR_WR_WORD(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data
|
||||
* @param data the data
|
||||
*/
|
||||
static inline void r61581_data(uint8_t data)
|
||||
{
|
||||
r61581_data_mode();
|
||||
LV_DRV_DISP_PAR_WR_WORD(data);
|
||||
}
|
||||
#endif
|
||||
57
libs/lv_drivers/display/R61581.h
Normal file
57
libs/lv_drivers/display/R61581.h
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file R61581.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef R61581_H
|
||||
#define R61581_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_R61581
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void r61581_init(void);
|
||||
void r61581_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
|
||||
void r61581_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
|
||||
void r61581_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_R61581 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* R61581_H */
|
||||
182
libs/lv_drivers/display/SHARP_MIP.c
Normal file
182
libs/lv_drivers/display/SHARP_MIP.c
Normal file
@ -0,0 +1,182 @@
|
||||
/**
|
||||
* @file SHARP_MIP.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------
|
||||
* SHARP memory in pixel monochrome display series
|
||||
* LS012B7DD01 (184x38 pixels.)
|
||||
* LS013B7DH03 (128x128 pixels.)
|
||||
* LS013B7DH05 (144x168 pixels.)
|
||||
* LS027B7DH01 (400x240 pixels.) (tested)
|
||||
* LS032B7DD02 (336x536 pixels.)
|
||||
* LS044Q7DH01 (320x240 pixels.)
|
||||
*
|
||||
* These displays need periodic com inversion, there are two ways :
|
||||
* - software com inversion :
|
||||
* define SHARP_MIP_SOFT_COM_INVERSION 1 and set EXTMODE display pin LOW,
|
||||
* call sharp_mip_com_inversion() periodically
|
||||
* - hardware com inversion with EXTCOMIN display pin :
|
||||
* define SHARP_MIP_SOFT_COM_INVERSION 0,
|
||||
* set EXTMODE display pin HIGH and handle
|
||||
* EXTCOMIN waveform (for example with mcu pwm output),
|
||||
* see datasheet pages 8-12 for details
|
||||
*
|
||||
* draw_buf size : (LV_VER_RES / X) * (2 + LV_HOR_RES / 8) + 2 bytes, structure :
|
||||
* [FRAME_HEADER (1 byte)] [GATE_ADDR (1 byte )] [LINE_DATA (LV_HOR_RES / 8 bytes)] 1st line
|
||||
* [DUMMY (1 byte)] [GATE_ADDR (1 byte )] [LINE_DATA (LV_HOR_RES / 8 bytes)] 2nd line
|
||||
* ...........................................................................................
|
||||
* [DUMMY (1 byte)] [GATE_ADDR (1 byte )] [LINE_DATA (LV_HOR_RES / 8 bytes)] last line
|
||||
* [DUMMY (2 bytes)]
|
||||
*
|
||||
* Since extra bytes (dummy, addresses, header) are stored in draw_buf, we need to use
|
||||
* an "oversized" draw_buf. Buffer declaration in "lv_port_disp.c" becomes for example :
|
||||
* static lv_disp_buf_t disp_buf;
|
||||
* static uint8_t buf[(LV_VER_RES_MAX / X) * (2 + (LV_HOR_RES_MAX / 8)) + 2];
|
||||
* lv_disp_buf_init(&disp_buf, buf, NULL, LV_VER_RES_MAX * LV_HOR_RES_MAX / X);
|
||||
*-----------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "SHARP_MIP.h"
|
||||
|
||||
#if USE_SHARP_MIP
|
||||
|
||||
#include <stdbool.h>
|
||||
#include LV_DRV_DISP_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define SHARP_MIP_HEADER 0
|
||||
#define SHARP_MIP_UPDATE_RAM_FLAG (1 << 7) /* (M0) Mode flag : H -> update memory, L -> maintain memory */
|
||||
#define SHARP_MIP_COM_INVERSION_FLAG (1 << 6) /* (M1) Frame inversion flag : relevant when EXTMODE = L, */
|
||||
/* H -> outputs VCOM = H, L -> outputs VCOM = L */
|
||||
#define SHARP_MIP_CLEAR_SCREEN_FLAG (1 << 5) /* (M2) All clear flag : H -> clear all pixels */
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if SHARP_MIP_SOFT_COM_INVERSION
|
||||
static bool_t com_output_state = false;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/*
|
||||
* Return the draw_buf byte index corresponding to the pixel
|
||||
* relatives coordinates (x, y) in the area.
|
||||
* The area is rounded to a whole screen line.
|
||||
*/
|
||||
#define BUFIDX(x, y) (((x) >> 3) + ((y) * (2 + (SHARP_MIP_HOR_RES >> 3))) + 2)
|
||||
|
||||
/*
|
||||
* Return the byte bitmask of a pixel bit corresponding
|
||||
* to draw_buf arrangement (8 pixels per byte on lines).
|
||||
*/
|
||||
#define PIXIDX(x) SHARP_MIP_REV_BYTE(1 << ((x) & 7))
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void sharp_mip_init(void) {
|
||||
/* These displays have nothing to initialize */
|
||||
}
|
||||
|
||||
|
||||
void sharp_mip_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
|
||||
|
||||
/*Return if the area is out the screen*/
|
||||
if(area->y2 < 0) return;
|
||||
if(area->y1 > SHARP_MIP_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
uint16_t act_y1 = area->y1 < 0 ? 0 : area->y1;
|
||||
uint16_t act_y2 = area->y2 > SHARP_MIP_VER_RES - 1 ? SHARP_MIP_VER_RES - 1 : area->y2;
|
||||
|
||||
uint8_t * buf = (uint8_t *) color_p; /*Get the buffer address*/
|
||||
uint16_t buf_h = (act_y2 - act_y1 + 1); /*Number of buffer lines*/
|
||||
uint16_t buf_size = buf_h * (2 + SHARP_MIP_HOR_RES / 8) + 2; /*Buffer size in bytes */
|
||||
|
||||
/* Set lines to flush dummy byte & gate address in draw_buf*/
|
||||
for(uint16_t act_y = 0 ; act_y < buf_h ; act_y++) {
|
||||
buf[BUFIDX(0, act_y) - 1] = SHARP_MIP_REV_BYTE((act_y1 + act_y + 1));
|
||||
buf[BUFIDX(0, act_y) - 2] = 0;
|
||||
}
|
||||
|
||||
/* Set last dummy two bytes in draw_buf */
|
||||
buf[BUFIDX(0, buf_h) - 1] = 0;
|
||||
buf[BUFIDX(0, buf_h) - 2] = 0;
|
||||
|
||||
/* Set frame header in draw_buf */
|
||||
buf[0] = SHARP_MIP_HEADER |
|
||||
SHARP_MIP_UPDATE_RAM_FLAG;
|
||||
|
||||
/* Write the frame on display memory */
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY(buf, buf_size);
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
void sharp_mip_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa) {
|
||||
(void) disp_drv;
|
||||
(void) buf_w;
|
||||
(void) opa;
|
||||
|
||||
if (lv_color_to1(color) != 0) {
|
||||
buf[BUFIDX(x, y)] |= PIXIDX(x); /*Set draw_buf pixel bit to 1 for other colors than BLACK*/
|
||||
} else {
|
||||
buf[BUFIDX(x, y)] &= ~PIXIDX(x); /*Set draw_buf pixel bit to 0 for BLACK color*/
|
||||
}
|
||||
}
|
||||
|
||||
void sharp_mip_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area) {
|
||||
(void) disp_drv;
|
||||
|
||||
/* Round area to a whole line */
|
||||
area->x1 = 0;
|
||||
area->x2 = SHARP_MIP_HOR_RES - 1;
|
||||
}
|
||||
|
||||
#if SHARP_MIP_SOFT_COM_INVERSION
|
||||
void sharp_mip_com_inversion(void) {
|
||||
uint8_t inversion_header[2] = {0};
|
||||
|
||||
/* Set inversion header */
|
||||
if (com_output_state) {
|
||||
com_output_state = false;
|
||||
} else {
|
||||
inversion_header[0] |= SHARP_MIP_COM_INVERSION_FLAG;
|
||||
com_output_state = true;
|
||||
}
|
||||
|
||||
/* Write inversion header on display memory */
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY(inversion_header, 2);
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif
|
||||
63
libs/lv_drivers/display/SHARP_MIP.h
Normal file
63
libs/lv_drivers/display/SHARP_MIP.h
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file SHARP_MIP.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARP_MIP_H
|
||||
#define SHARP_MIP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_SHARP_MIP
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void sharp_mip_init(void);
|
||||
void sharp_mip_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void sharp_mip_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area);
|
||||
void sharp_mip_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
#if SHARP_MIP_SOFT_COM_INVERSION
|
||||
void sharp_mip_com_inversion(void);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_SHARP_MIP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SHARP_MIP_H */
|
||||
292
libs/lv_drivers/display/SSD1963.c
Normal file
292
libs/lv_drivers/display/SSD1963.c
Normal file
@ -0,0 +1,292 @@
|
||||
/**
|
||||
* @file SSD1963.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "SSD1963.h"
|
||||
#if USE_SSD1963
|
||||
|
||||
#include <stdbool.h>
|
||||
#include LV_DRV_DISP_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define SSD1963_CMD_MODE 0
|
||||
#define SSD1963_DATA_MODE 1
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static inline void ssd1963_cmd_mode(void);
|
||||
static inline void ssd1963_data_mode(void);
|
||||
static inline void ssd1963_cmd(uint8_t cmd);
|
||||
static inline void ssd1963_data(uint8_t data);
|
||||
static void ssd1963_io_init(void);
|
||||
static void ssd1963_reset(void);
|
||||
static void ssd1963_set_clk(void);
|
||||
static void ssd1963_set_tft_spec(void);
|
||||
static void ssd1963_init_bl(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static bool cmd_mode = true;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void ssd1963_init(void)
|
||||
{
|
||||
|
||||
LV_DRV_DISP_CMD_DATA(SSD1963_CMD_MODE);
|
||||
cmd_mode = true;
|
||||
|
||||
LV_DRV_DELAY_MS(250);
|
||||
|
||||
|
||||
ssd1963_cmd(0x00E2); //PLL multiplier, set PLL clock to 120M
|
||||
ssd1963_data(0x0023); //N=0x36 for 6.5M, 0x23 for 10M crystal
|
||||
ssd1963_data(0x0002);
|
||||
ssd1963_data(0x0004);
|
||||
ssd1963_cmd(0x00E0); // PLL enable
|
||||
ssd1963_data(0x0001);
|
||||
LV_DRV_DELAY_MS(1);
|
||||
ssd1963_cmd(0x00E0);
|
||||
ssd1963_data(0x0003); // now, use PLL output as system clock
|
||||
LV_DRV_DELAY_MS(1);
|
||||
ssd1963_cmd(0x0001); // software reset
|
||||
LV_DRV_DELAY_MS(1);
|
||||
ssd1963_cmd(0x00E6); //PLL setting for PCLK, depends on resolution
|
||||
|
||||
ssd1963_data(0x0001); //HX8257C
|
||||
ssd1963_data(0x0033); //HX8257C
|
||||
ssd1963_data(0x0033); //HX8257C
|
||||
|
||||
|
||||
ssd1963_cmd(0x00B0); //LCD SPECIFICATION
|
||||
ssd1963_data(0x0020);
|
||||
ssd1963_data(0x0000);
|
||||
ssd1963_data(((SSD1963_HOR_RES - 1) >> 8) & 0X00FF); //Set HDP
|
||||
ssd1963_data((SSD1963_HOR_RES - 1) & 0X00FF);
|
||||
ssd1963_data(((SSD1963_VER_RES - 1) >> 8) & 0X00FF); //Set VDP
|
||||
ssd1963_data((SSD1963_VER_RES - 1) & 0X00FF);
|
||||
ssd1963_data(0x0000);
|
||||
LV_DRV_DELAY_MS(1);//Delay10us(5);
|
||||
ssd1963_cmd(0x00B4); //HSYNC
|
||||
ssd1963_data((SSD1963_HT >> 8) & 0X00FF); //Set HT
|
||||
ssd1963_data(SSD1963_HT & 0X00FF);
|
||||
ssd1963_data((SSD1963_HPS >> 8) & 0X00FF); //Set HPS
|
||||
ssd1963_data(SSD1963_HPS & 0X00FF);
|
||||
ssd1963_data(SSD1963_HPW); //Set HPW
|
||||
ssd1963_data((SSD1963_LPS >> 8) & 0X00FF); //SetLPS
|
||||
ssd1963_data(SSD1963_LPS & 0X00FF);
|
||||
ssd1963_data(0x0000);
|
||||
|
||||
ssd1963_cmd(0x00B6); //VSYNC
|
||||
ssd1963_data((SSD1963_VT >> 8) & 0X00FF); //Set VT
|
||||
ssd1963_data(SSD1963_VT & 0X00FF);
|
||||
ssd1963_data((SSD1963_VPS >> 8) & 0X00FF); //Set VPS
|
||||
ssd1963_data(SSD1963_VPS & 0X00FF);
|
||||
ssd1963_data(SSD1963_VPW); //Set VPW
|
||||
ssd1963_data((SSD1963_FPS >> 8) & 0X00FF); //Set FPS
|
||||
ssd1963_data(SSD1963_FPS & 0X00FF);
|
||||
|
||||
ssd1963_cmd(0x00B8);
|
||||
ssd1963_data(0x000f); //GPIO is controlled by host GPIO[3:0]=output GPIO[0]=1 LCD ON GPIO[0]=1 LCD OFF
|
||||
ssd1963_data(0x0001); //GPIO0 normal
|
||||
|
||||
ssd1963_cmd(0x00BA);
|
||||
ssd1963_data(0x0001); //GPIO[0] out 1 --- LCD display on/off control PIN
|
||||
|
||||
ssd1963_cmd(0x0036); //rotation
|
||||
ssd1963_data(0x0008); //RGB=BGR
|
||||
|
||||
ssd1963_cmd(0x003A); //Set the current pixel format for RGB image data
|
||||
ssd1963_data(0x0050); //16-bit/pixel
|
||||
|
||||
ssd1963_cmd(0x00F0); //Pixel Data Interface Format
|
||||
ssd1963_data(0x0003); //16-bit(565 format) data
|
||||
|
||||
ssd1963_cmd(0x00BC);
|
||||
ssd1963_data(0x0040); //contrast value
|
||||
ssd1963_data(0x0080); //brightness value
|
||||
ssd1963_data(0x0040); //saturation value
|
||||
ssd1963_data(0x0001); //Post Processor Enable
|
||||
|
||||
LV_DRV_DELAY_MS(1);
|
||||
|
||||
ssd1963_cmd(0x0029); //display on
|
||||
|
||||
ssd1963_cmd(0x00BE); //set PWM for B/L
|
||||
ssd1963_data(0x0006);
|
||||
ssd1963_data(0x0080);
|
||||
ssd1963_data(0x0001);
|
||||
ssd1963_data(0x00f0);
|
||||
ssd1963_data(0x0000);
|
||||
ssd1963_data(0x0000);
|
||||
|
||||
ssd1963_cmd(0x00d0);
|
||||
ssd1963_data(0x000d);
|
||||
|
||||
//DisplayBacklightOn();
|
||||
|
||||
LV_DRV_DELAY_MS(30);
|
||||
}
|
||||
|
||||
void ssd1963_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
|
||||
/*Return if the area is out the screen*/
|
||||
if(area->x2 < 0) return;
|
||||
if(area->y2 < 0) return;
|
||||
if(area->x1 > SSD1963_HOR_RES - 1) return;
|
||||
if(area->y1 > SSD1963_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
|
||||
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
|
||||
int32_t act_x2 = area->x2 > SSD1963_HOR_RES - 1 ? SSD1963_HOR_RES - 1 : area->x2;
|
||||
int32_t act_y2 = area->y2 > SSD1963_VER_RES - 1 ? SSD1963_VER_RES - 1 : area->y2;
|
||||
|
||||
//Set the rectangular area
|
||||
ssd1963_cmd(0x002A);
|
||||
ssd1963_data(act_x1 >> 8);
|
||||
ssd1963_data(0x00FF & act_x1);
|
||||
ssd1963_data(act_x2 >> 8);
|
||||
ssd1963_data(0x00FF & act_x2);
|
||||
|
||||
ssd1963_cmd(0x002B);
|
||||
ssd1963_data(act_y1 >> 8);
|
||||
ssd1963_data(0x00FF & act_y1);
|
||||
ssd1963_data(act_y2 >> 8);
|
||||
ssd1963_data(0x00FF & act_y2);
|
||||
|
||||
ssd1963_cmd(0x2c);
|
||||
int16_t i;
|
||||
uint16_t full_w = area->x2 - area->x1 + 1;
|
||||
|
||||
ssd1963_data_mode();
|
||||
LV_DRV_DISP_PAR_CS(0);
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
uint16_t act_w = act_x2 - act_x1 + 1;
|
||||
for(i = act_y1; i <= act_y2; i++) {
|
||||
LV_DRV_DISP_PAR_WR_ARRAY((uint16_t *)color_p, act_w);
|
||||
color_p += full_w;
|
||||
}
|
||||
LV_DRV_DISP_PAR_CS(1);
|
||||
#else
|
||||
int16_t j;
|
||||
for(i = act_y1; i <= act_y2; i++) {
|
||||
for(j = 0; j <= act_x2 - act_x1 + 1; j++) {
|
||||
LV_DRV_DISP_PAR_WR_WORD(color_p[j]);
|
||||
color_p += full_w;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void ssd1963_io_init(void)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(SSD1963_CMD_MODE);
|
||||
cmd_mode = true;
|
||||
}
|
||||
|
||||
static void ssd1963_reset(void)
|
||||
{
|
||||
/*Hardware reset*/
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
LV_DRV_DISP_RST(0);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
|
||||
/*Chip enable*/
|
||||
LV_DRV_DISP_PAR_CS(0);
|
||||
LV_DRV_DELAY_MS(10);
|
||||
LV_DRV_DISP_PAR_CS(1);
|
||||
LV_DRV_DELAY_MS(5);
|
||||
|
||||
/*Software reset*/
|
||||
ssd1963_cmd(0x01);
|
||||
LV_DRV_DELAY_MS(20);
|
||||
|
||||
ssd1963_cmd(0x01);
|
||||
LV_DRV_DELAY_MS(20);
|
||||
|
||||
ssd1963_cmd(0x01);
|
||||
LV_DRV_DELAY_MS(20);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Command mode
|
||||
*/
|
||||
static inline void ssd1963_cmd_mode(void)
|
||||
{
|
||||
if(cmd_mode == false) {
|
||||
LV_DRV_DISP_CMD_DATA(SSD1963_CMD_MODE);
|
||||
cmd_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data mode
|
||||
*/
|
||||
static inline void ssd1963_data_mode(void)
|
||||
{
|
||||
if(cmd_mode != false) {
|
||||
LV_DRV_DISP_CMD_DATA(SSD1963_DATA_MODE);
|
||||
cmd_mode = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write command
|
||||
* @param cmd the command
|
||||
*/
|
||||
static inline void ssd1963_cmd(uint8_t cmd)
|
||||
{
|
||||
|
||||
LV_DRV_DISP_PAR_CS(0);
|
||||
ssd1963_cmd_mode();
|
||||
LV_DRV_DISP_PAR_WR_WORD(cmd);
|
||||
LV_DRV_DISP_PAR_CS(1);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data
|
||||
* @param data the data
|
||||
*/
|
||||
static inline void ssd1963_data(uint8_t data)
|
||||
{
|
||||
|
||||
LV_DRV_DISP_PAR_CS(0);
|
||||
ssd1963_data_mode();
|
||||
LV_DRV_DISP_PAR_WR_WORD(data);
|
||||
LV_DRV_DISP_PAR_CS(1);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
150
libs/lv_drivers/display/SSD1963.h
Normal file
150
libs/lv_drivers/display/SSD1963.h
Normal file
@ -0,0 +1,150 @@
|
||||
/**
|
||||
* @file SSD1963.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SSD1963_H
|
||||
#define SSD1963_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_SSD1963
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
// SSD1963 command table
|
||||
#define CMD_NOP 0x00 //No operation
|
||||
#define CMD_SOFT_RESET 0x01 //Software reset
|
||||
#define CMD_GET_PWR_MODE 0x0A //Get the current power mode
|
||||
#define CMD_GET_ADDR_MODE 0x0B //Get the frame memory to the display panel read order
|
||||
#define CMD_GET_PIXEL_FORMAT 0x0C //Get the current pixel format
|
||||
#define CMD_GET_DISPLAY_MODE 0x0D //Returns the display mode
|
||||
#define CMD_GET_SIGNAL_MODE 0x0E //
|
||||
#define CMD_GET_DIAGNOSTIC 0x0F
|
||||
#define CMD_ENT_SLEEP 0x10
|
||||
#define CMD_EXIT_SLEEP 0x11
|
||||
#define CMD_ENT_PARTIAL_MODE 0x12
|
||||
#define CMD_ENT_NORMAL_MODE 0x13
|
||||
#define CMD_EXIT_INVERT_MODE 0x20
|
||||
#define CMD_ENT_INVERT_MODE 0x21
|
||||
#define CMD_SET_GAMMA 0x26
|
||||
#define CMD_BLANK_DISPLAY 0x28
|
||||
#define CMD_ON_DISPLAY 0x29
|
||||
#define CMD_SET_COLUMN 0x2A
|
||||
#define CMD_SET_PAGE 0x2B
|
||||
#define CMD_WR_MEMSTART 0x2C
|
||||
#define CMD_RD_MEMSTART 0x2E
|
||||
#define CMD_SET_PARTIAL_AREA 0x30
|
||||
#define CMD_SET_SCROLL_AREA 0x33
|
||||
#define CMD_SET_TEAR_OFF 0x34 //synchronization information is not sent from the display
|
||||
#define CMD_SET_TEAR_ON 0x35 //sync. information is sent from the display
|
||||
#define CMD_SET_ADDR_MODE 0x36 //set fram buffer read order to the display panel
|
||||
#define CMD_SET_SCROLL_START 0x37
|
||||
#define CMD_EXIT_IDLE_MODE 0x38
|
||||
#define CMD_ENT_IDLE_MODE 0x39
|
||||
#define CMD_SET_PIXEL_FORMAT 0x3A //defines how many bits per pixel is used
|
||||
#define CMD_WR_MEM_AUTO 0x3C
|
||||
#define CMD_RD_MEM_AUTO 0x3E
|
||||
#define CMD_SET_TEAR_SCANLINE 0x44
|
||||
#define CMD_GET_SCANLINE 0x45
|
||||
#define CMD_RD_DDB_START 0xA1
|
||||
#define CMD_RD_DDB_AUTO 0xA8
|
||||
#define CMD_SET_PANEL_MODE 0xB0
|
||||
#define CMD_GET_PANEL_MODE 0xB1
|
||||
#define CMD_SET_HOR_PERIOD 0xB4
|
||||
#define CMD_GET_HOR_PERIOD 0xB5
|
||||
#define CMD_SET_VER_PERIOD 0xB6
|
||||
#define CMD_GET_VER_PERIOD 0xB7
|
||||
#define CMD_SET_GPIO_CONF 0xB8
|
||||
#define CMD_GET_GPIO_CONF 0xB9
|
||||
#define CMD_SET_GPIO_VAL 0xBA
|
||||
#define CMD_GET_GPIO_STATUS 0xBB
|
||||
#define CMD_SET_POST_PROC 0xBC
|
||||
#define CMD_GET_POST_PROC 0xBD
|
||||
#define CMD_SET_PWM_CONF 0xBE
|
||||
#define CMD_GET_PWM_CONF 0xBF
|
||||
#define CMD_SET_LCD_GEN0 0xC0
|
||||
#define CMD_GET_LCD_GEN0 0xC1
|
||||
#define CMD_SET_LCD_GEN1 0xC2
|
||||
#define CMD_GET_LCD_GEN1 0xC3
|
||||
#define CMD_SET_LCD_GEN2 0xC4
|
||||
#define CMD_GET_LCD_GEN2 0xC5
|
||||
#define CMD_SET_LCD_GEN3 0xC6
|
||||
#define CMD_GET_LCD_GEN3 0xC7
|
||||
#define CMD_SET_GPIO0_ROP 0xC8
|
||||
#define CMD_GET_GPIO0_ROP 0xC9
|
||||
#define CMD_SET_GPIO1_ROP 0xCA
|
||||
#define CMD_GET_GPIO1_ROP 0xCB
|
||||
#define CMD_SET_GPIO2_ROP 0xCC
|
||||
#define CMD_GET_GPIO2_ROP 0xCD
|
||||
#define CMD_SET_GPIO3_ROP 0xCE
|
||||
#define CMD_GET_GPIO3_ROP 0xCF
|
||||
#define CMD_SET_ABC_DBC_CONF 0xD0
|
||||
#define CMD_GET_ABC_DBC_CONF 0xD1
|
||||
#define CMD_SET_DBC_HISTO_PTR 0xD2
|
||||
#define CMD_GET_DBC_HISTO_PTR 0xD3
|
||||
#define CMD_SET_DBC_THRES 0xD4
|
||||
#define CMD_GET_DBC_THRES 0xD5
|
||||
#define CMD_SET_ABM_TMR 0xD6
|
||||
#define CMD_GET_ABM_TMR 0xD7
|
||||
#define CMD_SET_AMB_LVL0 0xD8
|
||||
#define CMD_GET_AMB_LVL0 0xD9
|
||||
#define CMD_SET_AMB_LVL1 0xDA
|
||||
#define CMD_GET_AMB_LVL1 0xDB
|
||||
#define CMD_SET_AMB_LVL2 0xDC
|
||||
#define CMD_GET_AMB_LVL2 0xDD
|
||||
#define CMD_SET_AMB_LVL3 0xDE
|
||||
#define CMD_GET_AMB_LVL3 0xDF
|
||||
#define CMD_PLL_START 0xE0 //start the PLL
|
||||
#define CMD_PLL_STOP 0xE1 //disable the PLL
|
||||
#define CMD_SET_PLL_MN 0xE2
|
||||
#define CMD_GET_PLL_MN 0xE3
|
||||
#define CMD_GET_PLL_STATUS 0xE4 //get the current PLL status
|
||||
#define CMD_ENT_DEEP_SLEEP 0xE5
|
||||
#define CMD_SET_PCLK 0xE6 //set pixel clock (LSHIFT signal) frequency
|
||||
#define CMD_GET_PCLK 0xE7 //get pixel clock (LSHIFT signal) freq. settings
|
||||
#define CMD_SET_DATA_INTERFACE 0xF0
|
||||
#define CMD_GET_DATA_INTERFACE 0xF1
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void ssd1963_init(void);
|
||||
void ssd1963_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_SSD1963 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SSD1963_H */
|
||||
289
libs/lv_drivers/display/ST7565.c
Normal file
289
libs/lv_drivers/display/ST7565.c
Normal file
@ -0,0 +1,289 @@
|
||||
/**
|
||||
* @file ST7565.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "ST7565.h"
|
||||
#if USE_ST7565
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "lvgl/lv_core/lv_vdb.h"
|
||||
#include LV_DRV_DISP_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ST7565_BAUD 2000000 /*< 2,5 MHz (400 ns)*/
|
||||
|
||||
#define ST7565_CMD_MODE 0
|
||||
#define ST7565_DATA_MODE 1
|
||||
|
||||
#define ST7565_HOR_RES 128
|
||||
#define ST7565_VER_RES 64
|
||||
|
||||
#define CMD_DISPLAY_OFF 0xAE
|
||||
#define CMD_DISPLAY_ON 0xAF
|
||||
|
||||
#define CMD_SET_DISP_START_LINE 0x40
|
||||
#define CMD_SET_PAGE 0xB0
|
||||
|
||||
#define CMD_SET_COLUMN_UPPER 0x10
|
||||
#define CMD_SET_COLUMN_LOWER 0x00
|
||||
|
||||
#define CMD_SET_ADC_NORMAL 0xA0
|
||||
#define CMD_SET_ADC_REVERSE 0xA1
|
||||
|
||||
#define CMD_SET_DISP_NORMAL 0xA6
|
||||
#define CMD_SET_DISP_REVERSE 0xA7
|
||||
|
||||
#define CMD_SET_ALLPTS_NORMAL 0xA4
|
||||
#define CMD_SET_ALLPTS_ON 0xA5
|
||||
#define CMD_SET_BIAS_9 0xA2
|
||||
#define CMD_SET_BIAS_7 0xA3
|
||||
|
||||
#define CMD_RMW 0xE0
|
||||
#define CMD_RMW_CLEAR 0xEE
|
||||
#define CMD_INTERNAL_RESET 0xE2
|
||||
#define CMD_SET_COM_NORMAL 0xC0
|
||||
#define CMD_SET_COM_REVERSE 0xC8
|
||||
#define CMD_SET_POWER_CONTROL 0x28
|
||||
#define CMD_SET_RESISTOR_RATIO 0x20
|
||||
#define CMD_SET_VOLUME_FIRST 0x81
|
||||
#define CMD_SET_VOLUME_SECOND 0x00
|
||||
#define CMD_SET_STATIC_OFF 0xAC
|
||||
#define CMD_SET_STATIC_ON 0xAD
|
||||
#define CMD_SET_STATIC_REG 0x00
|
||||
#define CMD_SET_BOOSTER_FIRST 0xF8
|
||||
#define CMD_SET_BOOSTER_234 0x00
|
||||
#define CMD_SET_BOOSTER_5 0x01
|
||||
#define CMD_SET_BOOSTER_6 0x03
|
||||
#define CMD_NOP 0xE3
|
||||
#define CMD_TEST 0xF0
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void st7565_sync(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
|
||||
static void st7565_command(uint8_t cmd);
|
||||
static void st7565_data(uint8_t data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint8_t lcd_fb[ST7565_HOR_RES * ST7565_VER_RES / 8] = {0xAA, 0xAA};
|
||||
static uint8_t pagemap[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the ST7565
|
||||
*/
|
||||
void st7565_init(void)
|
||||
{
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(10);
|
||||
LV_DRV_DISP_RST(0);
|
||||
LV_DRV_DELAY_MS(10);
|
||||
LV_DRV_DISP_RST(1);
|
||||
LV_DRV_DELAY_MS(10);
|
||||
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
|
||||
st7565_command(CMD_SET_BIAS_7);
|
||||
st7565_command(CMD_SET_ADC_NORMAL);
|
||||
st7565_command(CMD_SET_COM_NORMAL);
|
||||
st7565_command(CMD_SET_DISP_START_LINE);
|
||||
st7565_command(CMD_SET_POWER_CONTROL | 0x4);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
|
||||
st7565_command(CMD_SET_POWER_CONTROL | 0x6);
|
||||
LV_DRV_DELAY_MS(50);
|
||||
|
||||
st7565_command(CMD_SET_POWER_CONTROL | 0x7);
|
||||
LV_DRV_DELAY_MS(10);
|
||||
|
||||
st7565_command(CMD_SET_RESISTOR_RATIO | 0x6); // Defaulted to 0x26 (but could also be between 0x20-0x27 based on display's specs)
|
||||
|
||||
st7565_command(CMD_DISPLAY_ON);
|
||||
st7565_command(CMD_SET_ALLPTS_NORMAL);
|
||||
|
||||
/*Set brightness*/
|
||||
st7565_command(CMD_SET_VOLUME_FIRST);
|
||||
st7565_command(CMD_SET_VOLUME_SECOND | (0x18 & 0x3f));
|
||||
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
|
||||
memset(lcd_fb, 0x00, sizeof(lcd_fb));
|
||||
}
|
||||
|
||||
|
||||
void st7565_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
{
|
||||
/*Return if the area is out the screen*/
|
||||
if(x2 < 0) return;
|
||||
if(y2 < 0) return;
|
||||
if(x1 > ST7565_HOR_RES - 1) return;
|
||||
if(y1 > ST7565_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = x1 < 0 ? 0 : x1;
|
||||
int32_t act_y1 = y1 < 0 ? 0 : y1;
|
||||
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
|
||||
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
|
||||
|
||||
int32_t x, y;
|
||||
|
||||
/*Set the first row in */
|
||||
|
||||
/*Refresh frame buffer*/
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
for(x = act_x1; x <= act_x2; x++) {
|
||||
if(lv_color_to1(*color_p) != 0) {
|
||||
lcd_fb[x + (y / 8)*ST7565_HOR_RES] &= ~(1 << (7 - (y % 8)));
|
||||
} else {
|
||||
lcd_fb[x + (y / 8)*ST7565_HOR_RES] |= (1 << (7 - (y % 8)));
|
||||
}
|
||||
color_p ++;
|
||||
}
|
||||
|
||||
color_p += x2 - act_x2; /*Next row*/
|
||||
}
|
||||
|
||||
st7565_sync(act_x1, act_y1, act_x2, act_y2);
|
||||
lv_flush_ready();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void st7565_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
|
||||
{
|
||||
/*Return if the area is out the screen*/
|
||||
if(x2 < 0) return;
|
||||
if(y2 < 0) return;
|
||||
if(x1 > ST7565_HOR_RES - 1) return;
|
||||
if(y1 > ST7565_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = x1 < 0 ? 0 : x1;
|
||||
int32_t act_y1 = y1 < 0 ? 0 : y1;
|
||||
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
|
||||
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
|
||||
|
||||
int32_t x, y;
|
||||
uint8_t white = lv_color_to1(color);
|
||||
|
||||
/*Refresh frame buffer*/
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
for(x = act_x1; x <= act_x2; x++) {
|
||||
if(white != 0) {
|
||||
lcd_fb[x + (y / 8)*ST7565_HOR_RES] |= (1 << (7 - (y % 8)));
|
||||
} else {
|
||||
lcd_fb[x + (y / 8)*ST7565_HOR_RES] &= ~(1 << (7 - (y % 8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
st7565_sync(act_x1, act_y1, act_x2, act_y2);
|
||||
}
|
||||
|
||||
void st7565_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
{
|
||||
/*Return if the area is out the screen*/
|
||||
if(x2 < 0) return;
|
||||
if(y2 < 0) return;
|
||||
if(x1 > ST7565_HOR_RES - 1) return;
|
||||
if(y1 > ST7565_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = x1 < 0 ? 0 : x1;
|
||||
int32_t act_y1 = y1 < 0 ? 0 : y1;
|
||||
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
|
||||
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
|
||||
|
||||
int32_t x, y;
|
||||
|
||||
/*Set the first row in */
|
||||
|
||||
/*Refresh frame buffer*/
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
for(x = act_x1; x <= act_x2; x++) {
|
||||
if(lv_color_to1(*color_p) != 0) {
|
||||
lcd_fb[x + (y / 8)*ST7565_HOR_RES] &= ~(1 << (7 - (y % 8)));
|
||||
} else {
|
||||
lcd_fb[x + (y / 8)*ST7565_HOR_RES] |= (1 << (7 - (y % 8)));
|
||||
}
|
||||
color_p ++;
|
||||
}
|
||||
|
||||
color_p += x2 - act_x2; /*Next row*/
|
||||
}
|
||||
|
||||
st7565_sync(act_x1, act_y1, act_x2, act_y2);
|
||||
}
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
/**
|
||||
* Flush a specific part of the buffer to the display
|
||||
* @param x1 left coordinate of the area to flush
|
||||
* @param y1 top coordinate of the area to flush
|
||||
* @param x2 right coordinate of the area to flush
|
||||
* @param y2 bottom coordinate of the area to flush
|
||||
*/
|
||||
static void st7565_sync(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
|
||||
{
|
||||
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
|
||||
uint8_t c, p;
|
||||
for(p = y1 / 8; p <= y2 / 8; p++) {
|
||||
st7565_command(CMD_SET_PAGE | pagemap[p]);
|
||||
st7565_command(CMD_SET_COLUMN_LOWER | (x1 & 0xf));
|
||||
st7565_command(CMD_SET_COLUMN_UPPER | ((x1 >> 4) & 0xf));
|
||||
st7565_command(CMD_RMW);
|
||||
|
||||
for(c = x1; c <= x2; c++) {
|
||||
st7565_data(lcd_fb[(ST7565_HOR_RES * p) + c]);
|
||||
}
|
||||
}
|
||||
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a command to the ST7565
|
||||
* @param cmd the command
|
||||
*/
|
||||
static void st7565_command(uint8_t cmd)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(ST7565_CMD_MODE);
|
||||
LV_DRV_DISP_SPI_WR_BYTE(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to the ST7565
|
||||
* @param data the data
|
||||
*/
|
||||
static void st7565_data(uint8_t data)
|
||||
{
|
||||
LV_DRV_DISP_CMD_DATA(ST7565_DATA_MODE);
|
||||
LV_DRV_DISP_SPI_WR_BYTE(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
58
libs/lv_drivers/display/ST7565.h
Normal file
58
libs/lv_drivers/display/ST7565.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file ST7565.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ST7565_H
|
||||
#define ST7565_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_ST7565
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void st7565_init(void);
|
||||
void st7565_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
|
||||
void st7565_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
|
||||
void st7565_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_ST7565 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* ST7565_H */
|
||||
206
libs/lv_drivers/display/UC1610.c
Normal file
206
libs/lv_drivers/display/UC1610.c
Normal file
@ -0,0 +1,206 @@
|
||||
/**
|
||||
* @file UC1610.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "UC1610.h"
|
||||
|
||||
#if USE_UC1610
|
||||
|
||||
#include <stdbool.h>
|
||||
#include LV_DRV_DISP_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define UC1610_CMD_MODE 0
|
||||
#define UC1610_DATA_MODE 1
|
||||
#define UC1610_RESET_MODE 0
|
||||
#define UC1610_SET_MODE 1
|
||||
|
||||
/* hardware control commands */
|
||||
#define UC1610_SYSTEM_RESET 0xE2 /* software reset */
|
||||
#define UC1610_NOP 0xE3
|
||||
#define UC1610_SET_TEMP_COMP 0x24 /* set temperature compensation, default -0.05%/°C */
|
||||
#define UC1610_SET_PANEL_LOADING 0x29 /* set panel loading, default 16~21 nF */
|
||||
#define UC1610_SET_PUMP_CONTROL 0x2F /* default internal Vlcd (8x pump) */
|
||||
#define UC1610_SET_LCD_BIAS_RATIO 0xEB /* default 11 */
|
||||
#define UC1610_SET_VBIAS_POT 0x81 /* 1 byte (0~255) to follow setting the contrast, default 0x81 */
|
||||
#define UC1610_SET_LINE_RATE 0xA0 /* default 12,1 Klps */
|
||||
#define UC1610_SET_DISPLAY_ENABLE 0xAE /* + 1 / 0 : exit sleep mode / entering sleep mode */
|
||||
#define UC1610_SET_LCD_GRAY_SHADE 0xD0 /* default 24% between the two gray shade levels */
|
||||
#define UC1610_SET_COM_END 0xF1 /* set the number of used com electrodes (lines number -1) */
|
||||
|
||||
/* ram address control */
|
||||
#define UC1610_SET_AC 0x88 /* set ram address control */
|
||||
#define UC1610_AC_WA_FLAG 1 /* automatic column/page increment wrap around (1 : cycle increment) */
|
||||
#define UC1610_AC_AIO_FLAG (1 << 1) /* auto increment order (0/1 : column/page increment first) */
|
||||
#define UC1610_AC_PID_FLAG (1 << 2) /* page address auto increment order (0/1 : +1/-1) */
|
||||
|
||||
/* set cursor ram address */
|
||||
#define UC1610_SET_CA_LSB 0x00 /* + 4 LSB bits */
|
||||
#define UC1610_SET_CA_MSB 0x10 /* + 4 MSB bits // MSB + LSB values range : 0~159 */
|
||||
#define UC1610_SET_PA 0x60 /* + 5 bits // values range : 0~26 */
|
||||
|
||||
/* display control commands */
|
||||
#define UC1610_SET_FIXED_LINES 0x90 /* + 4 bits = 2xFL */
|
||||
#define UC1610_SET_SCROLL_LINES_LSB 0x40 /* + 4 LSB bits scroll up display by N (7 bits) lines */
|
||||
#define UC1610_SET_SCROLL_LINES_MSB 0x50 /* + 3 MSB bits */
|
||||
#define UC1610_SET_ALL_PIXEL_ON 0xA4 /* + 1 / 0 : set all pixel on, reverse */
|
||||
#define UC1610_SET_INVERSE_DISPLAY 0xA6 /* + 1 / 0 : inverse all data stored in ram, reverse */
|
||||
#define UC1610_SET_MAPPING_CONTROL 0xC0 /* control mirroring */
|
||||
#define UC1610_SET_MAPPING_CONTROL_LC_FLAG 1
|
||||
#define UC1610_SET_MAPPING_CONTROL_MX_FLAG (1 << 1)
|
||||
#define UC1610_SET_MAPPING_CONTROL_MY_FLAG (1 << 2)
|
||||
|
||||
/* window program mode */
|
||||
#define UC1610_SET_WINDOW_PROGRAM_ENABLE 0xF8 /* + 1 / 0 : enable / disable window programming mode, */
|
||||
/* reset before changing boundaries */
|
||||
#define UC1610_SET_WP_STARTING_CA 0xF4 /* 1 byte to follow for column address */
|
||||
#define UC1610_SET_WP_ENDING_CA 0xF6 /* 1 byte to follow for column address */
|
||||
#define UC1610_SET_WP_STARTING_PA 0xF5 /* 1 byte to follow for page address */
|
||||
#define UC1610_SET_WP_ENDING_PA 0xF7 /* 1 byte to follow for page address */
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint8_t cmd_buf[12];
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/* Return the byte bitmask of a pixel color corresponding to draw_buf arrangement */
|
||||
#define PIXIDX(y, c) ((c) << (((y) & 3) << 1))
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void uc1610_init(void) {
|
||||
LV_DRV_DELAY_MS(12);
|
||||
|
||||
/* initialization sequence */
|
||||
#if UC1610_INIT_HARD_RST
|
||||
LV_DRV_DISP_RST(UC1610_RESET_MODE); /* hardware reset */
|
||||
LV_DRV_DELAY_MS(1);
|
||||
LV_DRV_DISP_RST(UC1610_SET_MODE);
|
||||
#else
|
||||
cmd_buf[0] = UC1610_SYSTEM_RESET; /* software reset */
|
||||
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 1);
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
#endif
|
||||
|
||||
LV_DRV_DELAY_MS(2);
|
||||
cmd_buf[0] = UC1610_SET_COM_END; /* set com end value */
|
||||
cmd_buf[1] = UC1610_VER_RES - 1;
|
||||
cmd_buf[2] = UC1610_SET_PANEL_LOADING;
|
||||
cmd_buf[3] = UC1610_SET_LCD_BIAS_RATIO;
|
||||
cmd_buf[4] = UC1610_SET_VBIAS_POT; /* set contrast */
|
||||
cmd_buf[5] = (UC1610_INIT_CONTRAST * 255) / 100;
|
||||
#if UC1610_TOP_VIEW
|
||||
cmd_buf[6] = UC1610_SET_MAPPING_CONTROL | /* top view */
|
||||
UC1610_SET_MAPPING_CONTROL_MY_FLAG |
|
||||
UC1610_SET_MAPPING_CONTROL_MX_FLAG;
|
||||
#else
|
||||
cmd_buf[6] = UC1610_SET_MAPPING_CONTROL; /* bottom view */
|
||||
#endif
|
||||
cmd_buf[7] = UC1610_SET_SCROLL_LINES_LSB | 0; /* set scroll line on line 0 */
|
||||
cmd_buf[8] = UC1610_SET_SCROLL_LINES_MSB | 0;
|
||||
cmd_buf[9] = UC1610_SET_AC | UC1610_AC_WA_FLAG; /* set auto increment wrap around */
|
||||
cmd_buf[10] = UC1610_SET_INVERSE_DISPLAY | 1; /* invert colors to complies lv color system */
|
||||
cmd_buf[11] = UC1610_SET_DISPLAY_ENABLE | 1; /* turn display on */
|
||||
|
||||
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 12);
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
}
|
||||
|
||||
|
||||
void uc1610_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
|
||||
/*Return if the area is out the screen*/
|
||||
if(area->x2 < 0) return;
|
||||
if(area->y2 < 0) return;
|
||||
if(area->x1 > UC1610_HOR_RES - 1) return;
|
||||
if(area->y1 > UC1610_VER_RES - 1) return;
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
uint8_t act_x1 = area->x1 < 0 ? 0 : area->x1;
|
||||
uint8_t act_y1 = area->y1 < 0 ? 0 : area->y1;
|
||||
uint8_t act_x2 = area->x2 > UC1610_HOR_RES - 1 ? UC1610_HOR_RES - 1 : area->x2;
|
||||
uint8_t act_y2 = area->y2 > UC1610_VER_RES - 1 ? UC1610_VER_RES - 1 : area->y2;
|
||||
|
||||
uint8_t * buf = (uint8_t *) color_p;
|
||||
uint16_t buf_size = (act_x2 - act_x1 + 1) * (((act_y2 - act_y1) >> 2) + 1);
|
||||
|
||||
/*Set display window to fill*/
|
||||
cmd_buf[0] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 0; /* before changing boundaries */
|
||||
cmd_buf[1] = UC1610_SET_WP_STARTING_CA;
|
||||
cmd_buf[2] = act_x1;
|
||||
cmd_buf[3] = UC1610_SET_WP_ENDING_CA;
|
||||
cmd_buf[4] = act_x2;
|
||||
cmd_buf[5] = UC1610_SET_WP_STARTING_PA;
|
||||
cmd_buf[6] = act_y1 >> 2;
|
||||
cmd_buf[7] = UC1610_SET_WP_ENDING_PA;
|
||||
cmd_buf[8] = act_y2 >> 2;
|
||||
cmd_buf[9] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 1; /* entering window programming */
|
||||
|
||||
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 10);
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
|
||||
/*Flush draw_buf on display memory*/
|
||||
LV_DRV_DISP_CMD_DATA(UC1610_DATA_MODE);
|
||||
LV_DRV_DISP_SPI_CS(0);
|
||||
LV_DRV_DISP_SPI_WR_ARRAY(buf, buf_size);
|
||||
LV_DRV_DISP_SPI_CS(1);
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
void uc1610_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa) {
|
||||
(void) disp_drv;
|
||||
(void) opa;
|
||||
|
||||
uint16_t idx = x + buf_w * (y >> 2);
|
||||
|
||||
/* Convert color to depth 2 */
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
uint8_t color2 = color.full * 3;
|
||||
#else
|
||||
uint8_t color2 = color.full >> (LV_COLOR_DEPTH - 2);
|
||||
#endif
|
||||
|
||||
buf[idx] &= ~PIXIDX(y, 3); /* reset pixel color */
|
||||
buf[idx] |= PIXIDX(y, color2); /* write new color */
|
||||
}
|
||||
|
||||
void uc1610_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area) {
|
||||
(void) disp_drv;
|
||||
|
||||
/* Round y window to display memory page size */
|
||||
area->y1 = (area->y1 & (~3));
|
||||
area->y2 = (area->y2 & (~3)) + 3;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif
|
||||
58
libs/lv_drivers/display/UC1610.h
Normal file
58
libs/lv_drivers/display/UC1610.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file UC1610.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UC1610_H
|
||||
#define UC1610_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_UC1610
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void uc1610_init(void);
|
||||
void uc1610_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void uc1610_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area);
|
||||
void uc1610_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_UC1610 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* UC1610_H */
|
||||
801
libs/lv_drivers/display/drm.c
Normal file
801
libs/lv_drivers/display/drm.c
Normal file
@ -0,0 +1,801 @@
|
||||
/**
|
||||
* @file drm.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "drm.h"
|
||||
#if USE_DRM
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#define DBG_TAG "drm"
|
||||
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
|
||||
#define print(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__);
|
||||
#define err(msg, ...) print("error: " msg "\n", ##__VA_ARGS__)
|
||||
#define info(msg, ...) print(msg "\n", ##__VA_ARGS__)
|
||||
#define dbg(msg, ...) {} //print(DBG_TAG ": " msg "\n", ##__VA_ARGS__)
|
||||
|
||||
struct drm_buffer {
|
||||
uint32_t handle;
|
||||
uint32_t pitch;
|
||||
uint32_t offset;
|
||||
unsigned long int size;
|
||||
void * map;
|
||||
uint32_t fb_handle;
|
||||
};
|
||||
|
||||
struct drm_dev {
|
||||
int fd;
|
||||
uint32_t conn_id, enc_id, crtc_id, plane_id, crtc_idx;
|
||||
uint32_t width, height;
|
||||
uint32_t mmWidth, mmHeight;
|
||||
uint32_t fourcc;
|
||||
drmModeModeInfo mode;
|
||||
uint32_t blob_id;
|
||||
drmModeCrtc *saved_crtc;
|
||||
drmModeAtomicReq *req;
|
||||
drmEventContext drm_event_ctx;
|
||||
drmModePlane *plane;
|
||||
drmModeCrtc *crtc;
|
||||
drmModeConnector *conn;
|
||||
uint32_t count_plane_props;
|
||||
uint32_t count_crtc_props;
|
||||
uint32_t count_conn_props;
|
||||
drmModePropertyPtr plane_props[128];
|
||||
drmModePropertyPtr crtc_props[128];
|
||||
drmModePropertyPtr conn_props[128];
|
||||
struct drm_buffer drm_bufs[2]; /* DUMB buffers */
|
||||
struct drm_buffer *cur_bufs[2]; /* double buffering handling */
|
||||
} drm_dev;
|
||||
|
||||
static uint32_t get_plane_property_id(const char *name)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
dbg("Find plane property: %s", name);
|
||||
|
||||
for (i = 0; i < drm_dev.count_plane_props; ++i)
|
||||
if (!strcmp(drm_dev.plane_props[i]->name, name))
|
||||
return drm_dev.plane_props[i]->prop_id;
|
||||
|
||||
dbg("Unknown plane property: %s", name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t get_crtc_property_id(const char *name)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
dbg("Find crtc property: %s", name);
|
||||
|
||||
for (i = 0; i < drm_dev.count_crtc_props; ++i)
|
||||
if (!strcmp(drm_dev.crtc_props[i]->name, name))
|
||||
return drm_dev.crtc_props[i]->prop_id;
|
||||
|
||||
dbg("Unknown crtc property: %s", name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t get_conn_property_id(const char *name)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
dbg("Find conn property: %s", name);
|
||||
|
||||
for (i = 0; i < drm_dev.count_conn_props; ++i)
|
||||
if (!strcmp(drm_dev.conn_props[i]->name, name))
|
||||
return drm_dev.conn_props[i]->prop_id;
|
||||
|
||||
dbg("Unknown conn property: %s", name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void page_flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
|
||||
unsigned int tv_usec, void *user_data)
|
||||
{
|
||||
dbg("flip");
|
||||
}
|
||||
|
||||
static int drm_get_plane_props(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(drm_dev.fd, drm_dev.plane_id,
|
||||
DRM_MODE_OBJECT_PLANE);
|
||||
if (!props) {
|
||||
err("drmModeObjectGetProperties failed");
|
||||
return -1;
|
||||
}
|
||||
dbg("Found %u plane props", props->count_props);
|
||||
drm_dev.count_plane_props = props->count_props;
|
||||
for (i = 0; i < props->count_props; i++) {
|
||||
drm_dev.plane_props[i] = drmModeGetProperty(drm_dev.fd, props->props[i]);
|
||||
dbg("Added plane prop %u:%s", drm_dev.plane_props[i]->prop_id, drm_dev.plane_props[i]->name);
|
||||
}
|
||||
drmModeFreeObjectProperties(props);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_get_crtc_props(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(drm_dev.fd, drm_dev.crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC);
|
||||
if (!props) {
|
||||
err("drmModeObjectGetProperties failed");
|
||||
return -1;
|
||||
}
|
||||
dbg("Found %u crtc props", props->count_props);
|
||||
drm_dev.count_crtc_props = props->count_props;
|
||||
for (i = 0; i < props->count_props; i++) {
|
||||
drm_dev.crtc_props[i] = drmModeGetProperty(drm_dev.fd, props->props[i]);
|
||||
dbg("Added crtc prop %u:%s", drm_dev.crtc_props[i]->prop_id, drm_dev.crtc_props[i]->name);
|
||||
}
|
||||
drmModeFreeObjectProperties(props);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_get_conn_props(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(drm_dev.fd, drm_dev.conn_id,
|
||||
DRM_MODE_OBJECT_CONNECTOR);
|
||||
if (!props) {
|
||||
err("drmModeObjectGetProperties failed");
|
||||
return -1;
|
||||
}
|
||||
dbg("Found %u connector props", props->count_props);
|
||||
drm_dev.count_conn_props = props->count_props;
|
||||
for (i = 0; i < props->count_props; i++) {
|
||||
drm_dev.conn_props[i] = drmModeGetProperty(drm_dev.fd, props->props[i]);
|
||||
dbg("Added connector prop %u:%s", drm_dev.conn_props[i]->prop_id, drm_dev.conn_props[i]->name);
|
||||
}
|
||||
drmModeFreeObjectProperties(props);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_add_plane_property(const char *name, uint64_t value)
|
||||
{
|
||||
int ret;
|
||||
uint32_t prop_id = get_plane_property_id(name);
|
||||
|
||||
if (!prop_id) {
|
||||
err("Couldn't find plane prop %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = drmModeAtomicAddProperty(drm_dev.req, drm_dev.plane_id, get_plane_property_id(name), value);
|
||||
if (ret < 0) {
|
||||
err("drmModeAtomicAddProperty (%s:%" PRIu64 ") failed: %d", name, value, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_add_crtc_property(const char *name, uint64_t value)
|
||||
{
|
||||
int ret;
|
||||
uint32_t prop_id = get_crtc_property_id(name);
|
||||
|
||||
if (!prop_id) {
|
||||
err("Couldn't find crtc prop %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = drmModeAtomicAddProperty(drm_dev.req, drm_dev.crtc_id, get_crtc_property_id(name), value);
|
||||
if (ret < 0) {
|
||||
err("drmModeAtomicAddProperty (%s:%" PRIu64 ") failed: %d", name, value, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_add_conn_property(const char *name, uint64_t value)
|
||||
{
|
||||
int ret;
|
||||
uint32_t prop_id = get_conn_property_id(name);
|
||||
|
||||
if (!prop_id) {
|
||||
err("Couldn't find conn prop %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = drmModeAtomicAddProperty(drm_dev.req, drm_dev.conn_id, get_conn_property_id(name), value);
|
||||
if (ret < 0) {
|
||||
err("drmModeAtomicAddProperty (%s:%" PRIu64 ") failed: %d", name, value, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_dmabuf_set_plane(struct drm_buffer *buf)
|
||||
{
|
||||
int ret;
|
||||
static int first = 1;
|
||||
uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT;
|
||||
|
||||
drm_dev.req = drmModeAtomicAlloc();
|
||||
|
||||
/* On first Atomic commit, do a modeset */
|
||||
if (first) {
|
||||
drm_add_conn_property("CRTC_ID", drm_dev.crtc_id);
|
||||
|
||||
drm_add_crtc_property("MODE_ID", drm_dev.blob_id);
|
||||
drm_add_crtc_property("ACTIVE", 1);
|
||||
|
||||
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||
|
||||
first = 0;
|
||||
}
|
||||
|
||||
drm_add_plane_property("FB_ID", buf->fb_handle);
|
||||
drm_add_plane_property("CRTC_ID", drm_dev.crtc_id);
|
||||
drm_add_plane_property("SRC_X", 0);
|
||||
drm_add_plane_property("SRC_Y", 0);
|
||||
drm_add_plane_property("SRC_W", drm_dev.width << 16);
|
||||
drm_add_plane_property("SRC_H", drm_dev.height << 16);
|
||||
drm_add_plane_property("CRTC_X", 0);
|
||||
drm_add_plane_property("CRTC_Y", 0);
|
||||
drm_add_plane_property("CRTC_W", drm_dev.width);
|
||||
drm_add_plane_property("CRTC_H", drm_dev.height);
|
||||
|
||||
ret = drmModeAtomicCommit(drm_dev.fd, drm_dev.req, flags, NULL);
|
||||
if (ret) {
|
||||
err("drmModeAtomicCommit failed: %s", strerror(errno));
|
||||
drmModeAtomicFree(drm_dev.req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_plane(unsigned int fourcc, uint32_t *plane_id, uint32_t crtc_id, uint32_t crtc_idx)
|
||||
{
|
||||
drmModePlaneResPtr planes;
|
||||
drmModePlanePtr plane;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
int ret = 0;
|
||||
unsigned int format = fourcc;
|
||||
|
||||
planes = drmModeGetPlaneResources(drm_dev.fd);
|
||||
if (!planes) {
|
||||
err("drmModeGetPlaneResources failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbg("drm: found planes %u", planes->count_planes);
|
||||
|
||||
for (i = 0; i < planes->count_planes; ++i) {
|
||||
plane = drmModeGetPlane(drm_dev.fd, planes->planes[i]);
|
||||
if (!plane) {
|
||||
err("drmModeGetPlane failed: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(plane->possible_crtcs & (1 << crtc_idx))) {
|
||||
drmModeFreePlane(plane);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < plane->count_formats; ++j) {
|
||||
if (plane->formats[j] == format)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == plane->count_formats) {
|
||||
drmModeFreePlane(plane);
|
||||
continue;
|
||||
}
|
||||
|
||||
*plane_id = plane->plane_id;
|
||||
drmModeFreePlane(plane);
|
||||
|
||||
dbg("found plane %d", *plane_id);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == planes->count_planes)
|
||||
ret = -1;
|
||||
|
||||
drmModeFreePlaneResources(planes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int drm_find_connector(void)
|
||||
{
|
||||
drmModeConnector *conn = NULL;
|
||||
drmModeEncoder *enc = NULL;
|
||||
drmModeRes *res;
|
||||
int i;
|
||||
|
||||
if ((res = drmModeGetResources(drm_dev.fd)) == NULL) {
|
||||
err("drmModeGetResources() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (res->count_crtcs <= 0) {
|
||||
err("no Crtcs");
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
/* find all available connectors */
|
||||
for (i = 0; i < res->count_connectors; i++) {
|
||||
conn = drmModeGetConnector(drm_dev.fd, res->connectors[i]);
|
||||
if (!conn)
|
||||
continue;
|
||||
|
||||
#if DRM_CONNECTOR_ID >= 0
|
||||
if (conn->connector_id != DRM_CONNECTOR_ID) {
|
||||
drmModeFreeConnector(conn);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (conn->connection == DRM_MODE_CONNECTED) {
|
||||
dbg("drm: connector %d: connected", conn->connector_id);
|
||||
} else if (conn->connection == DRM_MODE_DISCONNECTED) {
|
||||
dbg("drm: connector %d: disconnected", conn->connector_id);
|
||||
} else if (conn->connection == DRM_MODE_UNKNOWNCONNECTION) {
|
||||
dbg("drm: connector %d: unknownconnection", conn->connector_id);
|
||||
} else {
|
||||
dbg("drm: connector %d: unknown", conn->connector_id);
|
||||
}
|
||||
|
||||
if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes > 0)
|
||||
break;
|
||||
|
||||
drmModeFreeConnector(conn);
|
||||
conn = NULL;
|
||||
};
|
||||
|
||||
if (!conn) {
|
||||
err("suitable connector not found");
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
drm_dev.conn_id = conn->connector_id;
|
||||
dbg("conn_id: %d", drm_dev.conn_id);
|
||||
drm_dev.mmWidth = conn->mmWidth;
|
||||
drm_dev.mmHeight = conn->mmHeight;
|
||||
|
||||
memcpy(&drm_dev.mode, &conn->modes[0], sizeof(drmModeModeInfo));
|
||||
|
||||
if (drmModeCreatePropertyBlob(drm_dev.fd, &drm_dev.mode, sizeof(drm_dev.mode),
|
||||
&drm_dev.blob_id)) {
|
||||
err("error creating mode blob");
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
drm_dev.width = conn->modes[0].hdisplay;
|
||||
drm_dev.height = conn->modes[0].vdisplay;
|
||||
|
||||
for (i = 0 ; i < res->count_encoders; i++) {
|
||||
enc = drmModeGetEncoder(drm_dev.fd, res->encoders[i]);
|
||||
if (!enc)
|
||||
continue;
|
||||
|
||||
dbg("enc%d enc_id %d conn enc_id %d", i, enc->encoder_id, conn->encoder_id);
|
||||
|
||||
if (enc->encoder_id == conn->encoder_id)
|
||||
break;
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
enc = NULL;
|
||||
}
|
||||
|
||||
if (enc) {
|
||||
drm_dev.enc_id = enc->encoder_id;
|
||||
dbg("enc_id: %d", drm_dev.enc_id);
|
||||
drm_dev.crtc_id = enc->crtc_id;
|
||||
dbg("crtc_id: %d", drm_dev.crtc_id);
|
||||
drmModeFreeEncoder(enc);
|
||||
} else {
|
||||
/* Encoder hasn't been associated yet, look it up */
|
||||
for (i = 0; i < conn->count_encoders; i++) {
|
||||
int crtc, crtc_id = -1;
|
||||
|
||||
enc = drmModeGetEncoder(drm_dev.fd, conn->encoders[i]);
|
||||
if (!enc)
|
||||
continue;
|
||||
|
||||
for (crtc = 0 ; crtc < res->count_crtcs; crtc++) {
|
||||
uint32_t crtc_mask = 1 << crtc;
|
||||
|
||||
crtc_id = res->crtcs[crtc];
|
||||
|
||||
dbg("enc_id %d crtc%d id %d mask %x possible %x", enc->encoder_id, crtc, crtc_id, crtc_mask, enc->possible_crtcs);
|
||||
|
||||
if (enc->possible_crtcs & crtc_mask)
|
||||
break;
|
||||
}
|
||||
|
||||
if (crtc_id > 0) {
|
||||
drm_dev.enc_id = enc->encoder_id;
|
||||
dbg("enc_id: %d", drm_dev.enc_id);
|
||||
drm_dev.crtc_id = crtc_id;
|
||||
dbg("crtc_id: %d", drm_dev.crtc_id);
|
||||
break;
|
||||
}
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
enc = NULL;
|
||||
}
|
||||
|
||||
if (!enc) {
|
||||
err("suitable encoder not found");
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
}
|
||||
|
||||
drm_dev.crtc_idx = -1;
|
||||
|
||||
for (i = 0; i < res->count_crtcs; ++i) {
|
||||
if (drm_dev.crtc_id == res->crtcs[i]) {
|
||||
drm_dev.crtc_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (drm_dev.crtc_idx == -1) {
|
||||
err("drm: CRTC not found");
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
dbg("crtc_idx: %d", drm_dev.crtc_idx);
|
||||
|
||||
return 0;
|
||||
|
||||
free_res:
|
||||
drmModeFreeResources(res);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int drm_open(const char *path)
|
||||
{
|
||||
int fd, flags;
|
||||
uint64_t has_dumb;
|
||||
int ret;
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
err("cannot open \"%s\"", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set FD_CLOEXEC flag */
|
||||
if ((flags = fcntl(fd, F_GETFD)) < 0 ||
|
||||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
|
||||
err("fcntl FD_CLOEXEC failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* check capability */
|
||||
ret = drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &has_dumb);
|
||||
if (ret < 0 || has_dumb == 0) {
|
||||
err("drmGetCap DRM_CAP_DUMB_BUFFER failed or \"%s\" doesn't have dumb "
|
||||
"buffer", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return fd;
|
||||
err:
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int drm_setup(unsigned int fourcc)
|
||||
{
|
||||
int ret;
|
||||
const char *device_path = NULL;
|
||||
|
||||
device_path = getenv("DRM_CARD");
|
||||
if (!device_path)
|
||||
device_path = DRM_CARD;
|
||||
|
||||
drm_dev.fd = drm_open(device_path);
|
||||
if (drm_dev.fd < 0)
|
||||
return -1;
|
||||
|
||||
ret = drmSetClientCap(drm_dev.fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
if (ret) {
|
||||
err("No atomic modesetting support: %s", strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = drm_find_connector();
|
||||
if (ret) {
|
||||
err("available drm devices not found");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = find_plane(fourcc, &drm_dev.plane_id, drm_dev.crtc_id, drm_dev.crtc_idx);
|
||||
if (ret) {
|
||||
err("Cannot find plane");
|
||||
goto err;
|
||||
}
|
||||
|
||||
drm_dev.plane = drmModeGetPlane(drm_dev.fd, drm_dev.plane_id);
|
||||
if (!drm_dev.plane) {
|
||||
err("Cannot get plane");
|
||||
goto err;
|
||||
}
|
||||
|
||||
drm_dev.crtc = drmModeGetCrtc(drm_dev.fd, drm_dev.crtc_id);
|
||||
if (!drm_dev.crtc) {
|
||||
err("Cannot get crtc");
|
||||
goto err;
|
||||
}
|
||||
|
||||
drm_dev.conn = drmModeGetConnector(drm_dev.fd, drm_dev.conn_id);
|
||||
if (!drm_dev.conn) {
|
||||
err("Cannot get connector");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = drm_get_plane_props();
|
||||
if (ret) {
|
||||
err("Cannot get plane props");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = drm_get_crtc_props();
|
||||
if (ret) {
|
||||
err("Cannot get crtc props");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = drm_get_conn_props();
|
||||
if (ret) {
|
||||
err("Cannot get connector props");
|
||||
goto err;
|
||||
}
|
||||
|
||||
drm_dev.drm_event_ctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||
drm_dev.drm_event_ctx.page_flip_handler = page_flip_handler;
|
||||
drm_dev.fourcc = fourcc;
|
||||
|
||||
info("drm: Found plane_id: %u connector_id: %d crtc_id: %d",
|
||||
drm_dev.plane_id, drm_dev.conn_id, drm_dev.crtc_id);
|
||||
|
||||
info("drm: %dx%d (%dmm X% dmm) pixel format %c%c%c%c",
|
||||
drm_dev.width, drm_dev.height, drm_dev.mmWidth, drm_dev.mmHeight,
|
||||
(fourcc>>0)&0xff, (fourcc>>8)&0xff, (fourcc>>16)&0xff, (fourcc>>24)&0xff);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
close(drm_dev.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int drm_allocate_dumb(struct drm_buffer *buf)
|
||||
{
|
||||
struct drm_mode_create_dumb creq;
|
||||
struct drm_mode_map_dumb mreq;
|
||||
uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
|
||||
int ret;
|
||||
|
||||
/* create dumb buffer */
|
||||
memset(&creq, 0, sizeof(creq));
|
||||
creq.width = drm_dev.width;
|
||||
creq.height = drm_dev.height;
|
||||
creq.bpp = LV_COLOR_DEPTH;
|
||||
ret = drmIoctl(drm_dev.fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
|
||||
if (ret < 0) {
|
||||
err("DRM_IOCTL_MODE_CREATE_DUMB fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf->handle = creq.handle;
|
||||
buf->pitch = creq.pitch;
|
||||
dbg("pitch %d", buf->pitch);
|
||||
buf->size = creq.size;
|
||||
dbg("size %d", buf->size);
|
||||
|
||||
/* prepare buffer for memory mapping */
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.handle = creq.handle;
|
||||
ret = drmIoctl(drm_dev.fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
|
||||
if (ret) {
|
||||
err("DRM_IOCTL_MODE_MAP_DUMB fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf->offset = mreq.offset;
|
||||
|
||||
/* perform actual memory mapping */
|
||||
buf->map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_dev.fd, mreq.offset);
|
||||
if (buf->map == MAP_FAILED) {
|
||||
err("mmap fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* clear the framebuffer to 0 (= full transparency in ARGB8888) */
|
||||
memset(buf->map, 0, creq.size);
|
||||
|
||||
/* create framebuffer object for the dumb-buffer */
|
||||
handles[0] = creq.handle;
|
||||
pitches[0] = creq.pitch;
|
||||
offsets[0] = 0;
|
||||
ret = drmModeAddFB2(drm_dev.fd, drm_dev.width, drm_dev.height, drm_dev.fourcc,
|
||||
handles, pitches, offsets, &buf->fb_handle, 0);
|
||||
if (ret) {
|
||||
err("drmModeAddFB fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_setup_buffers(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Allocate DUMB buffers */
|
||||
ret = drm_allocate_dumb(&drm_dev.drm_bufs[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_allocate_dumb(&drm_dev.drm_bufs[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set buffering handling */
|
||||
drm_dev.cur_bufs[0] = NULL;
|
||||
drm_dev.cur_bufs[1] = &drm_dev.drm_bufs[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void drm_wait_vsync(lv_disp_drv_t *disp_drv)
|
||||
{
|
||||
int ret;
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(drm_dev.fd, &fds);
|
||||
|
||||
do {
|
||||
ret = select(drm_dev.fd + 1, &fds, NULL, NULL, NULL);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret < 0) {
|
||||
err("select failed: %s", strerror(errno));
|
||||
drmModeAtomicFree(drm_dev.req);
|
||||
drm_dev.req = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FD_ISSET(drm_dev.fd, &fds))
|
||||
drmHandleEvent(drm_dev.fd, &drm_dev.drm_event_ctx);
|
||||
|
||||
drmModeAtomicFree(drm_dev.req);
|
||||
drm_dev.req = NULL;
|
||||
}
|
||||
|
||||
void drm_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
struct drm_buffer *fbuf = drm_dev.cur_bufs[1];
|
||||
lv_coord_t w = (area->x2 - area->x1 + 1);
|
||||
lv_coord_t h = (area->y2 - area->y1 + 1);
|
||||
int i, y;
|
||||
|
||||
dbg("x %d:%d y %d:%d w %d h %d", area->x1, area->x2, area->y1, area->y2, w, h);
|
||||
|
||||
/* Partial update */
|
||||
if ((w != drm_dev.width || h != drm_dev.height) && drm_dev.cur_bufs[0])
|
||||
memcpy(fbuf->map, drm_dev.cur_bufs[0]->map, fbuf->size);
|
||||
|
||||
for (y = 0, i = area->y1 ; i <= area->y2 ; ++i, ++y) {
|
||||
memcpy((uint8_t *)fbuf->map + (area->x1 * (LV_COLOR_SIZE/8)) + (fbuf->pitch * i),
|
||||
(uint8_t *)color_p + (w * (LV_COLOR_SIZE/8) * y),
|
||||
w * (LV_COLOR_SIZE/8));
|
||||
}
|
||||
|
||||
if (drm_dev.req)
|
||||
drm_wait_vsync(disp_drv);
|
||||
|
||||
/* show fbuf plane */
|
||||
if (drm_dmabuf_set_plane(fbuf)) {
|
||||
err("Flush fail");
|
||||
return;
|
||||
}
|
||||
else
|
||||
dbg("Flush done");
|
||||
|
||||
if (!drm_dev.cur_bufs[0])
|
||||
drm_dev.cur_bufs[1] = &drm_dev.drm_bufs[1];
|
||||
else
|
||||
drm_dev.cur_bufs[1] = drm_dev.cur_bufs[0];
|
||||
|
||||
drm_dev.cur_bufs[0] = fbuf;
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
#define DRM_FOURCC DRM_FORMAT_XRGB8888
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#define DRM_FOURCC DRM_FORMAT_RGB565
|
||||
#else
|
||||
#error LV_COLOR_DEPTH not supported
|
||||
#endif
|
||||
|
||||
void drm_get_sizes(lv_coord_t *width, lv_coord_t *height, uint32_t *dpi)
|
||||
{
|
||||
if (width)
|
||||
*width = drm_dev.width;
|
||||
|
||||
if (height)
|
||||
*height = drm_dev.height;
|
||||
|
||||
if (dpi && drm_dev.mmWidth)
|
||||
*dpi = DIV_ROUND_UP(drm_dev.width * 25400, drm_dev.mmWidth * 1000);
|
||||
}
|
||||
|
||||
void drm_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_setup(DRM_FOURCC);
|
||||
if (ret) {
|
||||
close(drm_dev.fd);
|
||||
drm_dev.fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = drm_setup_buffers();
|
||||
if (ret) {
|
||||
err("DRM buffer allocation failed");
|
||||
close(drm_dev.fd);
|
||||
drm_dev.fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
info("DRM subsystem and buffer mapped successfully");
|
||||
}
|
||||
|
||||
void drm_exit(void)
|
||||
{
|
||||
close(drm_dev.fd);
|
||||
drm_dev.fd = -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
60
libs/lv_drivers/display/drm.h
Normal file
60
libs/lv_drivers/display/drm.h
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file drm.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DRM_H
|
||||
#define DRM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_DRM
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void drm_init(void);
|
||||
void drm_get_sizes(lv_coord_t *width, lv_coord_t *height, uint32_t *dpi);
|
||||
void drm_exit(void);
|
||||
void drm_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void drm_wait_vsync(lv_disp_drv_t * drv);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_DRM*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*DRM_H*/
|
||||
277
libs/lv_drivers/display/fbdev.c
Normal file
277
libs/lv_drivers/display/fbdev.c
Normal file
@ -0,0 +1,277 @@
|
||||
/**
|
||||
* @file fbdev.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "fbdev.h"
|
||||
#if USE_FBDEV || USE_BSD_FBDEV
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#if USE_BSD_FBDEV
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/fbio.h>
|
||||
#else /* USE_BSD_FBDEV */
|
||||
#include <linux/fb.h>
|
||||
#endif /* USE_BSD_FBDEV */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef FBDEV_PATH
|
||||
#define FBDEV_PATH "/dev/fb0"
|
||||
#endif
|
||||
|
||||
#ifndef DIV_ROUND_UP
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STRUCTURES
|
||||
**********************/
|
||||
|
||||
struct bsd_fb_var_info{
|
||||
uint32_t xoffset;
|
||||
uint32_t yoffset;
|
||||
uint32_t xres;
|
||||
uint32_t yres;
|
||||
int bits_per_pixel;
|
||||
};
|
||||
|
||||
struct bsd_fb_fix_info{
|
||||
long int line_length;
|
||||
long int smem_len;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
#if USE_BSD_FBDEV
|
||||
static struct bsd_fb_var_info vinfo;
|
||||
static struct bsd_fb_fix_info finfo;
|
||||
#else
|
||||
static struct fb_var_screeninfo vinfo;
|
||||
static struct fb_fix_screeninfo finfo;
|
||||
#endif /* USE_BSD_FBDEV */
|
||||
static char *fbp = 0;
|
||||
static long int screensize = 0;
|
||||
static int fbfd = 0;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if USE_BSD_FBDEV
|
||||
#define FBIOBLANK FBIO_BLANK
|
||||
#endif /* USE_BSD_FBDEV */
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void fbdev_init(void)
|
||||
{
|
||||
// Open the file for reading and writing
|
||||
fbfd = open(FBDEV_PATH, O_RDWR);
|
||||
if(fbfd == -1) {
|
||||
perror("Error: cannot open framebuffer device");
|
||||
return;
|
||||
}
|
||||
LV_LOG_INFO("The framebuffer device was opened successfully");
|
||||
|
||||
#if FBDEV_DISPLAY_POWER_ON
|
||||
// Make sure that the display is on.
|
||||
if (ioctl(fbfd, FBIOBLANK, FB_BLANK_UNBLANK) != 0) {
|
||||
perror("ioctl(FBIOBLANK)");
|
||||
return;
|
||||
}
|
||||
#endif /* FBDEV_DISPLAY_POWER_ON */
|
||||
|
||||
#if USE_BSD_FBDEV
|
||||
struct fbtype fb;
|
||||
unsigned line_length;
|
||||
|
||||
//Get fb type
|
||||
if (ioctl(fbfd, FBIOGTYPE, &fb) != 0) {
|
||||
perror("ioctl(FBIOGTYPE)");
|
||||
return;
|
||||
}
|
||||
|
||||
//Get screen width
|
||||
if (ioctl(fbfd, FBIO_GETLINEWIDTH, &line_length) != 0) {
|
||||
perror("ioctl(FBIO_GETLINEWIDTH)");
|
||||
return;
|
||||
}
|
||||
|
||||
vinfo.xres = (unsigned) fb.fb_width;
|
||||
vinfo.yres = (unsigned) fb.fb_height;
|
||||
vinfo.bits_per_pixel = fb.fb_depth;
|
||||
vinfo.xoffset = 0;
|
||||
vinfo.yoffset = 0;
|
||||
finfo.line_length = line_length;
|
||||
finfo.smem_len = finfo.line_length * vinfo.yres;
|
||||
#else /* USE_BSD_FBDEV */
|
||||
|
||||
// Get fixed screen information
|
||||
if(ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
|
||||
perror("Error reading fixed information");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get variable screen information
|
||||
if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
|
||||
perror("Error reading variable information");
|
||||
return;
|
||||
}
|
||||
#endif /* USE_BSD_FBDEV */
|
||||
|
||||
LV_LOG_INFO("%dx%d, %dbpp", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
|
||||
|
||||
// Figure out the size of the screen in bytes
|
||||
screensize = finfo.smem_len; //finfo.line_length * vinfo.yres;
|
||||
|
||||
// Map the device to memory
|
||||
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
|
||||
if((intptr_t)fbp == -1) {
|
||||
perror("Error: failed to map framebuffer device to memory");
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't initialise the memory to retain what's currently displayed / avoid clearing the screen.
|
||||
// This is important for applications that only draw to a subsection of the full framebuffer.
|
||||
|
||||
LV_LOG_INFO("The framebuffer device was mapped to memory successfully");
|
||||
|
||||
}
|
||||
|
||||
void fbdev_exit(void)
|
||||
{
|
||||
close(fbfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
if(fbp == NULL ||
|
||||
area->x2 < 0 ||
|
||||
area->y2 < 0 ||
|
||||
area->x1 > (int32_t)vinfo.xres - 1 ||
|
||||
area->y1 > (int32_t)vinfo.yres - 1) {
|
||||
lv_disp_flush_ready(drv);
|
||||
return;
|
||||
}
|
||||
|
||||
/*Truncate the area to the screen*/
|
||||
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
|
||||
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
|
||||
int32_t act_x2 = area->x2 > (int32_t)vinfo.xres - 1 ? (int32_t)vinfo.xres - 1 : area->x2;
|
||||
int32_t act_y2 = area->y2 > (int32_t)vinfo.yres - 1 ? (int32_t)vinfo.yres - 1 : area->y2;
|
||||
|
||||
|
||||
lv_coord_t w = (act_x2 - act_x1 + 1);
|
||||
long int location = 0;
|
||||
long int byte_location = 0;
|
||||
unsigned char bit_location = 0;
|
||||
|
||||
/*32 or 24 bit per pixel*/
|
||||
if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
|
||||
uint32_t * fbp32 = (uint32_t *)fbp;
|
||||
int32_t y;
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 4;
|
||||
memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
|
||||
color_p += w;
|
||||
}
|
||||
}
|
||||
/*16 bit per pixel*/
|
||||
else if(vinfo.bits_per_pixel == 16) {
|
||||
uint16_t * fbp16 = (uint16_t *)fbp;
|
||||
int32_t y;
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 2;
|
||||
memcpy(&fbp16[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 2);
|
||||
color_p += w;
|
||||
}
|
||||
}
|
||||
/*8 bit per pixel*/
|
||||
else if(vinfo.bits_per_pixel == 8) {
|
||||
uint8_t * fbp8 = (uint8_t *)fbp;
|
||||
int32_t y;
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length;
|
||||
memcpy(&fbp8[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1));
|
||||
color_p += w;
|
||||
}
|
||||
}
|
||||
/*1 bit per pixel*/
|
||||
else if(vinfo.bits_per_pixel == 1) {
|
||||
uint8_t * fbp8 = (uint8_t *)fbp;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
for(y = act_y1; y <= act_y2; y++) {
|
||||
for(x = act_x1; x <= act_x2; x++) {
|
||||
location = (x + vinfo.xoffset) + (y + vinfo.yoffset) * vinfo.xres;
|
||||
byte_location = location / 8; /* find the byte we need to change */
|
||||
bit_location = location % 8; /* inside the byte found, find the bit we need to change */
|
||||
fbp8[byte_location] &= ~(((uint8_t)(1)) << bit_location);
|
||||
fbp8[byte_location] |= ((uint8_t)(color_p->full)) << bit_location;
|
||||
color_p++;
|
||||
}
|
||||
|
||||
color_p += area->x2 - act_x2;
|
||||
}
|
||||
} else {
|
||||
/*Not supported bit per pixel*/
|
||||
}
|
||||
|
||||
//May be some direct update command is required
|
||||
//ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
|
||||
|
||||
lv_disp_flush_ready(drv);
|
||||
}
|
||||
|
||||
void fbdev_get_sizes(uint32_t *width, uint32_t *height, uint32_t *dpi) {
|
||||
if (width)
|
||||
*width = vinfo.xres;
|
||||
|
||||
if (height)
|
||||
*height = vinfo.yres;
|
||||
|
||||
if (dpi && vinfo.height)
|
||||
*dpi = DIV_ROUND_UP(vinfo.xres * 254, vinfo.width * 10);
|
||||
}
|
||||
|
||||
void fbdev_set_offset(uint32_t xoffset, uint32_t yoffset) {
|
||||
vinfo.xoffset = xoffset;
|
||||
vinfo.yoffset = yoffset;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif
|
||||
65
libs/lv_drivers/display/fbdev.h
Normal file
65
libs/lv_drivers/display/fbdev.h
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @file fbdev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FBDEV_H
|
||||
#define FBDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_FBDEV || USE_BSD_FBDEV
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void fbdev_init(void);
|
||||
void fbdev_exit(void);
|
||||
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void fbdev_get_sizes(uint32_t *width, uint32_t *height, uint32_t *dpi);
|
||||
/**
|
||||
* Set the X and Y offset in the variable framebuffer info.
|
||||
* @param xoffset horizontal offset
|
||||
* @param yoffset vertical offset
|
||||
*/
|
||||
void fbdev_set_offset(uint32_t xoffset, uint32_t yoffset);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_FBDEV*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*FBDEV_H*/
|
||||
57
libs/lv_drivers/display/monitor.h
Normal file
57
libs/lv_drivers/display/monitor.h
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file monitor.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MONITOR_H
|
||||
#define MONITOR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void monitor_init(void);
|
||||
void monitor_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void monitor_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_MONITOR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* MONITOR_H */
|
||||
1
libs/lv_drivers/docs/astyle_c
Normal file
1
libs/lv_drivers/docs/astyle_c
Normal file
@ -0,0 +1 @@
|
||||
--style=kr --convert-tabs --indent=spaces=4 --indent-switches --pad-oper --unpad-paren --align-pointer=middle --suffix=.bak --lineend=linux --min-conditional-indent=
|
||||
1
libs/lv_drivers/docs/astyle_h
Normal file
1
libs/lv_drivers/docs/astyle_h
Normal file
@ -0,0 +1 @@
|
||||
--convert-tabs --indent=spaces=4
|
||||
97
libs/lv_drivers/gtkdrv/README.md
Normal file
97
libs/lv_drivers/gtkdrv/README.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Add GTK under Linux in Eclipse
|
||||
|
||||
## Install GDK
|
||||
|
||||
```
|
||||
sudo apt-get install libgtk-3-dev
|
||||
sudo apt-get install libglib2.0-dev
|
||||
```
|
||||
|
||||
## Add GTK include paths and libraries
|
||||
|
||||
In "Project properties > C/C++ Build > Settings" set the followings:
|
||||
|
||||
- "Cross GCC Compiler > Command line pattern"
|
||||
- Add ` ${gtk+-cflags}` to the end (add a space between the last command and this)
|
||||
|
||||
- "Cross GCC Compiler > Includes"
|
||||
- /usr/include/glib-2.0
|
||||
- /usr/include/gtk-3.0
|
||||
- /usr/include/pango-1.0
|
||||
- /usr/include/cairo
|
||||
- /usr/include/gdk-pixbuf-2.0
|
||||
- /usr/include/atk-1.0
|
||||
|
||||
- "Cross GCC Linker > Command line pattern"
|
||||
- Add ` ${gtk+-libs}` to the end (add a space between the last command and this)
|
||||
|
||||
|
||||
- "Cross GCC Linker > Libraries"
|
||||
- Add `pthread`
|
||||
|
||||
|
||||
- In "C/C++ Build > Build variables"
|
||||
- Configuration: [All Configuration]
|
||||
|
||||
- Add
|
||||
- Variable name: `gtk+-cflags`
|
||||
- Type: `String`
|
||||
- Value: `pkg-config --cflags gtk+-3.0`
|
||||
- Variable name: `gtk+-libs`
|
||||
- Type: `String`
|
||||
- Value: `pkg-config --libs gtk+-3.0`
|
||||
|
||||
|
||||
## Init GDK in LVGL
|
||||
|
||||
1. In `main.c` `#include "lv_drivers/gtkdrv/gtkdrv.h"`
|
||||
2. Enable the GTK driver in `lv_drv_conf.h` with `USE_GTK 1`
|
||||
3. After `lv_init()` call `gdkdrv_init()`;
|
||||
4. Add a display:
|
||||
```c
|
||||
static lv_disp_buf_t disp_buf1;
|
||||
static lv_color_t buf1_1[LV_HOR_RES_MAX * LV_VER_RES_MAX];
|
||||
lv_disp_buf_init(&disp_buf1, buf1_1, NULL, LV_HOR_RES_MAX * LV_VER_RES_MAX);
|
||||
|
||||
/*Create a display*/
|
||||
lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.buffer = &disp_buf1;
|
||||
disp_drv.flush_cb = gtkdrv_flush_cb;
|
||||
```
|
||||
5. Add mouse:
|
||||
```c
|
||||
lv_indev_drv_t indev_drv_mouse;
|
||||
lv_indev_drv_init(&indev_drv_mouse);
|
||||
indev_drv_mouse.type = LV_INDEV_TYPE_POINTER;
|
||||
```
|
||||
6. Add keyboard:
|
||||
```c
|
||||
lv_indev_drv_t indev_drv_kb;
|
||||
lv_indev_drv_init(&indev_drv_kb);
|
||||
indev_drv_kb.type = LV_INDEV_TYPE_KEYPAD;
|
||||
indev_drv_kb.read_cb = lv_keyboard_read_cb;
|
||||
lv_indev_drv_register(&indev_drv_kb);
|
||||
```
|
||||
7. Configure tick in `lv_conf.h`
|
||||
```c
|
||||
#define LV_TICK_CUSTOM 1
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "lv_drivers/gtkdrv/gtkdrv.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (gtkdrv_tick_get()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
```
|
||||
8. Be sure `LV_COLOR_DEPTH` is `32` in `lv_conf.h`
|
||||
|
||||
## Run in a window
|
||||
Build and Run to "normally" run the UI in a window
|
||||
|
||||
## Run in browser
|
||||
With the help of `Broadway` the UI can be easily shown via a browser.
|
||||
|
||||
1. Open Terminal and start *Broadway* with `broadwayd :5`. Leave the terminal running.
|
||||
2. Navigate to where eclipse created the binary executable (my_project/Debug) and open a terminal in that folder.
|
||||
In this terminal run `GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 ./my_executable` (replace *my_executable* wih name of your executable)
|
||||
3. Open a web browser and go to `http://localhost:8085/`
|
||||
|
||||

|
||||
BIN
libs/lv_drivers/gtkdrv/broadway.png
Normal file
BIN
libs/lv_drivers/gtkdrv/broadway.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
323
libs/lv_drivers/gtkdrv/gtkdrv.c
Normal file
323
libs/lv_drivers/gtkdrv/gtkdrv.c
Normal file
@ -0,0 +1,323 @@
|
||||
/**
|
||||
* @file gtk.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "gtkdrv.h"
|
||||
|
||||
#if USE_GTK
|
||||
#define _DEFAULT_SOURCE /* needed for usleep() */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkx.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void gtkdrv_handler(void * p);
|
||||
static gboolean mouse_pressed(GtkWidget *widget, GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
static gboolean mouse_released(GtkWidget *widget, GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
static gboolean mouse_motion(GtkWidget *widget, GdkEventMotion *event,
|
||||
gpointer user_data);
|
||||
static gboolean keyboard_press(GtkWidget *widget, GdkEventKey *event,
|
||||
gpointer user_data);
|
||||
static gboolean keyboard_release(GtkWidget *widget, GdkEventKey *event,
|
||||
gpointer user_data);
|
||||
|
||||
static void quit_handler(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static GtkWidget *window;
|
||||
static GtkWidget *event_box;
|
||||
|
||||
static GtkWidget *output_image;
|
||||
static GdkPixbuf *pixbuf;
|
||||
|
||||
static unsigned char run_gtk;
|
||||
|
||||
static lv_coord_t mouse_x;
|
||||
static lv_coord_t mouse_y;
|
||||
static lv_indev_state_t mouse_btn = LV_INDEV_STATE_REL;
|
||||
static lv_key_t last_key;
|
||||
static lv_indev_state_t last_key_state;
|
||||
|
||||
static uint8_t fb[LV_HOR_RES_MAX * LV_VER_RES_MAX * 3];
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void gtkdrv_init(void)
|
||||
{
|
||||
// Init GTK
|
||||
gtk_init(NULL, NULL);
|
||||
|
||||
/* Or just set up the widgets in code */
|
||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), LV_HOR_RES_MAX, LV_VER_RES_MAX);
|
||||
gtk_window_set_resizable (GTK_WINDOW(window), FALSE);
|
||||
output_image = gtk_image_new();
|
||||
event_box = gtk_event_box_new (); // Use event_box around image, otherwise mouse position output in broadway is offset
|
||||
gtk_container_add(GTK_CONTAINER (event_box), output_image);
|
||||
gtk_container_add(GTK_CONTAINER (window), event_box);
|
||||
|
||||
gtk_widget_add_events(event_box, GDK_BUTTON_PRESS_MASK);
|
||||
gtk_widget_add_events(event_box, GDK_SCROLL_MASK);
|
||||
gtk_widget_add_events(event_box, GDK_POINTER_MOTION_MASK);
|
||||
gtk_widget_add_events(window, GDK_KEY_PRESS_MASK);
|
||||
|
||||
g_signal_connect(window, "destroy", G_CALLBACK(quit_handler), NULL);
|
||||
g_signal_connect(event_box, "button-press-event", G_CALLBACK(mouse_pressed), NULL);
|
||||
g_signal_connect(event_box, "button-release-event", G_CALLBACK(mouse_released), NULL);
|
||||
g_signal_connect(event_box, "motion-notify-event", G_CALLBACK(mouse_motion), NULL);
|
||||
g_signal_connect(window, "key_press_event", G_CALLBACK(keyboard_press), NULL);
|
||||
g_signal_connect(window, "key_release_event", G_CALLBACK(keyboard_release), NULL);
|
||||
|
||||
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_data((guchar*)fb, GDK_COLORSPACE_RGB, false, 8, LV_HOR_RES_MAX, LV_VER_RES_MAX, LV_HOR_RES_MAX * 3, NULL, NULL);
|
||||
if (pixbuf == NULL)
|
||||
{
|
||||
fprintf(stderr, "Creating pixbuf failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, gtkdrv_handler, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
|
||||
uint32_t gtkdrv_tick_get(void)
|
||||
{
|
||||
static uint64_t start_ms = 0;
|
||||
if(start_ms == 0) {
|
||||
struct timeval tv_start;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
|
||||
}
|
||||
|
||||
struct timeval tv_now;
|
||||
gettimeofday(&tv_now, NULL);
|
||||
uint64_t now_ms;
|
||||
now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;
|
||||
|
||||
uint32_t time_ms = now_ms - start_ms;
|
||||
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param disp_drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void gtkdrv_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
lv_coord_t hres = disp_drv->rotated == 0 ? disp_drv->hor_res : disp_drv->ver_res;
|
||||
lv_coord_t vres = disp_drv->rotated == 0 ? disp_drv->ver_res : disp_drv->hor_res;
|
||||
|
||||
|
||||
/*Return if the area is out the screen*/
|
||||
if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t y;
|
||||
int32_t x;
|
||||
int32_t p;
|
||||
for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) {
|
||||
p = (y * disp_drv->hor_res + area->x1) * 3;
|
||||
for(x = area->x1; x <= area->x2 && x < disp_drv->hor_res; x++) {
|
||||
fb[p] = color_p->ch.red;
|
||||
fb[p + 1] = color_p->ch.green;
|
||||
fb[p + 2] = color_p->ch.blue;
|
||||
|
||||
p += 3;
|
||||
color_p ++;
|
||||
}
|
||||
}
|
||||
|
||||
/*IMPORTANT! It must be called to tell the system the flush is ready*/
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
|
||||
void gtkdrv_mouse_read_cb(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
data->point.x = mouse_x;
|
||||
data->point.y = mouse_y;
|
||||
data->state = mouse_btn;
|
||||
}
|
||||
|
||||
|
||||
void gtkdrv_keyboard_read_cb(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
data->key = last_key;
|
||||
data->state = last_key_state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void gtkdrv_handler(void * p)
|
||||
{
|
||||
while(1) {
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(output_image), pixbuf); // Test code
|
||||
|
||||
/* Real code should: call gdk_pixbuf_new_from_data () with pointer to frame buffer
|
||||
generated by LVGL. See
|
||||
https://developer.gnome.org/gdk-pixbuf/2.36/gdk-pixbuf-Image-Data-in-Memory.html
|
||||
*/
|
||||
|
||||
gtk_main_iteration_do(FALSE);
|
||||
/* Explicitly calling each iteration of the GTK main loop allows LVGL to sync frame
|
||||
buffer updates with GTK. It is perhaps also possible to just call gtk_main(), but not
|
||||
sure how sync will work then
|
||||
*/
|
||||
usleep(1*1000);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean mouse_pressed(GtkWidget *widget, GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
mouse_btn = LV_INDEV_STATE_PR;
|
||||
// Important, if this function returns TRUE the window cannot be moved around inside the browser
|
||||
// when using broadway
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean mouse_released(GtkWidget *widget, GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
mouse_btn = LV_INDEV_STATE_REL;
|
||||
// Important, if this function returns TRUE the window cannot be moved around inside the browser
|
||||
// when using broadway
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean mouse_motion(GtkWidget *widget, GdkEventMotion *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
mouse_x = event->x;
|
||||
mouse_y = event->y;
|
||||
// Important, if this function returns TRUE the window cannot be moved around inside the browser
|
||||
// when using broadway
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean keyboard_press(GtkWidget *widget, GdkEventKey *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
||||
uint32_t ascii_key = event->keyval;
|
||||
/*Remap some key to LV_KEY_... to manage groups*/
|
||||
switch(event->keyval) {
|
||||
case GDK_KEY_rightarrow:
|
||||
case GDK_KEY_Right:
|
||||
ascii_key = LV_KEY_RIGHT;
|
||||
break;
|
||||
|
||||
case GDK_KEY_leftarrow:
|
||||
case GDK_KEY_Left:
|
||||
ascii_key = LV_KEY_LEFT;
|
||||
break;
|
||||
|
||||
case GDK_KEY_uparrow:
|
||||
case GDK_KEY_Up:
|
||||
ascii_key = LV_KEY_UP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_downarrow:
|
||||
case GDK_KEY_Down:
|
||||
ascii_key = LV_KEY_DOWN;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Escape:
|
||||
ascii_key = LV_KEY_ESC;
|
||||
break;
|
||||
|
||||
case GDK_KEY_BackSpace:
|
||||
ascii_key = LV_KEY_BACKSPACE;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Delete:
|
||||
ascii_key = LV_KEY_DEL;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Tab:
|
||||
ascii_key = LV_KEY_NEXT;
|
||||
break;
|
||||
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_Return:
|
||||
case '\r':
|
||||
ascii_key = LV_KEY_ENTER;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
last_key = ascii_key;
|
||||
last_key_state = LV_INDEV_STATE_PR;
|
||||
// For other codes refer to https://developer.gnome.org/gdk3/stable/gdk3-Event-Structures.html#GdkEventKey
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean keyboard_release(GtkWidget *widget, GdkEventKey *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
last_key = 0;
|
||||
last_key_state = LV_INDEV_STATE_REL;
|
||||
// For other codes refer to https://developer.gnome.org/gdk3/stable/gdk3-Event-Structures.html#GdkEventKey
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void quit_handler(void)
|
||||
{
|
||||
exit(0);
|
||||
run_gtk = FALSE;
|
||||
}
|
||||
#endif /*USE_GTK*/
|
||||
|
||||
59
libs/lv_drivers/gtkdrv/gtkdrv.h
Normal file
59
libs/lv_drivers/gtkdrv/gtkdrv.h
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @file gtkdrv
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GTKDRV_H
|
||||
#define GTKDRV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_GTK
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void gtkdrv_init(void);
|
||||
uint32_t gtkdrv_tick_get(void);
|
||||
void gtkdrv_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
void gtkdrv_mouse_read_cb(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
void gtkdrv_keyboard_read_cb(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_GTK*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* GTKDRV_H */
|
||||
383
libs/lv_drivers/indev/AD_touch.c
Normal file
383
libs/lv_drivers/indev/AD_touch.c
Normal file
@ -0,0 +1,383 @@
|
||||
/**
|
||||
* @file AD_touch.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AD_touch.h"
|
||||
|
||||
#if USE_AD_TOUCH
|
||||
|
||||
#include LV_DRV_INDEV_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
#define SAMPLE_POINTS 4
|
||||
|
||||
#define CALIBRATIONINSET 20 // range 0 <= CALIBRATIONINSET <= 40
|
||||
|
||||
#define RESISTIVETOUCH_AUTO_SAMPLE_MODE
|
||||
#define TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD 350 // between 0-0x03ff the lesser this value
|
||||
|
||||
|
||||
// Current ADC values for X and Y channels
|
||||
int16_t adcX = 0;
|
||||
int16_t adcY = 0;
|
||||
volatile unsigned int adcTC = 0;
|
||||
|
||||
// coefficient values
|
||||
volatile long _trA;
|
||||
volatile long _trB;
|
||||
volatile long _trC;
|
||||
volatile long _trD;
|
||||
|
||||
volatile int16_t xRawTouch[SAMPLE_POINTS] = {TOUCHCAL_ULX, TOUCHCAL_URX, TOUCHCAL_LRX, TOUCHCAL_LLX};
|
||||
volatile int16_t yRawTouch[SAMPLE_POINTS] = {TOUCHCAL_ULY, TOUCHCAL_URY, TOUCHCAL_LRY, TOUCHCAL_LLY};
|
||||
|
||||
#define TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR 8
|
||||
|
||||
// use this scale factor to avoid working in floating point numbers
|
||||
#define SCALE_FACTOR (1 << TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR)
|
||||
|
||||
typedef enum {
|
||||
IDLE, //0
|
||||
SET_X, //1
|
||||
RUN_X, //2
|
||||
GET_X, //3
|
||||
RUN_CHECK_X, //4
|
||||
CHECK_X, //5
|
||||
SET_Y, //6
|
||||
RUN_Y, //7
|
||||
GET_Y, //8
|
||||
CHECK_Y, //9
|
||||
SET_VALUES, //10
|
||||
GET_POT, //11
|
||||
RUN_POT //12
|
||||
} TOUCH_STATES;
|
||||
|
||||
volatile TOUCH_STATES state = IDLE;
|
||||
|
||||
#define CAL_X_INSET (((GetMaxX() + 1) * (CALIBRATIONINSET >> 1)) / 100)
|
||||
#define CAL_Y_INSET (((GetMaxY() + 1) * (CALIBRATIONINSET >> 1)) / 100)
|
||||
|
||||
int stat;
|
||||
int16_t temp_x, temp_y;
|
||||
|
||||
|
||||
static int16_t TouchGetX(void);
|
||||
static int16_t TouchGetRawX(void);
|
||||
static int16_t TouchGetY(void);
|
||||
static int16_t TouchGetRawY(void);
|
||||
static int16_t TouchDetectPosition(void);
|
||||
static void TouchCalculateCalPoints(void);
|
||||
|
||||
|
||||
/********************************************************************/
|
||||
void ad_touch_init(void)
|
||||
{
|
||||
// Initialize ADC for auto sampling mode
|
||||
AD1CON1 = 0; // reset
|
||||
AD1CON2 = 0; // AVdd, AVss, int every conversion, MUXA only
|
||||
AD1CON3 = 0x1FFF; // 31 Tad auto-sample, Tad = 256*Tcy
|
||||
AD1CON1 = 0x80E0; // Turn on A/D module, use auto-convert
|
||||
|
||||
|
||||
ADPCFG_XPOS = RESISTIVETOUCH_ANALOG;
|
||||
ADPCFG_YPOS = RESISTIVETOUCH_ANALOG;
|
||||
|
||||
AD1CSSL = 0; // No scanned inputs
|
||||
|
||||
state = SET_X; // set the state of the state machine to start the sampling
|
||||
|
||||
/*Load calibration data*/
|
||||
xRawTouch[0] = TOUCHCAL_ULX;
|
||||
yRawTouch[0] = TOUCHCAL_ULY;
|
||||
xRawTouch[1] = TOUCHCAL_URX;
|
||||
yRawTouch[1] = TOUCHCAL_URY;
|
||||
xRawTouch[3] = TOUCHCAL_LLX;
|
||||
yRawTouch[3] = TOUCHCAL_LLY;
|
||||
xRawTouch[2] = TOUCHCAL_LRX;
|
||||
yRawTouch[2] = TOUCHCAL_LRY;
|
||||
|
||||
TouchCalculateCalPoints();
|
||||
}
|
||||
|
||||
/*Use this in lv_indev_drv*/
|
||||
bool ad_touch_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
|
||||
int16_t x, y;
|
||||
|
||||
x = TouchGetX();
|
||||
y = TouchGetY();
|
||||
|
||||
if((x > 0) && (y > 0)) {
|
||||
data->point.x = x;
|
||||
data->point.y = y;
|
||||
last_x = data->point.x;
|
||||
last_y = data->point.y;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
} else {
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Call periodically (e.g. in every 1 ms) to handle reading with ADC*/
|
||||
int16_t ad_touch_handler(void)
|
||||
{
|
||||
static int16_t tempX, tempY;
|
||||
int16_t temp;
|
||||
|
||||
switch(state) {
|
||||
case IDLE:
|
||||
adcX = 0;
|
||||
adcY = 0;
|
||||
break;
|
||||
|
||||
case SET_VALUES:
|
||||
if(!TOUCH_ADC_DONE)
|
||||
break;
|
||||
if((WORD)TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD < (WORD)ADC1BUF0) {
|
||||
adcX = 0;
|
||||
adcY = 0;
|
||||
} else {
|
||||
adcX = tempX;
|
||||
adcY = tempY;
|
||||
}
|
||||
state = SET_X;
|
||||
return 1; // touch screen acquisition is done
|
||||
|
||||
case SET_X:
|
||||
TOUCH_ADC_INPUT_SEL = ADC_XPOS;
|
||||
|
||||
ResistiveTouchScreen_XPlus_Config_As_Input();
|
||||
ResistiveTouchScreen_YPlus_Config_As_Input();
|
||||
ResistiveTouchScreen_XMinus_Config_As_Input();
|
||||
ResistiveTouchScreen_YMinus_Drive_Low();
|
||||
ResistiveTouchScreen_YMinus_Config_As_Output();
|
||||
|
||||
ADPCFG_YPOS = RESISTIVETOUCH_DIGITAL; // set to digital pin
|
||||
ADPCFG_XPOS = RESISTIVETOUCH_ANALOG; // set to analog pin
|
||||
|
||||
TOUCH_ADC_START = 1; // run conversion
|
||||
state = CHECK_X;
|
||||
break;
|
||||
|
||||
case CHECK_X:
|
||||
case CHECK_Y:
|
||||
|
||||
if(TOUCH_ADC_DONE == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if((WORD)TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD > (WORD)ADC1BUF0) {
|
||||
if(state == CHECK_X) {
|
||||
ResistiveTouchScreen_YPlus_Drive_High();
|
||||
ResistiveTouchScreen_YPlus_Config_As_Output();
|
||||
tempX = 0;
|
||||
state = RUN_X;
|
||||
} else {
|
||||
ResistiveTouchScreen_XPlus_Drive_High();
|
||||
ResistiveTouchScreen_XPlus_Config_As_Output();
|
||||
tempY = 0;
|
||||
state = RUN_Y;
|
||||
}
|
||||
} else {
|
||||
adcX = 0;
|
||||
adcY = 0;
|
||||
state = SET_X;
|
||||
return 1; // touch screen acquisition is done
|
||||
break;
|
||||
}
|
||||
|
||||
case RUN_X:
|
||||
case RUN_Y:
|
||||
TOUCH_ADC_START = 1;
|
||||
state = (state == RUN_X) ? GET_X : GET_Y;
|
||||
// no break needed here since the next state is either GET_X or GET_Y
|
||||
break;
|
||||
|
||||
case GET_X:
|
||||
case GET_Y:
|
||||
if(!TOUCH_ADC_DONE)
|
||||
break;
|
||||
|
||||
temp = ADC1BUF0;
|
||||
if(state == GET_X) {
|
||||
if(temp != tempX) {
|
||||
tempX = temp;
|
||||
state = RUN_X;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(temp != tempY) {
|
||||
tempY = temp;
|
||||
state = RUN_Y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(state == GET_X)
|
||||
ResistiveTouchScreen_YPlus_Config_As_Input();
|
||||
else
|
||||
ResistiveTouchScreen_XPlus_Config_As_Input();
|
||||
TOUCH_ADC_START = 1;
|
||||
state = (state == GET_X) ? SET_Y : SET_VALUES;
|
||||
break;
|
||||
|
||||
case SET_Y:
|
||||
if(!TOUCH_ADC_DONE)
|
||||
break;
|
||||
|
||||
if((WORD)TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD < (WORD)ADC1BUF0) {
|
||||
adcX = 0;
|
||||
adcY = 0;
|
||||
state = SET_X;
|
||||
return 1; // touch screen acquisition is done
|
||||
break;
|
||||
}
|
||||
|
||||
TOUCH_ADC_INPUT_SEL = ADC_YPOS;
|
||||
|
||||
ResistiveTouchScreen_XPlus_Config_As_Input();
|
||||
ResistiveTouchScreen_YPlus_Config_As_Input();
|
||||
ResistiveTouchScreen_XMinus_Drive_Low();
|
||||
ResistiveTouchScreen_XMinus_Config_As_Output();
|
||||
ResistiveTouchScreen_YMinus_Config_As_Input();
|
||||
|
||||
ADPCFG_YPOS = RESISTIVETOUCH_ANALOG; // set to analog pin
|
||||
ADPCFG_XPOS = RESISTIVETOUCH_DIGITAL; // set to digital pin
|
||||
TOUCH_ADC_START = 1; // run conversion
|
||||
state = CHECK_Y;
|
||||
break;
|
||||
|
||||
default:
|
||||
state = SET_X;
|
||||
return 1; // touch screen acquisition is done
|
||||
}
|
||||
stat = state;
|
||||
temp_x = adcX;
|
||||
temp_y = adcY;
|
||||
|
||||
return 0; // touch screen acquisition is not done
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/********************************************************************/
|
||||
static int16_t TouchGetX(void)
|
||||
{
|
||||
long result;
|
||||
|
||||
result = TouchGetRawX();
|
||||
|
||||
if(result > 0) {
|
||||
result = (long)((((long)_trC * result) + _trD) >> TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR);
|
||||
|
||||
}
|
||||
return ((int16_t)result);
|
||||
}
|
||||
/********************************************************************/
|
||||
static int16_t TouchGetRawX(void)
|
||||
{
|
||||
#ifdef TOUCHSCREEN_RESISTIVE_SWAP_XY
|
||||
return adcY;
|
||||
#else
|
||||
return adcX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
static int16_t TouchGetY(void)
|
||||
{
|
||||
|
||||
long result;
|
||||
|
||||
result = TouchGetRawY();
|
||||
|
||||
if(result > 0) {
|
||||
result = (long)((((long)_trA * result) + (long)_trB) >> TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR);
|
||||
|
||||
}
|
||||
return ((int16_t)result);
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
static int16_t TouchGetRawY(void)
|
||||
{
|
||||
#ifdef TOUCHSCREEN_RESISTIVE_SWAP_XY
|
||||
return adcX;
|
||||
#else
|
||||
return adcY;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void TouchCalculateCalPoints(void)
|
||||
{
|
||||
long trA, trB, trC, trD; // variables for the coefficients
|
||||
long trAhold, trBhold, trChold, trDhold;
|
||||
long test1, test2; // temp variables (must be signed type)
|
||||
|
||||
int16_t xPoint[SAMPLE_POINTS], yPoint[SAMPLE_POINTS];
|
||||
|
||||
yPoint[0] = yPoint[1] = CAL_Y_INSET;
|
||||
yPoint[2] = yPoint[3] = (GetMaxY() - CAL_Y_INSET);
|
||||
xPoint[0] = xPoint[3] = CAL_X_INSET;
|
||||
xPoint[1] = xPoint[2] = (GetMaxX() - CAL_X_INSET);
|
||||
|
||||
// calculate points transfer functiona
|
||||
// based on two simultaneous equations solve for the
|
||||
// constants
|
||||
|
||||
// use sample points 1 and 4
|
||||
// Dy1 = aTy1 + b; Dy4 = aTy4 + b
|
||||
// Dx1 = cTx1 + d; Dy4 = aTy4 + b
|
||||
|
||||
test1 = (long)yPoint[0] - (long)yPoint[3];
|
||||
test2 = (long)yRawTouch[0] - (long)yRawTouch[3];
|
||||
|
||||
trA = ((long)((long)test1 * SCALE_FACTOR) / test2);
|
||||
trB = ((long)((long)yPoint[0] * SCALE_FACTOR) - (trA * (long)yRawTouch[0]));
|
||||
|
||||
test1 = (long)xPoint[0] - (long)xPoint[2];
|
||||
test2 = (long)xRawTouch[0] - (long)xRawTouch[2];
|
||||
|
||||
trC = ((long)((long)test1 * SCALE_FACTOR) / test2);
|
||||
trD = ((long)((long)xPoint[0] * SCALE_FACTOR) - (trC * (long)xRawTouch[0]));
|
||||
|
||||
trAhold = trA;
|
||||
trBhold = trB;
|
||||
trChold = trC;
|
||||
trDhold = trD;
|
||||
|
||||
// use sample points 2 and 3
|
||||
// Dy2 = aTy2 + b; Dy3 = aTy3 + b
|
||||
// Dx2 = cTx2 + d; Dy3 = aTy3 + b
|
||||
|
||||
test1 = (long)yPoint[1] - (long)yPoint[2];
|
||||
test2 = (long)yRawTouch[1] - (long)yRawTouch[2];
|
||||
|
||||
trA = ((long)(test1 * SCALE_FACTOR) / test2);
|
||||
trB = ((long)((long)yPoint[1] * SCALE_FACTOR) - (trA * (long)yRawTouch[1]));
|
||||
|
||||
test1 = (long)xPoint[1] - (long)xPoint[3];
|
||||
test2 = (long)xRawTouch[1] - (long)xRawTouch[3];
|
||||
|
||||
trC = ((long)((long)test1 * SCALE_FACTOR) / test2);
|
||||
trD = ((long)((long)xPoint[1] * SCALE_FACTOR) - (trC * (long)xRawTouch[1]));
|
||||
|
||||
// get the average and use the average
|
||||
_trA = (trA + trAhold) >> 1;
|
||||
_trB = (trB + trBhold) >> 1;
|
||||
_trC = (trC + trChold) >> 1;
|
||||
_trD = (trD + trDhold) >> 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
120
libs/lv_drivers/indev/AD_touch.h
Normal file
120
libs/lv_drivers/indev/AD_touch.h
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @file AD_touch.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AD_TOUCH_H
|
||||
#define AD_TOUCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_AD_TOUCH
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#define _SUPPRESS_PLIB_WARNING
|
||||
#include <plib.h>
|
||||
|
||||
#include "GenericTypeDefs.h"
|
||||
|
||||
#define DISP_ORIENTATION 0
|
||||
#define DISP_HOR_RESOLUTION 320
|
||||
#define DISP_VER_RESOLUTION 240
|
||||
|
||||
/*GetMaxX Macro*/
|
||||
#if (DISP_ORIENTATION == 90) || (DISP_ORIENTATION == 270)
|
||||
#define GetMaxX() (DISP_VER_RESOLUTION - 1)
|
||||
#elif (DISP_ORIENTATION == 0) || (DISP_ORIENTATION == 180)
|
||||
#define GetMaxX() (DISP_HOR_RESOLUTION - 1)
|
||||
#endif
|
||||
|
||||
/*GetMaxY Macro*/
|
||||
#if (DISP_ORIENTATION == 90) || (DISP_ORIENTATION == 270)
|
||||
#define GetMaxY() (DISP_HOR_RESOLUTION - 1)
|
||||
#elif (DISP_ORIENTATION == 0) || (DISP_ORIENTATION == 180)
|
||||
#define GetMaxY() (DISP_VER_RESOLUTION - 1)
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* HARDWARE PROFILE FOR THE RESISTIVE TOUCHSCREEN
|
||||
*********************************************************************/
|
||||
|
||||
#define TOUCH_ADC_INPUT_SEL AD1CHS
|
||||
|
||||
// ADC Sample Start
|
||||
#define TOUCH_ADC_START AD1CON1bits.SAMP
|
||||
|
||||
// ADC Status
|
||||
#define TOUCH_ADC_DONE AD1CON1bits.DONE
|
||||
|
||||
#define RESISTIVETOUCH_ANALOG 1
|
||||
#define RESISTIVETOUCH_DIGITAL 0
|
||||
|
||||
// ADC channel constants
|
||||
#define ADC_XPOS ADC_CH0_POS_SAMPLEA_AN12
|
||||
#define ADC_YPOS ADC_CH0_POS_SAMPLEA_AN13
|
||||
|
||||
// ADC Port Control Bits
|
||||
#define ADPCFG_XPOS AD1PCFGbits.PCFG12 //XR
|
||||
#define ADPCFG_YPOS AD1PCFGbits.PCFG13 //YD
|
||||
|
||||
// X port definitions
|
||||
#define ResistiveTouchScreen_XPlus_Drive_High() LATBbits.LATB12 = 1
|
||||
#define ResistiveTouchScreen_XPlus_Drive_Low() LATBbits.LATB12 = 0 //LAT_XPOS
|
||||
#define ResistiveTouchScreen_XPlus_Config_As_Input() TRISBbits.TRISB12 = 1 //TRIS_XPOS
|
||||
#define ResistiveTouchScreen_XPlus_Config_As_Output() TRISBbits.TRISB12 = 0
|
||||
|
||||
#define ResistiveTouchScreen_XMinus_Drive_High() LATFbits.LATF0 = 1
|
||||
#define ResistiveTouchScreen_XMinus_Drive_Low() LATFbits.LATF0 = 0 //LAT_XNEG
|
||||
#define ResistiveTouchScreen_XMinus_Config_As_Input() TRISFbits.TRISF0 = 1 //TRIS_XNEG
|
||||
#define ResistiveTouchScreen_XMinus_Config_As_Output() TRISFbits.TRISF0 = 0
|
||||
|
||||
// Y port definitions
|
||||
#define ResistiveTouchScreen_YPlus_Drive_High() LATBbits.LATB13 = 1
|
||||
#define ResistiveTouchScreen_YPlus_Drive_Low() LATBbits.LATB13 = 0 //LAT_YPOS
|
||||
#define ResistiveTouchScreen_YPlus_Config_As_Input() TRISBbits.TRISB13 = 1 //TRIS_YPOS
|
||||
#define ResistiveTouchScreen_YPlus_Config_As_Output() TRISBbits.TRISB13 = 0
|
||||
|
||||
#define ResistiveTouchScreen_YMinus_Drive_High() LATFbits.LATF1 = 1
|
||||
#define ResistiveTouchScreen_YMinus_Drive_Low() LATFbits.LATF1 = 0 //LAT_YNEG
|
||||
#define ResistiveTouchScreen_YMinus_Config_As_Input() TRISFbits.TRISF1 = 1 //TRIS_YNEG
|
||||
#define ResistiveTouchScreen_YMinus_Config_As_Output() TRISFbits.TRISF1 = 0
|
||||
|
||||
// Default calibration points
|
||||
#define TOUCHCAL_ULX 0x0348
|
||||
#define TOUCHCAL_ULY 0x00CC
|
||||
#define TOUCHCAL_URX 0x00D2
|
||||
#define TOUCHCAL_URY 0x00CE
|
||||
#define TOUCHCAL_LLX 0x034D
|
||||
#define TOUCHCAL_LLY 0x0335
|
||||
#define TOUCHCAL_LRX 0x00D6
|
||||
#define TOUCHCAL_LRY 0x032D
|
||||
|
||||
void ad_touch_init(void);
|
||||
bool ad_touch_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
int16_t ad_touch_handler(void);
|
||||
|
||||
#endif /* USE_AD_TOUCH */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* AD_TOUCH_H */
|
||||
179
libs/lv_drivers/indev/FT5406EE8.c
Normal file
179
libs/lv_drivers/indev/FT5406EE8.c
Normal file
@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @file FT5406EE8.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "FT5406EE8.h"
|
||||
#if USE_FT5406EE8
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include LV_DRV_INDEV_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define I2C_WR_BIT 0x00
|
||||
#define I2C_RD_BIT 0x01
|
||||
|
||||
/*DEVICE MODES*/
|
||||
#define OPERAT_MD 0x00
|
||||
#define TEST_MD 0x04
|
||||
#define SYS_INF_MD 0x01
|
||||
|
||||
/*OPERATING MODE*/
|
||||
#define DEVICE_MODE 0x00
|
||||
#define GEST_ID 0x01
|
||||
#define TD_STATUS 0x02
|
||||
|
||||
#define FT5406EE8_FINGER_MAX 10
|
||||
|
||||
/*Register addresses*/
|
||||
#define FT5406EE8_REG_DEVICE_MODE 0x00
|
||||
#define FT5406EE8_REG_GEST_ID 0x01
|
||||
#define FT5406EE8_REG_TD_STATUS 0x02
|
||||
#define FT5406EE8_REG_YH 0x03
|
||||
#define FT5406EE8_REG_YL 0x04
|
||||
#define FT5406EE8_REG_XH 0x05
|
||||
#define FT5406EE8_REG_XL 0x06
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static bool ft5406ee8_get_touch_num(void);
|
||||
static bool ft5406ee8_read_finger1(int16_t * x, int16_t * y);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void ft5406ee8_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position and state of the touchpad
|
||||
* @param data store the read data here
|
||||
* @return false: because no ore data to be read
|
||||
*/
|
||||
bool ft5406ee8_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int16_t x_last;
|
||||
static int16_t y_last;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
bool valid = true;
|
||||
|
||||
valid = ft5406ee8_get_touch_num();
|
||||
if(valid == true) {
|
||||
valid = ft5406ee8_read_finger1(&x, &y);
|
||||
}
|
||||
|
||||
if(valid == true) {
|
||||
x = (uint32_t)((uint32_t)x * 320) / 2048;
|
||||
y = (uint32_t)((uint32_t)y * 240) / 2048;
|
||||
|
||||
|
||||
x_last = x;
|
||||
y_last = y;
|
||||
} else {
|
||||
x = x_last;
|
||||
y = y_last;
|
||||
}
|
||||
|
||||
data->point.x = x;
|
||||
data->point.y = y;
|
||||
data->state = valid == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bool ft5406ee8_get_touch_num(void)
|
||||
{
|
||||
bool ok = true;
|
||||
uint8_t t_num = 0;
|
||||
|
||||
LV_DRV_INDEV_I2C_START;
|
||||
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_WR_BIT);
|
||||
LV_DRV_INDEV_I2C_WR(FT5406EE8_REG_TD_STATUS)
|
||||
LV_DRV_INDEV_I2C_RESTART;
|
||||
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_RD_BIT);
|
||||
t_num = LV_DRV_INDEV_I2C_READ(0);
|
||||
|
||||
/* Error if not touched or too much finger */
|
||||
if(t_num > FT5406EE8_FINGER_MAX || t_num == 0) {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the x and y coordinated
|
||||
* @param x store the x coordinate here
|
||||
* @param y store the y coordinate here
|
||||
* @return false: not valid point; true: valid point
|
||||
*/
|
||||
static bool ft5406ee8_read_finger1(int16_t * x, int16_t * y)
|
||||
{
|
||||
uint8_t temp_xH = 0;
|
||||
uint8_t temp_xL = 0;
|
||||
uint8_t temp_yH = 0;
|
||||
uint8_t temp_yL = 0;
|
||||
|
||||
/*Read Y High and low byte*/
|
||||
LV_DRV_INDEV_I2C_START;
|
||||
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_WR_BIT);
|
||||
LV_DRV_INDEV_I2C_WR(FT5406EE8_REG_YH)
|
||||
LV_DRV_INDEV_I2C_RESTART;
|
||||
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_RD_BIT);
|
||||
temp_yH = LV_DRV_INDEV_I2C_READ(1);
|
||||
temp_yL = LV_DRV_INDEV_I2C_READ(1);
|
||||
|
||||
/*The upper two bit must be 2 on valid press*/
|
||||
if(((temp_yH >> 6) & 0xFF) != 2) {
|
||||
(void) LV_DRV_INDEV_I2C_READ(0); /*Dummy read to close read sequence*/
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Read X High and low byte*/
|
||||
temp_xH = LV_DRV_INDEV_I2C_READ(1);
|
||||
temp_xL = LV_DRV_INDEV_I2C_READ(0);
|
||||
|
||||
/*Save the result*/
|
||||
*x = (temp_xH & 0x0F) << 8;
|
||||
*x += temp_xL;
|
||||
*y = (temp_yH & 0x0F) << 8;
|
||||
*y += temp_yL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
56
libs/lv_drivers/indev/FT5406EE8.h
Normal file
56
libs/lv_drivers/indev/FT5406EE8.h
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file FT5406EE8.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FT5406EE8_H
|
||||
#define FT5406EE8_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_FT5406EE8
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void ft5406ee8_init(void);
|
||||
bool ft5406ee8_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_FT5406EE8 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FT5406EE8_H */
|
||||
174
libs/lv_drivers/indev/XPT2046.c
Normal file
174
libs/lv_drivers/indev/XPT2046.c
Normal file
@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @file XPT2046.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "XPT2046.h"
|
||||
#if USE_XPT2046
|
||||
|
||||
#include <stddef.h>
|
||||
#include LV_DRV_INDEV_INCLUDE
|
||||
#include LV_DRV_DELAY_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define CMD_X_READ 0b10010000
|
||||
#define CMD_Y_READ 0b11010000
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void xpt2046_corr(int16_t * x, int16_t * y);
|
||||
static void xpt2046_avg(int16_t * x, int16_t * y);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
int16_t avg_buf_x[XPT2046_AVG];
|
||||
int16_t avg_buf_y[XPT2046_AVG];
|
||||
uint8_t avg_last;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the XPT2046
|
||||
*/
|
||||
void xpt2046_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position and state of the touchpad
|
||||
* @param data store the read data here
|
||||
* @return false: because no ore data to be read
|
||||
*/
|
||||
bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
uint8_t buf;
|
||||
|
||||
int16_t x = 0;
|
||||
int16_t y = 0;
|
||||
|
||||
uint8_t irq = LV_DRV_INDEV_IRQ_READ;
|
||||
|
||||
if(irq == 0) {
|
||||
LV_DRV_INDEV_SPI_CS(0);
|
||||
|
||||
LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_X_READ); /*Start x read*/
|
||||
|
||||
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read x MSB*/
|
||||
x = buf << 8;
|
||||
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_Y_READ); /*Until x LSB converted y command can be sent*/
|
||||
x += buf;
|
||||
|
||||
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y MSB*/
|
||||
y = buf << 8;
|
||||
|
||||
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y LSB*/
|
||||
y += buf;
|
||||
|
||||
/*Normalize Data*/
|
||||
x = x >> 3;
|
||||
y = y >> 3;
|
||||
xpt2046_corr(&x, &y);
|
||||
xpt2046_avg(&x, &y);
|
||||
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
|
||||
LV_DRV_INDEV_SPI_CS(1);
|
||||
} else {
|
||||
x = last_x;
|
||||
y = last_y;
|
||||
avg_last = 0;
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
data->point.x = x;
|
||||
data->point.y = y;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static void xpt2046_corr(int16_t * x, int16_t * y)
|
||||
{
|
||||
#if XPT2046_XY_SWAP != 0
|
||||
int16_t swap_tmp;
|
||||
swap_tmp = *x;
|
||||
*x = *y;
|
||||
*y = swap_tmp;
|
||||
#endif
|
||||
|
||||
if((*x) > XPT2046_X_MIN)(*x) -= XPT2046_X_MIN;
|
||||
else(*x) = 0;
|
||||
|
||||
if((*y) > XPT2046_Y_MIN)(*y) -= XPT2046_Y_MIN;
|
||||
else(*y) = 0;
|
||||
|
||||
(*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) /
|
||||
(XPT2046_X_MAX - XPT2046_X_MIN);
|
||||
|
||||
(*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) /
|
||||
(XPT2046_Y_MAX - XPT2046_Y_MIN);
|
||||
|
||||
#if XPT2046_X_INV != 0
|
||||
(*x) = XPT2046_HOR_RES - (*x);
|
||||
#endif
|
||||
|
||||
#if XPT2046_Y_INV != 0
|
||||
(*y) = XPT2046_VER_RES - (*y);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void xpt2046_avg(int16_t * x, int16_t * y)
|
||||
{
|
||||
/*Shift out the oldest data*/
|
||||
uint8_t i;
|
||||
for(i = XPT2046_AVG - 1; i > 0 ; i--) {
|
||||
avg_buf_x[i] = avg_buf_x[i - 1];
|
||||
avg_buf_y[i] = avg_buf_y[i - 1];
|
||||
}
|
||||
|
||||
/*Insert the new point*/
|
||||
avg_buf_x[0] = *x;
|
||||
avg_buf_y[0] = *y;
|
||||
if(avg_last < XPT2046_AVG) avg_last++;
|
||||
|
||||
/*Sum the x and y coordinates*/
|
||||
int32_t x_sum = 0;
|
||||
int32_t y_sum = 0;
|
||||
for(i = 0; i < avg_last ; i++) {
|
||||
x_sum += avg_buf_x[i];
|
||||
y_sum += avg_buf_y[i];
|
||||
}
|
||||
|
||||
/*Normalize the sums*/
|
||||
(*x) = (int32_t)x_sum / avg_last;
|
||||
(*y) = (int32_t)y_sum / avg_last;
|
||||
}
|
||||
|
||||
#endif
|
||||
56
libs/lv_drivers/indev/XPT2046.h
Normal file
56
libs/lv_drivers/indev/XPT2046.h
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file XPT2046.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XPT2046_H
|
||||
#define XPT2046_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_XPT2046
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void xpt2046_init(void);
|
||||
bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_XPT2046 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* XPT2046_H */
|
||||
251
libs/lv_drivers/indev/evdev.c
Normal file
251
libs/lv_drivers/indev/evdev.c
Normal file
@ -0,0 +1,251 @@
|
||||
/**
|
||||
* @file evdev.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "evdev.h"
|
||||
#if USE_EVDEV != 0 || USE_BSD_EVDEV
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#if USE_BSD_EVDEV
|
||||
#include <dev/evdev/input.h>
|
||||
#else
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
#if USE_XKB
|
||||
#include "xkb.h"
|
||||
#endif /* USE_XKB */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
int map(int x, int in_min, int in_max, int out_min, int out_max);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
int evdev_fd = -1;
|
||||
int evdev_root_x;
|
||||
int evdev_root_y;
|
||||
int evdev_button;
|
||||
|
||||
int evdev_key_val;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the evdev interface
|
||||
*/
|
||||
void evdev_init(void)
|
||||
{
|
||||
if (!evdev_set_file(EVDEV_NAME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if USE_XKB
|
||||
xkb_init();
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* reconfigure the device file for evdev
|
||||
* @param dev_name set the evdev device filename
|
||||
* @return true: the device file set complete
|
||||
* false: the device file doesn't exist current system
|
||||
*/
|
||||
bool evdev_set_file(char* dev_name)
|
||||
{
|
||||
if(evdev_fd != -1) {
|
||||
close(evdev_fd);
|
||||
}
|
||||
#if USE_BSD_EVDEV
|
||||
evdev_fd = open(dev_name, O_RDWR | O_NOCTTY);
|
||||
#else
|
||||
evdev_fd = open(dev_name, O_RDWR | O_NOCTTY | O_NDELAY);
|
||||
#endif
|
||||
|
||||
if(evdev_fd == -1) {
|
||||
perror("unable to open evdev interface:");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if USE_BSD_EVDEV
|
||||
fcntl(evdev_fd, F_SETFL, O_NONBLOCK);
|
||||
#else
|
||||
fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
evdev_root_x = 0;
|
||||
evdev_root_y = 0;
|
||||
evdev_key_val = 0;
|
||||
evdev_button = LV_INDEV_STATE_REL;
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Get the current position and state of the evdev
|
||||
* @param data store the evdev data here
|
||||
*/
|
||||
void evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
struct input_event in;
|
||||
|
||||
while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {
|
||||
if(in.type == EV_REL) {
|
||||
if(in.code == REL_X)
|
||||
#if EVDEV_SWAP_AXES
|
||||
evdev_root_y += in.value;
|
||||
#else
|
||||
evdev_root_x += in.value;
|
||||
#endif
|
||||
else if(in.code == REL_Y)
|
||||
#if EVDEV_SWAP_AXES
|
||||
evdev_root_x += in.value;
|
||||
#else
|
||||
evdev_root_y += in.value;
|
||||
#endif
|
||||
} else if(in.type == EV_ABS) {
|
||||
if(in.code == ABS_X)
|
||||
#if EVDEV_SWAP_AXES
|
||||
evdev_root_y = in.value;
|
||||
#else
|
||||
evdev_root_x = in.value;
|
||||
#endif
|
||||
else if(in.code == ABS_Y)
|
||||
#if EVDEV_SWAP_AXES
|
||||
evdev_root_x = in.value;
|
||||
#else
|
||||
evdev_root_y = in.value;
|
||||
#endif
|
||||
else if(in.code == ABS_MT_POSITION_X)
|
||||
#if EVDEV_SWAP_AXES
|
||||
evdev_root_y = in.value;
|
||||
#else
|
||||
evdev_root_x = in.value;
|
||||
#endif
|
||||
else if(in.code == ABS_MT_POSITION_Y)
|
||||
#if EVDEV_SWAP_AXES
|
||||
evdev_root_x = in.value;
|
||||
#else
|
||||
evdev_root_y = in.value;
|
||||
#endif
|
||||
else if(in.code == ABS_MT_TRACKING_ID) {
|
||||
if(in.value == -1)
|
||||
evdev_button = LV_INDEV_STATE_REL;
|
||||
else if(in.value == 0)
|
||||
evdev_button = LV_INDEV_STATE_PR;
|
||||
}
|
||||
} else if(in.type == EV_KEY) {
|
||||
if(in.code == BTN_MOUSE || in.code == BTN_TOUCH) {
|
||||
if(in.value == 0)
|
||||
evdev_button = LV_INDEV_STATE_REL;
|
||||
else if(in.value == 1)
|
||||
evdev_button = LV_INDEV_STATE_PR;
|
||||
} else if(drv->type == LV_INDEV_TYPE_KEYPAD) {
|
||||
#if USE_XKB
|
||||
data->key = xkb_process_key(in.code, in.value != 0);
|
||||
#else
|
||||
switch(in.code) {
|
||||
case KEY_BACKSPACE:
|
||||
data->key = LV_KEY_BACKSPACE;
|
||||
break;
|
||||
case KEY_ENTER:
|
||||
data->key = LV_KEY_ENTER;
|
||||
break;
|
||||
case KEY_PREVIOUS:
|
||||
data->key = LV_KEY_PREV;
|
||||
break;
|
||||
case KEY_NEXT:
|
||||
data->key = LV_KEY_NEXT;
|
||||
break;
|
||||
case KEY_UP:
|
||||
data->key = LV_KEY_UP;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
data->key = LV_KEY_LEFT;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
data->key = LV_KEY_RIGHT;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
data->key = LV_KEY_DOWN;
|
||||
break;
|
||||
case KEY_TAB:
|
||||
data->key = LV_KEY_NEXT;
|
||||
break;
|
||||
default:
|
||||
data->key = 0;
|
||||
break;
|
||||
}
|
||||
#endif /* USE_XKB */
|
||||
if (data->key != 0) {
|
||||
/* Only record button state when actual output is produced to prevent widgets from refreshing */
|
||||
data->state = (in.value) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
}
|
||||
evdev_key_val = data->key;
|
||||
evdev_button = data->state;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(drv->type == LV_INDEV_TYPE_KEYPAD) {
|
||||
/* No data retrieved */
|
||||
data->key = evdev_key_val;
|
||||
data->state = evdev_button;
|
||||
return;
|
||||
}
|
||||
if(drv->type != LV_INDEV_TYPE_POINTER)
|
||||
return ;
|
||||
/*Store the collected data*/
|
||||
|
||||
#if EVDEV_CALIBRATE
|
||||
data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX, 0, drv->disp->driver->hor_res);
|
||||
data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX, 0, drv->disp->driver->ver_res);
|
||||
#else
|
||||
data->point.x = evdev_root_x;
|
||||
data->point.y = evdev_root_y;
|
||||
#endif
|
||||
|
||||
data->state = evdev_button;
|
||||
|
||||
if(data->point.x < 0)
|
||||
data->point.x = 0;
|
||||
if(data->point.y < 0)
|
||||
data->point.y = 0;
|
||||
if(data->point.x >= drv->disp->driver->hor_res)
|
||||
data->point.x = drv->disp->driver->hor_res - 1;
|
||||
if(data->point.y >= drv->disp->driver->ver_res)
|
||||
data->point.y = drv->disp->driver->ver_res - 1;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
int map(int x, int in_min, int in_max, int out_min, int out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
#endif
|
||||
72
libs/lv_drivers/indev/evdev.h
Normal file
72
libs/lv_drivers/indev/evdev.h
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file evdev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EVDEV_H
|
||||
#define EVDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_EVDEV || USE_BSD_EVDEV
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the evdev
|
||||
*/
|
||||
void evdev_init(void);
|
||||
/**
|
||||
* reconfigure the device file for evdev
|
||||
* @param dev_name set the evdev device filename
|
||||
* @return true: the device file set complete
|
||||
* false: the device file doesn't exist current system
|
||||
*/
|
||||
bool evdev_set_file(char* dev_name);
|
||||
/**
|
||||
* Get the current position and state of the evdev
|
||||
* @param data store the evdev data here
|
||||
*/
|
||||
void evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_EVDEV */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* EVDEV_H */
|
||||
81
libs/lv_drivers/indev/keyboard.h
Normal file
81
libs/lv_drivers/indev/keyboard.h
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @file keyboard.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef KEYBOARD_H
|
||||
#define KEYBOARD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_KEYBOARD
|
||||
|
||||
#warning "Deprecated, use the SDL driver instead. See lv_drivers/sdl/sdl.c"
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if USE_SDL_GPU
|
||||
#include "../sdl/sdl_gpu.h"
|
||||
#else
|
||||
#include "../sdl/sdl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the keyboard
|
||||
*/
|
||||
static inline void keyboard_init(void)
|
||||
{
|
||||
/*Nothing to do*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last pressed or released character from the PC's keyboard
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the read data here
|
||||
*/
|
||||
static inline void keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
sdl_keyboard_read(indev_drv, data);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_KEYBOARD*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*KEYBOARD_H*/
|
||||
501
libs/lv_drivers/indev/libinput.c
Normal file
501
libs/lv_drivers/indev/libinput.c
Normal file
@ -0,0 +1,501 @@
|
||||
/**
|
||||
* @file libinput.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "libinput_drv.h"
|
||||
#if USE_LIBINPUT || USE_BSD_LIBINPUT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <dirent.h>
|
||||
#include <libinput.h>
|
||||
|
||||
#if USE_BSD_LIBINPUT
|
||||
#include <dev/evdev/input.h>
|
||||
#else
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct input_device {
|
||||
libinput_capability capabilities;
|
||||
char *path;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool rescan_devices(void);
|
||||
static bool add_scanned_device(char *path, libinput_capability capabilities);
|
||||
static void reset_scanned_devices(void);
|
||||
|
||||
static void read_pointer(libinput_drv_state_t *state, struct libinput_event *event);
|
||||
static void read_keypad(libinput_drv_state_t *state, struct libinput_event *event);
|
||||
|
||||
static int open_restricted(const char *path, int flags, void *user_data);
|
||||
static void close_restricted(int fd, void *user_data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static struct input_device *devices = NULL;
|
||||
static size_t num_devices = 0;
|
||||
|
||||
static libinput_drv_state_t default_state = { .most_recent_touch_point = { .x = 0, .y = 0 } };
|
||||
|
||||
static const int timeout = 0; // do not block
|
||||
static const nfds_t nfds = 1;
|
||||
|
||||
static const struct libinput_interface interface = {
|
||||
.open_restricted = open_restricted,
|
||||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* find connected input device with specific capabilities
|
||||
* @param capabilities required device capabilities
|
||||
* @param force_rescan erase the device cache (if any) and rescan the file system for available devices
|
||||
* @return device node path (e.g. /dev/input/event0) for the first matching device or NULL if no device was found.
|
||||
* The pointer is safe to use until the next forceful device search.
|
||||
*/
|
||||
char *libinput_find_dev(libinput_capability capabilities, bool force_rescan) {
|
||||
char *path = NULL;
|
||||
libinput_find_devs(capabilities, &path, 1, force_rescan);
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* find connected input devices with specific capabilities
|
||||
* @param capabilities required device capabilities
|
||||
* @param devices pre-allocated array to store the found device node paths (e.g. /dev/input/event0). The pointers are
|
||||
* safe to use until the next forceful device search.
|
||||
* @param count maximum number of devices to find (the devices array should be at least this long)
|
||||
* @param force_rescan erase the device cache (if any) and rescan the file system for available devices
|
||||
* @return number of devices that were found
|
||||
*/
|
||||
size_t libinput_find_devs(libinput_capability capabilities, char **found, size_t count, bool force_rescan) {
|
||||
if ((!devices || force_rescan) && !rescan_devices()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t num_found = 0;
|
||||
|
||||
for (size_t i = 0; i < num_devices && num_found < count; ++i) {
|
||||
if (devices[i].capabilities & capabilities) {
|
||||
found[num_found] = devices[i].path;
|
||||
num_found++;
|
||||
}
|
||||
}
|
||||
|
||||
return num_found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconfigure the device file for libinput using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
* @param dev_name input device node path (e.g. /dev/input/event0)
|
||||
* @return true: the device file set complete
|
||||
* false: the device file doesn't exist current system
|
||||
*/
|
||||
bool libinput_set_file(char* dev_name)
|
||||
{
|
||||
return libinput_set_file_state(&default_state, dev_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconfigure the device file for libinput using a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state the driver state to configure
|
||||
* @param dev_name input device node path (e.g. /dev/input/event0)
|
||||
* @return true: the device file set complete
|
||||
* false: the device file doesn't exist current system
|
||||
*/
|
||||
bool libinput_set_file_state(libinput_drv_state_t *state, char* dev_name)
|
||||
{
|
||||
// This check *should* not be necessary, yet applications crashes even on NULL handles.
|
||||
// citing libinput.h:libinput_path_remove_device:
|
||||
// > If no matching device exists, this function does nothing.
|
||||
if (state->libinput_device) {
|
||||
state->libinput_device = libinput_device_unref(state->libinput_device);
|
||||
libinput_path_remove_device(state->libinput_device);
|
||||
}
|
||||
|
||||
state->libinput_device = libinput_path_add_device(state->libinput_context, dev_name);
|
||||
if(!state->libinput_device) {
|
||||
perror("unable to add device to libinput context:");
|
||||
return false;
|
||||
}
|
||||
state->libinput_device = libinput_device_ref(state->libinput_device);
|
||||
if(!state->libinput_device) {
|
||||
perror("unable to reference device within libinput context:");
|
||||
return false;
|
||||
}
|
||||
|
||||
state->button = LV_INDEV_STATE_REL;
|
||||
state->key_val = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for reading input via libinput using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
*/
|
||||
void libinput_init(void)
|
||||
{
|
||||
libinput_init_state(&default_state, LIBINPUT_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for reading input via libinput using the a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state driver state to initialize
|
||||
* @param path input device node path (e.g. /dev/input/event0)
|
||||
*/
|
||||
void libinput_init_state(libinput_drv_state_t *state, char* path)
|
||||
{
|
||||
state->libinput_device = NULL;
|
||||
state->libinput_context = libinput_path_create_context(&interface, NULL);
|
||||
|
||||
if(path == NULL || !libinput_set_file_state(state, path)) {
|
||||
fprintf(stderr, "unable to add device \"%s\" to libinput context: %s\n", path ? path : "NULL", strerror(errno));
|
||||
return;
|
||||
}
|
||||
state->fd = libinput_get_fd(state->libinput_context);
|
||||
|
||||
/* prepare poll */
|
||||
state->fds[0].fd = state->fd;
|
||||
state->fds[0].events = POLLIN;
|
||||
state->fds[0].revents = 0;
|
||||
|
||||
#if USE_XKB
|
||||
xkb_init_state(&(state->xkb_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Read available input events via libinput using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
* @param indev_drv driver object itself
|
||||
* @param data store the libinput data here
|
||||
*/
|
||||
void libinput_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
libinput_read_state(&default_state, indev_drv, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read available input events via libinput using a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state the driver state to use
|
||||
* @param indev_drv driver object itself
|
||||
* @param data store the libinput data here
|
||||
*/
|
||||
void libinput_read_state(libinput_drv_state_t * state, lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
struct libinput_event *event;
|
||||
int rc = 0;
|
||||
|
||||
rc = poll(state->fds, nfds, timeout);
|
||||
switch (rc){
|
||||
case -1:
|
||||
perror(NULL);
|
||||
case 0:
|
||||
goto report_most_recent_state;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
libinput_dispatch(state->libinput_context);
|
||||
while((event = libinput_get_event(state->libinput_context)) != NULL) {
|
||||
switch (indev_drv->type) {
|
||||
case LV_INDEV_TYPE_POINTER:
|
||||
read_pointer(state, event);
|
||||
break;
|
||||
case LV_INDEV_TYPE_KEYPAD:
|
||||
read_keypad(state, event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
report_most_recent_state:
|
||||
data->point.x = state->most_recent_touch_point.x;
|
||||
data->point.y = state->most_recent_touch_point.y;
|
||||
data->state = state->button;
|
||||
data->key = state->key_val;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* rescan all attached evdev devices and store capable ones into the static devices array for quick later filtering
|
||||
* @return true if the operation succeeded
|
||||
*/
|
||||
static bool rescan_devices(void) {
|
||||
reset_scanned_devices();
|
||||
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
if (!(dir = opendir("/dev/input"))) {
|
||||
perror("unable to open directory /dev/input");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct libinput *context = libinput_path_create_context(&interface, NULL);
|
||||
|
||||
while ((ent = readdir(dir))) {
|
||||
if (strncmp(ent->d_name, "event", 5) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 11 characters for /dev/input/ + length of name + 1 NUL terminator */
|
||||
char *path = malloc((11 + strlen(ent->d_name) + 1) * sizeof(char));
|
||||
if (!path) {
|
||||
perror("could not allocate memory for device node path");
|
||||
libinput_unref(context);
|
||||
reset_scanned_devices();
|
||||
return false;
|
||||
}
|
||||
strcpy(path, "/dev/input/");
|
||||
strcat(path, ent->d_name);
|
||||
|
||||
struct libinput_device *device = libinput_path_add_device(context, path);
|
||||
if(!device) {
|
||||
perror("unable to add device to libinput context");
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The device pointer is guaranteed to be valid until the next libinput_dispatch. Since we're not dispatching events
|
||||
* as part of this function, we don't have to increase its reference count to keep it alive.
|
||||
* https://wayland.freedesktop.org/libinput/doc/latest/api/group__base.html#gaa797496f0150b482a4e01376bd33a47b */
|
||||
|
||||
libinput_capability capabilities = LIBINPUT_CAPABILITY_NONE;
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD)
|
||||
&& (libinput_device_keyboard_has_key(device, KEY_ENTER) || libinput_device_keyboard_has_key(device, KEY_KPENTER)))
|
||||
{
|
||||
capabilities |= LIBINPUT_CAPABILITY_KEYBOARD;
|
||||
}
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) {
|
||||
capabilities |= LIBINPUT_CAPABILITY_POINTER;
|
||||
}
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH)) {
|
||||
capabilities |= LIBINPUT_CAPABILITY_TOUCH;
|
||||
}
|
||||
|
||||
libinput_path_remove_device(device);
|
||||
|
||||
if (capabilities == LIBINPUT_CAPABILITY_NONE) {
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!add_scanned_device(path, capabilities)) {
|
||||
free(path);
|
||||
libinput_unref(context);
|
||||
reset_scanned_devices();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
libinput_unref(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a new scanned device to the static devices array, growing its size when necessary
|
||||
* @param path device file path
|
||||
* @param capabilities device input capabilities
|
||||
* @return true if the operation succeeded
|
||||
*/
|
||||
static bool add_scanned_device(char *path, libinput_capability capabilities) {
|
||||
/* Double array size every 2^n elements */
|
||||
if ((num_devices & (num_devices + 1)) == 0) {
|
||||
struct input_device *tmp = realloc(devices, (2 * num_devices + 1) * sizeof(struct input_device));
|
||||
if (!tmp) {
|
||||
perror("could not reallocate memory for devices array");
|
||||
return false;
|
||||
}
|
||||
devices = tmp;
|
||||
}
|
||||
|
||||
devices[num_devices].path = path;
|
||||
devices[num_devices].capabilities = capabilities;
|
||||
num_devices++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset the array of scanned devices and free any dynamically allocated memory
|
||||
*/
|
||||
static void reset_scanned_devices(void) {
|
||||
if (!devices) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_devices; ++i) {
|
||||
free(devices[i].path);
|
||||
}
|
||||
free(devices);
|
||||
|
||||
devices = NULL;
|
||||
num_devices = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle libinput touch / pointer events
|
||||
* @param state driver state to use
|
||||
* @param event libinput event
|
||||
*/
|
||||
static void read_pointer(libinput_drv_state_t *state, struct libinput_event *event) {
|
||||
struct libinput_event_touch *touch_event = NULL;
|
||||
struct libinput_event_pointer *pointer_event = NULL;
|
||||
enum libinput_event_type type = libinput_event_get_type(event);
|
||||
|
||||
/* We need to read unrotated display dimensions directly from the driver because libinput won't account
|
||||
* for any rotation inside of LVGL */
|
||||
lv_disp_drv_t *drv = lv_disp_get_default()->driver;
|
||||
|
||||
switch (type) {
|
||||
case LIBINPUT_EVENT_TOUCH_MOTION:
|
||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||||
touch_event = libinput_event_get_touch_event(event);
|
||||
lv_coord_t x_touch = libinput_event_touch_get_x_transformed(touch_event, drv->physical_hor_res > 0 ? drv->physical_hor_res : drv->hor_res) - drv->offset_x;
|
||||
lv_coord_t y_touch = libinput_event_touch_get_y_transformed(touch_event, drv->physical_ver_res > 0 ? drv->physical_ver_res : drv->ver_res) - drv->offset_y;
|
||||
if (x_touch < 0 || x_touch > drv->hor_res || y_touch < 0 || y_touch > drv->ver_res) {
|
||||
break; /* ignore touches that are out of bounds */
|
||||
}
|
||||
state->most_recent_touch_point.x = x_touch;
|
||||
state->most_recent_touch_point.y = y_touch;
|
||||
state->button = LV_INDEV_STATE_PR;
|
||||
break;
|
||||
case LIBINPUT_EVENT_TOUCH_UP:
|
||||
state->button = LV_INDEV_STATE_REL;
|
||||
break;
|
||||
case LIBINPUT_EVENT_POINTER_MOTION:
|
||||
pointer_event = libinput_event_get_pointer_event(event);
|
||||
state->most_recent_touch_point.x += libinput_event_pointer_get_dx(pointer_event);
|
||||
state->most_recent_touch_point.y += libinput_event_pointer_get_dy(pointer_event);
|
||||
state->most_recent_touch_point.x = LV_CLAMP(0, state->most_recent_touch_point.x, drv->hor_res - 1);
|
||||
state->most_recent_touch_point.y = LV_CLAMP(0, state->most_recent_touch_point.y, drv->ver_res - 1);
|
||||
break;
|
||||
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
|
||||
pointer_event = libinput_event_get_pointer_event(event);
|
||||
lv_coord_t x_pointer = libinput_event_pointer_get_absolute_x_transformed(pointer_event, drv->physical_hor_res > 0 ? drv->physical_hor_res : drv->hor_res) - drv->offset_x;
|
||||
lv_coord_t y_pointer = libinput_event_pointer_get_absolute_y_transformed(pointer_event, drv->physical_ver_res > 0 ? drv->physical_ver_res : drv->ver_res) - drv->offset_y;
|
||||
if (x_pointer < 0 || x_pointer > drv->hor_res || y_pointer < 0 || y_pointer > drv->ver_res) {
|
||||
break; /* ignore pointer events that are out of bounds */
|
||||
}
|
||||
state->most_recent_touch_point.x = x_pointer;
|
||||
state->most_recent_touch_point.y = y_pointer;
|
||||
break;
|
||||
case LIBINPUT_EVENT_POINTER_BUTTON:
|
||||
pointer_event = libinput_event_get_pointer_event(event);
|
||||
enum libinput_button_state button_state = libinput_event_pointer_get_button_state(pointer_event);
|
||||
state->button = button_state == LIBINPUT_BUTTON_STATE_RELEASED ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle libinput keyboard events
|
||||
* @param state driver state to use
|
||||
* @param event libinput event
|
||||
*/
|
||||
static void read_keypad(libinput_drv_state_t *state, struct libinput_event *event) {
|
||||
struct libinput_event_keyboard *keyboard_event = NULL;
|
||||
enum libinput_event_type type = libinput_event_get_type(event);
|
||||
switch (type) {
|
||||
case LIBINPUT_EVENT_KEYBOARD_KEY:
|
||||
keyboard_event = libinput_event_get_keyboard_event(event);
|
||||
enum libinput_key_state key_state = libinput_event_keyboard_get_key_state(keyboard_event);
|
||||
uint32_t code = libinput_event_keyboard_get_key(keyboard_event);
|
||||
#if USE_XKB
|
||||
state->key_val = xkb_process_key_state(&(state->xkb_state), code, key_state == LIBINPUT_KEY_STATE_PRESSED);
|
||||
#else
|
||||
switch(code) {
|
||||
case KEY_BACKSPACE:
|
||||
state->key_val = LV_KEY_BACKSPACE;
|
||||
break;
|
||||
case KEY_ENTER:
|
||||
state->key_val = LV_KEY_ENTER;
|
||||
break;
|
||||
case KEY_PREVIOUS:
|
||||
state->key_val = LV_KEY_PREV;
|
||||
break;
|
||||
case KEY_NEXT:
|
||||
state->key_val = LV_KEY_NEXT;
|
||||
break;
|
||||
case KEY_UP:
|
||||
state->key_val = LV_KEY_UP;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
state->key_val = LV_KEY_LEFT;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
state->key_val = LV_KEY_RIGHT;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
state->key_val = LV_KEY_DOWN;
|
||||
break;
|
||||
case KEY_TAB:
|
||||
state->key_val = LV_KEY_NEXT;
|
||||
break;
|
||||
default:
|
||||
state->key_val = 0;
|
||||
break;
|
||||
}
|
||||
#endif /* USE_XKB */
|
||||
if (state->key_val != 0) {
|
||||
/* Only record button state when actual output is produced to prevent widgets from refreshing */
|
||||
state->button = (key_state == LIBINPUT_KEY_STATE_RELEASED) ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int open_restricted(const char *path, int flags, void *user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
int fd = open(path, flags);
|
||||
return fd < 0 ? -errno : fd;
|
||||
}
|
||||
|
||||
static void close_restricted(int fd, void *user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#endif /* USE_LIBINPUT || USE_BSD_LIBINPUT */
|
||||
145
libs/lv_drivers/indev/libinput_drv.h
Normal file
145
libs/lv_drivers/indev/libinput_drv.h
Normal file
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @file libinput.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LVGL_LIBINPUT_H
|
||||
#define LVGL_LIBINPUT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_LIBINPUT || USE_BSD_LIBINPUT
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
#if USE_XKB
|
||||
#include "xkb.h"
|
||||
#endif /* USE_XKB */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef enum {
|
||||
LIBINPUT_CAPABILITY_NONE = 0,
|
||||
LIBINPUT_CAPABILITY_KEYBOARD = 1U << 0,
|
||||
LIBINPUT_CAPABILITY_POINTER = 1U << 1,
|
||||
LIBINPUT_CAPABILITY_TOUCH = 1U << 2
|
||||
} libinput_capability;
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
struct pollfd fds[1];
|
||||
|
||||
int button;
|
||||
int key_val;
|
||||
lv_point_t most_recent_touch_point;
|
||||
|
||||
struct libinput *libinput_context;
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
#if USE_XKB
|
||||
xkb_drv_state_t xkb_state;
|
||||
#endif /* USE_XKB */
|
||||
} libinput_drv_state_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* find connected input device with specific capabilities
|
||||
* @param capabilities required device capabilities
|
||||
* @param force_rescan erase the device cache (if any) and rescan the file system for available devices
|
||||
* @return device node path (e.g. /dev/input/event0) for the first matching device or NULL if no device was found.
|
||||
* The pointer is safe to use until the next forceful device search.
|
||||
*/
|
||||
char *libinput_find_dev(libinput_capability capabilities, bool force_rescan);
|
||||
/**
|
||||
* find connected input devices with specific capabilities
|
||||
* @param capabilities required device capabilities
|
||||
* @param devices pre-allocated array to store the found device node paths (e.g. /dev/input/event0). The pointers are
|
||||
* safe to use until the next forceful device search.
|
||||
* @param count maximum number of devices to find (the devices array should be at least this long)
|
||||
* @param force_rescan erase the device cache (if any) and rescan the file system for available devices
|
||||
* @return number of devices that were found
|
||||
*/
|
||||
size_t libinput_find_devs(libinput_capability capabilities, char **found, size_t count, bool force_rescan);
|
||||
/**
|
||||
* Prepare for reading input via libinput using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
*/
|
||||
void libinput_init(void);
|
||||
/**
|
||||
* Prepare for reading input via libinput using a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state driver state to initialize
|
||||
* @param path input device node path (e.g. /dev/input/event0)
|
||||
*/
|
||||
void libinput_init_state(libinput_drv_state_t *state, char* path);
|
||||
/**
|
||||
* Reconfigure the device file for libinput using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
* @param dev_name input device node path (e.g. /dev/input/event0)
|
||||
* @return true: the device file set complete
|
||||
* false: the device file doesn't exist current system
|
||||
*/
|
||||
bool libinput_set_file(char* dev_name);
|
||||
/**
|
||||
* Reconfigure the device file for libinput using a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state the driver state to configure
|
||||
* @param dev_name input device node path (e.g. /dev/input/event0)
|
||||
* @return true: the device file set complete
|
||||
* false: the device file doesn't exist current system
|
||||
*/
|
||||
bool libinput_set_file_state(libinput_drv_state_t *state, char* dev_name);
|
||||
/**
|
||||
* Read available input events via libinput using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
* @param indev_drv driver object itself
|
||||
* @param data store the libinput data here
|
||||
*/
|
||||
void libinput_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
/**
|
||||
* Read available input events via libinput using a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state the driver state to use
|
||||
* @param indev_drv driver object itself
|
||||
* @param data store the libinput data here
|
||||
*/
|
||||
void libinput_read_state(libinput_drv_state_t * state, lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_LIBINPUT || USE_BSD_LIBINPUT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LVGL_LIBINPUT_H */
|
||||
81
libs/lv_drivers/indev/mouse.h
Normal file
81
libs/lv_drivers/indev/mouse.h
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @file mouse.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MOUSE_H
|
||||
#define MOUSE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_MOUSE
|
||||
|
||||
#warning "Deprecated, use the SDL driver instead. See lv_drivers/sdl/sdl.c"
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if USE_SDL_GPU
|
||||
#include "../sdl/sdl_gpu.h"
|
||||
#else
|
||||
#include "../sdl/sdl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the mouse
|
||||
*/
|
||||
static inline void mouse_init(void)
|
||||
{
|
||||
/*Nothing to do*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position and state of the mouse
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the mouse data here
|
||||
*/
|
||||
void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
sdl_mouse_read(indev_drv, data);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_MOUSE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* MOUSE_H */
|
||||
80
libs/lv_drivers/indev/mousewheel.h
Normal file
80
libs/lv_drivers/indev/mousewheel.h
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @file mousewheel.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MOUSEWHEEL_H
|
||||
#define MOUSEWHEEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_MOUSEWHEEL
|
||||
|
||||
#warning "Deprecated, use the SDL driver instead. See lv_drivers/sdl/sdl.c"
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if USE_SDL_GPU
|
||||
#include "../sdl/sdl_gpu.h"
|
||||
#else
|
||||
#include "../sdl/sdl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the encoder
|
||||
*/
|
||||
static inline void mousewheel_init(void)
|
||||
{
|
||||
/*Nothing to do*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the read data here
|
||||
*/
|
||||
static inline void mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
sdl_mousewheel_read(indev_drv, data);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_MOUSEWHEEL*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*MOUSEWHEEL_H*/
|
||||
217
libs/lv_drivers/indev/xkb.c
Normal file
217
libs/lv_drivers/indev/xkb.c
Normal file
@ -0,0 +1,217 @@
|
||||
/**
|
||||
* @file xkb.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "xkb.h"
|
||||
#if USE_XKB
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static struct xkb_context *context = NULL;
|
||||
static xkb_drv_state_t default_state = { .keymap = NULL, .state = NULL };
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialise the XKB system using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
* @return true if the initialisation was successful
|
||||
*/
|
||||
bool xkb_init(void) {
|
||||
return xkb_init_state(&default_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the XKB system using a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state XKB driver state to use
|
||||
* @return true if the initialisation was successful
|
||||
*/
|
||||
bool xkb_init_state(xkb_drv_state_t *state) {
|
||||
if (!context) {
|
||||
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!context) {
|
||||
perror("could not create new XKB context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XKB_KEY_MAP
|
||||
struct xkb_rule_names names = XKB_KEY_MAP;
|
||||
return xkb_set_keymap_state(state, names);
|
||||
#else
|
||||
return false; /* Keymap needs to be set manually using xkb_set_keymap_state to complete initialisation */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new keymap to be used for processing future key events using the default driver state. Use
|
||||
* this function if you only want to connect a single device.
|
||||
* @param names XKB rule names structure (use NULL components for default values)
|
||||
* @return true if creating the keymap and associated state succeeded
|
||||
*/
|
||||
bool xkb_set_keymap(struct xkb_rule_names names) {
|
||||
return xkb_set_keymap_state(&default_state, names);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new keymap to be used for processing future key events using a specific driver state. Use
|
||||
* this function if you want to connect multiple devices.
|
||||
* @param state XKB driver state to use
|
||||
* @param names XKB rule names structure (use NULL components for default values)
|
||||
* @return true if creating the keymap and associated state succeeded
|
||||
*/
|
||||
bool xkb_set_keymap_state(xkb_drv_state_t *state, struct xkb_rule_names names) {
|
||||
if (state->keymap) {
|
||||
xkb_keymap_unref(state->keymap);
|
||||
state->keymap = NULL;
|
||||
}
|
||||
|
||||
state->keymap = xkb_keymap_new_from_names(context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if (!state->keymap) {
|
||||
perror("could not create XKB keymap");
|
||||
return false;
|
||||
}
|
||||
|
||||
state->keymap = xkb_keymap_ref(state->keymap);
|
||||
if (!state->keymap) {
|
||||
perror("could not reference XKB keymap");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state->state) {
|
||||
xkb_state_unref(state->state);
|
||||
state->state = NULL;
|
||||
}
|
||||
|
||||
state->state = xkb_state_new(state->keymap);
|
||||
if (!state->state) {
|
||||
perror("could not create XKB state");
|
||||
return false;
|
||||
}
|
||||
|
||||
state->state = xkb_state_ref(state->state);
|
||||
if (!state->state) {
|
||||
perror("could not reference XKB state");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an evdev scancode using the default driver state. Use this function if you only want to
|
||||
* connect a single device.
|
||||
* @param scancode evdev scancode to process
|
||||
* @param down true if the key was pressed, false if it was releases
|
||||
* @return the (first) UTF-8 character produced by the event or 0 if no output was produced
|
||||
*/
|
||||
uint32_t xkb_process_key(uint32_t scancode, bool down) {
|
||||
return xkb_process_key_state(&default_state, scancode, down);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an evdev scancode using a specific driver state. Use this function if you want to connect
|
||||
* multiple devices.
|
||||
* @param state XKB driver state to use
|
||||
* @param scancode evdev scancode to process
|
||||
* @param down true if the key was pressed, false if it was releases
|
||||
* @return the (first) UTF-8 character produced by the event or 0 if no output was produced
|
||||
*/
|
||||
uint32_t xkb_process_key_state(xkb_drv_state_t *state, uint32_t scancode, bool down) {
|
||||
/* Offset the evdev scancode by 8, see https://xkbcommon.org/doc/current/xkbcommon_8h.html#ac29aee92124c08d1953910ab28ee1997 */
|
||||
xkb_keycode_t keycode = scancode + 8;
|
||||
|
||||
uint32_t result = 0;
|
||||
|
||||
switch (xkb_state_key_get_one_sym(state->state, keycode)) {
|
||||
case XKB_KEY_BackSpace:
|
||||
result = LV_KEY_BACKSPACE;
|
||||
break;
|
||||
case XKB_KEY_Return:
|
||||
case XKB_KEY_KP_Enter:
|
||||
result = LV_KEY_ENTER;
|
||||
break;
|
||||
case XKB_KEY_Prior:
|
||||
case XKB_KEY_KP_Prior:
|
||||
result = LV_KEY_PREV;
|
||||
break;
|
||||
case XKB_KEY_Next:
|
||||
case XKB_KEY_KP_Next:
|
||||
result = LV_KEY_NEXT;
|
||||
break;
|
||||
case XKB_KEY_Up:
|
||||
case XKB_KEY_KP_Up:
|
||||
result = LV_KEY_UP;
|
||||
break;
|
||||
case XKB_KEY_Left:
|
||||
case XKB_KEY_KP_Left:
|
||||
result = LV_KEY_LEFT;
|
||||
break;
|
||||
case XKB_KEY_Right:
|
||||
case XKB_KEY_KP_Right:
|
||||
result = LV_KEY_RIGHT;
|
||||
break;
|
||||
case XKB_KEY_Down:
|
||||
case XKB_KEY_KP_Down:
|
||||
result = LV_KEY_DOWN;
|
||||
break;
|
||||
case XKB_KEY_Tab:
|
||||
case XKB_KEY_KP_Tab:
|
||||
result = LV_KEY_NEXT;
|
||||
break;
|
||||
case XKB_KEY_ISO_Left_Tab: /* Sent on SHIFT + TAB */
|
||||
result = LV_KEY_PREV;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
char buffer[4] = { 0, 0, 0, 0 };
|
||||
int size = xkb_state_key_get_utf8(state->state, keycode, NULL, 0) + 1;
|
||||
if (size > 1) {
|
||||
xkb_state_key_get_utf8(state->state, keycode, buffer, size);
|
||||
memcpy(&result, buffer, 4);
|
||||
}
|
||||
}
|
||||
|
||||
xkb_state_update_key(state->state, keycode, down ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_XKB */
|
||||
106
libs/lv_drivers/indev/xkb.h
Normal file
106
libs/lv_drivers/indev/xkb.h
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file xkb.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XKB_H
|
||||
#define XKB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_XKB
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct xkb_rule_names;
|
||||
|
||||
typedef struct {
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
} xkb_drv_state_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialise the XKB system using the default driver state. Use this function if you only want
|
||||
* to connect a single device.
|
||||
* @return true if the initialisation was successful
|
||||
*/
|
||||
bool xkb_init(void);
|
||||
/**
|
||||
* Initialise the XKB system using a specific driver state. Use this function if you want to
|
||||
* connect multiple devices.
|
||||
* @param state XKB driver state to use
|
||||
* @return true if the initialisation was successful
|
||||
*/
|
||||
bool xkb_init_state(xkb_drv_state_t *state);
|
||||
/**
|
||||
* Set a new keymap to be used for processing future key events using the default driver state. Use
|
||||
* this function if you only want to connect a single device.
|
||||
* @param names XKB rule names structure (use NULL components for default values)
|
||||
* @return true if creating the keymap and associated state succeeded
|
||||
*/
|
||||
bool xkb_set_keymap(struct xkb_rule_names names);
|
||||
/**
|
||||
* Set a new keymap to be used for processing future key events using a specific driver state. Use
|
||||
* this function if you want to connect multiple devices.
|
||||
* @param state XKB driver state to use
|
||||
* @param names XKB rule names structure (use NULL components for default values)
|
||||
* @return true if creating the keymap and associated state succeeded
|
||||
*/
|
||||
bool xkb_set_keymap_state(xkb_drv_state_t *state, struct xkb_rule_names names);
|
||||
/**
|
||||
* Process an evdev scancode using the default driver state. Use this function if you only want to
|
||||
* connect a single device.
|
||||
* @param scancode evdev scancode to process
|
||||
* @param down true if the key was pressed, false if it was releases
|
||||
* @return the (first) UTF-8 character produced by the event or 0 if no output was produced
|
||||
*/
|
||||
uint32_t xkb_process_key(uint32_t scancode, bool down);
|
||||
/**
|
||||
* Process an evdev scancode using a specific driver state. Use this function if you want to connect
|
||||
* multiple devices.
|
||||
* @param state XKB driver state to use
|
||||
* @param scancode evdev scancode to process
|
||||
* @param down true if the key was pressed, false if it was releases
|
||||
* @return the (first) UTF-8 character produced by the event or 0 if no output was produced
|
||||
*/
|
||||
uint32_t xkb_process_key_state(xkb_drv_state_t *state, uint32_t scancode, bool down);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_XKB */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* XKB_H */
|
||||
13
libs/lv_drivers/library.json
Normal file
13
libs/lv_drivers/library.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "lv_drivers",
|
||||
"version": "8.3.0",
|
||||
"keywords": "littlevgl, lvgl, driver, display, touchpad",
|
||||
"description": "Drivers for LittlevGL graphics library.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/littlevgl/lv_drivers.git"
|
||||
},
|
||||
"build": {
|
||||
"includeDir": "."
|
||||
}
|
||||
}
|
||||
10
libs/lv_drivers/lv_drivers.mk
Normal file
10
libs/lv_drivers/lv_drivers.mk
Normal file
@ -0,0 +1,10 @@
|
||||
LV_DRIVERS_DIR_NAME ?= lv_drivers
|
||||
|
||||
override CFLAGS := -I$(LVGL_DIR) $(CFLAGS)
|
||||
|
||||
CSRCS += $(wildcard $(LVGL_DIR)/$(LV_DRIVERS_DIR_NAME)/*.c)
|
||||
CSRCS += $(wildcard $(LVGL_DIR)/$(LV_DRIVERS_DIR_NAME)/wayland/*.c)
|
||||
CSRCS += $(wildcard $(LVGL_DIR)/$(LV_DRIVERS_DIR_NAME)/indev/*.c)
|
||||
CSRCS += $(wildcard $(LVGL_DIR)/$(LV_DRIVERS_DIR_NAME)/gtkdrv/*.c)
|
||||
CSRCS += $(wildcard $(LVGL_DIR)/$(LV_DRIVERS_DIR_NAME)/display/*.c)
|
||||
CSRCS += $(wildcard $(LVGL_DIR)/$(LV_DRIVERS_DIR_NAME)/sdl/*.c)
|
||||
496
libs/lv_drivers/lv_drv_conf_template.h
Normal file
496
libs/lv_drivers/lv_drv_conf_template.h
Normal file
@ -0,0 +1,496 @@
|
||||
/**
|
||||
* @file lv_drv_conf.h
|
||||
* Configuration file for v8.3.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPY THIS FILE AS lv_drv_conf.h
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
#if 0 /*Set it to "1" to enable the content*/
|
||||
|
||||
#ifndef LV_DRV_CONF_H
|
||||
#define LV_DRV_CONF_H
|
||||
|
||||
#include "lv_conf.h"
|
||||
|
||||
/*********************
|
||||
* DELAY INTERFACE
|
||||
*********************/
|
||||
#define LV_DRV_DELAY_INCLUDE <stdint.h> /*Dummy include by default*/
|
||||
#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/
|
||||
#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/
|
||||
|
||||
/*********************
|
||||
* DISPLAY INTERFACE
|
||||
*********************/
|
||||
|
||||
/*------------
|
||||
* Common
|
||||
*------------*/
|
||||
#define LV_DRV_DISP_INCLUDE <stdint.h> /*Dummy include by default*/
|
||||
#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/
|
||||
#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
|
||||
|
||||
/*---------
|
||||
* SPI
|
||||
*---------*/
|
||||
#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
|
||||
#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/
|
||||
#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/
|
||||
|
||||
/*------------------
|
||||
* Parallel port
|
||||
*-----------------*/
|
||||
#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/
|
||||
#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/
|
||||
#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/
|
||||
#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/
|
||||
#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/
|
||||
|
||||
/***************************
|
||||
* INPUT DEVICE INTERFACE
|
||||
***************************/
|
||||
|
||||
/*----------
|
||||
* Common
|
||||
*----------*/
|
||||
#define LV_DRV_INDEV_INCLUDE <stdint.h> /*Dummy include by default*/
|
||||
#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
|
||||
#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/
|
||||
|
||||
/*---------
|
||||
* SPI
|
||||
*---------*/
|
||||
#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
|
||||
#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/
|
||||
|
||||
/*---------
|
||||
* I2C
|
||||
*---------*/
|
||||
#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/
|
||||
#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/
|
||||
#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/
|
||||
#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/
|
||||
#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/
|
||||
|
||||
|
||||
/*********************
|
||||
* DISPLAY DRIVERS
|
||||
*********************/
|
||||
|
||||
/*-------------------
|
||||
* SDL
|
||||
*-------------------*/
|
||||
|
||||
/* SDL based drivers for display, mouse, mousewheel and keyboard*/
|
||||
#ifndef USE_SDL
|
||||
# define USE_SDL 0
|
||||
#endif
|
||||
|
||||
/* Hardware accelerated SDL driver */
|
||||
#ifndef USE_SDL_GPU
|
||||
# define USE_SDL_GPU 0
|
||||
#endif
|
||||
|
||||
#if USE_SDL || USE_SDL_GPU
|
||||
# define SDL_HOR_RES 480
|
||||
# define SDL_VER_RES 320
|
||||
|
||||
/* Scale window by this factor (useful when simulating small screens) */
|
||||
# define SDL_ZOOM 1
|
||||
|
||||
/* Used to test true double buffering with only address changing.
|
||||
* Use 2 draw buffers, bith with SDL_HOR_RES x SDL_VER_RES size*/
|
||||
# define SDL_DOUBLE_BUFFERED 0
|
||||
|
||||
/*Eclipse: <SDL2/SDL.h> Visual Studio: <SDL.h>*/
|
||||
# define SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
|
||||
/*Open two windows to test multi display support*/
|
||||
# define SDL_DUAL_DISPLAY 0
|
||||
#endif
|
||||
|
||||
/*-------------------
|
||||
* Monitor of PC
|
||||
*-------------------*/
|
||||
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_MONITOR
|
||||
# define USE_MONITOR 0
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR
|
||||
# define MONITOR_HOR_RES 480
|
||||
# define MONITOR_VER_RES 320
|
||||
|
||||
/* Scale window by this factor (useful when simulating small screens) */
|
||||
# define MONITOR_ZOOM 1
|
||||
|
||||
/* Used to test true double buffering with only address changing.
|
||||
* Use 2 draw buffers, bith with MONITOR_HOR_RES x MONITOR_VER_RES size*/
|
||||
# define MONITOR_DOUBLE_BUFFERED 0
|
||||
|
||||
/*Eclipse: <SDL2/SDL.h> Visual Studio: <SDL.h>*/
|
||||
# define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
|
||||
/*Open two windows to test multi display support*/
|
||||
# define MONITOR_DUAL 0
|
||||
#endif
|
||||
|
||||
/*-----------------------------------
|
||||
* Native Windows (including mouse)
|
||||
*----------------------------------*/
|
||||
#ifndef USE_WINDOWS
|
||||
# define USE_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if USE_WINDOWS
|
||||
# define WINDOW_HOR_RES 480
|
||||
# define WINDOW_VER_RES 320
|
||||
#endif
|
||||
|
||||
/*----------------------------
|
||||
* Native Windows (win32drv)
|
||||
*---------------------------*/
|
||||
#ifndef USE_WIN32DRV
|
||||
# define USE_WIN32DRV 0
|
||||
#endif
|
||||
|
||||
#if USE_WIN32DRV
|
||||
/* Scale window by this factor (useful when simulating small screens) */
|
||||
# define WIN32DRV_MONITOR_ZOOM 1
|
||||
#endif
|
||||
|
||||
/*----------------------------------------
|
||||
* GTK drivers (monitor, mouse, keyboard
|
||||
*---------------------------------------*/
|
||||
#ifndef USE_GTK
|
||||
# define USE_GTK 0
|
||||
#endif
|
||||
|
||||
/*----------------------------------------
|
||||
* Wayland drivers (monitor, mouse, keyboard, touchscreen)
|
||||
*---------------------------------------*/
|
||||
#ifndef USE_WAYLAND
|
||||
# define USE_WAYLAND 0
|
||||
#endif
|
||||
|
||||
#if USE_WAYLAND
|
||||
/* Support for client-side decorations */
|
||||
# ifndef LV_WAYLAND_CLIENT_SIDE_DECORATIONS
|
||||
# define LV_WAYLAND_CLIENT_SIDE_DECORATIONS 1
|
||||
# endif
|
||||
/* Support for (deprecated) wl-shell protocol */
|
||||
# ifndef LV_WAYLAND_WL_SHELL
|
||||
# define LV_WAYLAND_WL_SHELL 1
|
||||
# endif
|
||||
/* Support for xdg-shell protocol */
|
||||
# ifndef LV_WAYLAND_XDG_SHELL
|
||||
# define LV_WAYLAND_XDG_SHELL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------
|
||||
* SSD1963
|
||||
*--------------*/
|
||||
#ifndef USE_SSD1963
|
||||
# define USE_SSD1963 0
|
||||
#endif
|
||||
|
||||
#if USE_SSD1963
|
||||
# define SSD1963_HOR_RES LV_HOR_RES
|
||||
# define SSD1963_VER_RES LV_VER_RES
|
||||
# define SSD1963_HT 531
|
||||
# define SSD1963_HPS 43
|
||||
# define SSD1963_LPS 8
|
||||
# define SSD1963_HPW 10
|
||||
# define SSD1963_VT 288
|
||||
# define SSD1963_VPS 12
|
||||
# define SSD1963_FPS 4
|
||||
# define SSD1963_VPW 10
|
||||
# define SSD1963_HS_NEG 0 /*Negative hsync*/
|
||||
# define SSD1963_VS_NEG 0 /*Negative vsync*/
|
||||
# define SSD1963_ORI 0 /*0, 90, 180, 270*/
|
||||
# define SSD1963_COLOR_DEPTH 16
|
||||
#endif
|
||||
|
||||
/*----------------
|
||||
* R61581
|
||||
*--------------*/
|
||||
#ifndef USE_R61581
|
||||
# define USE_R61581 0
|
||||
#endif
|
||||
|
||||
#if USE_R61581
|
||||
# define R61581_HOR_RES LV_HOR_RES
|
||||
# define R61581_VER_RES LV_VER_RES
|
||||
# define R61581_HSPL 0 /*HSYNC signal polarity*/
|
||||
# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/
|
||||
# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/
|
||||
# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */
|
||||
# define R61581_VSPL 0 /*VSYNC signal polarity*/
|
||||
# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/
|
||||
# define R61581_VFP 8 /*Vertical Front poarch*/
|
||||
# define R61581_VBP 8 /*Vertical Back poarch */
|
||||
# define R61581_DPL 0 /*DCLK signal polarity*/
|
||||
# define R61581_EPL 1 /*ENABLE signal polarity*/
|
||||
# define R61581_ORI 0 /*0, 180*/
|
||||
# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/
|
||||
#endif
|
||||
|
||||
/*------------------------------
|
||||
* ST7565 (Monochrome, low res.)
|
||||
*-----------------------------*/
|
||||
#ifndef USE_ST7565
|
||||
# define USE_ST7565 0
|
||||
#endif
|
||||
|
||||
#if USE_ST7565
|
||||
/*No settings*/
|
||||
#endif /*USE_ST7565*/
|
||||
|
||||
/*------------------------------
|
||||
* GC9A01 (color, low res.)
|
||||
*-----------------------------*/
|
||||
#ifndef USE_GC9A01
|
||||
# define USE_GC9A01 0
|
||||
#endif
|
||||
|
||||
#if USE_GC9A01
|
||||
/*No settings*/
|
||||
#endif /*USE_GC9A01*/
|
||||
|
||||
/*------------------------------------------
|
||||
* UC1610 (4 gray 160*[104|128])
|
||||
* (EA DOGXL160 160x104 tested)
|
||||
*-----------------------------------------*/
|
||||
#ifndef USE_UC1610
|
||||
# define USE_UC1610 0
|
||||
#endif
|
||||
|
||||
#if USE_UC1610
|
||||
# define UC1610_HOR_RES LV_HOR_RES
|
||||
# define UC1610_VER_RES LV_VER_RES
|
||||
# define UC1610_INIT_CONTRAST 33 /* init contrast, values in [%] */
|
||||
# define UC1610_INIT_HARD_RST 0 /* 1 : hardware reset at init, 0 : software reset */
|
||||
# define UC1610_TOP_VIEW 0 /* 0 : Bottom View, 1 : Top View */
|
||||
#endif /*USE_UC1610*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* SHARP memory in pixel monochrome display series
|
||||
* LS012B7DD01 (184x38 pixels.)
|
||||
* LS013B7DH03 (128x128 pixels.)
|
||||
* LS013B7DH05 (144x168 pixels.)
|
||||
* LS027B7DH01 (400x240 pixels.) (tested)
|
||||
* LS032B7DD02 (336x536 pixels.)
|
||||
* LS044Q7DH01 (320x240 pixels.)
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_SHARP_MIP
|
||||
# define USE_SHARP_MIP 0
|
||||
#endif
|
||||
|
||||
#if USE_SHARP_MIP
|
||||
# define SHARP_MIP_HOR_RES LV_HOR_RES
|
||||
# define SHARP_MIP_VER_RES LV_VER_RES
|
||||
# define SHARP_MIP_SOFT_COM_INVERSION 0
|
||||
# define SHARP_MIP_REV_BYTE(b) /*((uint8_t) __REV(__RBIT(b)))*/ /*Architecture / compiler dependent byte bits order reverse*/
|
||||
#endif /*USE_SHARP_MIP*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* ILI9341 240X320 TFT LCD
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_ILI9341
|
||||
# define USE_ILI9341 0
|
||||
#endif
|
||||
|
||||
#if USE_ILI9341
|
||||
# define ILI9341_HOR_RES LV_HOR_RES
|
||||
# define ILI9341_VER_RES LV_VER_RES
|
||||
# define ILI9341_GAMMA 1
|
||||
# define ILI9341_TEARING 0
|
||||
#endif /*USE_ILI9341*/
|
||||
|
||||
/*-----------------------------------------
|
||||
* Linux frame buffer device (/dev/fbx)
|
||||
*-----------------------------------------*/
|
||||
#ifndef USE_FBDEV
|
||||
# define USE_FBDEV 0
|
||||
#endif
|
||||
|
||||
#if USE_FBDEV
|
||||
# define FBDEV_PATH "/dev/fb0"
|
||||
# define FBDEV_DISPLAY_POWER_ON 1 /* 1 to force display power during initialization */
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------
|
||||
* FreeBSD frame buffer device (/dev/fbx)
|
||||
*.........................................*/
|
||||
#ifndef USE_BSD_FBDEV
|
||||
# define USE_BSD_FBDEV 0
|
||||
#endif
|
||||
|
||||
#if USE_BSD_FBDEV
|
||||
# define FBDEV_PATH "/dev/fb0"
|
||||
# define FBDEV_DISPLAY_POWER_ON 1 /* 1 to force display power during initialization */
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------
|
||||
* DRM/KMS device (/dev/dri/cardX)
|
||||
*-----------------------------------------*/
|
||||
#ifndef USE_DRM
|
||||
# define USE_DRM 0
|
||||
#endif
|
||||
|
||||
#if USE_DRM
|
||||
# define DRM_CARD "/dev/dri/card0"
|
||||
# define DRM_CONNECTOR_ID -1 /* -1 for the first connected one */
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INPUT DEVICES
|
||||
*********************/
|
||||
|
||||
/*--------------
|
||||
* XPT2046
|
||||
*--------------*/
|
||||
#ifndef USE_XPT2046
|
||||
# define USE_XPT2046 0
|
||||
#endif
|
||||
|
||||
#if USE_XPT2046
|
||||
# define XPT2046_HOR_RES 480
|
||||
# define XPT2046_VER_RES 320
|
||||
# define XPT2046_X_MIN 200
|
||||
# define XPT2046_Y_MIN 200
|
||||
# define XPT2046_X_MAX 3800
|
||||
# define XPT2046_Y_MAX 3800
|
||||
# define XPT2046_AVG 4
|
||||
# define XPT2046_X_INV 0
|
||||
# define XPT2046_Y_INV 0
|
||||
# define XPT2046_XY_SWAP 0
|
||||
#endif
|
||||
|
||||
/*-----------------
|
||||
* FT5406EE8
|
||||
*-----------------*/
|
||||
#ifndef USE_FT5406EE8
|
||||
# define USE_FT5406EE8 0
|
||||
#endif
|
||||
|
||||
#if USE_FT5406EE8
|
||||
# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/
|
||||
#endif
|
||||
|
||||
/*---------------
|
||||
* AD TOUCH
|
||||
*--------------*/
|
||||
#ifndef USE_AD_TOUCH
|
||||
# define USE_AD_TOUCH 0
|
||||
#endif
|
||||
|
||||
#if USE_AD_TOUCH
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------
|
||||
* Mouse or touchpad on PC (using SDL)
|
||||
*-------------------------------------*/
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_MOUSE
|
||||
# define USE_MOUSE 0
|
||||
#endif
|
||||
|
||||
#if USE_MOUSE
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------
|
||||
* Mousewheel as encoder on PC (using SDL)
|
||||
*------------------------------------------*/
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_MOUSEWHEEL
|
||||
# define USE_MOUSEWHEEL 0
|
||||
#endif
|
||||
|
||||
#if USE_MOUSEWHEEL
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------
|
||||
* Touchscreen, mouse/touchpad or keyboard as libinput interface (for Linux based systems)
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_LIBINPUT
|
||||
# define USE_LIBINPUT 0
|
||||
#endif
|
||||
|
||||
#ifndef USE_BSD_LIBINPUT
|
||||
# define USE_BSD_LIBINPUT 0
|
||||
#endif
|
||||
|
||||
#if USE_LIBINPUT || USE_BSD_LIBINPUT
|
||||
/*If only a single device of the same type is connected, you can also auto detect it, e.g.:
|
||||
*#define LIBINPUT_NAME libinput_find_dev(LIBINPUT_CAPABILITY_TOUCH, false)*/
|
||||
# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/
|
||||
|
||||
#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* Mouse or touchpad as evdev interface (for Linux based systems)
|
||||
*------------------------------------------------*/
|
||||
#ifndef USE_EVDEV
|
||||
# define USE_EVDEV 0
|
||||
#endif
|
||||
|
||||
#ifndef USE_BSD_EVDEV
|
||||
# define USE_BSD_EVDEV 0
|
||||
#endif
|
||||
|
||||
#if USE_EVDEV || USE_BSD_EVDEV
|
||||
# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/
|
||||
# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/
|
||||
|
||||
# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/
|
||||
|
||||
# if EVDEV_CALIBRATE
|
||||
# define EVDEV_HOR_MIN 0 /*to invert axis swap EVDEV_XXX_MIN by EVDEV_XXX_MAX*/
|
||||
# define EVDEV_HOR_MAX 4096 /*"evtest" Linux tool can help to get the correct calibraion values>*/
|
||||
# define EVDEV_VER_MIN 0
|
||||
# define EVDEV_VER_MAX 4096
|
||||
# endif /*EVDEV_CALIBRATE*/
|
||||
#endif /*USE_EVDEV*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* Full keyboard support for evdev and libinput interface
|
||||
*------------------------------------------------*/
|
||||
# ifndef USE_XKB
|
||||
# define USE_XKB 0
|
||||
# endif
|
||||
|
||||
#if USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV
|
||||
# if USE_XKB
|
||||
# define XKB_KEY_MAP { .rules = NULL, \
|
||||
.model = "pc101", \
|
||||
.layout = "us", \
|
||||
.variant = NULL, \
|
||||
.options = NULL } /*"setxkbmap -query" can help find the right values for your keyboard*/
|
||||
# endif /*USE_XKB*/
|
||||
#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV*/
|
||||
|
||||
/*-------------------------------
|
||||
* Keyboard of a PC (using SDL)
|
||||
*------------------------------*/
|
||||
/*DEPRECATED: Use the SDL driver instead. */
|
||||
#ifndef USE_KEYBOARD
|
||||
# define USE_KEYBOARD 0
|
||||
#endif
|
||||
|
||||
#if USE_KEYBOARD
|
||||
/*No settings*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
||||
391
libs/lv_drivers/sdl/sdl.c
Normal file
391
libs/lv_drivers/sdl/sdl.c
Normal file
@ -0,0 +1,391 @@
|
||||
/**
|
||||
* @file sdl.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "sdl.h"
|
||||
#if USE_MONITOR || USE_SDL
|
||||
|
||||
#if LV_USE_GPU_SDL
|
||||
# error "LV_USE_GPU_SDL must not be enabled"
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR
|
||||
# warning "MONITOR is deprecated, use SDL instead. See lv_drivers/sdl/sdl.c"
|
||||
#endif
|
||||
|
||||
#if USE_KEYBOARD
|
||||
# warning "KEYBOARD is deprecated, use SDL instead. See lv_drivers/sdl/sdl.c"
|
||||
#endif
|
||||
|
||||
#if USE_MOUSE
|
||||
# warning "MOUSE is deprecated, use SDL instead. See lv_drivers/sdl/sdl.c"
|
||||
#endif
|
||||
|
||||
#if USE_MOUSEWHEEL
|
||||
# warning "MOUSEWHEEL is deprecated, use SDL instead that. See lv_drivers/sdl/sdl.c"
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR && USE_SDL
|
||||
# error "Cannot enable both MONITOR and SDL at the same time. "
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR
|
||||
# define SDL_HOR_RES MONITOR_HOR_RES
|
||||
# define SDL_VER_RES MONITOR_VER_RES
|
||||
# define SDL_ZOOM MONITOR_ZOOM
|
||||
# define SDL_DOUBLE_BUFFERED MONITOR_DOUBLE_BUFFERED
|
||||
# define SDL_INCLUDE_PATH MONITOR_SDL_INCLUDE_PATH
|
||||
# define SDL_VIRTUAL_MACHINE MONITOR_VIRTUAL_MACHINE
|
||||
# define SDL_DUAL_DISPLAY MONITOR_DUAL
|
||||
#endif
|
||||
|
||||
#ifndef SDL_FULLSCREEN
|
||||
# define SDL_FULLSCREEN 0
|
||||
#endif
|
||||
|
||||
#include "sdl_common_internal.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include SDL_INCLUDE_PATH
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef KEYBOARD_BUFFER_SIZE
|
||||
#define KEYBOARD_BUFFER_SIZE SDL_TEXTINPUTEVENT_TEXT_SIZE
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
SDL_Window * window;
|
||||
SDL_Renderer * renderer;
|
||||
SDL_Texture * texture;
|
||||
volatile bool sdl_refr_qry;
|
||||
#if SDL_DOUBLE_BUFFERED
|
||||
uint32_t * tft_fb_act;
|
||||
#else
|
||||
uint32_t * tft_fb;
|
||||
#endif
|
||||
}monitor_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void window_create(monitor_t * m);
|
||||
static void window_update(monitor_t * m);
|
||||
static void monitor_sdl_clean_up(void);
|
||||
static void sdl_event_handler(lv_timer_t * t);
|
||||
static void monitor_sdl_refr(lv_timer_t * t);
|
||||
|
||||
/***********************
|
||||
* GLOBAL PROTOTYPES
|
||||
***********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
monitor_t monitor;
|
||||
|
||||
#if SDL_DUAL_DISPLAY
|
||||
monitor_t monitor2;
|
||||
#endif
|
||||
|
||||
static volatile bool sdl_inited = false;
|
||||
|
||||
static bool left_button_down = false;
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
|
||||
static int16_t wheel_diff = 0;
|
||||
static lv_indev_state_t wheel_state = LV_INDEV_STATE_RELEASED;
|
||||
|
||||
static char buf[KEYBOARD_BUFFER_SIZE];
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void sdl_init(void)
|
||||
{
|
||||
/*Initialize the SDL*/
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
SDL_SetEventFilter(quit_filter, NULL);
|
||||
|
||||
window_create(&monitor);
|
||||
#if SDL_DUAL_DISPLAY
|
||||
window_create(&monitor2);
|
||||
int x, y;
|
||||
SDL_GetWindowPosition(monitor2.window, &x, &y);
|
||||
SDL_SetWindowPosition(monitor.window, x + (SDL_HOR_RES * SDL_ZOOM) / 2 + 10, y);
|
||||
SDL_SetWindowPosition(monitor2.window, x - (SDL_HOR_RES * SDL_ZOOM) / 2 - 10, y);
|
||||
#endif
|
||||
|
||||
SDL_StartTextInput();
|
||||
|
||||
lv_timer_create(sdl_event_handler, 10, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param disp_drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void sdl_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
const lv_coord_t hres = disp_drv->physical_hor_res == -1 ? disp_drv->hor_res : disp_drv->physical_hor_res;
|
||||
const lv_coord_t vres = disp_drv->physical_ver_res == -1 ? disp_drv->ver_res : disp_drv->physical_ver_res;
|
||||
|
||||
// printf("x1:%d,y1:%d,x2:%d,y2:%d\n", area->x1, area->y1, area->x2, area->y2);
|
||||
|
||||
/*Return if the area is out the screen*/
|
||||
if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
return;
|
||||
}
|
||||
|
||||
#if SDL_DOUBLE_BUFFERED
|
||||
monitor.tft_fb_act = (uint32_t *)color_p;
|
||||
#else /*SDL_DOUBLE_BUFFERED*/
|
||||
|
||||
int32_t y;
|
||||
#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32 /*32 is valid but support 24 for backward compatibility too*/
|
||||
int32_t x;
|
||||
for(y = area->y1; y <= area->y2 && y < vres; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
monitor.tft_fb[y * hres + x] = lv_color_to32(*color_p);
|
||||
color_p++;
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
uint32_t w = lv_area_get_width(area);
|
||||
for(y = area->y1; y <= area->y2 && y < vres; y++) {
|
||||
memcpy(&monitor.tft_fb[y * hres + area->x1], color_p, w * sizeof(lv_color_t));
|
||||
color_p += w;
|
||||
}
|
||||
#endif
|
||||
#endif /*SDL_DOUBLE_BUFFERED*/
|
||||
|
||||
monitor.sdl_refr_qry = true;
|
||||
|
||||
/* TYPICALLY YOU DO NOT NEED THIS
|
||||
* If it was the last part to refresh update the texture of the window.*/
|
||||
if(lv_disp_flush_is_last(disp_drv)) {
|
||||
monitor_sdl_refr(NULL);
|
||||
}
|
||||
|
||||
/*IMPORTANT! It must be called to tell the system the flush is ready*/
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if SDL_DUAL_DISPLAY
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param disp_drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void sdl_display_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
const lv_coord_t hres = disp_drv->physical_hor_res == -1 ? disp_drv->hor_res : disp_drv->physical_hor_res;
|
||||
const lv_coord_t vres = disp_drv->physical_ver_res == -1 ? disp_drv->ver_res : disp_drv->physical_ver_res;
|
||||
|
||||
/*Return if the area is out the screen*/
|
||||
if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
return;
|
||||
}
|
||||
|
||||
#if SDL_DOUBLE_BUFFERED
|
||||
monitor2.tft_fb_act = (uint32_t *)color_p;
|
||||
|
||||
monitor2.sdl_refr_qry = true;
|
||||
|
||||
/*IMPORTANT! It must be called to tell the system the flush is ready*/
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
#else
|
||||
|
||||
int32_t y;
|
||||
#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32 /*32 is valid but support 24 for backward compatibility too*/
|
||||
int32_t x;
|
||||
for(y = area->y1; y <= area->y2 && y < vres; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
monitor2.tft_fb[y * hres + x] = lv_color_to32(*color_p);
|
||||
color_p++;
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
uint32_t w = lv_area_get_width(area);
|
||||
for(y = area->y1; y <= area->y2 && y < vres; y++) {
|
||||
memcpy(&monitor2.tft_fb[y * hres + area->x1], color_p, w * sizeof(lv_color_t));
|
||||
color_p += w;
|
||||
}
|
||||
#endif
|
||||
|
||||
monitor2.sdl_refr_qry = true;
|
||||
|
||||
/* TYPICALLY YOU DO NOT NEED THIS
|
||||
* If it was the last part to refresh update the texture of the window.*/
|
||||
if(lv_disp_flush_is_last(disp_drv)) {
|
||||
monitor_sdl_refr(NULL);
|
||||
}
|
||||
|
||||
/*IMPORTANT! It must be called to tell the system the flush is ready*/
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* SDL main thread. All SDL related task have to be handled here!
|
||||
* It initializes SDL, handles drawing and the mouse.
|
||||
*/
|
||||
|
||||
static void sdl_event_handler(lv_timer_t * t)
|
||||
{
|
||||
(void)t;
|
||||
|
||||
/*Refresh handling*/
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
mouse_handler(&event);
|
||||
mousewheel_handler(&event);
|
||||
keyboard_handler(&event);
|
||||
|
||||
if((&event)->type == SDL_WINDOWEVENT) {
|
||||
switch((&event)->window.event) {
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
||||
case SDL_WINDOWEVENT_TAKE_FOCUS:
|
||||
#endif
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
window_update(&monitor);
|
||||
#if SDL_DUAL_DISPLAY
|
||||
window_update(&monitor2);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Run until quit event not arrives*/
|
||||
if(sdl_quit_qry) {
|
||||
monitor_sdl_clean_up();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SDL main thread. All SDL related task have to be handled here!
|
||||
* It initializes SDL, handles drawing and the mouse.
|
||||
*/
|
||||
|
||||
static void monitor_sdl_refr(lv_timer_t * t)
|
||||
{
|
||||
(void)t;
|
||||
|
||||
/*Refresh handling*/
|
||||
if(monitor.sdl_refr_qry != false) {
|
||||
monitor.sdl_refr_qry = false;
|
||||
window_update(&monitor);
|
||||
}
|
||||
|
||||
#if SDL_DUAL_DISPLAY
|
||||
if(monitor2.sdl_refr_qry != false) {
|
||||
monitor2.sdl_refr_qry = false;
|
||||
window_update(&monitor2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void monitor_sdl_clean_up(void)
|
||||
{
|
||||
SDL_DestroyTexture(monitor.texture);
|
||||
SDL_DestroyRenderer(monitor.renderer);
|
||||
SDL_DestroyWindow(monitor.window);
|
||||
|
||||
#if SDL_DUAL_DISPLAY
|
||||
SDL_DestroyTexture(monitor2.texture);
|
||||
SDL_DestroyRenderer(monitor2.renderer);
|
||||
SDL_DestroyWindow(monitor2.window);
|
||||
|
||||
#endif
|
||||
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
static void window_create(monitor_t * m)
|
||||
{
|
||||
|
||||
int flag = 0;
|
||||
#if SDL_FULLSCREEN
|
||||
flag |= SDL_WINDOW_FULLSCREEN;
|
||||
#endif
|
||||
|
||||
m->window = SDL_CreateWindow(SDL_WINDOW_NAME,
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_HOR_RES * SDL_ZOOM, SDL_VER_RES * SDL_ZOOM, flag); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/
|
||||
|
||||
m->renderer = SDL_CreateRenderer(m->window, -1, SDL_RENDERER_SOFTWARE);
|
||||
m->texture = SDL_CreateTexture(m->renderer,
|
||||
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, SDL_HOR_RES, SDL_VER_RES);
|
||||
SDL_SetTextureBlendMode(m->texture, SDL_BLENDMODE_BLEND);
|
||||
|
||||
/*Initialize the frame buffer to gray (77 is an empirical value) */
|
||||
#if SDL_DOUBLE_BUFFERED
|
||||
SDL_UpdateTexture(m->texture, NULL, m->tft_fb_act, SDL_HOR_RES * sizeof(uint32_t));
|
||||
#else
|
||||
m->tft_fb = (uint32_t *)malloc(sizeof(uint32_t) * SDL_HOR_RES * SDL_VER_RES);
|
||||
memset(m->tft_fb, 0x44, SDL_HOR_RES * SDL_VER_RES * sizeof(uint32_t));
|
||||
#endif
|
||||
|
||||
m->sdl_refr_qry = true;
|
||||
|
||||
}
|
||||
|
||||
static void window_update(monitor_t * m)
|
||||
{
|
||||
#if SDL_DOUBLE_BUFFERED == 0
|
||||
SDL_UpdateTexture(m->texture, NULL, m->tft_fb, SDL_HOR_RES * sizeof(uint32_t));
|
||||
#else
|
||||
if(m->tft_fb_act == NULL) return;
|
||||
SDL_UpdateTexture(m->texture, NULL, m->tft_fb_act, SDL_HOR_RES * sizeof(uint32_t));
|
||||
#endif
|
||||
SDL_RenderClear(m->renderer);
|
||||
lv_disp_t * d = _lv_refr_get_disp_refreshing();
|
||||
if(d->driver->screen_transp) {
|
||||
SDL_SetRenderDrawColor(m->renderer, 0xff, 0, 0, 0xff);
|
||||
SDL_Rect r;
|
||||
r.x = 0; r.y = 0; r.w = SDL_HOR_RES; r.h = SDL_VER_RES;
|
||||
SDL_RenderDrawRect(m->renderer, &r);
|
||||
}
|
||||
|
||||
/*Update the renderer with the texture containing the rendered image*/
|
||||
SDL_RenderCopy(m->renderer, m->texture, NULL, NULL);
|
||||
SDL_RenderPresent(m->renderer);
|
||||
}
|
||||
|
||||
#endif /*USE_MONITOR || USE_SDL*/
|
||||
103
libs/lv_drivers/sdl/sdl.h
Normal file
103
libs/lv_drivers/sdl/sdl.h
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @file sdl.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SDL_H
|
||||
#define SDL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR || USE_SDL
|
||||
|
||||
#include "sdl_common.h"
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize SDL to be used as display, mouse and mouse wheel drivers.
|
||||
*/
|
||||
void sdl_init(void);
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param disp_drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void sdl_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param disp_drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void sdl_display_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/**
|
||||
* Get the current position and state of the mouse
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the mouse data here
|
||||
*/
|
||||
void sdl_mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**
|
||||
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the read data here
|
||||
*/
|
||||
void sdl_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**
|
||||
* Get input from the keyboard.
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the red data here
|
||||
*/
|
||||
void sdl_keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/*For backward compatibility. Will be removed.*/
|
||||
#define monitor_init sdl_init
|
||||
#define monitor_flush sdl_display_flush
|
||||
#define monitor_flush2 sdl_display_flush2
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_MONITOR || USE_SDL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SDL_H */
|
||||
273
libs/lv_drivers/sdl/sdl_common.c
Normal file
273
libs/lv_drivers/sdl/sdl_common.c
Normal file
@ -0,0 +1,273 @@
|
||||
//
|
||||
// Created by Mariotaku on 2021/10/14.
|
||||
//
|
||||
|
||||
#include "sdl_common.h"
|
||||
|
||||
#if USE_SDL || USE_SDL_GPU
|
||||
#include "sdl_common_internal.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#ifndef KEYBOARD_BUFFER_SIZE
|
||||
#define KEYBOARD_BUFFER_SIZE SDL_TEXTINPUTEVENT_TEXT_SIZE
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
volatile bool sdl_quit_qry = false;
|
||||
|
||||
static bool left_button_down = false;
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
|
||||
static int16_t wheel_diff = 0;
|
||||
static lv_indev_state_t wheel_state = LV_INDEV_STATE_RELEASED;
|
||||
|
||||
static char buf[KEYBOARD_BUFFER_SIZE];
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
/**
|
||||
* Get the current position and state of the mouse
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the mouse data here
|
||||
*/
|
||||
void sdl_mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
(void) indev_drv; /*Unused*/
|
||||
|
||||
/*Store the collected data*/
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = left_button_down ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the read data here
|
||||
*/
|
||||
void sdl_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
(void) indev_drv; /*Unused*/
|
||||
|
||||
data->state = wheel_state;
|
||||
data->enc_diff = wheel_diff;
|
||||
wheel_diff = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get input from the keyboard.
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the red data here
|
||||
*/
|
||||
void sdl_keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
(void) indev_drv; /*Unused*/
|
||||
|
||||
static bool dummy_read = false;
|
||||
const size_t len = strlen(buf);
|
||||
|
||||
/*Send a release manually*/
|
||||
if (dummy_read) {
|
||||
dummy_read = false;
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
data->continue_reading = len > 0;
|
||||
}
|
||||
/*Send the pressed character*/
|
||||
else if (len > 0) {
|
||||
dummy_read = true;
|
||||
data->state = LV_INDEV_STATE_PRESSED;
|
||||
data->key = buf[0];
|
||||
memmove(buf, buf + 1, len);
|
||||
data->continue_reading = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
int quit_filter(void * userdata, SDL_Event * event)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
if(event->type == SDL_QUIT) {
|
||||
sdl_quit_qry = true;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mouse_handler(SDL_Event * event)
|
||||
{
|
||||
switch(event->type) {
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if(event->button.button == SDL_BUTTON_LEFT)
|
||||
left_button_down = false;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if(event->button.button == SDL_BUTTON_LEFT) {
|
||||
left_button_down = true;
|
||||
last_x = event->motion.x / SDL_ZOOM;
|
||||
last_y = event->motion.y / SDL_ZOOM;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
last_x = event->motion.x / SDL_ZOOM;
|
||||
last_y = event->motion.y / SDL_ZOOM;
|
||||
break;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
left_button_down = false;
|
||||
last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM;
|
||||
last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM;
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
left_button_down = true;
|
||||
last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM;
|
||||
last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM;
|
||||
break;
|
||||
case SDL_FINGERMOTION:
|
||||
last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM;
|
||||
last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It is called periodically from the SDL thread to check mouse wheel state
|
||||
* @param event describes the event
|
||||
*/
|
||||
void mousewheel_handler(SDL_Event * event)
|
||||
{
|
||||
switch(event->type) {
|
||||
case SDL_MOUSEWHEEL:
|
||||
// Scroll down (y = -1) means positive encoder turn,
|
||||
// so invert it
|
||||
#ifdef __EMSCRIPTEN__
|
||||
/*Escripten scales it wrong*/
|
||||
if(event->wheel.y < 0) wheel_diff++;
|
||||
if(event->wheel.y > 0) wheel_diff--;
|
||||
#else
|
||||
wheel_diff = -event->wheel.y;
|
||||
#endif
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if(event->button.button == SDL_BUTTON_MIDDLE) {
|
||||
wheel_state = LV_INDEV_STATE_PRESSED;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if(event->button.button == SDL_BUTTON_MIDDLE) {
|
||||
wheel_state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called periodically from the SDL thread, store text input or control characters in the buffer.
|
||||
* @param event describes the event
|
||||
*/
|
||||
void keyboard_handler(SDL_Event * event)
|
||||
{
|
||||
/* We only care about SDL_KEYDOWN and SDL_TEXTINPUT events */
|
||||
switch(event->type) {
|
||||
case SDL_KEYDOWN: /*Button press*/
|
||||
{
|
||||
const uint32_t ctrl_key = keycode_to_ctrl_key(event->key.keysym.sym);
|
||||
if (ctrl_key == '\0')
|
||||
return;
|
||||
const size_t len = strlen(buf);
|
||||
if (len < KEYBOARD_BUFFER_SIZE - 1) {
|
||||
buf[len] = ctrl_key;
|
||||
buf[len + 1] = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_TEXTINPUT: /*Text input*/
|
||||
{
|
||||
const size_t len = strlen(buf) + strlen(event->text.text);
|
||||
if (len < KEYBOARD_BUFFER_SIZE - 1)
|
||||
strcat(buf, event->text.text);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a SDL key code to it's LV_KEY_* counterpart or return '\0' if it's not a control character.
|
||||
* @param sdl_key the key code
|
||||
* @return LV_KEY_* control character or '\0'
|
||||
*/
|
||||
uint32_t keycode_to_ctrl_key(SDL_Keycode sdl_key)
|
||||
{
|
||||
/*Remap some key to LV_KEY_... to manage groups*/
|
||||
|
||||
SDL_Keymod mode = SDL_GetModState();
|
||||
|
||||
switch(sdl_key) {
|
||||
case SDLK_RIGHT:
|
||||
case SDLK_KP_PLUS:
|
||||
return LV_KEY_RIGHT;
|
||||
|
||||
case SDLK_LEFT:
|
||||
case SDLK_KP_MINUS:
|
||||
return LV_KEY_LEFT;
|
||||
|
||||
case SDLK_UP:
|
||||
return LV_KEY_UP;
|
||||
|
||||
case SDLK_DOWN:
|
||||
return LV_KEY_DOWN;
|
||||
|
||||
case SDLK_ESCAPE:
|
||||
return LV_KEY_ESC;
|
||||
|
||||
case SDLK_BACKSPACE:
|
||||
return LV_KEY_BACKSPACE;
|
||||
|
||||
case SDLK_DELETE:
|
||||
return LV_KEY_DEL;
|
||||
|
||||
case SDLK_KP_ENTER:
|
||||
case '\r':
|
||||
return LV_KEY_ENTER;
|
||||
|
||||
case SDLK_TAB:
|
||||
return (mode & KMOD_SHIFT)? LV_KEY_PREV: LV_KEY_NEXT;
|
||||
|
||||
case SDLK_PAGEDOWN:
|
||||
return LV_KEY_NEXT;
|
||||
|
||||
case SDLK_PAGEUP:
|
||||
return LV_KEY_PREV;
|
||||
|
||||
default:
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_SDL || USD_SDL_GPU */
|
||||
93
libs/lv_drivers/sdl/sdl_common.h
Normal file
93
libs/lv_drivers/sdl/sdl_common.h
Normal file
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file sdl_common.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SDL_COMMON_H
|
||||
#define SDL_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if USE_SDL || USE_SDL_GPU
|
||||
|
||||
#ifndef SDL_INCLUDE_PATH
|
||||
#define SDL_INCLUDE_PATH MONITOR_SDL_INCLUDE_PATH
|
||||
#endif
|
||||
|
||||
#ifndef SDL_ZOOM
|
||||
#define SDL_ZOOM MONITOR_ZOOM
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
extern volatile bool sdl_quit_qry;
|
||||
|
||||
/**
|
||||
* Initialize SDL to be used as display, mouse and mouse wheel drivers.
|
||||
*/
|
||||
void sdl_init(void);
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixel to copy to the `area` part of the screen
|
||||
*/
|
||||
void sdl_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/**
|
||||
* Get the current position and state of the mouse
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the mouse data here
|
||||
*/
|
||||
void sdl_mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**
|
||||
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the read data here
|
||||
*/
|
||||
void sdl_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**
|
||||
* Get input from the keyboard.
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the red data here
|
||||
*/
|
||||
void sdl_keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
#endif /* USE_SDL || USE_SDL_GPU */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SDL_COMMON_H */
|
||||
39
libs/lv_drivers/sdl/sdl_common_internal.h
Normal file
39
libs/lv_drivers/sdl/sdl_common_internal.h
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file sdl_common_internal.h
|
||||
* Provides SDL related functions which are only used internal.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SDL_COMMON_INTERNAL_H
|
||||
#define SDL_COMMON_INTERNAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "sdl_common.h"
|
||||
|
||||
#if USE_SDL || USE_SDL_GPU
|
||||
|
||||
#include SDL_INCLUDE_PATH
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
int quit_filter(void * userdata, SDL_Event * event);
|
||||
|
||||
void mouse_handler(SDL_Event * event);
|
||||
void mousewheel_handler(SDL_Event * event);
|
||||
uint32_t keycode_to_ctrl_key(SDL_Keycode sdl_key);
|
||||
void keyboard_handler(SDL_Event * event);
|
||||
|
||||
#endif /* USE_SDL || USE_SDL_GPU */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SDL_COMMON_INTERNAL_H */
|
||||
279
libs/lv_drivers/sdl/sdl_gpu.c
Normal file
279
libs/lv_drivers/sdl/sdl_gpu.c
Normal file
@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @file sdl_gpu.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "sdl_gpu.h"
|
||||
#if USE_SDL_GPU
|
||||
|
||||
#if LV_USE_GPU_SDL == 0
|
||||
# error "LV_USE_DRAW_SDL must be enabled"
|
||||
#endif
|
||||
|
||||
#if USE_KEYBOARD
|
||||
# warning "KEYBOARD is deprecated, use SDL instead. See lv_drivers/sdl/sdl.c"
|
||||
#endif
|
||||
|
||||
#if USE_MOUSE
|
||||
# warning "MOUSE is deprecated, use SDL instead. See lv_drivers/sdl/sdl.c"
|
||||
#endif
|
||||
|
||||
#if USE_MOUSEWHEEL
|
||||
# warning "MOUSEWHEEL is deprecated, use SDL instead that. See lv_drivers/sdl/sdl.c"
|
||||
#endif
|
||||
|
||||
#if USE_MONITOR
|
||||
# error "Cannot enable both MONITOR and SDL at the same time. "
|
||||
#endif
|
||||
|
||||
#include "sdl_common_internal.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <lvgl/src/draw/sdl/lv_draw_sdl.h>
|
||||
#include SDL_INCLUDE_PATH
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef KEYBOARD_BUFFER_SIZE
|
||||
#define KEYBOARD_BUFFER_SIZE SDL_TEXTINPUTEVENT_TEXT_SIZE
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
lv_draw_sdl_drv_param_t drv_param;
|
||||
SDL_Window * window;
|
||||
SDL_Texture * texture;
|
||||
}monitor_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void window_create(monitor_t * m);
|
||||
static void window_update(lv_disp_drv_t *disp_drv, void * buf);
|
||||
static void monitor_sdl_clean_up(void);
|
||||
static void sdl_event_handler(lv_timer_t * t);
|
||||
|
||||
/***********************
|
||||
* GLOBAL PROTOTYPES
|
||||
***********************/
|
||||
|
||||
static volatile bool sdl_inited = false;
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void sdl_init(void)
|
||||
{
|
||||
/*Initialize the SDL*/
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
SDL_SetEventFilter(quit_filter, NULL);
|
||||
|
||||
sdl_inited = true;
|
||||
|
||||
SDL_StartTextInput();
|
||||
|
||||
lv_timer_create(sdl_event_handler, 1, NULL);
|
||||
}
|
||||
|
||||
void sdl_disp_drv_init(lv_disp_drv_t * disp_drv, lv_coord_t hor_res, lv_coord_t ver_res)
|
||||
{
|
||||
monitor_t *m = lv_mem_alloc(sizeof(monitor_t));
|
||||
window_create(m);
|
||||
lv_disp_drv_init(disp_drv);
|
||||
disp_drv->direct_mode = 1;
|
||||
disp_drv->flush_cb = monitor_flush;
|
||||
disp_drv->hor_res = hor_res;
|
||||
disp_drv->ver_res = ver_res;
|
||||
lv_disp_draw_buf_t *disp_buf = lv_mem_alloc(sizeof(lv_disp_draw_buf_t));
|
||||
lv_disp_draw_buf_init(disp_buf, m->texture, NULL, hor_res * ver_res);
|
||||
disp_drv->draw_buf = disp_buf;
|
||||
disp_drv->antialiasing = 1;
|
||||
disp_drv->user_data = &m->drv_param;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param disp_drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void sdl_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
lv_coord_t hres = disp_drv->hor_res;
|
||||
lv_coord_t vres = disp_drv->ver_res;
|
||||
|
||||
// printf("x1:%d,y1:%d,x2:%d,y2:%d\n", area->x1, area->y1, area->x2, area->y2);
|
||||
|
||||
/*Return if the area is out the screen*/
|
||||
if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TYPICALLY YOU DO NOT NEED THIS
|
||||
* If it was the last part to refresh update the texture of the window.*/
|
||||
if(lv_disp_flush_is_last(disp_drv)) {
|
||||
window_update(disp_drv, color_p);
|
||||
}
|
||||
|
||||
/*IMPORTANT! It must be called to tell the system the flush is ready*/
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
|
||||
}
|
||||
|
||||
void sdl_display_resize(lv_disp_t *disp, int width, int height)
|
||||
{
|
||||
lv_disp_drv_t *driver = disp->driver;
|
||||
SDL_Renderer *renderer = ((lv_draw_sdl_drv_param_t *) driver->user_data)->renderer;
|
||||
if (driver->draw_buf->buf1) {
|
||||
SDL_DestroyTexture(driver->draw_buf->buf1);
|
||||
}
|
||||
SDL_Texture *texture = lv_draw_sdl_create_screen_texture(renderer, width, height);
|
||||
lv_disp_draw_buf_init(driver->draw_buf, texture, NULL, width * height);
|
||||
driver->hor_res = (lv_coord_t) width;
|
||||
driver->ver_res = (lv_coord_t) height;
|
||||
SDL_RendererInfo renderer_info;
|
||||
SDL_GetRendererInfo(renderer, &renderer_info);
|
||||
SDL_assert(renderer_info.flags & SDL_RENDERER_TARGETTEXTURE);
|
||||
SDL_SetRenderTarget(renderer, texture);
|
||||
lv_disp_drv_update(disp, driver);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* SDL main thread. All SDL related task have to be handled here!
|
||||
* It initializes SDL, handles drawing and the mouse.
|
||||
*/
|
||||
|
||||
static void sdl_event_handler(lv_timer_t * t)
|
||||
{
|
||||
(void)t;
|
||||
|
||||
/*Refresh handling*/
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
mouse_handler(&event);
|
||||
mousewheel_handler(&event);
|
||||
keyboard_handler(&event);
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_WINDOWEVENT: {
|
||||
SDL_Window * window = SDL_GetWindowFromID(event.window.windowID);
|
||||
switch (event.window.event) {
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
||||
case SDL_WINDOWEVENT_TAKE_FOCUS:
|
||||
#endif
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
for (lv_disp_t *cur = lv_disp_get_next(NULL); cur; cur = lv_disp_get_next(cur)) {
|
||||
window_update(cur->driver, cur->driver->draw_buf->buf_act);
|
||||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED: {
|
||||
for (lv_disp_t *cur = lv_disp_get_next(NULL); cur; cur = lv_disp_get_next(cur)) {
|
||||
lv_draw_sdl_drv_param_t *param = cur->driver->user_data;
|
||||
SDL_Renderer *renderer = SDL_GetRenderer(window);
|
||||
if (param->renderer != renderer) continue;
|
||||
int w, h;
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
sdl_display_resize(cur, w, h);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_CLOSE: {
|
||||
for (lv_disp_t *cur = lv_disp_get_next(NULL); cur; ) {
|
||||
lv_disp_t * tmp = cur;
|
||||
cur = lv_disp_get_next(tmp);
|
||||
monitor_t * m = tmp->driver->user_data;
|
||||
SDL_Renderer *renderer = SDL_GetRenderer(window);
|
||||
if (m->drv_param.renderer != renderer) continue;
|
||||
SDL_DestroyTexture(tmp->driver->draw_buf->buf1);
|
||||
SDL_DestroyRenderer(m->drv_param.renderer);
|
||||
lv_disp_remove(tmp);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Run until quit event not arrives*/
|
||||
if(sdl_quit_qry) {
|
||||
monitor_sdl_clean_up();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void monitor_sdl_clean_up(void)
|
||||
{
|
||||
for (lv_disp_t *cur = lv_disp_get_next(NULL); cur; ) {
|
||||
lv_disp_t * tmp = cur;
|
||||
monitor_t * m = tmp->driver->user_data;
|
||||
SDL_DestroyTexture(tmp->driver->draw_buf->buf1);
|
||||
SDL_DestroyRenderer(m->drv_param.renderer);
|
||||
cur = lv_disp_get_next(cur);
|
||||
lv_disp_remove(tmp);
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
static void window_create(monitor_t * m)
|
||||
{
|
||||
// SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
||||
m->window = SDL_CreateWindow("TFT Simulator",
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_HOR_RES * SDL_ZOOM, SDL_VER_RES * SDL_ZOOM, SDL_WINDOW_RESIZABLE);
|
||||
|
||||
m->drv_param.renderer = SDL_CreateRenderer(m->window, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
||||
m->texture = lv_draw_sdl_create_screen_texture(m->drv_param.renderer, SDL_HOR_RES, SDL_VER_RES);
|
||||
/* For first frame */
|
||||
SDL_SetRenderTarget(m->drv_param.renderer, m->texture);
|
||||
}
|
||||
|
||||
static void window_update(lv_disp_drv_t *disp_drv, void * buf)
|
||||
{
|
||||
SDL_Renderer *renderer = ((lv_draw_sdl_drv_param_t *) disp_drv->user_data)->renderer;
|
||||
SDL_Texture *texture = buf;
|
||||
SDL_SetRenderTarget(renderer, NULL);
|
||||
SDL_RenderClear(renderer);
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
SDL_SetRenderDrawColor(renderer, 0xff, 0, 0, 0xff);
|
||||
SDL_Rect r;
|
||||
r.x = 0; r.y = 0; r.w = SDL_HOR_RES; r.h = SDL_VER_RES;
|
||||
SDL_RenderDrawRect(renderer, &r);
|
||||
#endif
|
||||
|
||||
/*Update the renderer with the texture containing the rendered image*/
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
SDL_RenderSetClipRect(renderer, NULL);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
SDL_SetRenderTarget(renderer, texture);
|
||||
}
|
||||
|
||||
#endif /*USE_SDL_GPU*/
|
||||
96
libs/lv_drivers/sdl/sdl_gpu.h
Normal file
96
libs/lv_drivers/sdl/sdl_gpu.h
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file sdl_gpu.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SDL_GPU_H
|
||||
#define SDL_GPU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_SDL_GPU
|
||||
|
||||
#include "sdl_common.h"
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize SDL to be used as display, mouse and mouse wheel drivers.
|
||||
*/
|
||||
void sdl_init(void);
|
||||
|
||||
void sdl_disp_drv_init(lv_disp_drv_t * disp_drv, lv_coord_t hor_res, lv_coord_t ver_res);
|
||||
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param disp_drv pointer to driver where this function belongs
|
||||
* @param area an area where to copy `color_p`
|
||||
* @param color_p an array of pixels to copy to the `area` part of the screen
|
||||
*/
|
||||
void sdl_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
|
||||
/**
|
||||
* Get the current position and state of the mouse
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the mouse data here
|
||||
*/
|
||||
void sdl_mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**
|
||||
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the read data here
|
||||
*/
|
||||
void sdl_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/**
|
||||
* Get input from the keyboard.
|
||||
* @param indev_drv pointer to the related input device driver
|
||||
* @param data store the red data here
|
||||
*/
|
||||
void sdl_keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
/*For backward compatibility. Will be removed.*/
|
||||
#define monitor_init sdl_init
|
||||
#define monitor_flush sdl_display_flush
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_SDL_GPU */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SDL_GPU_H */
|
||||
5
libs/lv_drivers/wayland/.gitignore
vendored
Normal file
5
libs/lv_drivers/wayland/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
/protocols
|
||||
39
libs/lv_drivers/wayland/CMakeLists.txt
Normal file
39
libs/lv_drivers/wayland/CMakeLists.txt
Normal file
@ -0,0 +1,39 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(lv_wayland)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(wayland-client REQUIRED wayland-client)
|
||||
pkg_check_modules(wayland-cursor REQUIRED wayland-cursor)
|
||||
pkg_check_modules(xkbcommon REQUIRED xkbcommon)
|
||||
|
||||
# Wayland protocols
|
||||
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
|
||||
pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols>=1.15)
|
||||
pkg_get_variable(WAYLAND_PROTOCOLS_BASE wayland-protocols pkgdatadir)
|
||||
|
||||
macro(wayland_generate protocol_xml_file output_dir target)
|
||||
get_filename_component(output_file_base ${protocol_xml_file} NAME_WE)
|
||||
set(output_file_noext "${output_dir}/wayland-${output_file_base}-client-protocol")
|
||||
add_custom_command(OUTPUT "${output_file_noext}.h"
|
||||
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" client-header "${protocol_xml_file}" "${output_file_noext}.h"
|
||||
DEPENDS "${protocol_xml_file}"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_command(OUTPUT "${output_file_noext}.c"
|
||||
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" private-code "${protocol_xml_file}" "${output_file_noext}.c"
|
||||
DEPENDS "${protocol_xml_file}"
|
||||
VERBATIM)
|
||||
|
||||
if(NOT EXISTS ${protocol_xml_file})
|
||||
message("Protocol XML file not found: " ${protocol_xml_file})
|
||||
else()
|
||||
set_property(TARGET ${target} APPEND PROPERTY SOURCES "${output_file_noext}.h" "${output_file_noext}.c")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
set(WAYLAND_PROTOCOLS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/protocols")
|
||||
file(MAKE_DIRECTORY ${WAYLAND_PROTOCOLS_DIR})
|
||||
|
||||
add_custom_target(generate_protocols ALL)
|
||||
|
||||
wayland_generate("${WAYLAND_PROTOCOLS_BASE}/stable/xdg-shell/xdg-shell.xml" ${WAYLAND_PROTOCOLS_DIR} generate_protocols)
|
||||
157
libs/lv_drivers/wayland/README.md
Normal file
157
libs/lv_drivers/wayland/README.md
Normal file
@ -0,0 +1,157 @@
|
||||
# Wayland display and input driver
|
||||
|
||||
Wayland display and input driver, with support for keyboard, pointer (i.e. mouse) and touchscreen.
|
||||
Keyboard support is based on libxkbcommon.
|
||||
|
||||
Following shell are supported:
|
||||
|
||||
* wl_shell (deprecated)
|
||||
* xdg_shell
|
||||
|
||||
> xdg_shell requires an extra build step; see section _Generate protocols_ below.
|
||||
|
||||
|
||||
Basic client-side window decorations (simple title bar, minimize and close buttons)
|
||||
are supported, while integration with desktop environments is not.
|
||||
|
||||
|
||||
## Install headers and libraries
|
||||
|
||||
### Ubuntu
|
||||
|
||||
```
|
||||
sudo apt-get install libwayland-dev libxkbcommon-dev libwayland-bin wayland-protocols
|
||||
```
|
||||
|
||||
### Fedora
|
||||
|
||||
```
|
||||
sudo dnf install wayland-devel libxkbcommon-devel wayland-utils wayland-protocols-devel
|
||||
```
|
||||
|
||||
|
||||
## Generate protocols
|
||||
|
||||
Support for non-basic shells (i.e. other than _wl_shell_) requires additional
|
||||
source files to be generated before the first build of the project. To do so,
|
||||
navigate to the _wayland_ folder (the one which includes this file) and issue
|
||||
the following commands:
|
||||
|
||||
```
|
||||
cmake .
|
||||
make
|
||||
```
|
||||
|
||||
|
||||
## Build configuration under Eclipse
|
||||
|
||||
In "Project properties > C/C++ Build > Settings" set the followings:
|
||||
|
||||
- "Cross GCC Compiler > Command line pattern"
|
||||
- Add ` ${wayland-cflags}` and ` ${xkbcommon-cflags}` to the end (add a space between the last command and this)
|
||||
|
||||
|
||||
- "Cross GCC Linker > Command line pattern"
|
||||
- Add ` ${wayland-libs}` and ` ${xkbcommon-libs}` to the end (add a space between the last command and this)
|
||||
|
||||
|
||||
- In "C/C++ Build > Build variables"
|
||||
- Configuration: [All Configuration]
|
||||
|
||||
- Add
|
||||
- Variable name: `wayland-cflags`
|
||||
- Type: `String`
|
||||
- Value: `pkg-config --cflags wayland-client`
|
||||
- Variable name: `wayland-libs`
|
||||
- Type: `String`
|
||||
- Value: `pkg-config --libs wayland-client`
|
||||
- Variable name: `xkbcommon-cflags`
|
||||
- Type: `String`
|
||||
- Value: `pkg-config --cflags xkbcommon`
|
||||
- Variable name: `xkbcommon-libs`
|
||||
- Type: `String`
|
||||
- Value: `pkg-config --libs xkbcommon`
|
||||
|
||||
|
||||
## Init Wayland in LVGL
|
||||
|
||||
1. In `main.c` `#incude "lv_drivers/wayland/wayland.h"`
|
||||
2. Enable the Wayland driver in `lv_drv_conf.h` with `USE_WAYLAND 1` and
|
||||
configure its features below, enabling at least support for one shell.
|
||||
3. `LV_COLOR_DEPTH` should be set either to `32` or `16` in `lv_conf.h`;
|
||||
support for `8` and `1` depends on target platform.
|
||||
4. After `lv_init()` call `lv_wayland_init()`.
|
||||
5. Add a display (or more than one) using `lv_wayland_create_window()`,
|
||||
possibly with a close callback to track the status of each display:
|
||||
```c
|
||||
#define H_RES (800)
|
||||
#define V_RES (480)
|
||||
|
||||
/* Create a display */
|
||||
lv_disp_t * disp = lv_wayland_create_window(H_RES, V_RES, "Window Title", close_cb);
|
||||
```
|
||||
As part of the above call, the Wayland driver will register four input devices
|
||||
for each display:
|
||||
- a KEYPAD connected to Wayland keyboard events
|
||||
- a POINTER connected to Wayland touch events
|
||||
- a POINTER connected to Wayland pointer events
|
||||
- a ENCODER connected to Wayland pointer axis events
|
||||
Handles for input devices of each display can be get using respectively
|
||||
`lv_wayland_get_indev_keyboard()`, `lv_wayland_get_indev_touchscreen()`,
|
||||
`lv_wayland_get_indev_pointer()` and `lv_wayland_get_indev_pointeraxis()`, using
|
||||
`disp` as argument.
|
||||
5. After `lv_deinit()` (if used), or in any case during de-initialization, call
|
||||
`lv_wayland_deinit()`.
|
||||
|
||||
### Fullscreen mode
|
||||
|
||||
In order to set one window as fullscreen or restore it as a normal one,
|
||||
call the `lv_wayland_window_set_fullscreen()` function respectively with `true`
|
||||
or `false` as `fullscreen` argument.
|
||||
|
||||
### Disable window client-side decoration at runtime
|
||||
|
||||
Even when client-side decorations are enabled at compile time, they can be
|
||||
disabled at runtime setting the `LV_WAYLAND_DISABLE_WINDOWDECORATION`
|
||||
environment variable to `1`.
|
||||
|
||||
### Event-driven timer handler
|
||||
|
||||
Set `LV_WAYLAND_TIMER_HANDLER` in `lv_drv_conf.h` and call `lv_wayland_timer_handler()`
|
||||
in your timer loop (in place of `lv_timer_handler()`).
|
||||
|
||||
You can now sleep/wait until the next timer/event is ready, e.g.:
|
||||
```
|
||||
/* [After initialization and display creation] */
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
|
||||
struct pollfd pfd;
|
||||
uint32_t time_till_next;
|
||||
int sleep;
|
||||
|
||||
pfd.fd = lv_wayland_get_fd();
|
||||
pfd.events = POLLIN;
|
||||
|
||||
while (1) {
|
||||
/* Handle any Wayland/LVGL timers/events */
|
||||
time_till_next = lv_wayland_timer_handler();
|
||||
|
||||
/* Run until the last window closes */
|
||||
if (!lv_wayland_window_is_open(NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait for something interesting to happen */
|
||||
if (time_till_next == LV_NO_TIMER_READY) {
|
||||
sleep = -1;
|
||||
} else if (time_till_next > INT_MAX) {
|
||||
sleep = INT_MAX;
|
||||
} else {
|
||||
sleep = time_till_next;
|
||||
}
|
||||
|
||||
while ((poll(&pfd, 1, sleep) < 0) && (errno == EINTR));
|
||||
}
|
||||
```
|
||||
2638
libs/lv_drivers/wayland/wayland.c
Normal file
2638
libs/lv_drivers/wayland/wayland.c
Normal file
File diff suppressed because it is too large
Load Diff
77
libs/lv_drivers/wayland/wayland.h
Normal file
77
libs/lv_drivers/wayland/wayland.h
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file wayland
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WAYLAND_H
|
||||
#define WAYLAND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_WAYLAND
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_USER_DATA == 0
|
||||
#error "Support for user data is required by wayland driver. Set LV_USE_USER_DATA to 1 in lv_conf.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef bool (*lv_wayland_display_close_f_t)(lv_disp_t * disp);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_wayland_init(void);
|
||||
void lv_wayland_deinit(void);
|
||||
int lv_wayland_get_fd(void);
|
||||
lv_disp_t * lv_wayland_create_window(lv_coord_t hor_res, lv_coord_t ver_res, char *title,
|
||||
lv_wayland_display_close_f_t close_cb);
|
||||
void lv_wayland_close_window(lv_disp_t * disp);
|
||||
bool lv_wayland_window_is_open(lv_disp_t * disp);
|
||||
bool lv_wayland_window_is_flush_pending(lv_disp_t * disp);
|
||||
void lv_wayland_window_set_fullscreen(lv_disp_t * disp, bool fullscreen);
|
||||
lv_indev_t * lv_wayland_get_pointer(lv_disp_t * disp);
|
||||
lv_indev_t * lv_wayland_get_pointeraxis(lv_disp_t * disp);
|
||||
lv_indev_t * lv_wayland_get_keyboard(lv_disp_t * disp);
|
||||
lv_indev_t * lv_wayland_get_touchscreen(lv_disp_t * disp);
|
||||
#ifdef LV_WAYLAND_TIMER_HANDLER
|
||||
uint32_t lv_wayland_timer_handler(void);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* USE_WAYLAND */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* WAYLAND_H */
|
||||
1054
libs/lv_drivers/win32drv/win32drv.c
Normal file
1054
libs/lv_drivers/win32drv/win32drv.c
Normal file
File diff suppressed because it is too large
Load Diff
79
libs/lv_drivers/win32drv/win32drv.h
Normal file
79
libs/lv_drivers/win32drv/win32drv.h
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file win32drv.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_WIN32DRV_H
|
||||
#define LV_WIN32DRV_H
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_WIN32DRV
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#if _MSC_VER >= 1200
|
||||
// Disable compilation warnings.
|
||||
#pragma warning(push)
|
||||
// nonstandard extension used : bit field types other than int
|
||||
#pragma warning(disable:4214)
|
||||
// 'conversion' conversion from 'type1' to 'type2', possible loss of data
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if _MSC_VER >= 1200
|
||||
// Restore compilation warnings.
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
EXTERN_C bool lv_win32_quit_signal;
|
||||
|
||||
EXTERN_C lv_indev_t* lv_win32_pointer_device_object;
|
||||
EXTERN_C lv_indev_t* lv_win32_keypad_device_object;
|
||||
EXTERN_C lv_indev_t* lv_win32_encoder_device_object;
|
||||
|
||||
EXTERN_C void lv_win32_add_all_input_devices_to_group(
|
||||
lv_group_t* group);
|
||||
|
||||
EXTERN_C bool lv_win32_init(
|
||||
HINSTANCE instance_handle,
|
||||
int show_window_mode,
|
||||
lv_coord_t hor_res,
|
||||
lv_coord_t ver_res,
|
||||
HICON icon_handle);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_WIN32DRV*/
|
||||
|
||||
#endif /*LV_WIN32DRV_H*/
|
||||
304
libs/lv_drivers/win_drv.c
Normal file
304
libs/lv_drivers/win_drv.c
Normal file
@ -0,0 +1,304 @@
|
||||
/**
|
||||
* @file win_drv.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "win_drv.h"
|
||||
#if USE_WINDOWS
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
#if LV_COLOR_DEPTH < 16
|
||||
#error Windows driver only supports true RGB colors at this time
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* DEFINES
|
||||
**********************/
|
||||
|
||||
#define WINDOW_STYLE (WS_OVERLAPPEDWINDOW & ~(WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void do_register(void);
|
||||
static void win_drv_flush(lv_disp_t *drv, lv_area_t *area, const lv_color_t * color_p);
|
||||
static void win_drv_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
|
||||
static void win_drv_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
|
||||
static void win_drv_read(lv_indev_t *drv, lv_indev_data_t * data);
|
||||
static void msg_handler(void *param);
|
||||
|
||||
static COLORREF lv_color_to_colorref(const lv_color_t color);
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
bool lv_win_exit_flag = false;
|
||||
lv_disp_t *lv_windows_disp;
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static HWND hwnd;
|
||||
static uint32_t *fbp = NULL; /* Raw framebuffer memory */
|
||||
static bool mouse_pressed;
|
||||
static int mouse_x, mouse_y;
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
const char g_szClassName[] = "LVGL";
|
||||
|
||||
HWND windrv_init(void)
|
||||
{
|
||||
WNDCLASSEX wc;
|
||||
RECT winrect;
|
||||
HICON lvgl_icon;
|
||||
|
||||
//Step 1: Registering the Window Class
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandle(NULL);
|
||||
lvgl_icon = (HICON) LoadImage( NULL, "lvgl_icon.bmp", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
|
||||
|
||||
if(lvgl_icon == NULL)
|
||||
lvgl_icon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
|
||||
wc.hIcon = lvgl_icon;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = g_szClassName;
|
||||
wc.hIconSm = lvgl_icon;
|
||||
|
||||
if(!RegisterClassEx(&wc))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
winrect.left = 0;
|
||||
winrect.right = WINDOW_HOR_RES - 1;
|
||||
winrect.top = 0;
|
||||
winrect.bottom = WINDOW_VER_RES - 1;
|
||||
AdjustWindowRectEx(&winrect, WINDOW_STYLE, FALSE, WS_EX_CLIENTEDGE);
|
||||
OffsetRect(&winrect, -winrect.left, -winrect.top);
|
||||
// Step 2: Creating the Window
|
||||
hwnd = CreateWindowEx(
|
||||
WS_EX_CLIENTEDGE,
|
||||
g_szClassName,
|
||||
"LVGL Simulator",
|
||||
WINDOW_STYLE,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, winrect.right, winrect.bottom,
|
||||
NULL, NULL, GetModuleHandle(NULL), NULL);
|
||||
|
||||
if(hwnd == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ShowWindow(hwnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
|
||||
lv_task_create(msg_handler, 0, LV_TASK_PRIO_HIGHEST, NULL);
|
||||
lv_win_exit_flag = false;
|
||||
do_register();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void do_register(void)
|
||||
{
|
||||
static lv_disp_draw_buf_t disp_buf_1;
|
||||
static lv_color_t buf1_1[WINDOW_HOR_RES * 100]; /*A buffer for 10 rows*/
|
||||
lv_disp_draw_buf_init(&disp_draw_buf_1, buf1_1, NULL, WINDOW_HOR_RES * 100); /*Initialize the display buffer*/
|
||||
|
||||
|
||||
/*-----------------------------------
|
||||
* Register the display in LVGLGL
|
||||
*----------------------------------*/
|
||||
|
||||
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
|
||||
/*Set up the functions to access to your display*/
|
||||
|
||||
/*Set the resolution of the display*/
|
||||
disp_drv.hor_res = WINDOW_HOR_RES;
|
||||
disp_drv.ver_res = WINDOW_VER_RES;
|
||||
|
||||
/*Used to copy the buffer's content to the display*/
|
||||
disp_drv.flush_cb = win_drv_flush;
|
||||
|
||||
/*Set a display buffer*/
|
||||
disp_drv.draw_buf = &disp_buf_1;
|
||||
|
||||
/*Finally register the driver*/
|
||||
lv_windows_disp = lv_disp_drv_register(&disp_drv);
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = win_drv_read;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
static void msg_handler(void *param)
|
||||
{
|
||||
(void)param;
|
||||
|
||||
MSG msg;
|
||||
BOOL bRet;
|
||||
if( (bRet = PeekMessage( &msg, NULL, 0, 0, TRUE )) != 0)
|
||||
{
|
||||
if (bRet == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
if(msg.message == WM_QUIT)
|
||||
lv_win_exit_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void win_drv_read(lv_indev_t *drv, lv_indev_data_t * data)
|
||||
{
|
||||
data->state = mouse_pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
data->point.x = mouse_x;
|
||||
data->point.y = mouse_y;
|
||||
}
|
||||
|
||||
static void on_paint(void)
|
||||
{
|
||||
HBITMAP bmp = CreateBitmap(WINDOW_HOR_RES, WINDOW_VER_RES, 1, 32, fbp);
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
HDC hdcMem = CreateCompatibleDC(hdc);
|
||||
HBITMAP hbmOld = SelectObject(hdcMem, bmp);
|
||||
|
||||
BitBlt(hdc, 0, 0, WINDOW_HOR_RES, WINDOW_VER_RES, hdcMem, 0, 0, SRCCOPY);
|
||||
|
||||
SelectObject(hdcMem, hbmOld);
|
||||
DeleteDC(hdcMem);
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
DeleteObject(bmp);
|
||||
|
||||
}
|
||||
/**
|
||||
* Flush a buffer to the marked area
|
||||
* @param x1 left coordinate
|
||||
* @param y1 top coordinate
|
||||
* @param x2 right coordinate
|
||||
* @param y2 bottom coordinate
|
||||
* @param color_p an array of colors
|
||||
*/
|
||||
static void win_drv_flush(lv_disp_t *drv, lv_area_t *area, const lv_color_t * color_p)
|
||||
{
|
||||
win_drv_map(area->x1, area->y1, area->x2, area->y2, color_p);
|
||||
lv_disp_flush_ready(drv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a color map to the marked area
|
||||
* @param x1 left coordinate
|
||||
* @param y1 top coordinate
|
||||
* @param x2 right coordinate
|
||||
* @param y2 bottom coordinate
|
||||
* @param color_p an array of colors
|
||||
*/
|
||||
static void win_drv_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
{
|
||||
for(int y = y1; y <= y2; y++)
|
||||
{
|
||||
for(int x = x1; x <= x2; x++)
|
||||
{
|
||||
fbp[y*WINDOW_HOR_RES+x] = lv_color_to32(*color_p);
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
UpdateWindow(hwnd);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
switch(msg) {
|
||||
case WM_CREATE:
|
||||
fbp = malloc(4*WINDOW_HOR_RES*WINDOW_VER_RES);
|
||||
if(fbp == NULL)
|
||||
return 1;
|
||||
SetTimer(hwnd, 0, 10, (TIMERPROC)lv_task_handler);
|
||||
SetTimer(hwnd, 1, 25, NULL);
|
||||
|
||||
return 0;
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
mouse_x = GET_X_LPARAM(lParam);
|
||||
mouse_y = GET_Y_LPARAM(lParam);
|
||||
if(msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) {
|
||||
mouse_pressed = (msg == WM_LBUTTONDOWN);
|
||||
}
|
||||
return 0;
|
||||
case WM_CLOSE:
|
||||
free(fbp);
|
||||
fbp = NULL;
|
||||
DestroyWindow(hwnd);
|
||||
return 0;
|
||||
case WM_PAINT:
|
||||
on_paint();
|
||||
return 0;
|
||||
case WM_TIMER:
|
||||
lv_tick_inc(25);
|
||||
return 0;
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
static COLORREF lv_color_to_colorref(const lv_color_t color)
|
||||
{
|
||||
uint32_t raw_color = lv_color_to32(color);
|
||||
lv_color32_t tmp;
|
||||
tmp.full = raw_color;
|
||||
uint32_t colorref = RGB(tmp.ch.red, tmp.ch.green, tmp.ch.blue);
|
||||
return colorref;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
60
libs/lv_drivers/win_drv.h
Normal file
60
libs/lv_drivers/win_drv.h
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file fbdev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WINDRV_H
|
||||
#define WINDRV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifndef LV_DRV_NO_CONF
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_drv_conf.h"
|
||||
#else
|
||||
#include "../lv_drv_conf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_WINDOWS
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
extern bool lv_win_exit_flag;
|
||||
extern lv_disp_t *lv_windows_disp;
|
||||
|
||||
HWND windrv_init(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_WINDOWS*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*WIN_DRV_H*/
|
||||
@ -14,6 +14,5 @@ elseif(MICROPY_DIR)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/env_support/cmake/micropython.cmake)
|
||||
else()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/env_support/cmake/custom.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/env_support/cmake/custom_simple_config.cmake)
|
||||
endif()
|
||||
|
||||
|
||||
@ -1,959 +0,0 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
* Configuration file for v9.0.0-dev
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copy this file as `lv_conf.h`
|
||||
* 1. simply next to the `lvgl` folder
|
||||
* 2. or any other places and
|
||||
* - define `LV_CONF_INCLUDE_SIMPLE`
|
||||
* - add the path as include path
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
#if 1 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
/*====================
|
||||
COLOR SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
|
||||
#define LV_COLOR_DEPTH 16
|
||||
|
||||
/*=========================
|
||||
STDLIB WRAPPER SETTINGS
|
||||
*=========================*/
|
||||
|
||||
/* Possible values
|
||||
* - LV_STDLIB_BUILTIN: LVGL's built in implementation
|
||||
* - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc
|
||||
* - LV_STDLIB_MICROPYTHON: MicroPython implementation
|
||||
* - LV_STDLIB_RTTHREAD: RT-Thread implementation
|
||||
* - LV_STDLIB_CUSTOM: Implement the functions externally
|
||||
*/
|
||||
#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN
|
||||
#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN
|
||||
#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN
|
||||
|
||||
|
||||
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
|
||||
/*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/
|
||||
#define LV_MEM_SIZE (256 * 1024U) /*[bytes]*/
|
||||
|
||||
/*Size of the memory expand for `lv_malloc()` in bytes*/
|
||||
#define LV_MEM_POOL_EXPAND_SIZE 0
|
||||
|
||||
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
|
||||
#define LV_MEM_ADR 0 /*0: unused*/
|
||||
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
|
||||
#if LV_MEM_ADR == 0
|
||||
#undef LV_MEM_POOL_INCLUDE
|
||||
#undef LV_MEM_POOL_ALLOC
|
||||
#endif
|
||||
#endif /*LV_USE_MALLOC == LV_STDLIB_BUILTIN*/
|
||||
|
||||
/*====================
|
||||
HAL SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*Default display refresh, input device read and animation step period.*/
|
||||
#define LV_DEF_REFR_PERIOD 33 /*[ms]*/
|
||||
|
||||
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
|
||||
*(Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI_DEF 130 /*[px/inch]*/
|
||||
|
||||
/*=================
|
||||
* OPERATING SYSTEM
|
||||
*=================*/
|
||||
/*Select an operating system to use. Possible options:
|
||||
* - LV_OS_NONE
|
||||
* - LV_OS_PTHREAD
|
||||
* - LV_OS_FREERTOS
|
||||
* - LV_OS_CMSIS_RTOS2
|
||||
* - LV_OS_RTTHREAD
|
||||
* - LV_OS_WINDOWS
|
||||
* - LV_OS_CUSTOM */
|
||||
#define LV_USE_OS LV_OS_NONE
|
||||
|
||||
#if LV_USE_OS == LV_OS_CUSTOM
|
||||
#define LV_OS_CUSTOM_INCLUDE <stdint.h>
|
||||
#endif
|
||||
|
||||
/*========================
|
||||
* RENDERING CONFIGURATION
|
||||
*========================*/
|
||||
|
||||
/*Align the stride of all layers and images to this bytes*/
|
||||
#define LV_DRAW_BUF_STRIDE_ALIGN 1
|
||||
|
||||
/*Align the start address of draw_buf addresses to this bytes*/
|
||||
#define LV_DRAW_BUF_ALIGN 4
|
||||
|
||||
#define LV_USE_DRAW_SW 1
|
||||
#if LV_USE_DRAW_SW == 1
|
||||
/* Set the number of draw unit.
|
||||
* > 1 requires an operating system enabled in `LV_USE_OS`
|
||||
* > 1 means multiply threads will render the screen in parallel */
|
||||
#define LV_DRAW_SW_DRAW_UNIT_CNT 1
|
||||
|
||||
/* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode
|
||||
* it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks.
|
||||
* "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers
|
||||
* and can't be drawn in chunks. */
|
||||
|
||||
/*The target buffer size for simple layer chunks.*/
|
||||
#define LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/
|
||||
|
||||
/* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only
|
||||
* 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */
|
||||
#define LV_DRAW_SW_COMPLEX 1
|
||||
|
||||
#if LV_DRAW_SW_COMPLEX == 1
|
||||
/*Allow buffering some shadow calculation.
|
||||
*LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
|
||||
*Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/
|
||||
#define LV_DRAW_SW_SHADOW_CACHE_SIZE 0
|
||||
|
||||
/* Set number of maximally cached circle data.
|
||||
* The circumference of 1/4 circle are saved for anti-aliasing
|
||||
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
|
||||
* 0: to disable caching */
|
||||
#define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4
|
||||
#endif
|
||||
|
||||
#define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE
|
||||
|
||||
#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM
|
||||
#define LV_DRAW_SW_ASM_CUSTOM_INCLUDE ""
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use Arm-2D on Cortex-M based devices. Please only enable it for Helium Powered devices for now */
|
||||
#define LV_USE_DRAW_ARM2D 0
|
||||
|
||||
/* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */
|
||||
#define LV_USE_DRAW_VGLITE 0
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
/* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */
|
||||
#define LV_USE_VGLITE_BLIT_SPLIT 0
|
||||
|
||||
#if LV_USE_OS
|
||||
/* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */
|
||||
#define LV_USE_VGLITE_DRAW_ASYNC 1
|
||||
#endif
|
||||
|
||||
/* Enable VGLite asserts. */
|
||||
#define LV_USE_VGLITE_ASSERT 0
|
||||
#endif
|
||||
|
||||
/* Use NXP's PXP on iMX RTxxx platforms. */
|
||||
#define LV_USE_DRAW_PXP 0
|
||||
|
||||
#if LV_USE_DRAW_PXP
|
||||
/* Enable PXP asserts. */
|
||||
#define LV_USE_PXP_ASSERT 0
|
||||
#endif
|
||||
|
||||
/* Use Renesas Dave2D on RA platforms. */
|
||||
#define LV_USE_DRAW_DAVE2D 0
|
||||
|
||||
/* Draw using cached SDL textures*/
|
||||
#define LV_USE_DRAW_SDL 0
|
||||
|
||||
/* Use VG-Lite GPU. */
|
||||
#define LV_USE_DRAW_VG_LITE 0
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
/* Enable VG-Lite custom external 'gpu_init()' function */
|
||||
#define LV_VG_LITE_USE_GPU_INIT 0
|
||||
|
||||
/* Enable VG-Lite assert. */
|
||||
#define LV_VG_LITE_USE_ASSERT 0
|
||||
|
||||
#endif
|
||||
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
|
||||
/*-------------
|
||||
* Logging
|
||||
*-----------*/
|
||||
|
||||
/*Enable the log module*/
|
||||
#define LV_USE_LOG 1
|
||||
#if LV_USE_LOG
|
||||
|
||||
/*How important log should be added:
|
||||
*LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
*LV_LOG_LEVEL_INFO Log important events
|
||||
*LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
/*1: Print the log with 'printf';
|
||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
||||
#define LV_LOG_PRINTF 1
|
||||
|
||||
/*1: Enable print timestamp;
|
||||
*0: Disable print timestamp*/
|
||||
#define LV_LOG_USE_TIMESTAMP 1
|
||||
|
||||
/*1: Print file and line number of the log;
|
||||
*0: Do not print file and line number of the log*/
|
||||
#define LV_LOG_USE_FILE_LINE 1
|
||||
|
||||
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
|
||||
#define LV_LOG_TRACE_MEM 1
|
||||
#define LV_LOG_TRACE_TIMER 1
|
||||
#define LV_LOG_TRACE_INDEV 1
|
||||
#define LV_LOG_TRACE_DISP_REFR 1
|
||||
#define LV_LOG_TRACE_EVENT 1
|
||||
#define LV_LOG_TRACE_OBJ_CREATE 1
|
||||
#define LV_LOG_TRACE_LAYOUT 1
|
||||
#define LV_LOG_TRACE_ANIM 1
|
||||
#define LV_LOG_TRACE_CACHE 1
|
||||
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*-------------
|
||||
* Asserts
|
||||
*-----------*/
|
||||
|
||||
/*Enable asserts if an operation is failed or an invalid data is found.
|
||||
*If LV_USE_LOG is enabled an error message will be printed on failure*/
|
||||
#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_STYLE 1 /*Check if the styles are properly initialized. (Very fast, recommended)*/
|
||||
#define LV_USE_ASSERT_MEM_INTEGRITY 1 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
|
||||
#define LV_USE_ASSERT_OBJ 1 /*Check the object's type and existence (e.g. not deleted). (Slow)*/
|
||||
|
||||
/*Add a custom handler when assert happens e.g. to restart the MCU*/
|
||||
#define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
|
||||
#define LV_ASSERT_HANDLER while(1); /*Halt by default*/
|
||||
|
||||
/*-------------
|
||||
* Debug
|
||||
*-----------*/
|
||||
|
||||
/*1: Draw random colored rectangles over the redrawn areas*/
|
||||
#define LV_USE_REFR_DEBUG 0
|
||||
|
||||
/*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/
|
||||
#define LV_USE_LAYER_DEBUG 0
|
||||
|
||||
/*1: Draw overlays with different colors for each draw_unit's tasks.
|
||||
*Also add the index number of the draw unit on white background.
|
||||
*For layers add the index number of the draw unit on black background.*/
|
||||
#define LV_USE_PARALLEL_DRAW_DEBUG 0
|
||||
|
||||
/*-------------
|
||||
* Others
|
||||
*-----------*/
|
||||
|
||||
#define LV_ENABLE_GLOBAL_CUSTOM 0
|
||||
#if LV_ENABLE_GLOBAL_CUSTOM
|
||||
/*Header to include for the custom 'lv_global' function"*/
|
||||
#define LV_GLOBAL_CUSTOM_INCLUDE <stdint.h>
|
||||
#endif
|
||||
|
||||
/*Default cache size in bytes.
|
||||
*Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory.
|
||||
*If size is not set to 0, the decoder will fail to decode when the cache is full.
|
||||
*If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/
|
||||
#define LV_CACHE_DEF_SIZE 0
|
||||
|
||||
/*Number of stops allowed per gradient. Increase this to allow more stops.
|
||||
*This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
|
||||
#define LV_GRADIENT_MAX_STOPS 2
|
||||
|
||||
/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently.
|
||||
* 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */
|
||||
#define LV_COLOR_MIX_ROUND_OFS 0
|
||||
|
||||
/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */
|
||||
#define LV_OBJ_STYLE_CACHE 0
|
||||
|
||||
/* Add `id` field to `lv_obj_t` */
|
||||
#define LV_USE_OBJ_ID 0
|
||||
|
||||
/* Use lvgl builtin method for obj ID */
|
||||
#define LV_USE_OBJ_ID_BUILTIN 0
|
||||
|
||||
/*Use obj property set/get API*/
|
||||
#define LV_USE_OBJ_PROPERTY 0
|
||||
|
||||
/* VG-Lite Simulator */
|
||||
/*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */
|
||||
#define LV_USE_VG_LITE_THORVG 0
|
||||
|
||||
#if LV_USE_VG_LITE_THORVG
|
||||
|
||||
/*Enable LVGL's blend mode support*/
|
||||
#define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0
|
||||
|
||||
/*Enable YUV color format support*/
|
||||
#define LV_VG_LITE_THORVG_YUV_SUPPORT 0
|
||||
|
||||
/*Enable 16 pixels alignment*/
|
||||
#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1
|
||||
|
||||
/*Enable multi-thread render*/
|
||||
#define LV_VG_LITE_THORVG_THREAD_RENDER 0
|
||||
|
||||
#endif
|
||||
|
||||
/*=====================
|
||||
* COMPILER SETTINGS
|
||||
*====================*/
|
||||
|
||||
/*For big endian systems set to 1*/
|
||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
||||
|
||||
/*Define a custom attribute to `lv_tick_inc` function*/
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
/*Define a custom attribute to `lv_timer_handler` function*/
|
||||
#define LV_ATTRIBUTE_TIMER_HANDLER
|
||||
|
||||
/*Define a custom attribute to `lv_display_flush_ready` function*/
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
|
||||
/*Required alignment size for buffers*/
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1
|
||||
|
||||
/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default).
|
||||
* E.g. __attribute__((aligned(4)))*/
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
||||
/*Attribute to mark large constant arrays for example font's bitmaps*/
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
|
||||
/*Compiler prefix for a big array declaration in RAM*/
|
||||
#define LV_ATTRIBUTE_LARGE_RAM_ARRAY
|
||||
|
||||
/*Place performance critical functions into a faster memory (e.g RAM)*/
|
||||
#define LV_ATTRIBUTE_FAST_MEM
|
||||
|
||||
/*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
|
||||
*should also appear on LVGL binding API such as Micropython.*/
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/
|
||||
|
||||
/*Prefix all global extern data with this*/
|
||||
#define LV_ATTRIBUTE_EXTERN_DATA
|
||||
|
||||
/* Use `float` as `lv_value_precise_t` */
|
||||
#define LV_USE_FLOAT 0
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
|
||||
*https://fonts.google.com/specimen/Montserrat*/
|
||||
#define LV_FONT_MONTSERRAT_8 1
|
||||
#define LV_FONT_MONTSERRAT_10 1
|
||||
#define LV_FONT_MONTSERRAT_12 1
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_16 1
|
||||
#define LV_FONT_MONTSERRAT_18 1
|
||||
#define LV_FONT_MONTSERRAT_20 1
|
||||
#define LV_FONT_MONTSERRAT_22 1
|
||||
#define LV_FONT_MONTSERRAT_24 1
|
||||
#define LV_FONT_MONTSERRAT_26 1
|
||||
#define LV_FONT_MONTSERRAT_28 1
|
||||
#define LV_FONT_MONTSERRAT_30 1
|
||||
#define LV_FONT_MONTSERRAT_32 1
|
||||
#define LV_FONT_MONTSERRAT_34 1
|
||||
#define LV_FONT_MONTSERRAT_36 1
|
||||
#define LV_FONT_MONTSERRAT_38 1
|
||||
#define LV_FONT_MONTSERRAT_40 1
|
||||
#define LV_FONT_MONTSERRAT_42 1
|
||||
#define LV_FONT_MONTSERRAT_44 1
|
||||
#define LV_FONT_MONTSERRAT_46 1
|
||||
#define LV_FONT_MONTSERRAT_48 1
|
||||
|
||||
/*Demonstrate special features*/
|
||||
#define LV_FONT_MONTSERRAT_28_COMPRESSED 1 /*bpp = 3*/
|
||||
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1 /*Hebrew, Arabic, Persian letters and all their forms*/
|
||||
#define LV_FONT_SIMSUN_16_CJK 1 /*1000 most common CJK radicals*/
|
||||
|
||||
/*Pixel perfect monospace fonts*/
|
||||
#define LV_FONT_UNSCII_8 1
|
||||
#define LV_FONT_UNSCII_16 1
|
||||
|
||||
/*Optionally declare custom fonts here.
|
||||
*You can use these fonts as default font too and they will be available globally.
|
||||
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
|
||||
/*Always set a default font*/
|
||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||
|
||||
/*Enable handling large font and/or fonts with a lot of characters.
|
||||
*The limit depends on the font size, font face and bpp.
|
||||
*Compiler error will be triggered if a font needs it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 1
|
||||
|
||||
/*Enables/disables support for compressed fonts.*/
|
||||
#define LV_USE_FONT_COMPRESSED 1
|
||||
|
||||
/*Enable drawing placeholders when glyph dsc is not found*/
|
||||
#define LV_USE_FONT_PLACEHOLDER 1
|
||||
|
||||
/*=================
|
||||
* TEXT SETTINGS
|
||||
*=================*/
|
||||
|
||||
/**
|
||||
* Select a character encoding for strings.
|
||||
* Your IDE or editor should have the same character encoding
|
||||
* - LV_TXT_ENC_UTF8
|
||||
* - LV_TXT_ENC_ASCII
|
||||
*/
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_)]}"
|
||||
|
||||
/*If a word is at least this long, will break wherever "prettiest"
|
||||
*To disable, set to a value <= 0*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 0
|
||||
|
||||
/*Minimum number of characters in a long word to put on a line before a break.
|
||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||
|
||||
/*Minimum number of characters in a long word to put on a line after a break.
|
||||
*Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||
|
||||
/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts.
|
||||
*The direction will be processed according to the Unicode Bidirectional Algorithm:
|
||||
*https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||
#define LV_USE_BIDI 0
|
||||
#if LV_USE_BIDI
|
||||
/*Set the default direction. Supported values:
|
||||
*`LV_BASE_DIR_LTR` Left-to-Right
|
||||
*`LV_BASE_DIR_RTL` Right-to-Left
|
||||
*`LV_BASE_DIR_AUTO` detect texts base direction*/
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
|
||||
#endif
|
||||
|
||||
/*Enable Arabic/Persian processing
|
||||
*In these languages characters should be replaced with an other form based on their position in the text*/
|
||||
#define LV_USE_ARABIC_PERSIAN_CHARS 0
|
||||
|
||||
/*==================
|
||||
* WIDGETS
|
||||
*================*/
|
||||
|
||||
/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/
|
||||
|
||||
#define LV_WIDGETS_HAS_DEFAULT_VALUE 1
|
||||
|
||||
#define LV_USE_ANIMIMG 1
|
||||
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
#define LV_USE_BUTTON 1
|
||||
|
||||
#define LV_USE_BUTTONMATRIX 1
|
||||
|
||||
#define LV_USE_CALENDAR 1
|
||||
#if LV_USE_CALENDAR
|
||||
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||
#if LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
|
||||
#else
|
||||
#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"}
|
||||
#endif
|
||||
|
||||
#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
|
||||
#define LV_USE_CALENDAR_HEADER_ARROW 1
|
||||
#define LV_USE_CALENDAR_HEADER_DROPDOWN 1
|
||||
#endif /*LV_USE_CALENDAR*/
|
||||
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
#define LV_USE_CHART 1
|
||||
|
||||
#define LV_USE_CHECKBOX 1
|
||||
|
||||
#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_IMAGE 1 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_IMAGEBUTTON 1
|
||||
|
||||
#define LV_USE_KEYBOARD 1
|
||||
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL
|
||||
#define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/
|
||||
#define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/
|
||||
#define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_LED 1
|
||||
|
||||
#define LV_USE_LINE 1
|
||||
|
||||
#define LV_USE_LIST 1
|
||||
|
||||
#define LV_USE_MENU 1
|
||||
|
||||
#define LV_USE_MSGBOX 1
|
||||
|
||||
#define LV_USE_ROLLER 1 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_SCALE 1
|
||||
|
||||
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/
|
||||
|
||||
#define LV_USE_SPAN 1
|
||||
#if LV_USE_SPAN
|
||||
/*A line text can contain maximum num of span descriptor */
|
||||
#define LV_SPAN_SNIPPET_STACK_SIZE 64
|
||||
#endif
|
||||
|
||||
#define LV_USE_SPINBOX 1
|
||||
|
||||
#define LV_USE_SPINNER 1
|
||||
|
||||
#define LV_USE_SWITCH 1
|
||||
|
||||
#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/
|
||||
#if LV_USE_TEXTAREA != 0
|
||||
#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
#define LV_USE_TABLE 1
|
||||
|
||||
#define LV_USE_TABVIEW 1
|
||||
|
||||
#define LV_USE_TILEVIEW 1
|
||||
|
||||
#define LV_USE_WIN 1
|
||||
|
||||
/*==================
|
||||
* THEMES
|
||||
*==================*/
|
||||
|
||||
/*A simple, impressive and very complete theme*/
|
||||
#define LV_USE_THEME_DEFAULT 1
|
||||
#if LV_USE_THEME_DEFAULT
|
||||
|
||||
/*0: Light mode; 1: Dark mode*/
|
||||
#define LV_THEME_DEFAULT_DARK 0
|
||||
|
||||
/*1: Enable grow on press*/
|
||||
#define LV_THEME_DEFAULT_GROW 1
|
||||
|
||||
/*Default transition time in [ms]*/
|
||||
#define LV_THEME_DEFAULT_TRANSITION_TIME 80
|
||||
#endif /*LV_USE_THEME_DEFAULT*/
|
||||
|
||||
/*A very simple theme that is a good starting point for a custom theme*/
|
||||
#define LV_USE_THEME_SIMPLE 1
|
||||
|
||||
/*A theme designed for monochrome displays*/
|
||||
#define LV_USE_THEME_MONO 1
|
||||
|
||||
/*==================
|
||||
* LAYOUTS
|
||||
*==================*/
|
||||
|
||||
/*A layout similar to Flexbox in CSS.*/
|
||||
#define LV_USE_FLEX 1
|
||||
|
||||
/*A layout similar to Grid in CSS.*/
|
||||
#define LV_USE_GRID 1
|
||||
|
||||
/*====================
|
||||
* 3RD PARTS LIBRARIES
|
||||
*====================*/
|
||||
|
||||
/*File system interfaces for common APIs */
|
||||
|
||||
/*API for fopen, fread, etc*/
|
||||
#define LV_USE_FS_STDIO 1
|
||||
#if LV_USE_FS_STDIO
|
||||
#define LV_FS_STDIO_LETTER 'A' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
||||
#define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*API for open, read, etc*/
|
||||
#define LV_USE_FS_POSIX 0
|
||||
#if LV_USE_FS_POSIX
|
||||
#define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
||||
#define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*API for CreateFile, ReadFile, etc*/
|
||||
#define LV_USE_FS_WIN32 0
|
||||
#if LV_USE_FS_WIN32
|
||||
#define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/
|
||||
#define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
|
||||
#define LV_USE_FS_FATFS 0
|
||||
#if LV_USE_FS_FATFS
|
||||
#define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
|
||||
#endif
|
||||
|
||||
/*API for memory-mapped file access. */
|
||||
#define LV_USE_FS_MEMFS 1
|
||||
#if LV_USE_FS_MEMFS
|
||||
#define LV_FS_MEMFS_LETTER 'M' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
#endif
|
||||
|
||||
/*LODEPNG decoder library*/
|
||||
#define LV_USE_LODEPNG 1
|
||||
|
||||
/*PNG decoder(libpng) library*/
|
||||
#define LV_USE_LIBPNG 0
|
||||
|
||||
/*BMP decoder library*/
|
||||
#define LV_USE_BMP 1
|
||||
|
||||
/* JPG + split JPG decoder library.
|
||||
* Split JPG is a custom format optimized for embedded systems. */
|
||||
#define LV_USE_TJPGD 1
|
||||
|
||||
/* libjpeg-turbo decoder library.
|
||||
* Supports complete JPEG specifications and high-performance JPEG decoding. */
|
||||
#define LV_USE_LIBJPEG_TURBO 0
|
||||
|
||||
/*GIF decoder library*/
|
||||
#define LV_USE_GIF 1
|
||||
#if LV_USE_GIF
|
||||
/*GIF decoder accelerate*/
|
||||
#define LV_GIF_CACHE_DECODE_DATA 0
|
||||
#endif
|
||||
|
||||
|
||||
/*Decode bin images to RAM*/
|
||||
#define LV_BIN_DECODER_RAM_LOAD 0
|
||||
|
||||
/*RLE decompress library*/
|
||||
#define LV_USE_RLE 1
|
||||
|
||||
/*QR code library*/
|
||||
#define LV_USE_QRCODE 1
|
||||
|
||||
/*Barcode code library*/
|
||||
#define LV_USE_BARCODE 1
|
||||
|
||||
/*FreeType library*/
|
||||
#ifndef LV_USE_FREETYPE
|
||||
#define LV_USE_FREETYPE 0
|
||||
#endif
|
||||
|
||||
#if LV_USE_FREETYPE
|
||||
/*Memory used by FreeType to cache characters in kilobytes*/
|
||||
#define LV_FREETYPE_CACHE_SIZE 768
|
||||
|
||||
/*Let FreeType to use LVGL memory and file porting*/
|
||||
#define LV_FREETYPE_USE_LVGL_PORT 0
|
||||
|
||||
/* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
|
||||
/* (0:use system defaults) */
|
||||
#define LV_FREETYPE_CACHE_FT_FACES 8
|
||||
#define LV_FREETYPE_CACHE_FT_SIZES 8
|
||||
#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256
|
||||
#endif
|
||||
|
||||
/* Built-in TTF decoder */
|
||||
#define LV_USE_TINY_TTF 1
|
||||
#if LV_USE_TINY_TTF
|
||||
/* Enable loading TTF data from files */
|
||||
#define LV_TINY_TTF_FILE_SUPPORT 0
|
||||
#endif
|
||||
|
||||
/*Rlottie library*/
|
||||
#define LV_USE_RLOTTIE 0
|
||||
|
||||
/*Enable Vector Graphic APIs*/
|
||||
#define LV_USE_VECTOR_GRAPHIC 1
|
||||
|
||||
/* Enable ThorVG (vector graphics library) from the src/libs folder */
|
||||
#define LV_USE_THORVG_INTERNAL 1
|
||||
|
||||
/* Enable ThorVG by assuming that its installed and linked to the project */
|
||||
#define LV_USE_THORVG_EXTERNAL 0
|
||||
|
||||
/*Enable LZ4 compress/decompress lib*/
|
||||
#define LV_USE_LZ4 1
|
||||
|
||||
/*Use lvgl built-in LZ4 lib*/
|
||||
#define LV_USE_LZ4_INTERNAL 1
|
||||
|
||||
/*Use external LZ4 library*/
|
||||
#define LV_USE_LZ4_EXTERNAL 0
|
||||
|
||||
/*FFmpeg library for image decoding and playing videos
|
||||
*Supports all major image formats so do not enable other image decoder with it*/
|
||||
#define LV_USE_FFMPEG 0
|
||||
#if LV_USE_FFMPEG
|
||||
/*Dump input information to stderr*/
|
||||
#define LV_FFMPEG_DUMP_FORMAT 0
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* OTHERS
|
||||
*==================*/
|
||||
|
||||
/*1: Enable API to take snapshot for object*/
|
||||
#define LV_USE_SNAPSHOT 1
|
||||
|
||||
/*1: Enable system monitor component*/
|
||||
#define LV_USE_SYSMON 1
|
||||
|
||||
#if LV_USE_SYSMON
|
||||
|
||||
/*1: Show CPU usage and FPS count
|
||||
* Requires `LV_USE_SYSMON = 1`*/
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
|
||||
|
||||
/*0: Displays performance data on the screen, 1: Prints performance data using log.*/
|
||||
#define LV_USE_PERF_MONITOR_LOG_MODE 0
|
||||
#endif
|
||||
|
||||
/*1: Show the used memory and the memory fragmentation
|
||||
* Requires `LV_USE_BUILTIN_MALLOC = 1`
|
||||
* Requires `LV_USE_SYSMON = 1`*/
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#if LV_USE_MEM_MONITOR
|
||||
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_SYSMON*/
|
||||
|
||||
/*1: Enable the runtime performance profiler*/
|
||||
#define LV_USE_PROFILER 0
|
||||
#if LV_USE_PROFILER
|
||||
/*1: Enable the built-in profiler*/
|
||||
#define LV_USE_PROFILER_BUILTIN 1
|
||||
#if LV_USE_PROFILER_BUILTIN
|
||||
/*Default profiler trace buffer size*/
|
||||
#define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/
|
||||
#endif
|
||||
|
||||
/*Header to include for the profiler*/
|
||||
#define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h"
|
||||
|
||||
/*Profiler start point function*/
|
||||
#define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN
|
||||
|
||||
/*Profiler end point function*/
|
||||
#define LV_PROFILER_END LV_PROFILER_BUILTIN_END
|
||||
|
||||
/*Profiler start point function with custom tag*/
|
||||
#define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG
|
||||
|
||||
/*Profiler end point function with custom tag*/
|
||||
#define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG
|
||||
#endif
|
||||
|
||||
/*1: Enable Monkey test*/
|
||||
#define LV_USE_MONKEY 1
|
||||
|
||||
/*1: Enable grid navigation*/
|
||||
#define LV_USE_GRIDNAV 1
|
||||
|
||||
/*1: Enable lv_obj fragment*/
|
||||
#define LV_USE_FRAGMENT 1
|
||||
|
||||
/*1: Support using images as font in label or span widgets */
|
||||
#define LV_USE_IMGFONT 1
|
||||
#if LV_USE_IMGFONT
|
||||
/*Imgfont image file path maximum length*/
|
||||
#define LV_IMGFONT_PATH_MAX_LEN 64
|
||||
|
||||
/*1: Use img cache to buffer header information*/
|
||||
#define LV_IMGFONT_USE_IMAGE_CACHE_HEADER 0
|
||||
#endif
|
||||
|
||||
/*1: Enable an observer pattern implementation*/
|
||||
#define LV_USE_OBSERVER 1
|
||||
|
||||
/*1: Enable Pinyin input method*/
|
||||
/*Requires: lv_keyboard*/
|
||||
#define LV_USE_IME_PINYIN 1
|
||||
#if LV_USE_IME_PINYIN
|
||||
/*1: Use default thesaurus*/
|
||||
/*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/
|
||||
#define LV_IME_PINYIN_USE_DEFAULT_DICT 1
|
||||
/*Set the maximum number of candidate panels that can be displayed*/
|
||||
/*This needs to be adjusted according to the size of the screen*/
|
||||
#define LV_IME_PINYIN_CAND_TEXT_NUM 6
|
||||
|
||||
/*Use 9 key input(k9)*/
|
||||
#define LV_IME_PINYIN_USE_K9_MODE 1
|
||||
#if LV_IME_PINYIN_USE_K9_MODE == 1
|
||||
#define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3
|
||||
#endif /*LV_IME_PINYIN_USE_K9_MODE*/
|
||||
#endif
|
||||
|
||||
/*1: Enable file explorer*/
|
||||
/*Requires: lv_table*/
|
||||
#define LV_USE_FILE_EXPLORER 1
|
||||
#if LV_USE_FILE_EXPLORER
|
||||
/*Maximum length of path*/
|
||||
#define LV_FILE_EXPLORER_PATH_MAX_LEN (128)
|
||||
/*Quick access bar, 1:use, 0:not use*/
|
||||
/*Requires: lv_list*/
|
||||
#define LV_FILE_EXPLORER_QUICK_ACCESS 1
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* DEVICES
|
||||
*==================*/
|
||||
|
||||
/*Use SDL to open window on PC and handle mouse and keyboard*/
|
||||
#define LV_USE_SDL 1
|
||||
#if LV_USE_SDL
|
||||
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||
#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/
|
||||
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/
|
||||
#define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
|
||||
#define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/
|
||||
#endif
|
||||
|
||||
/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/
|
||||
#define LV_USE_X11 0
|
||||
#if LV_USE_X11
|
||||
#define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/
|
||||
#define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/
|
||||
/*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/
|
||||
#define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/
|
||||
#define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/
|
||||
#define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/fb*/
|
||||
#define LV_USE_LINUX_FBDEV 0
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
#define LV_LINUX_FBDEV_BSD 0
|
||||
#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL
|
||||
#define LV_LINUX_FBDEV_BUFFER_COUNT 0
|
||||
#define LV_LINUX_FBDEV_BUFFER_SIZE 60
|
||||
#endif
|
||||
|
||||
/*Use Nuttx to open window and handle touchscreen*/
|
||||
#define LV_USE_NUTTX 0
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
#define LV_USE_NUTTX_LIBUV 0
|
||||
|
||||
/*Use Nuttx custom init API to open window and handle touchscreen*/
|
||||
#define LV_USE_NUTTX_CUSTOM_INIT 0
|
||||
|
||||
/*Driver for /dev/lcd*/
|
||||
#define LV_USE_NUTTX_LCD 0
|
||||
#if LV_USE_NUTTX_LCD
|
||||
#define LV_NUTTX_LCD_BUFFER_COUNT 0
|
||||
#define LV_NUTTX_LCD_BUFFER_SIZE 60
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/input*/
|
||||
#define LV_USE_NUTTX_TOUCHSCREEN 0
|
||||
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/dri/card*/
|
||||
#define LV_USE_LINUX_DRM 0
|
||||
|
||||
/*Interface for TFT_eSPI*/
|
||||
#define LV_USE_TFT_ESPI 0
|
||||
|
||||
/*Driver for evdev input devices*/
|
||||
#define LV_USE_EVDEV 0
|
||||
|
||||
/*Drivers for LCD devices connected via SPI/parallel port*/
|
||||
#define LV_USE_ST7735 0
|
||||
#define LV_USE_ST7789 0
|
||||
#define LV_USE_ST7796 0
|
||||
#define LV_USE_ILI9341 0
|
||||
|
||||
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
|
||||
/* LVGL Windows backend */
|
||||
#define LV_USE_WINDOWS 0
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
/*Enable the examples to be built with the library*/
|
||||
#define LV_BUILD_EXAMPLES 1
|
||||
|
||||
/*===================
|
||||
* DEMO USAGE
|
||||
====================*/
|
||||
|
||||
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
|
||||
#define LV_USE_DEMO_WIDGETS 1
|
||||
#if LV_USE_DEMO_WIDGETS
|
||||
#define LV_DEMO_WIDGETS_SLIDESHOW 0
|
||||
#endif
|
||||
|
||||
/*Demonstrate the usage of encoder and keyboard*/
|
||||
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
|
||||
|
||||
/*Benchmark your system*/
|
||||
#define LV_USE_DEMO_BENCHMARK 1
|
||||
|
||||
/*Render test for each primitives. Requires at least 480x272 display*/
|
||||
#define LV_USE_DEMO_RENDER 1
|
||||
|
||||
/*Stress test for LVGL*/
|
||||
#define LV_USE_DEMO_STRESS 1
|
||||
|
||||
/*Music player demo*/
|
||||
#define LV_USE_DEMO_MUSIC 0
|
||||
#if LV_USE_DEMO_MUSIC
|
||||
#define LV_DEMO_MUSIC_SQUARE 0
|
||||
#define LV_DEMO_MUSIC_LANDSCAPE 0
|
||||
#define LV_DEMO_MUSIC_ROUND 0
|
||||
#define LV_DEMO_MUSIC_LARGE 0
|
||||
#define LV_DEMO_MUSIC_AUTO_PLAY 0
|
||||
#endif
|
||||
|
||||
/*Flex layout demo*/
|
||||
#define LV_USE_DEMO_FLEX_LAYOUT 1
|
||||
|
||||
/*Smart-phone like multi-language demo*/
|
||||
#define LV_USE_DEMO_MULTILANG 1
|
||||
|
||||
/*Widget transformation demo*/
|
||||
#define LV_USE_DEMO_TRANSFORM 1
|
||||
|
||||
/*Demonstrate scroll settings*/
|
||||
#define LV_USE_DEMO_SCROLL 1
|
||||
|
||||
/*Vector graphic demo*/
|
||||
#define LV_USE_DEMO_VECTOR_GRAPHIC 1
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
||||
@ -1,2 +0,0 @@
|
||||
target_compile_definitions(lvgl PUBLIC "-DLV_CONF_INCLUDE_SIMPLE")
|
||||
target_include_directories(lvgl PUBLIC ${LVGL_ROOT_DIR}/config)
|
||||
1
run.sh
1
run.sh
@ -2,6 +2,7 @@
|
||||
if [[ -v ESP_IDF_VERSION ]]; then
|
||||
idf.py flash monitor $@
|
||||
else
|
||||
set -e
|
||||
cmake -S ./ -B build-sim
|
||||
cmake --build build-sim -j 12
|
||||
build-sim/app-sim/app-sim
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <tactility_core_config.h>
|
||||
#include "tactility_core_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@ -12,122 +12,127 @@
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
SemaphoreHandle_t handle;
|
||||
MutexType type;
|
||||
} MutexData;
|
||||
|
||||
Mutex* tt_mutex_alloc(MutexType type) {
|
||||
tt_assert(!TT_IS_IRQ_MODE());
|
||||
#define MUTEX_DEBUGGING false
|
||||
|
||||
SemaphoreHandle_t hMutex = NULL;
|
||||
|
||||
if (type == MutexTypeNormal) {
|
||||
hMutex = xSemaphoreCreateMutex();
|
||||
} else if (type == MutexTypeRecursive) {
|
||||
hMutex = xSemaphoreCreateRecursiveMutex();
|
||||
#if MUTEX_DEBUGGING
|
||||
#define TAG "mutex"
|
||||
void tt_mutex_info(Mutex mutex, const char* label) {
|
||||
MutexData* data = (MutexData*)mutex;
|
||||
if (data == NULL) {
|
||||
TT_LOG_I(TAG, "mutex %s: is NULL", label);
|
||||
} else {
|
||||
tt_crash("Programming error");
|
||||
TT_LOG_I(TAG, "mutex %s: handle=%0X type=%d owner=%0x", label, data->handle, data->type, tt_mutex_get_owner(mutex));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define tt_mutex_info(mutex, text)
|
||||
#endif
|
||||
|
||||
Mutex tt_mutex_alloc(MutexType type) {
|
||||
tt_assert(!TT_IS_IRQ_MODE());
|
||||
MutexData* data = malloc(sizeof(MutexData));
|
||||
|
||||
data->type = type;
|
||||
|
||||
switch (type) {
|
||||
case MutexTypeNormal:
|
||||
data->handle = xSemaphoreCreateMutex();
|
||||
break;
|
||||
case MutexTypeRecursive:
|
||||
data->handle = xSemaphoreCreateRecursiveMutex();
|
||||
break;
|
||||
default:
|
||||
tt_crash("mutex type unknown/corrupted");
|
||||
}
|
||||
|
||||
tt_check(hMutex != NULL);
|
||||
|
||||
if (type == MutexTypeRecursive) {
|
||||
/* Set LSB as 'recursive mutex flag' */
|
||||
hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
|
||||
}
|
||||
|
||||
/* Return mutex ID */
|
||||
return ((Mutex*)hMutex);
|
||||
tt_check(data->handle != NULL);
|
||||
tt_mutex_info(data, "alloc ");
|
||||
return (Mutex)data;
|
||||
}
|
||||
|
||||
void tt_mutex_free(Mutex* instance) {
|
||||
void tt_mutex_free(Mutex mutex) {
|
||||
tt_assert(!TT_IS_IRQ_MODE());
|
||||
tt_assert(instance);
|
||||
tt_assert(mutex);
|
||||
|
||||
vSemaphoreDelete((SemaphoreHandle_t)((uint32_t)instance & ~1U));
|
||||
MutexData* data = (MutexData*)mutex;
|
||||
vSemaphoreDelete(data->handle);
|
||||
data->handle = NULL; // If the mutex is used after release, this might help debugging
|
||||
data->type = 0xBAADF00D; // Set to an invalid value
|
||||
free(data);
|
||||
}
|
||||
|
||||
TtStatus tt_mutex_acquire(Mutex* instance, uint32_t timeout) {
|
||||
SemaphoreHandle_t hMutex;
|
||||
TtStatus stat;
|
||||
uint32_t rmtx;
|
||||
TtStatus tt_mutex_acquire(Mutex mutex, uint32_t timeout) {
|
||||
tt_assert(mutex);
|
||||
tt_assert(!TT_IS_IRQ_MODE());
|
||||
MutexData* data = (MutexData*)mutex;
|
||||
tt_assert(data->handle);
|
||||
TtStatus status = TtStatusOk;
|
||||
|
||||
hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U);
|
||||
tt_mutex_info(mutex, "acquire");
|
||||
|
||||
/* Extract recursive mutex flag */
|
||||
rmtx = (uint32_t)instance & 1U;
|
||||
|
||||
stat = TtStatusOk;
|
||||
|
||||
if (TT_IS_IRQ_MODE()) {
|
||||
stat = TtStatusErrorISR;
|
||||
} else if (hMutex == NULL) {
|
||||
stat = TtStatusErrorParameter;
|
||||
} else {
|
||||
if (rmtx != 0U) {
|
||||
if (xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) {
|
||||
switch (data->type) {
|
||||
case MutexTypeNormal:
|
||||
if (xSemaphoreTake(data->handle, timeout) != pdPASS) {
|
||||
if (timeout != 0U) {
|
||||
stat = TtStatusErrorTimeout;
|
||||
status = TtStatusErrorTimeout;
|
||||
} else {
|
||||
stat = TtStatusErrorResource;
|
||||
status = TtStatusErrorResource;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (xSemaphoreTake(hMutex, timeout) != pdPASS) {
|
||||
break;
|
||||
case MutexTypeRecursive:
|
||||
if (xSemaphoreTakeRecursive(data->handle, timeout) != pdPASS) {
|
||||
if (timeout != 0U) {
|
||||
stat = TtStatusErrorTimeout;
|
||||
status = TtStatusErrorTimeout;
|
||||
} else {
|
||||
stat = TtStatusErrorResource;
|
||||
status = TtStatusErrorResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tt_crash("mutex type unknown/corrupted");
|
||||
}
|
||||
|
||||
/* Return execution status */
|
||||
return (stat);
|
||||
return status;
|
||||
}
|
||||
|
||||
TtStatus tt_mutex_release(Mutex* instance) {
|
||||
SemaphoreHandle_t hMutex;
|
||||
TtStatus stat;
|
||||
uint32_t rmtx;
|
||||
TtStatus tt_mutex_release(Mutex mutex) {
|
||||
tt_assert(mutex);
|
||||
assert(!TT_IS_IRQ_MODE());
|
||||
MutexData* data = (MutexData*)mutex;
|
||||
tt_assert(data->handle);
|
||||
TtStatus status = TtStatusOk;
|
||||
|
||||
hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U);
|
||||
tt_mutex_info(mutex, "release");
|
||||
|
||||
/* Extract recursive mutex flag */
|
||||
rmtx = (uint32_t)instance & 1U;
|
||||
|
||||
stat = TtStatusOk;
|
||||
|
||||
if (TT_IS_IRQ_MODE()) {
|
||||
stat = TtStatusErrorISR;
|
||||
} else if (hMutex == NULL) {
|
||||
stat = TtStatusErrorParameter;
|
||||
} else {
|
||||
if (rmtx != 0U) {
|
||||
if (xSemaphoreGiveRecursive(hMutex) != pdPASS) {
|
||||
stat = TtStatusErrorResource;
|
||||
}
|
||||
} else {
|
||||
if (xSemaphoreGive(hMutex) != pdPASS) {
|
||||
stat = TtStatusErrorResource;
|
||||
switch (data->type) {
|
||||
case MutexTypeNormal: {
|
||||
if (xSemaphoreGive(data->handle) != pdPASS) {
|
||||
status = TtStatusErrorResource;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MutexTypeRecursive:
|
||||
if (xSemaphoreGiveRecursive(data->handle) != pdPASS) {
|
||||
status = TtStatusErrorResource;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tt_crash("mutex type unknown/corrupted %d");
|
||||
}
|
||||
|
||||
/* Return execution status */
|
||||
return (stat);
|
||||
return status;
|
||||
}
|
||||
|
||||
ThreadId tt_mutex_get_owner(Mutex* instance) {
|
||||
SemaphoreHandle_t hMutex;
|
||||
ThreadId owner;
|
||||
|
||||
hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U);
|
||||
|
||||
if ((TT_IS_IRQ_MODE()) || (hMutex == NULL)) {
|
||||
owner = 0;
|
||||
} else {
|
||||
owner = (ThreadId)xSemaphoreGetMutexHolder(hMutex);
|
||||
}
|
||||
|
||||
/* Return owner thread ID */
|
||||
return (owner);
|
||||
ThreadId tt_mutex_get_owner(Mutex mutex) {
|
||||
tt_assert(mutex != NULL);
|
||||
tt_assert(!TT_IS_IRQ_MODE());
|
||||
MutexData* data = (MutexData*)mutex;
|
||||
tt_assert(data->handle);
|
||||
return (ThreadId)xSemaphoreGetMutexHolder(data->handle);
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ typedef enum {
|
||||
MutexTypeRecursive,
|
||||
} MutexType;
|
||||
|
||||
typedef void Mutex;
|
||||
typedef void* Mutex;
|
||||
|
||||
/** Allocate Mutex
|
||||
*
|
||||
@ -24,38 +24,38 @@ typedef void Mutex;
|
||||
*
|
||||
* @return pointer to Mutex instance
|
||||
*/
|
||||
Mutex* tt_mutex_alloc(MutexType type);
|
||||
Mutex tt_mutex_alloc(MutexType type);
|
||||
|
||||
/** Free Mutex
|
||||
*
|
||||
* @param instance The pointer to Mutex instance
|
||||
* @param mutex The Mutex instance
|
||||
*/
|
||||
void tt_mutex_free(Mutex* instance);
|
||||
void tt_mutex_free(Mutex mutex);
|
||||
|
||||
/** Acquire mutex
|
||||
*
|
||||
* @param instance The pointer to Mutex instance
|
||||
* @param mutex The Mutex instance
|
||||
* @param[in] timeout The timeout
|
||||
*
|
||||
* @return The status.
|
||||
*/
|
||||
TtStatus tt_mutex_acquire(Mutex* instance, uint32_t timeout);
|
||||
TtStatus tt_mutex_acquire(Mutex mutex, uint32_t timeout);
|
||||
|
||||
/** Release mutex
|
||||
*
|
||||
* @param instance The pointer to Mutex instance
|
||||
* @param mutex The Mutex instance
|
||||
*
|
||||
* @return The status.
|
||||
*/
|
||||
TtStatus tt_mutex_release(Mutex* instance);
|
||||
TtStatus tt_mutex_release(Mutex mutex);
|
||||
|
||||
/** Get mutex owner thread id
|
||||
*
|
||||
* @param instance The pointer to Mutex instance
|
||||
* @param mutex The Mutex instance
|
||||
*
|
||||
* @return The thread identifier.
|
||||
*/
|
||||
ThreadId tt_mutex_get_owner(Mutex* instance);
|
||||
ThreadId tt_mutex_get_owner(Mutex mutex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ struct PubSub {
|
||||
PubSub* tt_pubsub_alloc() {
|
||||
PubSub* pubsub = malloc(sizeof(PubSub));
|
||||
|
||||
pubsub->mutex = tt_mutex_alloc(MutexTypeRecursive);
|
||||
pubsub->mutex = tt_mutex_alloc(MutexTypeNormal);
|
||||
tt_assert(pubsub->mutex);
|
||||
|
||||
PubSubSubscriptionList_init(pubsub->items);
|
||||
|
||||
@ -9,4 +9,5 @@
|
||||
#include "core_types.h"
|
||||
#include "critical.h"
|
||||
#include "event_flag.h"
|
||||
#include "kernel.h"
|
||||
#include "log.h"
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define TT_CONFIG_THREAD_MAX_PRIORITIES (32)
|
||||
#define TT_CONFIG_THREAD_MAX_PRIORITIES 10
|
||||
@ -21,11 +21,11 @@ typedef enum {
|
||||
typedef enum {
|
||||
ThreadPriorityNone = 0, /**< Uninitialized, choose system default */
|
||||
ThreadPriorityIdle = 1, /**< Idle priority */
|
||||
ThreadPriorityLowest = 14, /**< Lowest */
|
||||
ThreadPriorityLow = 15, /**< Low */
|
||||
ThreadPriorityNormal = 16, /**< Normal */
|
||||
ThreadPriorityHigh = 17, /**< High */
|
||||
ThreadPriorityHighest = 18, /**< Highest */
|
||||
ThreadPriorityLowest = 2, /**< Lowest */
|
||||
ThreadPriorityLow = 3, /**< Low */
|
||||
ThreadPriorityNormal = 4, /**< Normal */
|
||||
ThreadPriorityHigh = 5, /**< High */
|
||||
ThreadPriorityHighest = 6, /**< Highest */
|
||||
ThreadPriorityIsr =
|
||||
(TT_CONFIG_THREAD_MAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */
|
||||
} ThreadPriority;
|
||||
|
||||
@ -12,7 +12,7 @@ extern "C" {
|
||||
|
||||
typedef struct {
|
||||
PubSubSubscription* wifi_subscription;
|
||||
Mutex* mutex;
|
||||
Mutex mutex;
|
||||
WifiConnectState state;
|
||||
WifiConnectView view;
|
||||
bool view_enabled;
|
||||
|
||||
@ -10,7 +10,7 @@ extern "C" {
|
||||
|
||||
typedef struct {
|
||||
PubSubSubscription* wifi_subscription;
|
||||
Mutex* mutex;
|
||||
Mutex mutex;
|
||||
WifiManageState state;
|
||||
WifiManageView view;
|
||||
bool view_enabled;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
#include "check.h"
|
||||
#include "display.h"
|
||||
|
||||
DisplayDevice _Nonnull* tt_display_device_alloc(DisplayDriver _Nonnull* driver) {
|
||||
DisplayDevice _Nonnull* display = malloc(sizeof(DisplayDevice));
|
||||
DisplayDevice* tt_display_device_alloc(DisplayDriver* driver) {
|
||||
DisplayDevice* display = malloc(sizeof(DisplayDevice));
|
||||
memset(display, 0, sizeof(DisplayDevice));
|
||||
tt_check(driver->create_display_device(display), "failed to create display");
|
||||
tt_check(display->io_handle != NULL);
|
||||
|
||||
@ -7,8 +7,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
esp_lcd_panel_io_handle_t _Nonnull io_handle;
|
||||
esp_lcd_panel_handle_t _Nonnull display_handle;
|
||||
esp_lcd_panel_io_handle_t io_handle;
|
||||
esp_lcd_panel_handle_t display_handle;
|
||||
uint16_t horizontal_resolution;
|
||||
uint16_t vertical_resolution;
|
||||
uint16_t draw_buffer_height;
|
||||
@ -31,7 +31,7 @@ typedef struct {
|
||||
* @param[in] driver
|
||||
* @return allocated display object
|
||||
*/
|
||||
DisplayDevice _Nonnull* tt_display_device_alloc(DisplayDriver _Nonnull* driver);
|
||||
DisplayDevice* tt_display_device_alloc(DisplayDriver* driver);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
#define TAG "lvgl"
|
||||
|
||||
Lvgl tt_graphics_init(Hardware _Nonnull* hardware) {
|
||||
Lvgl tt_graphics_init(Hardware* hardware) {
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = 4,
|
||||
.task_stack = 8096,
|
||||
@ -15,7 +15,7 @@ Lvgl tt_graphics_init(Hardware _Nonnull* hardware) {
|
||||
};
|
||||
|
||||
tt_check(lvgl_port_init(&lvgl_cfg) == ESP_OK, "lvgl port init failed");
|
||||
DisplayDevice _Nonnull* display = hardware->display;
|
||||
DisplayDevice* display = hardware->display;
|
||||
|
||||
// Add display
|
||||
TT_LOG_I(TAG, "lvgl add display");
|
||||
@ -37,7 +37,7 @@ Lvgl tt_graphics_init(Hardware _Nonnull* hardware) {
|
||||
}
|
||||
};
|
||||
|
||||
lv_disp_t _Nonnull* disp = lvgl_port_add_disp(&disp_cfg);
|
||||
lv_disp_t* disp = lvgl_port_add_disp(&disp_cfg);
|
||||
tt_check(disp != NULL, "failed to add display");
|
||||
|
||||
lv_indev_t _Nullable* touch_indev = NULL;
|
||||
|
||||
@ -7,7 +7,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
lv_disp_t* _Nonnull disp;
|
||||
lv_disp_t* disp;
|
||||
lv_indev_t* _Nullable touch_indev;
|
||||
} Lvgl;
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "graphics.h"
|
||||
#include "hardare.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
Lvgl tt_graphics_init(Hardware _Nonnull* hardware);
|
||||
Lvgl tt_graphics_init(Hardware* hardware);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
#define TAG "hardware"
|
||||
|
||||
Hardware tt_hardware_init(const HardwareConfig _Nonnull* config) {
|
||||
Hardware tt_hardware_init(const HardwareConfig* config) {
|
||||
if (config->bootstrap != NULL) {
|
||||
TT_LOG_I(TAG, "Bootstrapping");
|
||||
config->bootstrap();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user