mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 04:37:55 +08:00
feat(EVE): Add EVE draw unit (#8211)
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
Co-authored-by: André Costa <andre_miguel_costa@hotmail.com>
This commit is contained in:
@@ -58,3 +58,6 @@ For the licenses, see the corresponding `LICENSE.txt` file in each library’s f
|
||||
- src/others/xml
|
||||
- xmls
|
||||
|
||||
**FT800-FT813 (EVE GPU driver)**
|
||||
- Path src/libs/FT800-FT813
|
||||
- Source: https://github.com/RudolphRiedel/FT800-FT813
|
||||
|
||||
@@ -537,6 +537,16 @@ menu "LVGL configuration"
|
||||
default n
|
||||
depends on LV_USE_PPA
|
||||
|
||||
config LV_USE_DRAW_EVE
|
||||
bool "Use EVE FT81X GPU."
|
||||
default n
|
||||
|
||||
config LV_DRAW_EVE_EVE_GENERATION
|
||||
int "EVE_GEN value"
|
||||
default 4
|
||||
range 2 4
|
||||
depends on LV_USE_DRAW_EVE
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Feature Configuration"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _ft81x:
|
||||
|
||||
=====
|
||||
FT81x
|
||||
=====
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
=========================
|
||||
EVE External GPU Renderer
|
||||
=========================
|
||||
|
||||
EVE is a type of external GPU IC which accepts high-level drawing commands over SPI
|
||||
and outputs the rendered graphics to a display over parallel RGB.
|
||||
|
||||
The advantage of using an EVE chip is that the rendering responsibility is removed
|
||||
from the driving MCU so it can be a lower-spec part or dedicate more of its
|
||||
processing time to other tasks. The SPI interface is simpler to connect than
|
||||
parallel RGB especially if the EVE chip is integrated into a display assembly.
|
||||
|
||||
LVGL features a renderer for EVE. LVGL UIs can be rendered by EVE
|
||||
and are effectively indistinguishable from the software renderer is most cases.
|
||||
|
||||
See also the :ref:`ft81x` framebuffer driver. It drives the same EVE chips
|
||||
but is a simpler, more standalone implementation which uses software rendering
|
||||
and sends all the pixels over SPI so it is much slower.
|
||||
|
||||
|
||||
Limitations
|
||||
***********
|
||||
|
||||
- Image format, size, and count limit.
|
||||
- Font format, size, and count limit.
|
||||
- The total number of tasks rendered per refresh has an upper limit.
|
||||
- Layers are not supported.
|
||||
|
||||
|
||||
Usage
|
||||
*****
|
||||
|
||||
Board Parameters
|
||||
----------------
|
||||
|
||||
Find your display parameters and populate a :cpp:struct:`lv_draw_eve_parameters_t`
|
||||
struct with them.
|
||||
|
||||
Here is an example ``lv_draw_eve_target_parameters.h`` for the Riverdi RVT50HQBNWC00-B
|
||||
which has a BT817Q --- the EVE chip.
|
||||
These parameters were taken from the collection of configs provided by the EVE
|
||||
library supporting this renderer.
|
||||
`See here <https://github.com/RudolphRiedel/FT800-FT813/blob/ee35fa45c37aed78dc4f1196b874ee1c8f80429f/EVE_config.h#L856-L872>`__.
|
||||
Check there for your board parameters.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
lv_draw_eve_parameters_t params = {
|
||||
.hor_res = 800,
|
||||
.ver_res = 480,
|
||||
.vsync0 = 0,
|
||||
.vsync1 = 4,
|
||||
.voffset = 8,
|
||||
.vcycle = 496,
|
||||
.hsync0 = 0,
|
||||
.hsync1 = 4,
|
||||
.hoffset = 8,
|
||||
.hcycle = 816,
|
||||
.pclk = 3,
|
||||
.pclkpol = 1,
|
||||
.swizzle = 0,
|
||||
.cspread = 0,
|
||||
.has_crystal = true,
|
||||
.has_gt911 = false,
|
||||
.backlight_freq = 4000,
|
||||
.backlight_pwm = 128,
|
||||
};
|
||||
|
||||
|
||||
EVE Chip IO Implementation
|
||||
--------------------------
|
||||
|
||||
The user is required to implement the GPIO and SPI IO functionality. The LVGL EVE
|
||||
renderer will call this callback to perform SPI communication with the EVE chip.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static void op_cb(lv_display_t * disp, lv_draw_eve_operation_t operation,
|
||||
void * data, uint32_t length)
|
||||
{
|
||||
/* optional: get the `user_data` parameter you passed to `lv_draw_eve_display_create` */
|
||||
void * your_user_data = lv_draw_eve_display_get_user_data(disp);
|
||||
|
||||
switch(operation) {
|
||||
case LV_DRAW_EVE_OPERATION_POWERDOWN_SET:
|
||||
/* setting the pin low powers down the EVE chip */
|
||||
your_gpio_write(PD_N_PIN, 0);
|
||||
break;
|
||||
case LV_DRAW_EVE_OPERATION_POWERDOWN_CLEAR:
|
||||
/* setting the pin high powers on the EVE chip */
|
||||
your_gpio_write(PD_N_PIN, 1);
|
||||
break;
|
||||
case LV_DRAW_EVE_OPERATION_CS_ASSERT:
|
||||
/* setting the pin low asserts the EVE chip SPI device */
|
||||
your_gpio_write(CS_N_PIN, 0);
|
||||
break;
|
||||
case LV_DRAW_EVE_OPERATION_CS_DEASSERT:
|
||||
/* setting the pin high de-asserts the EVE chip SPI device */
|
||||
your_gpio_write(CS_N_PIN, 1);
|
||||
break;
|
||||
case LV_DRAW_EVE_OPERATION_SPI_SEND:
|
||||
/* `data` is the data to send */
|
||||
your_spi_transmit(data, length);
|
||||
break;
|
||||
case LV_DRAW_EVE_OPERATION_SPI_RECEIVE:
|
||||
/* `data` is the destination for the data */
|
||||
your_spi_receive(data, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
You will also need to initialize your SPI peripheral and GPIO pins.
|
||||
|
||||
22 MHz was the highest SPI speed that worked during testing with the Riverdi board
|
||||
and the ESP32-S3. You may not have success with this speed so it is
|
||||
recommended to validate with an ``SPI_SPEED`` value of ``10`` (10 MHz)
|
||||
and increase experimentally in your testing.
|
||||
|
||||
|
||||
LVGL EVE Display Creation
|
||||
-------------------------
|
||||
|
||||
To create the LVGL display for the EVE renderer, you call
|
||||
:cpp:expr:`lv_draw_eve_display_create(params, op_cb, your_user_data)` which returns the
|
||||
created display. ``your_user_data`` can be ``NULL``. It should be called after GPIO and
|
||||
SPI is initialized. You may choose to initialize your IO
|
||||
the first time ``op_cb`` is called.
|
||||
|
||||
No buffers are required for the LVGL EVE renderer because no pixels
|
||||
are written to any buffers in the device running LVGL. When something
|
||||
needs to be drawn, a series of commands are sent to EVE.
|
||||
|
||||
|
||||
Touch Indev Creation
|
||||
--------------------
|
||||
|
||||
:cpp:expr:`lv_draw_eve_touch_create(disp)` creates a touch :ref:`indev` for the display.
|
||||
|
||||
You may need to configure the i2c address of the touch controller connected to EVE.
|
||||
See the section :ref:`eve register access` for more info about register access.
|
||||
|
||||
Here is an example of setting the ``REG_TOUCH_CONFIG`` register on a BT817q EVE chip
|
||||
for a capacitive touch screen with a controller that has the i2c address ``0x15``.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*
|
||||
15: 0: capacitive, 1: resistive CAPACITIVE
|
||||
14: host mode NO
|
||||
13: reserved
|
||||
12: ignore short circuit protection NO
|
||||
11: low-power mode NO
|
||||
10-4: 7-bit i2c address 0x15
|
||||
3: reserved
|
||||
2: suppress 300ms startup NO
|
||||
1-0: 2-bit sampling clocks val use 1 (the reset default)
|
||||
*/
|
||||
lv_draw_eve_memwrite16(disp, LV_EVE_REG_TOUCH_CONFIG, 0x0151);
|
||||
|
||||
|
||||
Display Rotation
|
||||
----------------
|
||||
|
||||
Efficient display rotation is fully supported through :cpp:func:`lv_display_set_rotation`.
|
||||
Touch input rotation is handled accordingly.
|
||||
|
||||
|
||||
.. _eve register access:
|
||||
|
||||
EVE Register Access
|
||||
-------------------
|
||||
|
||||
The functions :cpp:func:`lv_draw_eve_memread8`, :cpp:func:`lv_draw_eve_memread16`, :cpp:func:`lv_draw_eve_memread32`,
|
||||
:cpp:func:`lv_draw_eve_memwrite8`, :cpp:func:`lv_draw_eve_memwrite16`, are :cpp:func:`lv_draw_eve_memwrite32`
|
||||
available if needed. They are wrappers around ``EVE_memRead8``, etc.
|
||||
|
||||
Register definitions and other EVE enumerations are available when you include
|
||||
``lvgl.h`` under the prefix namespace ``LV_EVE_``. I.e., ``REG_ID`` is available
|
||||
as ``LV_EVE_REG_ID`` and ``EVE_ROM_CHIPID`` is available as ``LV_EVE_EVE_ROM_CHIPID``, etc.
|
||||
|
||||
|
||||
Further Reading
|
||||
---------------
|
||||
|
||||
- https://brtchip.com/wp-content/uploads/Support/Documentation/Programming_Guides/ICs/EVE/FT81X_Series_Programmer_Guide.pdf
|
||||
- https://brtchip.com/wp-content/uploads/2024/06/BRT_AN_033_BT81X-Series-Programming-Guide.pdf
|
||||
@@ -8,6 +8,7 @@ Renderers and GPUs
|
||||
sw
|
||||
arm2d
|
||||
espressif_ppa
|
||||
eve
|
||||
nema_gfx
|
||||
nxp_pxp
|
||||
nxp_vglite_gpu
|
||||
|
||||
@@ -362,6 +362,15 @@
|
||||
#if LV_USE_PPA
|
||||
#define LV_USE_PPA_IMG 0
|
||||
#endif
|
||||
|
||||
/* Use EVE FT81X GPU. */
|
||||
#define LV_USE_DRAW_EVE 0
|
||||
|
||||
#if LV_USE_DRAW_EVE
|
||||
/* EVE_GEN value: 2, 3, or 4 */
|
||||
#define LV_DRAW_EVE_EVE_GENERATION 4
|
||||
#endif
|
||||
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
|
||||
@@ -123,6 +123,7 @@ extern "C" {
|
||||
#include "src/draw/lv_draw_buf.h"
|
||||
#include "src/draw/lv_draw_vector.h"
|
||||
#include "src/draw/sw/lv_draw_sw_utils.h"
|
||||
#include "src/draw/eve/lv_draw_eve_target.h"
|
||||
|
||||
#include "src/themes/lv_theme.h"
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
--exclude=../src/libs/thorvg
|
||||
--exclude=../src/libs/expat
|
||||
--exclude=../src/libs/lz4
|
||||
--exclude=../src/libs/FT800-FT813
|
||||
--exclude=../src/others/vg_lite_tvg/vg_lite.h
|
||||
--exclude=../demos/high_res/fonts
|
||||
--exclude=../tests/unity/unity.c
|
||||
|
||||
@@ -263,6 +263,10 @@ typedef struct _lv_global_t {
|
||||
const char * xml_path_prefix;
|
||||
#endif
|
||||
|
||||
#if LV_USE_DRAW_EVE
|
||||
lv_draw_eve_unit_t * draw_eve_unit;
|
||||
#endif
|
||||
|
||||
void * user_data;
|
||||
} lv_global_t;
|
||||
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* @file lv_draw_eve.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 3 dic 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../../core/lv_refr.h"
|
||||
#include "../../display/lv_display_private.h"
|
||||
#include "../../stdlib/lv_string.h"
|
||||
#include "lv_draw_eve_ram_g.h"
|
||||
#include "lv_draw_eve.h"
|
||||
#include "lv_eve.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define DRAW_UNIT_ID_EVE 9
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void eve_execute_drawing(lv_draw_eve_unit_t * u);
|
||||
|
||||
static int32_t eve_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
|
||||
|
||||
static int32_t eve_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
|
||||
|
||||
static void disp_delete_cb(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_init(void)
|
||||
{
|
||||
lv_draw_eve_unit_t * draw_eve_unit = lv_draw_create_unit(sizeof(lv_draw_eve_unit_t));
|
||||
draw_eve_unit->base_unit.dispatch_cb = eve_dispatch;
|
||||
draw_eve_unit->base_unit.evaluate_cb = eve_evaluate;
|
||||
|
||||
lv_draw_eve_unit_g = draw_eve_unit;
|
||||
}
|
||||
|
||||
void lv_draw_eve_set_display_data(lv_display_t * disp, const lv_draw_eve_parameters_t * params,
|
||||
lv_draw_eve_operation_cb_t op_cb)
|
||||
{
|
||||
if(lv_draw_eve_unit_g == NULL) {
|
||||
LV_LOG_WARN("lv_draw_eve is not initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_eve_unit_g->disp = disp;
|
||||
lv_draw_eve_unit_g->params = *params; /* make a copy */
|
||||
lv_draw_eve_unit_g->op_cb = op_cb;
|
||||
|
||||
lv_display_add_event_cb(disp, disp_delete_cb, LV_EVENT_DELETE, NULL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static int32_t eve_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
|
||||
{
|
||||
lv_draw_eve_unit_t * draw_eve_unit = (lv_draw_eve_unit_t *) draw_unit;
|
||||
|
||||
lv_draw_task_t * t = NULL;
|
||||
t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_EVE);
|
||||
if(t == NULL) return LV_DRAW_UNIT_IDLE;
|
||||
|
||||
|
||||
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
|
||||
draw_eve_unit->task_act = t;
|
||||
|
||||
eve_execute_drawing(draw_eve_unit);
|
||||
|
||||
draw_eve_unit->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
draw_eve_unit->task_act = NULL;
|
||||
|
||||
/*The draw unit is free now. Request a new dispatching as it can get a new task*/
|
||||
lv_draw_dispatch_request();
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int32_t eve_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task)
|
||||
{
|
||||
LV_UNUSED(draw_unit);
|
||||
|
||||
if(((lv_draw_dsc_base_t *)task->draw_dsc)->user_data == NULL) {
|
||||
task->preference_score = 0;
|
||||
task->preferred_draw_unit_id = DRAW_UNIT_ID_EVE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void eve_execute_drawing(lv_draw_eve_unit_t * u)
|
||||
{
|
||||
lv_draw_task_t * t = u->task_act;
|
||||
|
||||
uint8_t coprocessor_status;
|
||||
do {
|
||||
coprocessor_status = EVE_busy();
|
||||
} while(coprocessor_status != E_OK && coprocessor_status != EVE_FIFO_HALF_EMPTY);
|
||||
|
||||
EVE_start_cmd_burst();
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_LINE:
|
||||
lv_draw_eve_line(t, t->draw_dsc);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_BORDER:
|
||||
lv_draw_eve_border(t, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
lv_draw_eve_fill(t, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
lv_draw_eve_image(t, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LABEL:
|
||||
lv_draw_eve_label(t, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_ARC:
|
||||
lv_draw_eve_arc(t, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
lv_draw_eve_triangle(t, t->draw_dsc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
EVE_end_cmd_burst();
|
||||
}
|
||||
|
||||
static void disp_delete_cb(lv_event_t * e)
|
||||
{
|
||||
lv_draw_eve_unit_g->disp = NULL;
|
||||
lv_draw_eve_unit_g = NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file lv_draw_eve.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 3 dic 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_EVE_H
|
||||
#define LV_DRAW_EVE_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "lv_draw_eve_target.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_init(void);
|
||||
|
||||
void lv_draw_eve_set_display_data(lv_display_t * disp, const lv_draw_eve_parameters_t * params,
|
||||
lv_draw_eve_operation_cb_t op_cb);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* LV_DRAW_EVE_H */
|
||||
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* @file lv_draw_eve_arc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 11 dic 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../lv_draw_arc.h"
|
||||
#include "lv_eve.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords);
|
||||
static bool is_same_quadrant(int16_t start_angle, int16_t end_angle) ;
|
||||
static void draw_rounded_end(lv_point_t center, int32_t radius, int32_t angle, int32_t width);
|
||||
static void lv_draw_eve_mask_angle(const lv_draw_arc_dsc_t * dsc, int32_t vertex_x, int32_t vertex_y,
|
||||
int32_t start_angle, int32_t end_angle);
|
||||
static lv_eve_primitive_t get_mask_direction(int16_t angle);
|
||||
static int32_t chord_length(int16_t radius, int16_t angle_degrees);
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
draw_eve_arc(t, dsc, coords);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
static int32_t chord_length(int16_t radius, int16_t angle_degrees)
|
||||
{
|
||||
angle_degrees %= 360;
|
||||
if(angle_degrees < 0) angle_degrees += 360;
|
||||
int32_t sin_value = lv_trigo_sin(angle_degrees / 2);
|
||||
int64_t chord_length = 2 * radius * sin_value / 32768.0;
|
||||
return (int32_t)chord_length ;
|
||||
}
|
||||
|
||||
|
||||
static lv_eve_primitive_t get_mask_direction(int16_t angle)
|
||||
{
|
||||
if(angle >= 315 || angle < 45) {
|
||||
return LV_EVE_PRIMITIVE_EDGE_STRIP_R;
|
||||
}
|
||||
if(angle >= 45 && angle < 135) {
|
||||
return LV_EVE_PRIMITIVE_EDGE_STRIP_B;
|
||||
}
|
||||
if(angle >= 135 && angle < 225) {
|
||||
return LV_EVE_PRIMITIVE_EDGE_STRIP_L;
|
||||
}
|
||||
if(angle >= 225 && angle < 315) {
|
||||
return LV_EVE_PRIMITIVE_EDGE_STRIP_A;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void draw_rounded_end(lv_point_t center, int32_t radius, int32_t angle, int32_t width)
|
||||
{
|
||||
int32_t rounded_y = center.y + ((lv_trigo_sin(angle) * radius) >> LV_TRIGO_SHIFT);
|
||||
int32_t rounded_x = center.x + ((lv_trigo_cos(angle) * radius) >> LV_TRIGO_SHIFT);
|
||||
lv_eve_draw_circle_simple(rounded_x, rounded_y, width);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool is_same_quadrant(int16_t start_angle, int16_t end_angle)
|
||||
{
|
||||
if(start_angle > end_angle) {
|
||||
if((start_angle >= 0 && start_angle < 90) && (end_angle >= 0 && end_angle < 90)) {
|
||||
return true;
|
||||
}
|
||||
else if((start_angle >= 90 && start_angle < 180) && (end_angle >= 90 && end_angle < 180)) {
|
||||
return true;
|
||||
}
|
||||
else if((start_angle >= 180 && start_angle < 270) && (end_angle >= 180 && end_angle < 270)) {
|
||||
return true;
|
||||
}
|
||||
else if((start_angle >= 270 && start_angle < 360) && (end_angle >= 270 && end_angle < 360)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void lv_draw_eve_mask_angle(const lv_draw_arc_dsc_t * dsc, int32_t vertex_x, int32_t vertex_y,
|
||||
int32_t start_angle, int32_t end_angle)
|
||||
{
|
||||
|
||||
/*Constrain the input angles*/
|
||||
|
||||
|
||||
if(start_angle < 0)
|
||||
start_angle = 0;
|
||||
else if(start_angle > 359)
|
||||
start_angle = 359;
|
||||
|
||||
if(end_angle < 0)
|
||||
end_angle = 0;
|
||||
else if(end_angle > 359)
|
||||
end_angle = 359;
|
||||
|
||||
LV_ASSERT_MSG(start_angle >= 0 && start_angle <= 360, "Unexpected start angle");
|
||||
|
||||
int32_t mid_angle_op;
|
||||
int32_t angle_range;
|
||||
int32_t mask_dir_start;
|
||||
int32_t mask_dir_end;
|
||||
lv_point_t start;
|
||||
lv_point_t end;
|
||||
lv_point_t angle_range_op;
|
||||
|
||||
if(end_angle > start_angle) {
|
||||
angle_range = LV_ABS(end_angle - start_angle);
|
||||
}
|
||||
else {
|
||||
angle_range = 360 - start_angle + end_angle;
|
||||
}
|
||||
|
||||
mid_angle_op = (angle_range / 2) + start_angle + 180;
|
||||
mid_angle_op = mid_angle_op % 360;
|
||||
|
||||
mask_dir_end = LV_ABS(((360 - angle_range) / 4) + end_angle);
|
||||
mask_dir_start = LV_ABS(((360 - angle_range) / 4) + mid_angle_op);
|
||||
|
||||
mask_dir_start = mask_dir_start % 360;
|
||||
mask_dir_end = mask_dir_end % 360;
|
||||
|
||||
start.y = (lv_trigo_sin(start_angle) >> 5) + vertex_y;
|
||||
start.x = (lv_trigo_cos(start_angle) >> 5) + vertex_x;
|
||||
|
||||
end.y = (lv_trigo_sin(end_angle) >> 5) + vertex_y;
|
||||
end.x = (lv_trigo_cos(end_angle) >> 5) + vertex_x;
|
||||
|
||||
angle_range_op.y = (lv_trigo_sin(mid_angle_op) >> 5) + vertex_y;
|
||||
angle_range_op.x = (lv_trigo_cos(mid_angle_op) >> 5) + vertex_x;
|
||||
|
||||
if(angle_range <= 180) {
|
||||
/* Two sides mask and 6 vertex points */
|
||||
|
||||
/* Masking end angle */
|
||||
lv_eve_primitive_t edge = get_mask_direction(mask_dir_end);
|
||||
lv_eve_primitive(edge); /* Side one */
|
||||
lv_eve_vertex_2f(angle_range_op.x, angle_range_op.y);
|
||||
lv_eve_vertex_2f(vertex_x, vertex_y);
|
||||
lv_eve_vertex_2f(end.x, end.y);
|
||||
|
||||
/* Masking start angle */
|
||||
edge = get_mask_direction(mask_dir_start);
|
||||
lv_eve_primitive(edge); /* Side two */
|
||||
lv_eve_vertex_2f(angle_range_op.x, angle_range_op.y);
|
||||
lv_eve_vertex_2f(vertex_x, vertex_y);
|
||||
lv_eve_vertex_2f(start.x, start.y);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if(is_same_quadrant(start_angle,
|
||||
end_angle)) { /* "It is not an optimal implementation for the case where both angles (start and end) are in the same quadrant */
|
||||
/* todo */
|
||||
lv_point_t end_line_cntr;
|
||||
lv_point_t start_line_cntr;
|
||||
|
||||
lv_point_t end_line_brd;
|
||||
lv_point_t start_line_brd;
|
||||
|
||||
int16_t chord = chord_length(dsc->radius, 360 - angle_range);
|
||||
int16_t w = ((chord / 4) < 1) ? 1 : chord / 4;
|
||||
int16_t r_width = w;
|
||||
|
||||
end_line_brd.y = vertex_y + ((lv_trigo_sin(end_angle) * dsc->radius) >> LV_TRIGO_SHIFT);
|
||||
end_line_brd.x = vertex_x + ((lv_trigo_cos(end_angle) * dsc->radius) >> LV_TRIGO_SHIFT);
|
||||
|
||||
start_line_brd.y = vertex_y + ((lv_trigo_sin(start_angle) * dsc->radius) >> LV_TRIGO_SHIFT);
|
||||
start_line_brd.x = vertex_x + ((lv_trigo_cos(start_angle) * dsc->radius) >> LV_TRIGO_SHIFT);
|
||||
|
||||
lv_eve_draw_rect_simple(start_line_brd.x, start_line_brd.y, end_line_brd.x, end_line_brd.y, 0);
|
||||
|
||||
start_line_brd.y = start_line_brd.y + ((lv_trigo_sin(start_angle - 90) * r_width) >> LV_TRIGO_SHIFT);
|
||||
start_line_brd.x = start_line_brd.x + ((lv_trigo_cos(start_angle - 90) * r_width) >> LV_TRIGO_SHIFT);
|
||||
|
||||
end_line_brd.y = end_line_brd.y + ((lv_trigo_sin(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT);
|
||||
end_line_brd.x = end_line_brd.x + ((lv_trigo_cos(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT);
|
||||
|
||||
end_line_cntr.y = vertex_y + ((lv_trigo_sin(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT);
|
||||
end_line_cntr.x = vertex_x + ((lv_trigo_cos(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT);
|
||||
|
||||
start_line_cntr.y = vertex_y + ((lv_trigo_sin(start_angle + 270) * r_width) >> LV_TRIGO_SHIFT);
|
||||
start_line_cntr.x = vertex_x + ((lv_trigo_cos(start_angle + 270) * r_width) >> LV_TRIGO_SHIFT);
|
||||
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_LINE_STRIP);
|
||||
lv_eve_line_width(r_width * 16);
|
||||
lv_eve_vertex_2f(start_line_cntr.x, start_line_cntr.y);
|
||||
lv_eve_vertex_2f(start_line_brd.x, start_line_brd.y);
|
||||
lv_eve_vertex_2f(end_line_brd.x, end_line_brd.y);
|
||||
lv_eve_vertex_2f(end_line_cntr.x, end_line_cntr.y);
|
||||
|
||||
}
|
||||
else { /* One side mask and 3 vertex points */
|
||||
/* Masking end and start angles */
|
||||
lv_eve_primitive_t edge = get_mask_direction(mid_angle_op);
|
||||
lv_eve_primitive(edge);
|
||||
lv_eve_vertex_2f(end.x, end.y);
|
||||
lv_eve_vertex_2f(vertex_x, vertex_y);
|
||||
lv_eve_vertex_2f(start.x, start.y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
|
||||
if(dsc->opa <= LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(dsc->start_angle == dsc->end_angle)
|
||||
return;
|
||||
|
||||
lv_color_t color = dsc->color;
|
||||
lv_opa_t opa = dsc->opa;
|
||||
lv_point_t center = dsc->center;
|
||||
int32_t width = dsc->width;
|
||||
uint16_t radius_out = dsc->radius;
|
||||
uint16_t radius_in = dsc->radius - dsc->width;
|
||||
int32_t start_angle = (int32_t) dsc->start_angle;
|
||||
int32_t end_angle = (int32_t) dsc->end_angle;
|
||||
|
||||
if(width > radius_out)
|
||||
width = radius_out;
|
||||
|
||||
while(start_angle >= 360)
|
||||
start_angle -= 360;
|
||||
while(end_angle >= 360)
|
||||
end_angle -= 360;
|
||||
|
||||
lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2);
|
||||
|
||||
lv_eve_save_context();
|
||||
|
||||
lv_eve_color(color);
|
||||
lv_eve_color_opa(opa);
|
||||
|
||||
lv_eve_color_mask(0, 0, 0, 1);
|
||||
lv_eve_stencil_func(EVE_ALWAYS, 0, 1);
|
||||
lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE);
|
||||
lv_eve_draw_circle_simple(center.x, center.y, radius_out); /* radius_out */
|
||||
|
||||
lv_eve_blend_func(EVE_ONE, EVE_ZERO);
|
||||
lv_eve_draw_circle_simple(center.x, center.y, radius_in + 2); /* radius_in */
|
||||
|
||||
lv_eve_stencil_func(EVE_ALWAYS, 1, 1);
|
||||
lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE);
|
||||
lv_eve_blend_func(EVE_ZERO, EVE_ONE_MINUS_SRC_ALPHA);
|
||||
lv_eve_color_opa(0XFF);
|
||||
|
||||
/* Start masking arc */
|
||||
|
||||
lv_draw_eve_mask_angle(dsc, center.x, center.y, start_angle, end_angle);
|
||||
|
||||
/* End masking arc */
|
||||
|
||||
lv_eve_draw_circle_simple(center.x, center.y, radius_in); /* radius_in */
|
||||
|
||||
lv_eve_color_mask(1, 1, 1, 1);
|
||||
lv_eve_blend_func(EVE_DST_ALPHA, EVE_ONE_MINUS_DST_ALPHA);
|
||||
lv_eve_draw_circle_simple(center.x, center.y, radius_in); /* radius_in */
|
||||
|
||||
lv_eve_stencil_func(EVE_NOTEQUAL, 1, 0XFF);
|
||||
lv_eve_blend_func(EVE_SRC_ALPHA, EVE_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
lv_eve_color_opa(opa);
|
||||
lv_eve_draw_circle_simple(center.x, center.y, radius_out); /* radius_out */
|
||||
|
||||
lv_eve_restore_context();
|
||||
|
||||
if(dsc->rounded) {
|
||||
lv_eve_save_context();
|
||||
lv_eve_color_opa(opa);
|
||||
lv_eve_color(color);
|
||||
int32_t half_width = width / 2;
|
||||
int32_t adjusted_radius = radius_out - half_width;
|
||||
draw_rounded_end(center, adjusted_radius, end_angle, half_width);
|
||||
draw_rounded_end(center, adjusted_radius, start_angle, half_width);
|
||||
lv_eve_restore_context();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @file lv_draw_eve_fill.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 27 mar 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
#include "lv_eve.h"
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
|
||||
int32_t rad = dsc->radius;
|
||||
int32_t bg_w = lv_area_get_width(coords);
|
||||
int32_t bg_h = lv_area_get_height(coords);
|
||||
int32_t real_radius = LV_MIN3(bg_w / 2, bg_h / 2, rad);
|
||||
|
||||
lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2);
|
||||
lv_eve_save_context();
|
||||
|
||||
lv_eve_color(dsc->color);
|
||||
lv_eve_color_opa(dsc->opa);
|
||||
|
||||
if(bg_w == bg_h && rad == LV_RADIUS_CIRCLE) {
|
||||
lv_eve_draw_circle_simple(coords->x1 + (bg_w / 2), coords->y1 + (bg_h / 2), real_radius);
|
||||
}
|
||||
else {
|
||||
lv_eve_draw_rect_simple(coords->x1, coords->y1, coords->x2, coords->y2, real_radius);
|
||||
}
|
||||
|
||||
lv_eve_restore_context();
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
|
||||
void lv_draw_eve_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
if(dsc->width == 0) return;
|
||||
if(dsc->side == LV_BORDER_SIDE_NONE) return;
|
||||
|
||||
int32_t coords_w = lv_area_get_width(coords);
|
||||
int32_t coords_h = lv_area_get_height(coords);
|
||||
int32_t rout = dsc->radius;
|
||||
int32_t short_side = LV_MIN(coords_w, coords_h);
|
||||
if(rout > short_side >> 1) rout = short_side >> 1;
|
||||
|
||||
/*Get the inner area*/
|
||||
lv_area_t area_inner;
|
||||
lv_area_copy(&area_inner, coords);
|
||||
area_inner.x1 += ((dsc->side & LV_BORDER_SIDE_LEFT) ? dsc->width : - (dsc->width));
|
||||
area_inner.x2 -= ((dsc->side & LV_BORDER_SIDE_RIGHT) ? dsc->width : - (dsc->width));
|
||||
area_inner.y1 += ((dsc->side & LV_BORDER_SIDE_TOP) ? dsc->width : - (dsc->width));
|
||||
area_inner.y2 -= ((dsc->side & LV_BORDER_SIDE_BOTTOM) ? dsc->width : - (dsc->width));
|
||||
|
||||
int32_t rin = rout - dsc->width;
|
||||
if(rin < 0) rin = 0;
|
||||
|
||||
lv_eve_save_context();
|
||||
|
||||
lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2);
|
||||
|
||||
lv_eve_color(dsc->color);
|
||||
lv_eve_color_opa(dsc->opa);
|
||||
|
||||
lv_eve_color_mask(0, 0, 0, 1);
|
||||
lv_eve_stencil_func(EVE_ALWAYS, 0, 1);
|
||||
lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE);
|
||||
lv_eve_draw_rect_simple(coords->x1, coords->y1, coords->x2, coords->y2, 0);
|
||||
|
||||
lv_eve_blend_func(EVE_ONE, EVE_ZERO);
|
||||
lv_eve_draw_rect_simple(area_inner.x1 - 2, area_inner.y1 - 1, area_inner.x2 + 1, area_inner.y2 + 2, rin);
|
||||
|
||||
lv_eve_stencil_func(EVE_ALWAYS, 1, 1);
|
||||
lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE);
|
||||
lv_eve_blend_func(EVE_ZERO, EVE_ONE_MINUS_SRC_ALPHA);
|
||||
lv_eve_color_opa(255);
|
||||
lv_eve_draw_rect_simple(area_inner.x1, area_inner.y1, area_inner.x2, area_inner.y2, rin);
|
||||
|
||||
lv_eve_color_mask(1, 1, 1, 1);
|
||||
|
||||
if(dsc->side == LV_BORDER_SIDE_FULL) {
|
||||
lv_eve_blend_func(EVE_DST_ALPHA, EVE_ONE_MINUS_DST_ALPHA);
|
||||
lv_eve_draw_rect_simple(area_inner.x1, area_inner.y1, area_inner.x2, area_inner.y2, rin);
|
||||
}
|
||||
|
||||
lv_eve_stencil_func(EVE_NOTEQUAL, 1, 255);
|
||||
lv_eve_blend_func(EVE_SRC_ALPHA, EVE_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
lv_eve_color_opa(dsc->opa);
|
||||
lv_eve_draw_rect_simple(coords->x1, coords->y1, coords->x2, coords->y2, rout);
|
||||
|
||||
lv_eve_restore_context();
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
/**
|
||||
* @file lv_draw_eve_image.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 17 jun 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../lv_draw_image_private.h"
|
||||
#include "lv_draw_eve_ram_g.h"
|
||||
#include "lv_eve.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void convert_row_rgb565a8_to_argb4444(const uint8_t * src, const uint8_t * src_alpha, uint8_t * dst,
|
||||
uint32_t width);
|
||||
static void convert_row_argb8888_to_argb4444(const uint8_t * src, uint8_t * dst, uint32_t width);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define F16_PIVOT_SHIFT(x) ((int32_t)((((x) >> 1)) * 65536L))
|
||||
#define F16_SCALE_DIV_256(x) ((int32_t)(((x) / 256.0f) * 65536L))
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(lv_image_src_get_type(draw_dsc->src) != LV_IMAGE_SRC_VARIABLE) {
|
||||
LV_LOG_WARN("v_draw_eve can only render images from variables (not files or symbols) for now.");
|
||||
return;
|
||||
}
|
||||
|
||||
const lv_image_dsc_t * img_dsc = draw_dsc->src;
|
||||
|
||||
int32_t clip_w = lv_area_get_width(&t->clip_area);
|
||||
int32_t clip_h = lv_area_get_height(&t->clip_area);
|
||||
|
||||
const uint8_t * src_buf = img_dsc->data;
|
||||
int32_t src_w = img_dsc->header.w;
|
||||
int32_t src_h = img_dsc->header.h;
|
||||
int32_t src_stride = img_dsc->header.stride;
|
||||
lv_color_format_t src_cf = img_dsc->header.cf;
|
||||
|
||||
if(src_stride == 0) {
|
||||
src_stride = src_w * lv_color_format_get_size(src_cf);
|
||||
}
|
||||
|
||||
uint8_t eve_format;
|
||||
int32_t eve_stride;
|
||||
uint8_t eve_alignment;
|
||||
|
||||
switch(src_cf) {
|
||||
case LV_COLOR_FORMAT_L8:
|
||||
eve_format = EVE_L8;
|
||||
eve_stride = src_stride;
|
||||
eve_alignment = 1;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
eve_format = EVE_RGB565;
|
||||
eve_stride = src_stride;
|
||||
eve_alignment = 2;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565A8:
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
eve_format = EVE_ARGB4;
|
||||
eve_stride = src_w * 2;
|
||||
eve_alignment = 2;
|
||||
break;
|
||||
default :
|
||||
LV_LOG_WARN("v_draw_eve can only render L8, RGB565, RGB565A8, and ARGB8888 images for now.");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t eve_size = eve_stride * src_h;
|
||||
|
||||
uint32_t img_addr;
|
||||
bool img_is_loaded = lv_draw_eve_ramg_get_addr(&img_addr, (uintptr_t) src_buf, eve_size, eve_alignment);
|
||||
|
||||
if(!img_is_loaded) { /* New image to load */
|
||||
if(img_addr == LV_DRAW_EVE_RAMG_OUT_OF_RAMG) {
|
||||
LV_LOG_WARN("Could not load image because space could not be allocated in RAM_G.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load image to RAM_G */
|
||||
EVE_end_cmd_burst();
|
||||
|
||||
switch(src_cf) {
|
||||
case LV_COLOR_FORMAT_L8 :
|
||||
case LV_COLOR_FORMAT_RGB565 :
|
||||
EVE_memWrite_flash_buffer(img_addr, src_buf, eve_size);
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565A8 : {
|
||||
uint8_t * tmp_buf = lv_malloc(eve_stride);
|
||||
LV_ASSERT_MALLOC(tmp_buf);
|
||||
const uint8_t * src_alpha_buf = src_buf + src_h * src_stride;
|
||||
int32_t src_alpha_stride = src_stride / 2;
|
||||
for(uint32_t y = 0; y < src_h; y++) {
|
||||
convert_row_rgb565a8_to_argb4444(src_buf + y * src_stride, src_alpha_buf + y * src_alpha_stride, tmp_buf, src_w);
|
||||
EVE_memWrite_flash_buffer(img_addr + y * eve_stride, tmp_buf, eve_stride);
|
||||
}
|
||||
lv_free(tmp_buf);
|
||||
break;
|
||||
}
|
||||
case LV_COLOR_FORMAT_ARGB8888 : {
|
||||
uint8_t * tmp_buf = lv_malloc(eve_stride);
|
||||
LV_ASSERT_MALLOC(tmp_buf);
|
||||
for(uint32_t y = 0; y < src_h; y++) {
|
||||
convert_row_argb8888_to_argb4444(src_buf + y * src_stride, tmp_buf, src_w);
|
||||
EVE_memWrite_flash_buffer(img_addr + y * eve_stride, tmp_buf, eve_stride);
|
||||
}
|
||||
lv_free(tmp_buf);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
return;
|
||||
}
|
||||
|
||||
EVE_start_cmd_burst();
|
||||
}
|
||||
|
||||
lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2);
|
||||
|
||||
lv_eve_save_context();
|
||||
|
||||
if(draw_dsc->recolor_opa > LV_OPA_MIN) {
|
||||
lv_eve_color_opa(draw_dsc->recolor_opa);
|
||||
lv_eve_color(draw_dsc->recolor);
|
||||
}
|
||||
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_BITMAPS);
|
||||
EVE_cmd_dl_burst(BITMAP_SOURCE(img_addr));
|
||||
/*real height and width is mandatory for rotation and scale (Clip Area)*/
|
||||
EVE_cmd_dl_burst(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, clip_w, clip_h));
|
||||
|
||||
EVE_cmd_dl_burst(BITMAP_LAYOUT(eve_format, eve_stride, src_h));
|
||||
|
||||
if(draw_dsc->rotation || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) {
|
||||
EVE_cmd_dl_burst(CMD_LOADIDENTITY);
|
||||
|
||||
EVE_cmd_translate_burst(F16(coords->x1 - t->clip_area.x1 + draw_dsc->pivot.x),
|
||||
F16(coords->y1 - t->clip_area.y1 + draw_dsc->pivot.y));
|
||||
if(draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) {
|
||||
/*Image Scale*/
|
||||
EVE_cmd_scale_burst(F16_SCALE_DIV_256(draw_dsc->scale_x), F16_SCALE_DIV_256(draw_dsc->scale_y));
|
||||
}
|
||||
if(draw_dsc->rotation != 0) {
|
||||
/*Image Rotate*/
|
||||
EVE_cmd_rotate_burst(DEGREES(draw_dsc->rotation));
|
||||
}
|
||||
EVE_cmd_translate_burst(-F16(draw_dsc->pivot.x), -F16(draw_dsc->pivot.y));
|
||||
EVE_cmd_dl_burst(CMD_SETMATRIX);
|
||||
EVE_cmd_dl_burst(CMD_LOADIDENTITY);
|
||||
lv_eve_vertex_2f(t->clip_area.x1, t->clip_area.y1);
|
||||
}
|
||||
else {
|
||||
lv_eve_vertex_2f(coords->x1, coords->y1);
|
||||
}
|
||||
lv_eve_restore_context();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void convert_row_rgb565a8_to_argb4444(const uint8_t * src, const uint8_t * src_alpha, uint8_t * dst,
|
||||
uint32_t width)
|
||||
{
|
||||
for(uint32_t x = 0; x < width; x++) {
|
||||
uint16_t rgb565 = ((const uint16_t *) src)[x];
|
||||
|
||||
uint8_t r5 = (rgb565 >> 11) & 0x1F;
|
||||
uint8_t g6 = (rgb565 >> 5) & 0x3F;
|
||||
uint8_t b5 = rgb565 & 0x1F;
|
||||
uint8_t alpha = src_alpha[x];
|
||||
|
||||
uint8_t r4 = r5 >> 1;
|
||||
uint8_t g4 = g6 >> 2;
|
||||
uint8_t b4 = b5 >> 1;
|
||||
uint8_t a4 = alpha >> 4;
|
||||
|
||||
uint16_t argb4444 = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4;
|
||||
|
||||
dst[2 * x] = argb4444 & 0xFF;
|
||||
dst[2 * x + 1] = (argb4444 >> 8) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static void convert_row_argb8888_to_argb4444(const uint8_t * src, uint8_t * dst, uint32_t width)
|
||||
{
|
||||
for(uint32_t x = 0; x < width; x++) {
|
||||
uint8_t blue = src[4 * x];
|
||||
uint8_t green = src[4 * x + 1];
|
||||
uint8_t red = src[4 * x + 2];
|
||||
uint8_t alpha = src[4 * x + 3];
|
||||
|
||||
uint8_t r4 = red >> 4;
|
||||
uint8_t g4 = green >> 4;
|
||||
uint8_t b4 = blue >> 4;
|
||||
uint8_t a4 = alpha >> 4;
|
||||
|
||||
uint16_t argb4444 = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4;
|
||||
|
||||
dst[2 * x] = argb4444 & 0xFF;
|
||||
dst[2 * x + 1] = (argb4444 >> 8) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @file lv_draw_eve_letter.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../lv_draw_private.h"
|
||||
#include "../lv_draw_label_private.h"
|
||||
#include "../lv_draw_rect.h"
|
||||
#include "lv_eve.h"
|
||||
#include "lv_draw_eve_ram_g.h"
|
||||
#include "../../font/lv_font_fmt_txt.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_draw_eve_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc,
|
||||
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area);
|
||||
static void font_bitmap_to_ramg(uint32_t addr, const uint8_t * src, uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define GET_NIBBLE_1(w) ((uint8_t) ((w) >> 4))
|
||||
#define GET_NIBBLE_2(w) ((uint8_t) ((w) & 0xf))
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2);
|
||||
lv_eve_save_context();
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_BITMAPS);
|
||||
lv_draw_label_iterate_characters(t, dsc, coords, lv_draw_eve_letter_cb);
|
||||
lv_eve_restore_context();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_draw_eve_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc,
|
||||
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area)
|
||||
{
|
||||
|
||||
if(fill_draw_dsc && fill_area) {
|
||||
/* draw UNDERLINE and STRIKETHROUGH */
|
||||
lv_eve_draw_rect_simple(fill_area->x1, fill_area->y1, fill_area->x2, fill_area->y2, 0);
|
||||
}
|
||||
|
||||
if(glyph_draw_dsc == NULL)
|
||||
return; /* Important */
|
||||
|
||||
const lv_font_t * font = glyph_draw_dsc->g->resolved_font;
|
||||
|
||||
if(font->get_glyph_bitmap != lv_font_get_bitmap_fmt_txt) {
|
||||
LV_LOG_WARN("lv_draw_eve can only render static fonts for now.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(glyph_draw_dsc->format != LV_FONT_GLYPH_FORMAT_A4) {
|
||||
LV_LOG_WARN("lv_draw_eve can only render 4 BPP fonts for now.");
|
||||
return;
|
||||
}
|
||||
|
||||
const lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *) font->dsc;
|
||||
uint32_t gid_index = glyph_draw_dsc->g->gid.index;
|
||||
const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = &font_dsc->glyph_dsc[gid_index];
|
||||
const uint8_t * glyph_bitmap = &font_dsc->glyph_bitmap[glyph_dsc->bitmap_index];
|
||||
|
||||
uint16_t g_box_w = glyph_dsc->box_w;
|
||||
uint16_t g_box_h = glyph_dsc->box_h;
|
||||
|
||||
uint16_t g_aligned_stride = (g_box_w + 1) / 2;
|
||||
|
||||
/* Only 4 bpp is supported for now. Support for 1 and 8 bpp can be added. (EVE_L1, EVE_L8) */
|
||||
uint8_t bpp_eve = EVE_L4;
|
||||
|
||||
uint32_t glyph_ramg_size = g_aligned_stride * g_box_h;
|
||||
|
||||
uint32_t ramg_addr;
|
||||
uintptr_t glyph_ramg_key = (uintptr_t) glyph_bitmap;
|
||||
bool font_is_loaded = lv_draw_eve_ramg_get_addr(&ramg_addr, glyph_ramg_key, glyph_ramg_size, 1);
|
||||
|
||||
if(!font_is_loaded) { /* If the font is not yet loaded in ramG, load it */
|
||||
if(ramg_addr == LV_DRAW_EVE_RAMG_OUT_OF_RAMG) {
|
||||
LV_LOG_WARN("Could not load glyph because space could not be allocated in RAM_G.");
|
||||
return;
|
||||
}
|
||||
|
||||
font_bitmap_to_ramg(ramg_addr, glyph_bitmap, g_box_w, g_box_h);
|
||||
}
|
||||
|
||||
lv_eve_color_opa(glyph_draw_dsc->opa);
|
||||
lv_eve_color(glyph_draw_dsc->color);
|
||||
|
||||
EVE_cmd_dl_burst(BITMAP_SOURCE(ramg_addr));
|
||||
|
||||
EVE_cmd_dl_burst(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, g_box_w, g_box_h));
|
||||
EVE_cmd_dl_burst(BITMAP_LAYOUT(bpp_eve, g_aligned_stride, g_box_h));
|
||||
|
||||
lv_eve_vertex_2f(glyph_draw_dsc->letter_coords->x1, glyph_draw_dsc->letter_coords->y1);
|
||||
}
|
||||
|
||||
static void font_bitmap_to_ramg(uint32_t addr, const uint8_t * src, uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
EVE_end_cmd_burst();
|
||||
|
||||
uint32_t stride = (width + 1) / 2;
|
||||
|
||||
if(width % 2 == 0) {
|
||||
uint32_t size = stride * height;
|
||||
EVE_memWrite_flash_buffer(addr, src, size);
|
||||
|
||||
EVE_start_cmd_burst();
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t * row_buf = lv_malloc(stride);
|
||||
LV_ASSERT_MALLOC(row_buf);
|
||||
|
||||
uint32_t src_i = 0;
|
||||
uint8_t nibble_1;
|
||||
uint8_t nibble_2;
|
||||
uint8_t key = 0;
|
||||
|
||||
/* Iterate through each row of the bitmap*/
|
||||
for(uint32_t y = 0; y < height; y++) {
|
||||
/* Iterate through each byte of the row*/
|
||||
uint32_t row_i;
|
||||
for(row_i = 0; row_i < (width / 2); ++row_i) {
|
||||
/*Get the two nibbles from the current byte*/
|
||||
if(key == 0) {
|
||||
nibble_1 = GET_NIBBLE_1(src[src_i]);
|
||||
nibble_2 = GET_NIBBLE_2(src[src_i]);
|
||||
}
|
||||
else {
|
||||
nibble_1 = GET_NIBBLE_2(src[src_i - 1]);
|
||||
nibble_2 = GET_NIBBLE_1(src[src_i]);
|
||||
}
|
||||
|
||||
/*Combine the nibbles and assign the result to the output byte*/
|
||||
row_buf[row_i] = (nibble_1 << 4) | nibble_2;
|
||||
|
||||
src_i++;
|
||||
}
|
||||
|
||||
/*process the last remaining nibble*/
|
||||
row_buf[row_i] =
|
||||
(key == 0) ?
|
||||
(GET_NIBBLE_1(src[src_i])) << 4 | 0x0 : (GET_NIBBLE_2(src[src_i - 1])) << 4 | 0x0;
|
||||
key = (key == 0) ? 1 : 0;
|
||||
src_i += (key == 1) ? 1 : 0;
|
||||
|
||||
EVE_memWrite_sram_buffer(addr, row_buf, stride);
|
||||
addr += stride;
|
||||
}
|
||||
|
||||
lv_free(row_buf);
|
||||
|
||||
EVE_start_cmd_burst();
|
||||
}
|
||||
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file lv_draw_eve_line.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 8 abr 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
#include "lv_eve.h"
|
||||
|
||||
|
||||
void lv_draw_eve_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(dsc->opa <= LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->p1.x == dsc->p2.x && dsc->p1.y == dsc->p2.y)
|
||||
return;
|
||||
|
||||
|
||||
|
||||
uint32_t line_w = dsc->width * 8;
|
||||
lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2);
|
||||
lv_eve_save_context();
|
||||
lv_eve_color_opa(dsc->opa);
|
||||
lv_eve_color(dsc->color);
|
||||
|
||||
if(dsc->dash_gap || dsc->dash_width) {
|
||||
LV_LOG_WARN("line dash_gap and dash_width not implemented by EVE yet.");
|
||||
}
|
||||
/* Check if it's a vertical or horizontal line without rounding */
|
||||
bool is_vertical = (dsc->p1.x == dsc->p2.x);
|
||||
bool is_horizontal = (dsc->p1.y == dsc->p2.y);
|
||||
bool no_round = (!dsc->round_end || !dsc->round_start);
|
||||
|
||||
if((is_vertical || is_horizontal) && no_round) {
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_RECTS);
|
||||
lv_eve_vertex_2f(dsc->p1.x, dsc->p1.y);
|
||||
lv_eve_vertex_2f(dsc->p2.x, dsc->p2.y);
|
||||
}
|
||||
else {
|
||||
/* Draw inclined line or line with rounding (not possible without rounding)*/
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_LINE_STRIP);
|
||||
lv_eve_line_width(line_w);
|
||||
lv_eve_vertex_2f(dsc->p1.x, dsc->p1.y);
|
||||
lv_eve_vertex_2f(dsc->p2.x, dsc->p2.y);
|
||||
}
|
||||
|
||||
lv_eve_restore_context();
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @file lv_draw_eve_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_EVE_PRIVATE_H
|
||||
#define LV_DRAW_EVE_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_eve.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "lv_draw_eve_target.h"
|
||||
#include "../lv_draw_private.h"
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../core/lv_global.h"
|
||||
#include "../lv_draw_triangle.h"
|
||||
#include "../lv_draw_line.h"
|
||||
#include "../lv_draw_label.h"
|
||||
#include "../lv_draw_arc.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
uintptr_t key;
|
||||
uint32_t addr;
|
||||
} lv_draw_eve_ramg_hash_table_cell_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ramg_addr_end;
|
||||
uint32_t hash_table_cell_count;
|
||||
uint32_t hash_table_cells_occupied;
|
||||
lv_draw_eve_ramg_hash_table_cell_t * hash_table;
|
||||
} lv_draw_eve_ramg_t;
|
||||
|
||||
struct _lv_draw_eve_unit_t {
|
||||
lv_draw_unit_t base_unit;
|
||||
lv_draw_task_t * task_act;
|
||||
lv_display_t * disp;
|
||||
lv_draw_eve_ramg_t ramg;
|
||||
lv_draw_eve_parameters_t params;
|
||||
lv_draw_eve_operation_cb_t op_cb;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_eve_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
void lv_draw_eve_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_eve_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
void lv_draw_eve_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
void lv_draw_eve_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define DEGREES(n) ((65536UL * (n)) / 3600)
|
||||
#define F16(x) ((int32_t)((x) * 65536L))
|
||||
|
||||
#define lv_draw_eve_unit_g (LV_GLOBAL_DEFAULT()->draw_eve_unit)
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_EVE_PRIVATE_H*/
|
||||
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* @file lv_draw_eve_ram_g.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 19 nov 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
#include "lv_draw_eve_ram_g.h"
|
||||
#include "lv_eve.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define RAMG_DEBUG 0
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void ramg_init(lv_draw_eve_ramg_t * ramg);
|
||||
static uint32_t hash_key(uintptr_t key);
|
||||
static uint32_t fnv_1a_hash(const void * src, size_t len);
|
||||
static void grow_hash_table(lv_draw_eve_ramg_t * ramg);
|
||||
|
||||
#if RAMG_DEBUG
|
||||
static void ramg_debug(lv_draw_eve_ramg_t * ramg, uint32_t key_hash, uint32_t table_index);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
bool lv_draw_eve_ramg_get_addr(uint32_t * addr_dst, uintptr_t key,
|
||||
uint32_t addr_size, uint32_t addr_align)
|
||||
{
|
||||
LV_ASSERT(key != 0);
|
||||
|
||||
lv_draw_eve_ramg_t * ramg = &lv_draw_eve_unit_g->ramg;
|
||||
|
||||
if(ramg->hash_table_cell_count == 0) {
|
||||
ramg_init(ramg);
|
||||
}
|
||||
|
||||
uint32_t key_hash = hash_key(key);
|
||||
uint32_t table_index = key_hash % ramg->hash_table_cell_count;
|
||||
lv_draw_eve_ramg_hash_table_cell_t * cell;
|
||||
|
||||
while(1) {
|
||||
cell = &ramg->hash_table[table_index];
|
||||
|
||||
if(cell->key == key) {
|
||||
#if RAMG_DEBUG
|
||||
ramg_debug(ramg, key_hash, table_index);
|
||||
#endif
|
||||
|
||||
*addr_dst = cell->addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(cell->key == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
table_index++;
|
||||
if(table_index >= ramg->hash_table_cell_count) table_index = 0;
|
||||
}
|
||||
|
||||
uint32_t addr_ret = LV_ALIGN_UP(ramg->ramg_addr_end, addr_align);
|
||||
uint32_t addr_new_end = addr_ret + addr_size;
|
||||
|
||||
if(addr_new_end > 1024 * 1024) {
|
||||
LV_LOG_WARN("EVE on-chip 1 MB RAM_G for images and fonts has run out.");
|
||||
*addr_dst = LV_DRAW_EVE_RAMG_OUT_OF_RAMG;
|
||||
return false;
|
||||
}
|
||||
|
||||
ramg->ramg_addr_end = addr_new_end;
|
||||
ramg->hash_table_cells_occupied++;
|
||||
|
||||
cell->key = key;
|
||||
cell->addr = addr_ret;
|
||||
*addr_dst = addr_ret;
|
||||
|
||||
#if RAMG_DEBUG
|
||||
ramg_debug(ramg, key_hash, table_index);
|
||||
#endif
|
||||
|
||||
if(ramg->hash_table_cells_occupied > ramg->hash_table_cell_count / 4 * 3) {
|
||||
grow_hash_table(ramg);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void ramg_init(lv_draw_eve_ramg_t * ramg)
|
||||
{
|
||||
ramg->hash_table_cell_count = 32;
|
||||
ramg->hash_table = lv_calloc(32, sizeof(lv_draw_eve_ramg_hash_table_cell_t));
|
||||
LV_ASSERT_MALLOC(ramg->hash_table);
|
||||
}
|
||||
|
||||
static uint32_t hash_key(uintptr_t key)
|
||||
{
|
||||
return fnv_1a_hash(&key, sizeof(key));
|
||||
}
|
||||
|
||||
static uint32_t fnv_1a_hash(const void * src, size_t len)
|
||||
{
|
||||
const uint8_t * src_u8 = src;
|
||||
uint32_t hash = 2166136261u;
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
hash ^= src_u8[i];
|
||||
hash *= 16777619u;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void grow_hash_table(lv_draw_eve_ramg_t * ramg)
|
||||
{
|
||||
uint32_t old_cell_count = ramg->hash_table_cell_count;
|
||||
lv_draw_eve_ramg_hash_table_cell_t * old_hash_table = ramg->hash_table;
|
||||
|
||||
ramg->hash_table_cell_count += ramg->hash_table_cell_count / 2;
|
||||
ramg->hash_table = lv_calloc(ramg->hash_table_cell_count,
|
||||
sizeof(lv_draw_eve_ramg_hash_table_cell_t));
|
||||
LV_ASSERT_MALLOC(ramg->hash_table);
|
||||
|
||||
for(uint32_t i = 0; i < old_cell_count; i++) {
|
||||
lv_draw_eve_ramg_hash_table_cell_t * old_cell = &old_hash_table[i];
|
||||
|
||||
if(old_cell->key == 0) continue;
|
||||
|
||||
uint32_t key_hash = hash_key(old_cell->key);
|
||||
uint32_t new_table_index = key_hash % ramg->hash_table_cell_count;
|
||||
lv_draw_eve_ramg_hash_table_cell_t * new_cell_dst = &ramg->hash_table[new_table_index];
|
||||
|
||||
while(new_cell_dst->key != 0) {
|
||||
new_table_index++;
|
||||
if(new_table_index >= ramg->hash_table_cell_count) new_table_index = 0;
|
||||
new_cell_dst = &ramg->hash_table[new_table_index];
|
||||
}
|
||||
*new_cell_dst = *old_cell;
|
||||
}
|
||||
|
||||
lv_free(old_hash_table);
|
||||
}
|
||||
|
||||
#if RAMG_DEBUG
|
||||
/*
|
||||
Print tables like this:
|
||||
113 kB of RAM_G used
|
||||
================================-==-=====---=---===---=====-=-=-=-==--=======----=-==-==---=--===--=-=-=========================
|
||||
========^$==========--=-==-=-=--=--=========---=----========-------===--=====----=======--=====--====--=====-=--=-=
|
||||
|
||||
'-' unoccupied cells
|
||||
'=' occupied cells
|
||||
'^' where the hash pointed to in the table initially and linear probing started
|
||||
'$' where linear probing ended because a matching or unoccupied cell
|
||||
was found. This symbol is not shown if the initial guess was correct.
|
||||
|
||||
This example has 244 cells. Each cell uses 8 bytes of local RAM, so just under 2 kB.
|
||||
Each cell represents an allocation in EVE RAM_G. The RAM_G allocation sizes are not
|
||||
represented in this table, except for the overall "113 kB of RAM_G used" message.
|
||||
*/
|
||||
static void ramg_debug(lv_draw_eve_ramg_t * ramg, uint32_t key_hash, uint32_t table_index)
|
||||
{
|
||||
uint32_t table_index_initial_guess = key_hash % ramg->hash_table_cell_count;
|
||||
|
||||
lv_log("%u kB of RAM_G used\n", (unsigned) ramg->ramg_addr_end / 1024);
|
||||
|
||||
for(uint32_t i = 0; i < ramg->hash_table_cell_count; i++) {
|
||||
if(i != 0 && i % 128 == 0) {
|
||||
lv_log("\n");
|
||||
}
|
||||
|
||||
if(i == table_index_initial_guess) {
|
||||
lv_log("^");
|
||||
}
|
||||
else if(i == table_index) {
|
||||
lv_log("$");
|
||||
}
|
||||
else if(ramg->hash_table[i].key) {
|
||||
lv_log("=");
|
||||
}
|
||||
else {
|
||||
lv_log("-");
|
||||
}
|
||||
}
|
||||
|
||||
lv_log("\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif/*LV_USE_EVE_DRAW*/
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file lv_draw_eve_ram_g.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 19 nov 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_EVE_RAM_G_H
|
||||
#define LV_DRAW_EVE_RAM_G_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_DRAW_EVE_RAMG_OUT_OF_RAMG UINT32_MAX
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
bool lv_draw_eve_ramg_get_addr(uint32_t * addr_dst, uintptr_t key,
|
||||
uint32_t addr_size, uint32_t addr_align);
|
||||
|
||||
#endif/*LV_USE_DRAW_EVE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* LV_DRAW_EVE_RAM_G_H */
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file lv_draw_eve_target.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_EVE_TARGET_H
|
||||
#define LV_DRAW_EVE_TARGET_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
#include LV_STDBOOL_INCLUDE
|
||||
#include LV_STDINT_INCLUDE
|
||||
|
||||
typedef struct {
|
||||
uint16_t hor_res; /**< active display width */
|
||||
uint16_t ver_res; /**< active display height */
|
||||
uint16_t hcycle; /**< total number of clocks per line, incl front/back porch */
|
||||
uint16_t hoffset; /**< start of active line */
|
||||
uint16_t hsync0; /**< start of horizontal sync pulse */
|
||||
uint16_t hsync1; /**< end of horizontal sync pulse */
|
||||
uint16_t vcycle; /**< total number of lines per screen, including pre/post */
|
||||
uint16_t voffset; /**< start of active screen */
|
||||
uint16_t vsync0; /**< start of vertical sync pulse */
|
||||
uint16_t vsync1; /**< end of vertical sync pulse */
|
||||
uint8_t swizzle; /**< FT8xx output to LCD - pin order */
|
||||
uint8_t pclkpol; /**< LCD data is clocked in on this PCLK edge */
|
||||
uint8_t cspread; /**< helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */
|
||||
uint8_t pclk; /**< 60MHz / pclk = pclk frequency */
|
||||
bool has_crystal; /**< has an external clock crystal */
|
||||
bool has_gt911; /**< has a touch controller */
|
||||
uint8_t backlight_pwm; /**< backlight PWM duty cycle 0 = off, 128 = max */
|
||||
uint16_t backlight_freq; /**< backlight PWM frequency. try 4000 if unsure */
|
||||
} lv_draw_eve_parameters_t;
|
||||
|
||||
typedef enum {
|
||||
LV_DRAW_EVE_OPERATION_POWERDOWN_SET, /**< set the "PD_N" pin low */
|
||||
LV_DRAW_EVE_OPERATION_POWERDOWN_CLEAR, /**< set the "PD_N" pin high */
|
||||
LV_DRAW_EVE_OPERATION_CS_ASSERT, /**< set the "CS_N" pin low */
|
||||
LV_DRAW_EVE_OPERATION_CS_DEASSERT, /**< set the "CS_N" pin high */
|
||||
LV_DRAW_EVE_OPERATION_SPI_SEND, /**< send `length` bytes of `data` over SPI */
|
||||
LV_DRAW_EVE_OPERATION_SPI_RECEIVE /**< receive `length` bytes into `data` from SPI */
|
||||
} lv_draw_eve_operation_t;
|
||||
|
||||
typedef void (*lv_draw_eve_operation_cb_t)(lv_display_t * disp, lv_draw_eve_operation_t operation, void * data,
|
||||
uint32_t length);
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_EVE_TARGET_H*/
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* @file lv_draw_eve_triangle.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 10 ene 2024
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve_private.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../../misc/lv_math.h"
|
||||
#include "../../stdlib/lv_mem.h"
|
||||
#include "../../misc/lv_area_private.h"
|
||||
#include "../../misc/lv_color.h"
|
||||
#include "../../stdlib/lv_string.h"
|
||||
#include "lv_eve.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_eve_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc)
|
||||
{
|
||||
|
||||
lv_area_t tri_area;
|
||||
tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
tri_area.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
tri_area.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
tri_area.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
|
||||
bool is_common;
|
||||
lv_area_t draw_area;
|
||||
is_common = lv_area_intersect(&draw_area, &tri_area, &t->clip_area);
|
||||
if(!is_common) return;
|
||||
|
||||
lv_point_t p[3];
|
||||
/*If there is a vertical side use it as p[0] and p[1]*/
|
||||
if(dsc->p[0].x == dsc->p[1].x) {
|
||||
p[0] = lv_point_from_precise(&dsc->p[0]);
|
||||
p[1] = lv_point_from_precise(&dsc->p[1]);
|
||||
p[2] = lv_point_from_precise(&dsc->p[2]);
|
||||
}
|
||||
else if(dsc->p[0].x == dsc->p[2].x) {
|
||||
p[0] = lv_point_from_precise(&dsc->p[0]);
|
||||
p[1] = lv_point_from_precise(&dsc->p[2]);
|
||||
p[2] = lv_point_from_precise(&dsc->p[1]);
|
||||
}
|
||||
else if(dsc->p[1].x == dsc->p[2].x) {
|
||||
p[0] = lv_point_from_precise(&dsc->p[1]);
|
||||
p[1] = lv_point_from_precise(&dsc->p[2]);
|
||||
p[2] = lv_point_from_precise(&dsc->p[0]);
|
||||
}
|
||||
else {
|
||||
p[0] = lv_point_from_precise(&dsc->p[0]);
|
||||
p[1] = lv_point_from_precise(&dsc->p[1]);
|
||||
p[2] = lv_point_from_precise(&dsc->p[2]);
|
||||
|
||||
/*Set the smallest y as p[0]*/
|
||||
if(p[0].y > p[1].y) lv_point_swap(&p[0], &p[1]);
|
||||
if(p[0].y > p[2].y) lv_point_swap(&p[0], &p[2]);
|
||||
|
||||
/*Set the greatest y as p[1]*/
|
||||
if(p[1].y < p[2].y) lv_point_swap(&p[1], &p[2]);
|
||||
}
|
||||
|
||||
/*Be sure p[0] is on the top*/
|
||||
if(p[0].y > p[1].y) lv_point_swap(&p[0], &p[1]);
|
||||
|
||||
lv_eve_save_context();
|
||||
|
||||
lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2);
|
||||
|
||||
lv_eve_color(dsc->color);
|
||||
lv_eve_color_opa(dsc->opa);
|
||||
|
||||
lv_eve_color_mask(0, 0, 0, 0);
|
||||
lv_eve_stencil_op(EVE_KEEP, EVE_INVERT);
|
||||
lv_eve_stencil_func(EVE_ALWAYS, 255, 255);
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_EDGE_STRIP_A);
|
||||
|
||||
lv_eve_vertex_2f(p[0].x, p[0].y);
|
||||
lv_eve_vertex_2f(p[1].x, p[1].y);
|
||||
lv_eve_vertex_2f(p[2].x, p[2].y);
|
||||
|
||||
lv_eve_color_mask(1, 1, 1, 1);
|
||||
lv_eve_stencil_func(EVE_EQUAL, 255, 255) ;
|
||||
|
||||
lv_eve_vertex_2f(0, 0);
|
||||
lv_eve_vertex_2f(1022, 0);
|
||||
|
||||
lv_eve_restore_context();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @file lv_eve.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 8 jun 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_eve.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
#include "lv_eve.h"
|
||||
#include "../../libs/FT800-FT813/EVE_commands.h"
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static uint16_t scissor_x1 = 0;
|
||||
static uint16_t scissor_y1 = 0;
|
||||
static uint16_t scissor_x2 = 0;
|
||||
static uint16_t scissor_y2 = 0;
|
||||
|
||||
static lv_eve_drawing_context_t ct = {
|
||||
.primitive = LV_EVE_PRIMITIVE_ZERO_VALUE,
|
||||
.color = {0xff, 0xff, 0xff},
|
||||
.opa = 255,
|
||||
.line_width = 1, /* for format(0) */
|
||||
.point_size = 1,
|
||||
.color_mask = {1, 1, 1, 1},
|
||||
.stencil_func = {EVE_ALWAYS, 0, 255},
|
||||
.stencil_op = {EVE_KEEP, EVE_KEEP},
|
||||
.blend_func = {EVE_SRC_ALPHA, EVE_ONE_MINUS_SRC_ALPHA},
|
||||
.scx = 0,
|
||||
.scy = 0,
|
||||
};
|
||||
|
||||
static lv_eve_drawing_context_t ct_temp;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_eve_save_context(void)
|
||||
{
|
||||
EVE_cmd_dl_burst(DL_SAVE_CONTEXT);
|
||||
ct_temp = ct;
|
||||
}
|
||||
|
||||
void lv_eve_restore_context(void)
|
||||
{
|
||||
EVE_cmd_dl_burst(DL_RESTORE_CONTEXT);
|
||||
ct = ct_temp;
|
||||
}
|
||||
|
||||
|
||||
void lv_eve_primitive(uint8_t context)
|
||||
{
|
||||
if(context != ct.primitive && context != LV_EVE_PRIMITIVE_ZERO_VALUE) {
|
||||
EVE_cmd_dl_burst(DL_BEGIN | context);
|
||||
ct.primitive = context;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_scissor(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
||||
{
|
||||
if(x1 != scissor_x1 || y1 != scissor_y1) {
|
||||
int16_t adjusted_x1 = x1 > 0 ? x1 - 1 : 0;
|
||||
int16_t adjusted_y1 = y1 > 0 ? y1 - 1 : 0;
|
||||
EVE_cmd_dl_burst(SCISSOR_XY(adjusted_x1, adjusted_y1));
|
||||
scissor_x1 = x1;
|
||||
scissor_y1 = y1;
|
||||
}
|
||||
|
||||
if(x2 != scissor_x2 || y2 != scissor_y2) {
|
||||
uint16_t w = x2 - x1 + 3;
|
||||
uint16_t h = y2 - y1 + 3;
|
||||
EVE_cmd_dl_burst(SCISSOR_SIZE(w, h));
|
||||
scissor_x2 = x2;
|
||||
scissor_y2 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_color(lv_color_t color)
|
||||
{
|
||||
if((ct.color.red != color.red) || (ct.color.green != color.green) || (ct.color.blue != color.blue)) {
|
||||
EVE_cmd_dl_burst(COLOR_RGB(color.red, color.green, color.blue));
|
||||
ct.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_color_mask(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
if((ct.color_mask[0] != r) ||
|
||||
(ct.color_mask[1] != g) ||
|
||||
(ct.color_mask[2] != b) ||
|
||||
(ct.color_mask[3] != a)) {
|
||||
|
||||
EVE_cmd_dl_burst(COLOR_MASK(r, g, b, a));
|
||||
ct.color_mask[0] = r;
|
||||
ct.color_mask[1] = g;
|
||||
ct.color_mask[2] = b;
|
||||
ct.color_mask[3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_stencil_func(uint8_t func, uint8_t ref, uint8_t mask)
|
||||
{
|
||||
if(func != ct.stencil_func[0] || ref != ct.stencil_func[1] || mask != ct.stencil_func[2]) {
|
||||
|
||||
EVE_cmd_dl_burst(STENCIL_FUNC(func, ref, mask));
|
||||
ct.stencil_func[0] = func;
|
||||
ct.stencil_func[1] = ref;
|
||||
ct.stencil_func[2] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_stencil_op(uint8_t sfail, uint8_t spass)
|
||||
{
|
||||
if(sfail != ct.stencil_op[0] || spass != ct.stencil_op[1]) {
|
||||
EVE_cmd_dl_burst(STENCIL_OP(sfail, spass));
|
||||
ct.stencil_op[0] = sfail;
|
||||
ct.stencil_op[1] = spass;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_blend_func(uint8_t src, uint8_t dst)
|
||||
{
|
||||
if(src != ct.blend_func[0] || dst != ct.blend_func[1]) {
|
||||
EVE_cmd_dl_burst(BLEND_FUNC(src, dst));
|
||||
ct.blend_func[0] = src;
|
||||
ct.blend_func[1] = dst;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_color_opa(lv_opa_t opa)
|
||||
{
|
||||
if(opa != ct.opa) {
|
||||
EVE_cmd_dl_burst(COLOR_A(opa));
|
||||
ct.opa = opa;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_line_width(int32_t width)
|
||||
{
|
||||
if(width != ct.line_width) {
|
||||
EVE_cmd_dl_burst(LINE_WIDTH(width));
|
||||
ct.line_width = width;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_point_size(uint16_t radius)
|
||||
{
|
||||
if(radius != ct.point_size) {
|
||||
EVE_cmd_dl_burst(POINT_SIZE(radius * 16));
|
||||
ct.point_size = radius;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_eve_vertex_2f(int16_t x, int16_t y)
|
||||
{
|
||||
EVE_cmd_dl_burst(VERTEX2F(x, y));
|
||||
}
|
||||
|
||||
void lv_eve_draw_circle_simple(int16_t coord_x1, int16_t coord_y1, uint16_t radius_t)
|
||||
{
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_POINTS);
|
||||
lv_eve_point_size(radius_t);
|
||||
lv_eve_vertex_2f(coord_x1, coord_y1);
|
||||
}
|
||||
|
||||
|
||||
void lv_eve_draw_rect_simple(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2, uint16_t radius)
|
||||
{
|
||||
lv_eve_primitive(LV_EVE_PRIMITIVE_RECTS);
|
||||
if(radius > 1) {
|
||||
lv_eve_line_width(radius * 16);
|
||||
}
|
||||
|
||||
lv_eve_vertex_2f(coord_x1 + radius, coord_y1 + radius);
|
||||
lv_eve_vertex_2f(coord_x2 - radius, coord_y2 - radius);
|
||||
}
|
||||
|
||||
void lv_eve_mask_round(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2, int16_t radius)
|
||||
{
|
||||
lv_eve_color_mask(0, 0, 0, 1);
|
||||
EVE_cmd_dl_burst(CLEAR(1, 1, 1));
|
||||
|
||||
|
||||
lv_eve_draw_rect_simple(coord_x1, coord_y1, coord_x2, coord_y2, radius);
|
||||
lv_eve_color_mask(1, 1, 1, 0);
|
||||
lv_eve_blend_func(EVE_DST_ALPHA, EVE_ONE_MINUS_DST_ALPHA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @file lv_eve.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* Created on: 8 jun 2023
|
||||
* Author: juanj
|
||||
*
|
||||
* Modified by LVGL
|
||||
*/
|
||||
|
||||
#ifndef LV_EVE_H
|
||||
#define LV_EVE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_eve.h"
|
||||
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../misc/lv_color.h"
|
||||
#include "../../libs/FT800-FT813/EVE.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef enum {
|
||||
LV_EVE_PRIMITIVE_ZERO_VALUE,
|
||||
LV_EVE_PRIMITIVE_BITMAPS = 1UL, /* Bitmap drawing primitive */
|
||||
LV_EVE_PRIMITIVE_POINTS = 2UL, /* Point drawing primitive */
|
||||
LV_EVE_PRIMITIVE_LINES = 3UL, /* Line drawing primitive */
|
||||
LV_EVE_PRIMITIVE_LINE_STRIP = 4UL, /* Line strip drawing primitive */
|
||||
LV_EVE_PRIMITIVE_EDGE_STRIP_R = 5UL, /* Edge strip right side drawing primitive */
|
||||
LV_EVE_PRIMITIVE_EDGE_STRIP_L = 6UL, /* Edge strip left side drawing primitive */
|
||||
LV_EVE_PRIMITIVE_EDGE_STRIP_A = 7UL, /* Edge strip above drawing primitive */
|
||||
LV_EVE_PRIMITIVE_EDGE_STRIP_B = 8UL, /* Edge strip below side drawing primitive */
|
||||
LV_EVE_PRIMITIVE_RECTS = 9UL, /* Rectangle drawing primitive */
|
||||
} lv_eve_primitive_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
lv_eve_primitive_t primitive;
|
||||
lv_color_t color;
|
||||
lv_opa_t opa;
|
||||
int32_t line_width;
|
||||
uint16_t point_size;
|
||||
uint8_t color_mask[4];
|
||||
uint8_t stencil_func[3];
|
||||
uint8_t stencil_op[2];
|
||||
uint8_t blend_func[2];
|
||||
uint16_t scx;
|
||||
uint16_t scy;
|
||||
} lv_eve_drawing_context_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_eve_save_context(void);
|
||||
void lv_eve_restore_context(void);
|
||||
void lv_eve_scissor(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
|
||||
void lv_eve_primitive(uint8_t context);
|
||||
void lv_eve_color(lv_color_t color);
|
||||
void lv_eve_color_opa(lv_opa_t opa);
|
||||
void lv_eve_line_width(int32_t width);
|
||||
void lv_eve_point_size(uint16_t radius);
|
||||
void lv_eve_vertex_2f(int16_t x, int16_t y);
|
||||
void lv_eve_color_mask(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
void lv_eve_stencil_func(uint8_t func, uint8_t ref, uint8_t mask);
|
||||
void lv_eve_stencil_op(uint8_t sfail, uint8_t spass);
|
||||
void lv_eve_blend_func(uint8_t sfail, uint8_t spass);
|
||||
|
||||
void lv_eve_draw_circle_simple(int16_t coord_x1, int16_t coord_y1, uint16_t radius_t);
|
||||
void lv_eve_draw_rect_simple(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2,
|
||||
uint16_t radius);
|
||||
void lv_eve_mask_round(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2, int16_t radius);
|
||||
|
||||
/**********************
|
||||
* EXTERN VARIABLES
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* INLINE FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* LV_EVE_H */
|
||||
@@ -28,24 +28,24 @@ extern "C" {
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
uint16_t hor_res;
|
||||
uint16_t ver_res;
|
||||
uint16_t hor_res; /**< active display width */
|
||||
uint16_t ver_res; /**< active display height */
|
||||
|
||||
uint16_t hcycle;
|
||||
uint16_t hoffset;
|
||||
uint16_t hsync0;
|
||||
uint16_t hsync1;
|
||||
uint16_t vcycle;
|
||||
uint16_t voffset;
|
||||
uint16_t vsync0;
|
||||
uint16_t vsync1;
|
||||
uint8_t swizzle;
|
||||
uint8_t pclkpol;
|
||||
uint8_t cspread;
|
||||
uint8_t pclk;
|
||||
uint16_t hcycle; /**< total number of clocks per line, incl front/back porch */
|
||||
uint16_t hoffset; /**< start of active line */
|
||||
uint16_t hsync0; /**< start of horizontal sync pulse */
|
||||
uint16_t hsync1; /**< end of horizontal sync pulse */
|
||||
uint16_t vcycle; /**< total number of lines per screen, including pre/post */
|
||||
uint16_t voffset; /**< start of active screen */
|
||||
uint16_t vsync0; /**< start of vertical sync pulse */
|
||||
uint16_t vsync1; /**< end of vertical sync pulse */
|
||||
uint8_t swizzle; /**< FT8xx output to LCD - pin order */
|
||||
uint8_t pclkpol; /**< LCD data is clocked in on this PCLK edge */
|
||||
uint8_t cspread; /**< helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */
|
||||
uint8_t pclk; /**< 60MHz / pclk = pclk frequency */
|
||||
|
||||
bool has_crystal;
|
||||
bool is_bt81x;
|
||||
bool has_crystal; /**< has an external clock crystal */
|
||||
bool is_bt81x; /**< is a BT series model, not FT */
|
||||
} lv_ft81x_parameters_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -53,9 +53,10 @@ typedef enum {
|
||||
LV_FT81X_SPI_OPERATION_CS_DEASSERT,
|
||||
LV_FT81X_SPI_OPERATION_SEND,
|
||||
LV_FT81X_SPI_OPERATION_RECEIVE
|
||||
} lv_ft81x_spi_operation;
|
||||
} lv_ft81x_spi_operation_t;
|
||||
|
||||
typedef void (*lv_ft81x_spi_cb_t)(lv_display_t * disp, lv_ft81x_spi_operation operation, void * data, uint32_t length);
|
||||
typedef void (*lv_ft81x_spi_cb_t)(lv_display_t * disp, lv_ft81x_spi_operation_t operation, void * data,
|
||||
uint32_t length);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @file lv_draw_eve_display.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_eve_display.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../../../draw/eve/lv_eve.h"
|
||||
#include "../../../draw/eve/lv_draw_eve.h"
|
||||
#include "../../../display/lv_display_private.h"
|
||||
|
||||
#include "../../../libs/FT800-FT813/EVE_commands.h"
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
static void resolution_changed_cb(lv_event_t * e);
|
||||
static void touch_read_cb(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_draw_eve_display_create(const lv_draw_eve_parameters_t * params, lv_draw_eve_operation_cb_t op_cb,
|
||||
void * user_data)
|
||||
{
|
||||
static uint8_t dummy_buf; /* It won't be used as it will send commands instead of draw pixels. */
|
||||
|
||||
lv_display_t * disp = lv_display_create(params->hor_res, params->ver_res);
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
lv_display_set_buffers(disp, &dummy_buf, NULL,
|
||||
params->hor_res * params->ver_res * LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_NATIVE),
|
||||
LV_DISPLAY_RENDER_MODE_FULL); /* recreate the full display list each refresh */
|
||||
lv_display_add_event_cb(disp, resolution_changed_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
|
||||
lv_display_set_driver_data(disp, user_data);
|
||||
|
||||
lv_draw_eve_set_display_data(disp, params, op_cb);
|
||||
|
||||
EVE_init();
|
||||
EVE_memWrite8(REG_PWM_DUTY, EVE_BACKLIGHT_PWM); /* 0 = off, 0x80 = max */
|
||||
|
||||
EVE_start_cmd_burst();
|
||||
EVE_cmd_dl_burst(CMD_DLSTART); /* start the display list */
|
||||
EVE_cmd_dl_burst(DL_CLEAR_COLOR_RGB | 0x000000);
|
||||
EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
|
||||
EVE_cmd_dl_burst(VERTEX_FORMAT(0));
|
||||
EVE_end_cmd_burst();
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
void * lv_draw_eve_display_get_user_data(lv_display_t * disp)
|
||||
{
|
||||
return lv_display_get_driver_data(disp);
|
||||
}
|
||||
|
||||
lv_indev_t * lv_draw_eve_touch_create(lv_display_t * disp)
|
||||
{
|
||||
lv_indev_t * indev = lv_indev_create();
|
||||
|
||||
lv_indev_set_display(indev, disp);
|
||||
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
|
||||
lv_indev_set_read_cb(indev, touch_read_cb);
|
||||
|
||||
return indev;
|
||||
}
|
||||
|
||||
uint8_t lv_draw_eve_memread8(lv_display_t * disp, uint32_t address)
|
||||
{
|
||||
LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command without a draw_eve display");
|
||||
return EVE_memRead8(address);
|
||||
}
|
||||
|
||||
uint16_t lv_draw_eve_memread16(lv_display_t * disp, uint32_t address)
|
||||
{
|
||||
LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display");
|
||||
return EVE_memRead16(address);
|
||||
}
|
||||
|
||||
uint32_t lv_draw_eve_memread32(lv_display_t * disp, uint32_t address)
|
||||
{
|
||||
LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display");
|
||||
return EVE_memRead32(address);
|
||||
}
|
||||
|
||||
void lv_draw_eve_memwrite8(lv_display_t * disp, uint32_t address, uint8_t data)
|
||||
{
|
||||
LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display");
|
||||
EVE_memWrite8(address, data);
|
||||
}
|
||||
|
||||
void lv_draw_eve_memwrite16(lv_display_t * disp, uint32_t address, uint16_t data)
|
||||
{
|
||||
LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display");
|
||||
EVE_memWrite16(address, data);
|
||||
}
|
||||
|
||||
void lv_draw_eve_memwrite32(lv_display_t * disp, uint32_t address, uint32_t data)
|
||||
{
|
||||
LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display");
|
||||
EVE_memWrite32(address, data);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
if(lv_display_flush_is_last(disp)) {
|
||||
EVE_start_cmd_burst();
|
||||
EVE_cmd_dl_burst(DL_DISPLAY); /* instruct the co-processor to show the list */
|
||||
EVE_cmd_dl_burst(CMD_SWAP); /* make this list active */
|
||||
EVE_end_cmd_burst();
|
||||
|
||||
EVE_execute_cmd();
|
||||
|
||||
EVE_start_cmd_burst();
|
||||
EVE_cmd_dl_burst(CMD_DLSTART);
|
||||
EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
|
||||
EVE_cmd_dl_burst(VERTEX_FORMAT(0));
|
||||
EVE_end_cmd_burst();
|
||||
}
|
||||
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
static void resolution_changed_cb(lv_event_t * e)
|
||||
{
|
||||
lv_display_t * disp = lv_event_get_target(e);
|
||||
|
||||
lv_display_rotation_t rotation = lv_display_get_rotation(disp);
|
||||
uint32_t cmd_value;
|
||||
switch(rotation) {
|
||||
case LV_DISPLAY_ROTATION_0:
|
||||
cmd_value = 0;
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_90:
|
||||
cmd_value = 2;
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_180:
|
||||
cmd_value = 1;
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_270:
|
||||
cmd_value = 3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* no need to rotate the touch coordinates with CMD_SETROTATE, as LVGL
|
||||
* already rotates the input coordinates.
|
||||
*/
|
||||
EVE_memWrite8(REG_ROTATE, cmd_value);
|
||||
}
|
||||
|
||||
static void touch_read_cb(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
lv_display_t * disp = lv_indev_get_display(indev);
|
||||
|
||||
if(disp == NULL || disp->flush_cb != flush_cb) return;
|
||||
|
||||
uint32_t xy = EVE_memRead32(REG_TOUCH_SCREEN_XY);
|
||||
uint16_t x = xy >> 16;
|
||||
uint16_t y = xy & 0xffff;
|
||||
|
||||
int32_t disp_w = lv_display_get_original_horizontal_resolution(disp);
|
||||
int32_t disp_h = lv_display_get_original_vertical_resolution(disp);
|
||||
|
||||
if(x < disp_w && y < disp_h) {
|
||||
data->state = LV_INDEV_STATE_PRESSED;
|
||||
data->point.x = x;
|
||||
data->point.y = y;
|
||||
}
|
||||
else {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @file lv_draw_eve_display.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_EVE_DISPLAY_H
|
||||
#define LV_DRAW_EVE_DISPLAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
|
||||
#include "../../../draw/eve/lv_draw_eve_target.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a display for the EVE draw unit.
|
||||
* @param params Pointer to a struct of display parameters. Can be a temporary variable
|
||||
* @param op_cb A callback that will be called to perform pin and SPI IO operations with the EVE chip
|
||||
* @param user_data use `lv_draw_eve_display_get_user_data` to get this pointer inside the `op_cb`
|
||||
* @return the EVE display
|
||||
*/
|
||||
lv_display_t * lv_draw_eve_display_create(const lv_draw_eve_parameters_t * params, lv_draw_eve_operation_cb_t op_cb,
|
||||
void * user_data);
|
||||
|
||||
/**
|
||||
* Get the `user_data` parameter that was passed to `lv_draw_eve_display_create`. Useful in the operation callback.
|
||||
* @param disp pointer to the lv_draw_eve display
|
||||
* @return the `user_data` pointer
|
||||
*/
|
||||
void * lv_draw_eve_display_get_user_data(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Create a touchscreen indev for the EVE display.
|
||||
* @param disp pointer to the lv_draw_eve display
|
||||
* @return the EVE touchscreen indev
|
||||
*/
|
||||
lv_indev_t * lv_draw_eve_touch_create(lv_display_t * disp);
|
||||
|
||||
|
||||
/* Low-level EVE control functions */
|
||||
|
||||
/**
|
||||
* Call `EVE_memRead8` for custom low-level control of the display.
|
||||
* @param disp the display returned by `lv_draw_eve_display_create`
|
||||
* @param address the EVE address to read from
|
||||
* @return the read value
|
||||
*/
|
||||
uint8_t lv_draw_eve_memread8(lv_display_t * disp, uint32_t address);
|
||||
|
||||
/**
|
||||
* Call `EVE_memRead16` for custom low-level control of the display.
|
||||
* @param disp the display returned by `lv_draw_eve_display_create`
|
||||
* @param address the EVE address to read from
|
||||
* @return the read value
|
||||
*/
|
||||
uint16_t lv_draw_eve_memread16(lv_display_t * disp, uint32_t address);
|
||||
|
||||
/**
|
||||
* Call `EVE_memRead32` for custom low-level control of the display.
|
||||
* @param disp the display returned by `lv_draw_eve_display_create`
|
||||
* @param address the EVE address to read from
|
||||
* @return the read value
|
||||
*/
|
||||
uint32_t lv_draw_eve_memread32(lv_display_t * disp, uint32_t address);
|
||||
|
||||
/**
|
||||
* Call `EVE_memWrite8` for custom low-level control of the display.
|
||||
* @param disp the display returned by `lv_draw_eve_display_create`
|
||||
* @param address the EVE address to write to
|
||||
* @param data the value to write
|
||||
*/
|
||||
void lv_draw_eve_memwrite8(lv_display_t * disp, uint32_t address, uint8_t data);
|
||||
|
||||
/**
|
||||
* Call `EVE_memWrite16` for custom low-level control of the display.
|
||||
* @param disp the display returned by `lv_draw_eve_display_create`
|
||||
* @param address the EVE address to write to
|
||||
* @param data the value to write
|
||||
*/
|
||||
void lv_draw_eve_memwrite16(lv_display_t * disp, uint32_t address, uint16_t data);
|
||||
|
||||
/**
|
||||
* Call `EVE_memWrite32` for custom low-level control of the display.
|
||||
* @param disp the display returned by `lv_draw_eve_display_create`
|
||||
* @param address the EVE address to write to
|
||||
* @param data the value to write
|
||||
*/
|
||||
void lv_draw_eve_memwrite32(lv_display_t * disp, uint32_t address, uint32_t data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_EVE_DISPLAY_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,9 @@ extern "C" {
|
||||
#include "display/st_ltdc/lv_st_ltdc.h"
|
||||
#include "display/ft81x/lv_ft81x.h"
|
||||
|
||||
#include "draw/eve/lv_draw_eve_display.h"
|
||||
#include "draw/eve/lv_draw_eve_display_defines.h"
|
||||
|
||||
#include "nuttx/lv_nuttx_entry.h"
|
||||
#include "nuttx/lv_nuttx_fbdev.h"
|
||||
#include "nuttx/lv_nuttx_touchscreen.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
@file EVE_commands.h
|
||||
@brief contains FT8xx / BT8xx function prototypes
|
||||
@version 5.0
|
||||
@date 2023-12-29
|
||||
@author Rudolph Riedel
|
||||
|
||||
@section LICENSE
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2023 Rudolph Riedel
|
||||
|
||||
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.
|
||||
|
||||
@section History
|
||||
|
||||
5.0
|
||||
- added prototype for EVE_cmd_plkfreq()
|
||||
- replaced BT81X_ENABLE with "EVE_GEN > 2"
|
||||
- removed FT81X_ENABLE as FT81x already is the lowest supported chip revision now
|
||||
- removed the formerly as deprected marked EVE_get_touch_tag()
|
||||
- changed EVE_color_rgb() to use a 32 bit value like the rest of the color commands
|
||||
- removed the meta-commands EVE_cmd_point(), EVE_cmd_line() and EVE_cmd_rect()
|
||||
- removed obsolete functions EVE_get_cmdoffset(void) and EVE_report_cmdoffset(void) - cmdoffset is gone
|
||||
- renamed EVE_LIB_GetProps() back to EVE_cmd_getprops() since it does not do anything special to justify a special name
|
||||
- added prototype for helper function EVE_memWrite_sram_buffer()
|
||||
- added prototypes for EVE_cmd_bitmap_transform() and EVE_cmd_bitmap_transform_burst()
|
||||
- added prototype for EVE_cmd_playvideo()
|
||||
- added prototypes for EVE_cmd_setfont_burst() and EVE_cmd_setfont2_burst()
|
||||
- added prototype for EVE_cmd_videoframe()
|
||||
- restructured: functions are sorted by chip-generation and within their group in alphabetical order
|
||||
- reimplementedEVE_cmd_getmatrix() again, it needs to read values, not write them
|
||||
- added prototypes for EVE_cmd_fontcache() and EVE_cmd_fontcachequery()
|
||||
- added prototype for EVE_cmd_flashprogram()
|
||||
- added prototype for EVE_cmd_calibratesub()
|
||||
- added prototypes for EVE_cmd_animframeram(), EVE_cmd_animframeram_burst(), EVE_cmd_animstartram(),
|
||||
EVE_cmd_animstartram_burst()
|
||||
- added prototypes for EVE_cmd_apilevel(), EVE_cmd_apilevel_burst()
|
||||
- added prototypes for EVE_cmd_calllist(), EVE_cmd_calllist_burst()
|
||||
- added prototype for EVE_cmd_getimage()
|
||||
- added prototypes for EVE_cmd_hsf(), EVE_cmd_hsf_burst()
|
||||
- added prototype for EVE_cmd_linetime()
|
||||
- added prototypes for EVE_cmd_newlist(), EVE_cmd_newlist_burst()
|
||||
- added prototypes for EVE_cmd_runanim(), EVE_cmd_runanim_burst()
|
||||
- added prototype for EVE_cmd_wait()
|
||||
- removed the history from before 4.0
|
||||
- added an enum with return codes to have the functions return something more meaningfull
|
||||
- finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release
|
||||
- renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command
|
||||
- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available
|
||||
- removed the 4.0 history
|
||||
- added parameter width to EVE_calibrate_manual()
|
||||
- changed the varargs versions of cmd_button, cmd_text and cmd_toggle to use an array of uint32_t values to comply with MISRA-C
|
||||
- fixed some MISRA-C issues
|
||||
- basic maintenance: checked for violations of white space and indent rules
|
||||
- more linter fixes for minor issues like variables shorter than 3 characters
|
||||
- added EVE_color_a() / EVE_color_a_burst()
|
||||
- removed EVE_cmd_newlist_burst() prototype as the function got removed earlier
|
||||
- added prototype for EVE_write_display_parameters()
|
||||
- added EVE_memRead_sram_buffer()
|
||||
- added EVE_FAULT_RECOVERED to the list of return codes
|
||||
- added defines for the state of the external flash
|
||||
- added protype for EVE_get_and_reset_fault_state()
|
||||
- put E_OK and E_NOT_OK in #ifndef/#endif guards as these are usually defined
|
||||
already in AUTOSAR projects
|
||||
- renamed EVE_FAIL_CHIPID_TIMEOUT to EVE_FAIL_REGID_TIMEOUT as suggested by #93 on github
|
||||
- changed a number of function parameters from signed to unsigned following the
|
||||
updated BT81x series programming guide V2.4
|
||||
- commented out EVE_cmd_regread() prototype
|
||||
- removed prototype for EVE_cmd_hsf_burst()
|
||||
|
||||
*/
|
||||
|
||||
#ifndef EVE_COMMANDS_H
|
||||
#define EVE_COMMANDS_H
|
||||
|
||||
#include "EVE.h"
|
||||
|
||||
#if !defined E_OK
|
||||
#define E_OK 0U
|
||||
#endif
|
||||
|
||||
#if !defined E_NOT_OK
|
||||
#define E_NOT_OK 1U
|
||||
#endif
|
||||
|
||||
#define EVE_FAIL_REGID_TIMEOUT 2U
|
||||
#define EVE_FAIL_RESET_TIMEOUT 3U
|
||||
#define EVE_FAIL_PCLK_FREQ 4U
|
||||
#define EVE_FAIL_FLASH_STATUS_INIT 5U
|
||||
#define EVE_FAIL_FLASH_STATUS_DETACHED 6U
|
||||
#define EVE_FAIL_FLASHFAST_NOT_SUPPORTED 7U
|
||||
#define EVE_FAIL_FLASHFAST_NO_HEADER_DETECTED 8U
|
||||
#define EVE_FAIL_FLASHFAST_SECTOR0_FAILED 9U
|
||||
#define EVE_FAIL_FLASHFAST_BLOB_MISMATCH 10U
|
||||
#define EVE_FAIL_FLASHFAST_SPEED_TEST 11U
|
||||
#define EVE_IS_BUSY 12U
|
||||
#define EVE_FIFO_HALF_EMPTY 13U
|
||||
#define EVE_FAULT_RECOVERED 14U
|
||||
|
||||
#define EVE_FLASH_STATUS_INIT 0U
|
||||
#define EVE_FLASH_STATUS_DETACHED 1U
|
||||
#define EVE_FLASH_STATUS_BASIC 2U
|
||||
#define EVE_FLASH_STATUS_FULL 3U
|
||||
|
||||
/* ##################################################################
|
||||
helper functions
|
||||
##################################################################### */
|
||||
|
||||
void EVE_cmdWrite(uint8_t const command, uint8_t const parameter);
|
||||
|
||||
uint8_t EVE_memRead8(uint32_t const ft_address);
|
||||
uint16_t EVE_memRead16(uint32_t const ft_address);
|
||||
uint32_t EVE_memRead32(uint32_t const ft_address);
|
||||
void EVE_memWrite8(uint32_t const ft_address, uint8_t const ft_data);
|
||||
void EVE_memWrite16(uint32_t const ft_address, uint16_t const ft_data);
|
||||
void EVE_memWrite32(uint32_t const ft_address, uint32_t const ft_data);
|
||||
void EVE_memWrite_flash_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len);
|
||||
void EVE_memWrite_sram_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len);
|
||||
void EVE_memRead_sram_buffer(uint32_t const ft_address, uint8_t *p_data, uint32_t const len);
|
||||
uint8_t EVE_busy(void);
|
||||
uint8_t EVE_get_and_reset_fault_state(void);
|
||||
void EVE_execute_cmd(void);
|
||||
|
||||
/* ##################################################################
|
||||
commands and functions to be used outside of display-lists
|
||||
##################################################################### */
|
||||
|
||||
/* EVE4: BT817 / BT818 */
|
||||
#if EVE_GEN > 3
|
||||
|
||||
void EVE_cmd_flashprogram(uint32_t dest, uint32_t src, uint32_t num);
|
||||
void EVE_cmd_fontcache(uint32_t font, uint32_t ptr, uint32_t num);
|
||||
void EVE_cmd_fontcachequery(uint32_t *p_total, uint32_t *p_used);
|
||||
void EVE_cmd_getimage(uint32_t *p_source, uint32_t *p_fmt, uint32_t *p_width, uint32_t *p_height, uint32_t *p_palette);
|
||||
void EVE_cmd_linetime(uint32_t dest);
|
||||
void EVE_cmd_newlist(uint32_t adr);
|
||||
uint32_t EVE_cmd_pclkfreq(uint32_t ftarget, int32_t rounding);
|
||||
void EVE_cmd_wait(uint32_t usec);
|
||||
|
||||
#endif /* EVE_GEN > 3 */
|
||||
|
||||
/* EVE3: BT815 / BT816 */
|
||||
#if EVE_GEN > 2
|
||||
|
||||
void EVE_cmd_clearcache(void);
|
||||
void EVE_cmd_flashattach(void);
|
||||
void EVE_cmd_flashdetach(void);
|
||||
void EVE_cmd_flasherase(void);
|
||||
uint32_t EVE_cmd_flashfast(void);
|
||||
void EVE_cmd_flashspidesel(void);
|
||||
void EVE_cmd_flashread(uint32_t dest, uint32_t src, uint32_t num);
|
||||
void EVE_cmd_flashsource(uint32_t ptr);
|
||||
void EVE_cmd_flashspirx(uint32_t dest, uint32_t num);
|
||||
void EVE_cmd_flashspitx(uint32_t num, const uint8_t *p_data);
|
||||
void EVE_cmd_flashupdate(uint32_t dest, uint32_t src, uint32_t num);
|
||||
void EVE_cmd_flashwrite(uint32_t ptr, uint32_t num, const uint8_t *p_data);
|
||||
void EVE_cmd_inflate2(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len);
|
||||
|
||||
#endif /* EVE_GEN > 2 */
|
||||
|
||||
void EVE_cmd_getprops(uint32_t *p_pointer, uint32_t *p_width, uint32_t *p_height);
|
||||
uint32_t EVE_cmd_getptr(void);
|
||||
void EVE_cmd_inflate(uint32_t ptr, const uint8_t *p_data, uint32_t len);
|
||||
void EVE_cmd_interrupt(uint32_t msec);
|
||||
void EVE_cmd_loadimage(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len);
|
||||
void EVE_cmd_mediafifo(uint32_t ptr, uint32_t size);
|
||||
void EVE_cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num);
|
||||
uint32_t EVE_cmd_memcrc(uint32_t ptr, uint32_t num);
|
||||
void EVE_cmd_memset(uint32_t ptr, uint8_t value, uint32_t num);
|
||||
void EVE_cmd_memzero(uint32_t ptr, uint32_t num);
|
||||
void EVE_cmd_playvideo(uint32_t options, const uint8_t *p_data, uint32_t len);
|
||||
void EVE_cmd_setrotate(uint32_t rotation);
|
||||
void EVE_cmd_snapshot(uint32_t ptr);
|
||||
void EVE_cmd_snapshot2(uint32_t fmt, uint32_t ptr, int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt);
|
||||
void EVE_cmd_track(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t tag);
|
||||
void EVE_cmd_videoframe(uint32_t dest, uint32_t result_ptr);
|
||||
/*void EVE_cmd_memwrite(uint32_t dest, uint32_t num, const uint8_t *p_data);*/
|
||||
/*uint32_t EVE_cmd_regread(uint32_t ptr);*/
|
||||
|
||||
/* ##################################################################
|
||||
patching and initialization
|
||||
##################################################################### */
|
||||
|
||||
#if EVE_GEN > 2
|
||||
uint8_t EVE_init_flash(void);
|
||||
#endif /* EVE_GEN > 2 */
|
||||
|
||||
void EVE_write_display_parameters(void);
|
||||
uint8_t EVE_init(void);
|
||||
|
||||
/* ##################################################################
|
||||
functions for display lists
|
||||
##################################################################### */
|
||||
|
||||
void EVE_start_cmd_burst(void);
|
||||
void EVE_end_cmd_burst(void);
|
||||
|
||||
/* EVE4: BT817 / BT818 */
|
||||
#if EVE_GEN > 3
|
||||
|
||||
void EVE_cmd_animframeram(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame);
|
||||
void EVE_cmd_animframeram_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame);
|
||||
void EVE_cmd_animstartram(int32_t chnl, uint32_t aoptr, uint32_t loop);
|
||||
void EVE_cmd_animstartram_burst(int32_t chnl, uint32_t aoptr, uint32_t loop);
|
||||
void EVE_cmd_apilevel(uint32_t level);
|
||||
void EVE_cmd_apilevel_burst(uint32_t level);
|
||||
void EVE_cmd_calibratesub(uint16_t xc0, uint16_t yc0, uint16_t width, uint16_t height);
|
||||
void EVE_cmd_calllist(uint32_t adr);
|
||||
void EVE_cmd_calllist_burst(uint32_t adr);
|
||||
void EVE_cmd_hsf(uint32_t hsf);
|
||||
void EVE_cmd_runanim(uint32_t waitmask, uint32_t play);
|
||||
void EVE_cmd_runanim_burst(uint32_t waitmask, uint32_t play);
|
||||
|
||||
#endif /* EVE_GEN > 3 */
|
||||
|
||||
/* EVE3: BT815 / BT816 */
|
||||
#if EVE_GEN > 2
|
||||
|
||||
void EVE_cmd_animdraw(int32_t chnl);
|
||||
void EVE_cmd_animdraw_burst(int32_t chnl);
|
||||
void EVE_cmd_animframe(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame);
|
||||
void EVE_cmd_animframe_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame);
|
||||
void EVE_cmd_animstart(int32_t chnl, uint32_t aoptr, uint32_t loop);
|
||||
void EVE_cmd_animstart_burst(int32_t chnl, uint32_t aoptr, uint32_t loop);
|
||||
void EVE_cmd_animstop(int32_t chnl);
|
||||
void EVE_cmd_animstop_burst(int32_t chnl);
|
||||
void EVE_cmd_animxy(int32_t chnl, int16_t xc0, int16_t yc0);
|
||||
void EVE_cmd_animxy_burst(int32_t chnl, int16_t xc0, int16_t yc0);
|
||||
void EVE_cmd_appendf(uint32_t ptr, uint32_t num);
|
||||
void EVE_cmd_appendf_burst(uint32_t ptr, uint32_t num);
|
||||
uint16_t EVE_cmd_bitmap_transform(int32_t xc0, int32_t yc0, int32_t xc1, int32_t yc1, int32_t xc2, int32_t yc2, int32_t tx0,
|
||||
int32_t ty0, int32_t tx1, int32_t ty1, int32_t tx2, int32_t ty2);
|
||||
void EVE_cmd_bitmap_transform_burst(int32_t xc0, int32_t yc0, int32_t xc1, int32_t yc1, int32_t xc2, int32_t yc2, int32_t tx0,
|
||||
int32_t ty0, int32_t tx1, int32_t ty1, int32_t tx2, int32_t ty2);
|
||||
void EVE_cmd_fillwidth(uint32_t pixel);
|
||||
void EVE_cmd_fillwidth_burst(uint32_t pixel);
|
||||
void EVE_cmd_gradienta(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1);
|
||||
void EVE_cmd_gradienta_burst(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1);
|
||||
void EVE_cmd_rotatearound(int32_t xc0, int32_t yc0, uint32_t angle, int32_t scale);
|
||||
void EVE_cmd_rotatearound_burst(int32_t xc0, int32_t yc0, uint32_t angle, int32_t scale);
|
||||
|
||||
void EVE_cmd_button_var(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]);
|
||||
void EVE_cmd_button_var_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]);
|
||||
void EVE_cmd_text_var(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]);
|
||||
void EVE_cmd_text_var_burst(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]);
|
||||
void EVE_cmd_toggle_var(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]);
|
||||
void EVE_cmd_toggle_var_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]);
|
||||
|
||||
#endif /* EVE_GEN > 2 */
|
||||
|
||||
void EVE_cmd_dl(uint32_t command);
|
||||
void EVE_cmd_dl_burst(uint32_t command);
|
||||
|
||||
void EVE_cmd_append(uint32_t ptr, uint32_t num);
|
||||
void EVE_cmd_append_burst(uint32_t ptr, uint32_t num);
|
||||
void EVE_cmd_bgcolor(uint32_t color);
|
||||
void EVE_cmd_bgcolor_burst(uint32_t color);
|
||||
void EVE_cmd_button(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text);
|
||||
void EVE_cmd_button_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text);
|
||||
void EVE_cmd_calibrate(void);
|
||||
void EVE_cmd_clock(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t hours, uint16_t mins, uint16_t secs, uint16_t msecs);
|
||||
void EVE_cmd_clock_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t hours, uint16_t mins, uint16_t secs, uint16_t msecs);
|
||||
void EVE_cmd_dial(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t val);
|
||||
void EVE_cmd_dial_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t val);
|
||||
void EVE_cmd_fgcolor(uint32_t color);
|
||||
void EVE_cmd_fgcolor_burst(uint32_t color);
|
||||
void EVE_cmd_gauge(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range);
|
||||
void EVE_cmd_gauge_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range);
|
||||
void EVE_cmd_getmatrix(int32_t *p_a, int32_t *p_b, int32_t *p_c, int32_t *p_d, int32_t *p_e, int32_t *p_f);
|
||||
void EVE_cmd_gradcolor(uint32_t color);
|
||||
void EVE_cmd_gradcolor_burst(uint32_t color);
|
||||
void EVE_cmd_gradient(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, int16_t yc1, uint32_t rgb1);
|
||||
void EVE_cmd_gradient_burst(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, int16_t yc1, uint32_t rgb1);
|
||||
void EVE_cmd_keys(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text);
|
||||
void EVE_cmd_keys_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text);
|
||||
void EVE_cmd_number(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, int32_t number);
|
||||
void EVE_cmd_number_burst(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, int32_t number);
|
||||
void EVE_cmd_progress(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range);
|
||||
void EVE_cmd_progress_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range);
|
||||
void EVE_cmd_romfont(uint32_t font, uint32_t romslot);
|
||||
void EVE_cmd_romfont_burst(uint32_t font, uint32_t romslot);
|
||||
void EVE_cmd_rotate(uint32_t angle);
|
||||
void EVE_cmd_rotate_burst(uint32_t angle);
|
||||
void EVE_cmd_scale(int32_t scx, int32_t scy);
|
||||
void EVE_cmd_scale_burst(int32_t scx, int32_t scy);
|
||||
void EVE_cmd_scrollbar(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t size, uint16_t range);
|
||||
void EVE_cmd_scrollbar_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t size, uint16_t range);
|
||||
void EVE_cmd_setbase(uint32_t base);
|
||||
void EVE_cmd_setbase_burst(uint32_t base);
|
||||
void EVE_cmd_setbitmap(uint32_t addr, uint16_t fmt, uint16_t width, uint16_t height);
|
||||
void EVE_cmd_setbitmap_burst(uint32_t addr, uint16_t fmt, uint16_t width, uint16_t height);
|
||||
void EVE_cmd_setfont(uint32_t font, uint32_t ptr);
|
||||
void EVE_cmd_setfont_burst(uint32_t font, uint32_t ptr);
|
||||
void EVE_cmd_setfont2(uint32_t font, uint32_t ptr, uint32_t firstchar);
|
||||
void EVE_cmd_setfont2_burst(uint32_t font, uint32_t ptr, uint32_t firstchar);
|
||||
void EVE_cmd_setscratch(uint32_t handle);
|
||||
void EVE_cmd_setscratch_burst(uint32_t handle);
|
||||
void EVE_cmd_sketch(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint32_t ptr, uint16_t format);
|
||||
void EVE_cmd_sketch_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint32_t ptr, uint16_t format);
|
||||
void EVE_cmd_slider(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range);
|
||||
void EVE_cmd_slider_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range);
|
||||
void EVE_cmd_spinner(int16_t xc0, int16_t yc0, uint16_t style, uint16_t scale);
|
||||
void EVE_cmd_spinner_burst(int16_t xc0, int16_t yc0, uint16_t style, uint16_t scale);
|
||||
void EVE_cmd_text(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text);
|
||||
void EVE_cmd_text_burst(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text);
|
||||
void EVE_cmd_toggle(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text);
|
||||
void EVE_cmd_toggle_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text);
|
||||
void EVE_cmd_translate(int32_t tr_x, int32_t tr_y);
|
||||
void EVE_cmd_translate_burst(int32_t tr_x, int32_t tr_y);
|
||||
|
||||
void EVE_color_rgb(uint32_t color);
|
||||
void EVE_color_rgb_burst(uint32_t color);
|
||||
void EVE_color_a(uint8_t alpha);
|
||||
void EVE_color_a_burst(uint8_t alpha);
|
||||
|
||||
/* ##################################################################
|
||||
special purpose functions
|
||||
##################################################################### */
|
||||
|
||||
void EVE_calibrate_manual(uint16_t width, uint16_t height);
|
||||
|
||||
#endif /* EVE_COMMANDS_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef EVE_CONFIG_H
|
||||
#define EVE_CONFIG_H
|
||||
|
||||
#include "../../draw/eve/lv_draw_eve_private.h"
|
||||
|
||||
#define EVE_HSIZE (lv_draw_eve_unit_g->params.hor_res)
|
||||
#define EVE_VSIZE (lv_draw_eve_unit_g->params.ver_res)
|
||||
#define EVE_VSYNC0 (lv_draw_eve_unit_g->params.vsync0)
|
||||
#define EVE_VSYNC1 (lv_draw_eve_unit_g->params.vsync1)
|
||||
#define EVE_VOFFSET (lv_draw_eve_unit_g->params.voffset)
|
||||
#define EVE_VCYCLE (lv_draw_eve_unit_g->params.vcycle)
|
||||
#define EVE_HSYNC0 (lv_draw_eve_unit_g->params.hsync0)
|
||||
#define EVE_HSYNC1 (lv_draw_eve_unit_g->params.hsync1)
|
||||
#define EVE_HOFFSET (lv_draw_eve_unit_g->params.hoffset)
|
||||
#define EVE_HCYCLE (lv_draw_eve_unit_g->params.hcycle)
|
||||
#define EVE_PCLK (lv_draw_eve_unit_g->params.pclk)
|
||||
#define EVE_PCLKPOL (lv_draw_eve_unit_g->params.pclkpol)
|
||||
#define EVE_SWIZZLE (lv_draw_eve_unit_g->params.swizzle)
|
||||
#define EVE_CSPREAD (lv_draw_eve_unit_g->params.cspread)
|
||||
#define EVE_HAS_CRYSTAL (lv_draw_eve_unit_g->params.has_crystal)
|
||||
#define EVE_HAS_GT911 (lv_draw_eve_unit_g->params.has_gt911)
|
||||
#define EVE_GEN LV_DRAW_EVE_EVE_GENERATION
|
||||
#define EVE_BACKLIGHT_PWM (lv_draw_eve_unit_g->params.backlight_pwm)
|
||||
#define EVE_BACKLIGHT_FREQ (lv_draw_eve_unit_g->params.backlight_freq)
|
||||
|
||||
#endif /* EVE_CONFIG_H */
|
||||
@@ -0,0 +1,145 @@
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_DRAW_EVE
|
||||
/*
|
||||
@file EVE_supplemental.h
|
||||
@brief supplemental functions
|
||||
@version 5.0
|
||||
@date 2023-12-23
|
||||
@author Rudolph Riedel
|
||||
|
||||
@section LICENSE
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2023 Rudolph Riedel
|
||||
|
||||
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.
|
||||
|
||||
@section History
|
||||
|
||||
5.0
|
||||
- added EVE_polar_cartesian()
|
||||
|
||||
*/
|
||||
|
||||
#include "EVE_suppplemental.h"
|
||||
|
||||
/* define NULL if it not already is */
|
||||
#ifndef NULL
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined (__AVR__)
|
||||
#include <avr/pgmspace.h>
|
||||
#else
|
||||
#define PROGMEM
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @brief widget function to draw a circle
|
||||
*/
|
||||
void EVE_widget_circle(int16_t xc0, int16_t yc0, uint16_t radius, uint16_t border, uint32_t bgcolor)
|
||||
{
|
||||
EVE_cmd_dl_burst(DL_SAVE_CONTEXT);
|
||||
EVE_cmd_dl(DL_BEGIN | EVE_POINTS);
|
||||
EVE_cmd_dl(POINT_SIZE(radius));
|
||||
EVE_cmd_dl(VERTEX2F(xc0, yc0));
|
||||
EVE_color_rgb(bgcolor);
|
||||
EVE_cmd_dl(POINT_SIZE(radius - border));
|
||||
EVE_cmd_dl(VERTEX2F(xc0, yc0));
|
||||
EVE_cmd_dl(DL_END);
|
||||
EVE_cmd_dl_burst(DL_RESTORE_CONTEXT);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief widget function to draw a rectangle
|
||||
*/
|
||||
void EVE_widget_rectangle(int16_t xc0, int16_t yc0, int16_t wid, int16_t hgt, int16_t border, uint16_t linewidth, uint32_t bgcolor)
|
||||
{
|
||||
EVE_cmd_dl_burst(DL_SAVE_CONTEXT);
|
||||
EVE_cmd_dl(DL_BEGIN | EVE_RECTS);
|
||||
EVE_cmd_dl(LINE_WIDTH(linewidth));
|
||||
EVE_cmd_dl(VERTEX2F(xc0, yc0));
|
||||
EVE_cmd_dl(VERTEX2F(xc0 + wid, yc0 + hgt));
|
||||
EVE_color_rgb(bgcolor);
|
||||
EVE_cmd_dl(VERTEX2F(xc0 + border, yc0 + border));
|
||||
EVE_cmd_dl(VERTEX2F(xc0 + wid - border, yc0 + hgt - border));
|
||||
EVE_cmd_dl(DL_END);
|
||||
EVE_cmd_dl_burst(DL_RESTORE_CONTEXT);
|
||||
}
|
||||
|
||||
static const int8_t sine_table[360] PROGMEM =
|
||||
{
|
||||
0, 2, 4, 7, 9, 11, 13, 15, 18, 20, 22, 24, 26, 29, 31, 33, 35, 37, 39, 41,
|
||||
43, 46, 48, 50, 52, 54, 56, 58, 60, 62, 63, 65, 67, 69, 71, 73, 75, 76, 78,
|
||||
80, 82, 83, 85, 87, 88, 90, 91, 93, 94, 96, 97, 99, 100, 101, 103, 104, 105,
|
||||
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 119, 120,
|
||||
121, 121, 122, 123, 123, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 125, 125, 125,
|
||||
124, 124, 123, 123, 122, 121, 121, 120, 119, 119, 118, 117, 116, 115, 114,
|
||||
113, 112, 111, 110, 109, 108, 107, 105, 104, 103, 101, 100, 99, 97, 96, 94,
|
||||
93, 91, 90, 88, 87, 85, 83, 82, 80, 78, 76, 75, 73, 71, 69, 67, 65, 63, 62,
|
||||
60, 58, 56, 54, 52, 50, 48, 46, 43, 41, 39, 37, 35, 33, 31, 29, 26, 24, 22,
|
||||
20, 18, 15, 13, 11, 9, 7, 4, 2, 0, -2, -4, -7, -9, -11, -13, -15, -18, -20,
|
||||
-22, -24, -26, -29, -31, -33, -35, -37, -39, -41, -43, -46, -48, -50, -52,
|
||||
-54, -56, -58, -60, -62, -63, -65, -67, -69, -71, -73, -75, -76, -78, -80,
|
||||
-82, -83, -85, -87, -88, -90, -91, -93, -94, -96, -97, -99,-100,-101,-103,
|
||||
-104, -105, -107, -108, -109, -110, -111, -112, -113, -114, -115, -116,
|
||||
-117, -118, -119, -119, -120, -121, -121, -122, -123, -123, -124, -124,
|
||||
-125, -125, -125, -126, -126, -126, -127, -127, -127, -127, -127, -127,
|
||||
-127, -127, -127, -127, -127, -126, -126, -126, -125, -125, -125, -124,
|
||||
-124, -123, -123, -122, -121, -121, -120, -119, -119, -118, -117, -116,
|
||||
-115, -114, -113, -112, -111, -110, -109, -108, -107, -105, -104, -103,
|
||||
-101, -100, -99, -97, -96, -94, -93, -91, -90, -88, -87, -85, -83, -82,
|
||||
-80, -78, -76, -75, -73, -71, -69, -67, -65, -63, -62, -60, -58, -56, -54,
|
||||
-52, -50, -48, -46, -43, -41, -39, -37, -35, -33, -31, -29, -26, -24,
|
||||
-22, -20, -18, -15, -13, -11, -9, -7, -4, -2
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Calculate coordinates from an angle and a length.
|
||||
* @param length distance from coordinate origin (0,0)
|
||||
* @param angle rotation in degrees
|
||||
* @return signed X/Y coordinates for use with VERTEX2F
|
||||
* @note - resolution for angle is 1° and rotation is clockwise
|
||||
* @note - angle should be limited to a (n*360)-1
|
||||
*/
|
||||
void EVE_polar_cartesian(uint16_t length, uint16_t angle, int16_t *p_xc0, int16_t *p_yc0)
|
||||
{
|
||||
uint16_t anglev;
|
||||
anglev = angle % 360U;
|
||||
|
||||
if (p_xc0 != NULL)
|
||||
{
|
||||
int32_t calc = (int16_t) length;
|
||||
calc = ((calc * (sine_table[anglev])) + 64) / 128;
|
||||
*p_xc0 = (int16_t) calc;
|
||||
}
|
||||
|
||||
if (p_yc0 != NULL)
|
||||
{
|
||||
anglev = anglev + 270U;
|
||||
anglev = anglev % 360U;
|
||||
|
||||
int32_t calc = (int16_t) length;
|
||||
calc = ((calc * (sine_table[anglev])) + 64) / 128;
|
||||
*p_yc0 = (int16_t) calc;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_EVE*/
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
@file EVE_supplemental.h
|
||||
@brief prototypes for supplemental functions
|
||||
@version 5.0
|
||||
@date 2023-12-23
|
||||
@author Rudolph Riedel
|
||||
|
||||
@section LICENSE
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2023 Rudolph Riedel
|
||||
|
||||
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.
|
||||
|
||||
@section History
|
||||
|
||||
5.0
|
||||
- added EVE_polar_cartesian()
|
||||
|
||||
*/
|
||||
|
||||
#ifndef EVE_SUPPLEMENTAL_H
|
||||
#define EVE_SUPPLEMENTAL_H
|
||||
|
||||
#include "EVE.h"
|
||||
#include "EVE_commands.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void EVE_widget_circle(int16_t xc0, int16_t yc0, uint16_t radius, uint16_t border, uint32_t bgcolor);
|
||||
void EVE_widget_rectangle(int16_t xc0, int16_t yc0, int16_t wid, int16_t hgt, int16_t border, uint16_t linewidth, uint32_t bgcolor);
|
||||
void EVE_polar_cartesian(uint16_t length, uint16_t angle, int16_t *p_xc0, int16_t *p_yc0);
|
||||
|
||||
#endif /* EVE_SUPPLEMENTAL_H */
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef EVE_TARGET_H
|
||||
#define EVE_TARGET_H
|
||||
|
||||
#include "../../draw/eve/lv_draw_eve_private.h"
|
||||
#include "../../tick/lv_tick.h"
|
||||
#include "../../misc/lv_utils.h"
|
||||
|
||||
static inline void DELAY_MS(uint16_t ms)
|
||||
{
|
||||
lv_delay_ms(ms);
|
||||
}
|
||||
|
||||
static inline void EVE_cs_set(void)
|
||||
{
|
||||
lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_CS_ASSERT, NULL, 0);
|
||||
}
|
||||
|
||||
static inline void EVE_cs_clear(void)
|
||||
{
|
||||
lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_CS_DEASSERT, NULL, 0);
|
||||
}
|
||||
|
||||
static inline void EVE_pdn_set(void)
|
||||
{
|
||||
lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_POWERDOWN_SET, NULL, 0);
|
||||
}
|
||||
|
||||
static inline void EVE_pdn_clear(void)
|
||||
{
|
||||
lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_POWERDOWN_CLEAR, NULL, 0);
|
||||
}
|
||||
|
||||
static inline void spi_transmit(uint8_t data)
|
||||
{
|
||||
lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_SEND, &data, 1);
|
||||
}
|
||||
|
||||
static inline void spi_transmit_32(uint32_t data)
|
||||
{
|
||||
#if LV_BIG_ENDIAN_SYSTEM
|
||||
data = lv_swap_bytes_32(data);
|
||||
#endif
|
||||
lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_SEND, &data, 4);
|
||||
}
|
||||
|
||||
static inline void spi_transmit_burst(uint32_t data)
|
||||
{
|
||||
spi_transmit_32(data);
|
||||
}
|
||||
|
||||
static inline uint8_t spi_receive(uint8_t data)
|
||||
{
|
||||
/* `data` is 0 everywhere `spi_receive` is called in the FT800-FT813 library */
|
||||
LV_UNUSED(data);
|
||||
|
||||
uint8_t byte;
|
||||
lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_RECEIVE, &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
static inline uint8_t fetch_flash_byte(const uint8_t *p_data)
|
||||
{
|
||||
return (*p_data);
|
||||
}
|
||||
|
||||
#endif /* EVE_TARGET_H_ */
|
||||
@@ -0,0 +1,20 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2024 Rudolph Riedel
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,245 @@
|
||||
# EVE2 / EVE3 / EVE4 code library
|
||||
This is a code library for EVE2/EVE3/EVE4 graphics controller ICs from FTDI/Bridgetek:
|
||||
|
||||
http://www.ftdichip.com/EVE.htm
|
||||
http://brtchip.com/eve/
|
||||
http://brtchip.com/ft81x/
|
||||
https://brtchip.com/bt81x/
|
||||
|
||||
It contains code for and has been used with various micro-controllers and displays.
|
||||
|
||||
## Controllers
|
||||
|
||||
I have used it so far with:
|
||||
|
||||
- 8-Bit AVR, specifically the 90CAN series
|
||||
- Arduino: Uno R3, mini-pro, ESP8266, ESP32, Metro-M4 (DMA), STM32 Nucleo_F446RE (DMA), XMC1100, Uno R4
|
||||
- Renesas F1L RH850
|
||||
- Infineon Aurix TC222
|
||||
- GD32VF103
|
||||
- ATSAMC21J18A (DMA)
|
||||
- ATSAME51J19A (DMA)
|
||||
- ESP32 (DMA)
|
||||
- RP2040 Baremetal (DMA) + Arduino (DMA) - Raspberry Pi Pico
|
||||
- S32K144 (DMA)
|
||||
- GD32C103CBT6 (DMA)
|
||||
- STM32G0B1CET6
|
||||
|
||||
I have reports of successfully using it with:
|
||||
|
||||
- ATSAMV70
|
||||
- ATSAMD20
|
||||
- ATSAME4
|
||||
- MSP430
|
||||
- MSP432
|
||||
- some PICs
|
||||
- ATxmega128A1
|
||||
- TMS320F28335
|
||||
|
||||
## Displays
|
||||
|
||||
The TFTs tested so far:
|
||||
|
||||
- FT810CB-HY50HD http://www.hotmcu.com/5-graphical-lcd-touchscreen-800x480-spi-ft810-p-286.html
|
||||
- FT811CB-HY50HD http://www.hotmcu.com/5-graphical-lcd-capacitive-touch-screen-800x480-spi-ft811-p-301.html
|
||||
- RVT70UQFNWC0x https://riverdi.com/product/rvt70uqfnwc0x/
|
||||
- RVT50
|
||||
- ADAM101-LCP-SWVGA-NEW from Glyn, 10.1" 1024x600 cap-touch
|
||||
- EVE2-38A https://www.matrixorbital.com/eve2-38a
|
||||
- EVE2-35G https://www.matrixorbital.com/eve2-35g
|
||||
- EVE2-43G https://www.matrixorbital.com/eve2-43g
|
||||
- EVE2-50G https://www.matrixorbital.com/eve2-50g
|
||||
- EVE2-70G https://www.matrixorbital.com/eve2-70g
|
||||
- NHD-3.5-320240FT-CSXV-CTP
|
||||
- RVT43ULBNWC00 (RiTFT-43-CAP-UX) https://riverdi.com/product/ritft43capux/
|
||||
- RVT50AQBNWC00 (RiTFT-50-CAP) https://riverdi.com/product/ritft50cap/
|
||||
- EVE3-50G https://www.matrixorbital.com/eve3-50g
|
||||
- PAF90B5WFNWC01 http://www.panadisplay.com/ftdi-intelligent-display/9-inch-lcd-with-touch-with-bt815-board.html
|
||||
- EVE3-43G https://www.matrixorbital.com/eve3-43g
|
||||
- EVE3-35G https://www.matrixorbital.com/eve3-35g
|
||||
- CFAF240400C0-030SC https://www.crystalfontz.com/product/cfaf240400c0030sca11-240x400-eve-touchscreen-tft-ft813
|
||||
- CFAF320240F-035T https://www.crystalfontz.com/product/cfaf320240f035ttsa11-320x240-eve-tft-lcd-display-kit
|
||||
- CFAF480128A0-039TC
|
||||
- CFAF800480E0-050SC https://www.crystalfontz.com/product/cfaf800480e1050sca11-800x480-eve-accelerated-tft
|
||||
- GEN4-FT813-50CTP-CLB https://4dsystems.com.au/gen4-ft813-50ctp-clb
|
||||
- RVT101HVBNWC00-B https://riverdi.com/product/rvt101hvbnwc00-b/
|
||||
- RVT70HSBNWC00-B https://riverdi.com/product/rvt70hsbnwc00-b/
|
||||
- RVT50HQBNWC00-B https://riverdi.com/product/rvt50hqbnwc00-b/
|
||||
- CFAF1024600B0-070SC-A1 https://www.crystalfontz.com/product/cfaf1024600b0070sca1-1024x600-7-inch-eve-tft
|
||||
- Sunflower shield from Cowfish Studios
|
||||
- GD3X Gameduino shield
|
||||
|
||||
## This is version 5
|
||||
|
||||
This is version 5 of this code library and there are a couple of changes from V4.
|
||||
|
||||
First of all, support for FT80x is gone. The main reason is that this allowed a nice speed improvement modification that only works with FT81x and beyond.
|
||||
Then there is a hard break from FT80x to FT81x with ony 256k of memory in FT80x but 1MB in FT81x. The memory map is different and all the registers are located elsewhere.
|
||||
FT810, FT811, FT812, FT813, BT815, BT816, BT817 and BT818 can use the exact same code as long none of the new features of BT81x are used - and there are plenty of modules with these available to choose from
|
||||
|
||||
As a side effect all commands are automatically started now.
|
||||
|
||||
Second is that there are two sets of display-list building command functions now: EVE_cmd_xxx() and EVE_cmd_xxx_burst().
|
||||
The EVE_cmd_xxx_burst() functions are optimized for speed, these are pure data transfer functions and do not even check anymore if burst mode is active.
|
||||
|
||||
## Structure
|
||||
|
||||
This library currently has nine files that I hope are named to make clear what these do:
|
||||
|
||||
- EVE.h - this has all defines for FT81x / BT81x itself, so here are options, registers, commands and macros defined
|
||||
- EVE_commands.c - this has all the API functions that are to be called from an application
|
||||
- EVE_commands.h - this contains the prototypes for the functions in EVE_commands.c
|
||||
- EVE_config.h - this has all the parameters for the numerous supported display modules, here is definded which set of parameters is to be used
|
||||
- EVE_target.c - this has non-portable specific code for a number of supported controllers, mostly to support DMA
|
||||
- EVE_target.h - this has non-portable pin defines and code as "static inline" functions for all supported controllers
|
||||
- EVE_target.cpp - this is for Arduino C++ targets
|
||||
- EVE_cpp_wrapper.cpp - this is for Arduino C++ targets
|
||||
- EVE_cpp_wrapper.h - this is for Arduino C++ targets
|
||||
|
||||
Addtionally there are these two:
|
||||
- EVE_supplemental.c
|
||||
- EVE_suppplemental.h
|
||||
|
||||
This has the prototype and implementation for extra functions, so far:
|
||||
- EVE_widget_circle() - widget function to draw a circle
|
||||
- EVE_widget_rectangle() - widget function to draw a rectangle
|
||||
- EVE_polar_cartesian() - calculate coordinates from an angle and a length
|
||||
|
||||
## Examples
|
||||
|
||||
Generate a basic display list and tell EVE to use it:
|
||||
````
|
||||
EVE_cmd_dl(CMD_DLSTART); // tells EVE to start a new display-list
|
||||
EVE_cmd_dl(DL_CLEAR_COLOR_RGB | WHITE); // sets the background color
|
||||
EVE_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
|
||||
EVE_color_rgb(BLACK);
|
||||
EVE_cmd_text(5, 15, 28, 0, "Hello there!");
|
||||
EVE_cmd_dl(DL_DISPLAY); // put in the display list to mark its end
|
||||
EVE_cmd_dl(CMD_SWAP); // tell EVE to use the new display list
|
||||
while (EVE_busy());
|
||||
````
|
||||
|
||||
Note, these commands are executed one by one, for each command chip-select is pulled low, a three byte address is send, the data for the command and its parameters is send and then chip-select is pulled high again which also makes EVE execute the command.
|
||||
|
||||
But there is a way to speed things up, we can get away with only sending the address once:
|
||||
````
|
||||
EVE_start_cmd_burst();
|
||||
EVE_cmd_dl_burst(CMD_DLSTART);
|
||||
EVE_cmd_dl_burst(DL_CLEAR_COLOR_RGB | WHITE);
|
||||
EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
|
||||
EVE_color_rgb_burst(BLACK);
|
||||
EVE_cmd_text_burst(5, 15, 28, 0, "Hello there!");
|
||||
EVE_cmd_dl_burst(DL_DISPLAY);
|
||||
EVE_cmd_dl_burst(CMD_SWAP);
|
||||
EVE_end_cmd_burst();
|
||||
while (EVE_busy());
|
||||
````
|
||||
|
||||
This does the same as the first example but faster.
|
||||
The preceding EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address.
|
||||
Or if DMA is available for the target you are compiling for with support code in EVE_target.c / EVE_target.cpp and EVE_target.h, it writes the address to EVE_dma_buffer and sets EVE_dma_buffer_index to 1.
|
||||
|
||||
Note the trailing "_burst" in the following functions, these are special versions of these commands that can only be used within an EVE_start_cmd_burst()/EVE_end_cmd_bust() pair.
|
||||
These functions are optimized to push out data and nothing else.
|
||||
|
||||
The final EVE_end_cmd_burst() either pulls back the chip-select to high.
|
||||
Or if we have DMA it calls EVE_start_dma_transfer() to start pushing out the buffer in the background.
|
||||
|
||||
As we have 7 commands for EVE in these simple examples, the second one has the address overhead removed from six commands and therefore needs to transfer 18 bytes less over SPI.
|
||||
So even with a small 8-bit controller that does not support DMA this is a usefull optimization for building display lists.
|
||||
|
||||
Using DMA has one caveat: we need to limit the transfer to <4k as we are writing to the FIFO of EVEs command co-processor. This is usually not an issue though as we can shorten the display list generation with previously generated snippets that we attach to the current list with CMD_APPEND. And when we use widgets like CMD_BUTTON or CMD_CLOCK the generated display list grows by a larger amount than what we need to put into the command-FIFO so we likely reach the 8k limit of the display-list before we hit the 4k limit of the command-FIFO.
|
||||
It is possible to use two or more DMA transfers to the FIFO to build a single display list, either to get around the 4k limit of the FIFO or in order to distribute the workload better of the time necessary between two display renewals.
|
||||
|
||||
You could for example do this, spread over three consecutive calls:
|
||||
````
|
||||
EVE_start_cmd_burst();
|
||||
EVE_cmd_dl_burst(CMD_DLSTART);
|
||||
EVE_cmd_dl_burst(DL_CLEAR_COLOR_RGB | WHITE);
|
||||
EVE_end_cmd_burst();
|
||||
````
|
||||
|
||||
````
|
||||
EVE_start_cmd_burst();
|
||||
EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
|
||||
EVE_color_rgb_burst(BLACK);
|
||||
EVE_end_cmd_burst();
|
||||
````
|
||||
|
||||
````
|
||||
EVE_start_cmd_burst();
|
||||
EVE_cmd_text_burst(5, 15, 28, 0, "Hello there!");
|
||||
EVE_cmd_dl_burst(DL_DISPLAY);
|
||||
EVE_cmd_dl_burst(CMD_SWAP);
|
||||
EVE_end_cmd_burst();
|
||||
````
|
||||
|
||||
But you need to check with EVE_busy() before each of these blocks.
|
||||
Maybe similar like this never compiled pseudo-code:
|
||||
|
||||
thread_1ms_update_display()
|
||||
{
|
||||
static uint8_t state = 0;
|
||||
static uint8_t count = 0;
|
||||
|
||||
count++;
|
||||
|
||||
if (E_OK == EVE_busy())
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
update_first();
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
update_second();
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (counter > 19)
|
||||
{
|
||||
update_last_swap_list();
|
||||
count = 0;
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
## Remarks
|
||||
|
||||
The examples in the "example_projects" drawer are for use with AtmelStudio7.
|
||||
For Arduino I am using PlatformIO with Visual Studio Code.
|
||||
|
||||
The platform the code is compiled for is automatically detected thru compiler flags in EVE_target.h.
|
||||
|
||||
The desired TFT is selected by adding a define for it to the build-environment, e.g. -DEVE_EVE3_50G
|
||||
There is a list of available options at the start of EVE_config.h sorted by chipset.
|
||||
|
||||
The pins used for Chip-Select and Power-Down setup in the EVE_target/EVE_target_XXXXX.h file for your target with defines and these defines can be bypassed with defines in the build-environment.
|
||||
Check the apropriate header file for your desired target.
|
||||
|
||||
When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialize the TFT work with the intended timing.
|
||||
For other plattforms you need to provide a DELAY_MS(ms) function that works at least between 1ms and 56ms and is not performing these delays shorter than requested.
|
||||
The DELAY_MS(ms) is only used during initialization of the FT8xx/BT8xx.
|
||||
|
||||
In Addition you need to initialize the pins used for Chip-Select and Power-Down in your hardware correctly to output.
|
||||
Plus setup the SPI accordingly, mode-0, 8-bit, MSB-first, not more than 11MHz for the initialization.
|
||||
A couple of targets already have a function EVE_init_spi() in EVE_target.c.
|
||||
|
||||
A word of "warning", you have to take care yourself to not send more than 4kiB at once to the command co-processor
|
||||
or to not generate display lists that are longer than 8kiB.
|
||||
My library does not check and re-check the command-FIFO on every step.
|
||||
Also there are no checks for the validity of function arguments.
|
||||
This is optimized for speed, so the training wheels are off.
|
||||
|
||||
## Post questions here
|
||||
|
||||
Originally the project went public in the German mikrocontroller.net forum, the thread contains some insight: https://www.mikrocontroller.net/topic/395608
|
||||
|
||||
Feel free to add to the discussion with questions or remarks.
|
||||
|
||||
New: Github has a discussions feature as well: https://github.com/RudolphRiedel/FT800-FT813/discussions
|
||||
@@ -48,6 +48,8 @@ extern "C" {
|
||||
#define LV_SCR_LOAD_ANIM_OUT_TOP LV_SCREEN_LOAD_ANIM_OUT_TOP
|
||||
#define LV_SCR_LOAD_ANIM_OUT_BOTTOM LV_SCREEN_LOAD_ANIM_OUT_BOTTOM
|
||||
|
||||
#define lv_ft81x_spi_operation lv_ft81x_spi_operation_t
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
@@ -1017,6 +1017,27 @@
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use EVE FT81X GPU. */
|
||||
#ifndef LV_USE_DRAW_EVE
|
||||
#ifdef CONFIG_LV_USE_DRAW_EVE
|
||||
#define LV_USE_DRAW_EVE CONFIG_LV_USE_DRAW_EVE
|
||||
#else
|
||||
#define LV_USE_DRAW_EVE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LV_USE_DRAW_EVE
|
||||
/* EVE_GEN value: 2, 3, or 4 */
|
||||
#ifndef LV_DRAW_EVE_EVE_GENERATION
|
||||
#ifdef CONFIG_LV_DRAW_EVE_EVE_GENERATION
|
||||
#define LV_DRAW_EVE_EVE_GENERATION CONFIG_LV_DRAW_EVE_EVE_GENERATION
|
||||
#else
|
||||
#define LV_DRAW_EVE_EVE_GENERATION 4
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*=======================
|
||||
* FEATURE CONFIGURATION
|
||||
*=======================*/
|
||||
|
||||
@@ -149,7 +149,7 @@ extern "C" {
|
||||
|
||||
#ifdef CONFIG_LV_MEM_MONITOR_ALIGN_TOP_LEFT
|
||||
# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_LEFT
|
||||
#elif defined(CONFIG_LV_USE_MEM_MONITOR_ALIGN_TOP_MID)
|
||||
#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_TOP_MID)
|
||||
# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_MID
|
||||
#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_TOP_RIGHT)
|
||||
# define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_RIGHT
|
||||
|
||||
@@ -87,6 +87,9 @@
|
||||
#if LV_USE_EVDEV
|
||||
#include "drivers/evdev/lv_evdev_private.h"
|
||||
#endif
|
||||
#if LV_USE_DRAW_EVE
|
||||
#include "draw/eve/lv_draw_eve.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -276,6 +279,10 @@ void lv_init(void)
|
||||
lv_uefi_platform_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_DRAW_EVE
|
||||
lv_draw_eve_init();
|
||||
#endif
|
||||
|
||||
lv_obj_style_init();
|
||||
|
||||
/*Initialize the screen refresh system*/
|
||||
|
||||
@@ -386,6 +386,10 @@ typedef struct _lv_translation_tag_dsc_t lv_translation_tag_dsc_t;
|
||||
typedef struct _lv_translation_pack_t lv_translation_pack_t;
|
||||
#endif
|
||||
|
||||
#if LV_USE_DRAW_EVE
|
||||
typedef struct _lv_draw_eve_unit_t lv_draw_eve_unit_t;
|
||||
#endif
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
|
||||
/**********************
|
||||
|
||||
Reference in New Issue
Block a user