From b6061140b872fbe14380e469a2bd83c619bbe474 Mon Sep 17 00:00:00 2001 From: Liam Howatt <30486941+liamHowatt@users.noreply.github.com> Date: Thu, 7 Aug 2025 05:09:44 -0400 Subject: [PATCH] feat(EVE): Add EVE draw unit (#8211) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: André Costa --- COPYRIGHTS.md | 3 + Kconfig | 10 + .../integration/driver/display/ft81x.rst | 2 + .../src/details/integration/renderers/eve.rst | 186 + .../details/integration/renderers/index.rst | 1 + lv_conf_template.h | 9 + lvgl.h | 1 + scripts/code-format.cfg | 1 + src/core/lv_global.h | 4 + src/draw/eve/lv_draw_eve.c | 173 + src/draw/eve/lv_draw_eve.h | 57 + src/draw/eve/lv_draw_eve_arc.c | 323 ++ src/draw/eve/lv_draw_eve_fill.c | 121 + src/draw/eve/lv_draw_eve_image.c | 242 + src/draw/eve/lv_draw_eve_letter.c | 196 + src/draw/eve/lv_draw_eve_line.c | 63 + src/draw/eve/lv_draw_eve_private.h | 99 + src/draw/eve/lv_draw_eve_ram_g.c | 221 + src/draw/eve/lv_draw_eve_ram_g.h | 48 + src/draw/eve/lv_draw_eve_target.h | 79 + src/draw/eve/lv_draw_eve_triangle.c | 127 + src/draw/eve/lv_eve.c | 224 + src/draw/eve/lv_eve.h | 113 + src/drivers/display/ft81x/lv_ft81x.h | 37 +- src/drivers/draw/eve/lv_draw_eve_display.c | 204 + src/drivers/draw/eve/lv_draw_eve_display.h | 119 + .../draw/eve/lv_draw_eve_display_defines.h | 1207 +++++ src/drivers/lv_drivers.h | 3 + src/libs/FT800-FT813/EVE.h | 1257 ++++++ src/libs/FT800-FT813/EVE_commands.c | 3936 +++++++++++++++++ src/libs/FT800-FT813/EVE_commands.h | 339 ++ src/libs/FT800-FT813/EVE_config.h | 26 + src/libs/FT800-FT813/EVE_supplemental.c | 145 + src/libs/FT800-FT813/EVE_suppplemental.h | 53 + src/libs/FT800-FT813/EVE_target.h | 67 + src/libs/FT800-FT813/LICENSE | 20 + src/libs/FT800-FT813/README.md | 245 + src/lv_api_map_v9_2.h | 2 + src/lv_conf_internal.h | 21 + src/lv_conf_kconfig.h | 2 +- src/lv_init.c | 7 + src/misc/lv_types.h | 4 + 42 files changed, 9978 insertions(+), 19 deletions(-) create mode 100644 docs/src/details/integration/renderers/eve.rst create mode 100644 src/draw/eve/lv_draw_eve.c create mode 100644 src/draw/eve/lv_draw_eve.h create mode 100644 src/draw/eve/lv_draw_eve_arc.c create mode 100644 src/draw/eve/lv_draw_eve_fill.c create mode 100644 src/draw/eve/lv_draw_eve_image.c create mode 100644 src/draw/eve/lv_draw_eve_letter.c create mode 100644 src/draw/eve/lv_draw_eve_line.c create mode 100644 src/draw/eve/lv_draw_eve_private.h create mode 100644 src/draw/eve/lv_draw_eve_ram_g.c create mode 100644 src/draw/eve/lv_draw_eve_ram_g.h create mode 100644 src/draw/eve/lv_draw_eve_target.h create mode 100644 src/draw/eve/lv_draw_eve_triangle.c create mode 100644 src/draw/eve/lv_eve.c create mode 100644 src/draw/eve/lv_eve.h create mode 100644 src/drivers/draw/eve/lv_draw_eve_display.c create mode 100644 src/drivers/draw/eve/lv_draw_eve_display.h create mode 100644 src/drivers/draw/eve/lv_draw_eve_display_defines.h create mode 100644 src/libs/FT800-FT813/EVE.h create mode 100644 src/libs/FT800-FT813/EVE_commands.c create mode 100644 src/libs/FT800-FT813/EVE_commands.h create mode 100644 src/libs/FT800-FT813/EVE_config.h create mode 100644 src/libs/FT800-FT813/EVE_supplemental.c create mode 100644 src/libs/FT800-FT813/EVE_suppplemental.h create mode 100644 src/libs/FT800-FT813/EVE_target.h create mode 100644 src/libs/FT800-FT813/LICENSE create mode 100644 src/libs/FT800-FT813/README.md diff --git a/COPYRIGHTS.md b/COPYRIGHTS.md index e85eb44209..99ed2ea51b 100644 --- a/COPYRIGHTS.md +++ b/COPYRIGHTS.md @@ -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 diff --git a/Kconfig b/Kconfig index 454f9ddb4f..01a541cf0a 100644 --- a/Kconfig +++ b/Kconfig @@ -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" diff --git a/docs/src/details/integration/driver/display/ft81x.rst b/docs/src/details/integration/driver/display/ft81x.rst index eff21f9f9b..6d8f42e2e2 100644 --- a/docs/src/details/integration/driver/display/ft81x.rst +++ b/docs/src/details/integration/driver/display/ft81x.rst @@ -1,3 +1,5 @@ +.. _ft81x: + ===== FT81x ===== diff --git a/docs/src/details/integration/renderers/eve.rst b/docs/src/details/integration/renderers/eve.rst new file mode 100644 index 0000000000..352e92c030 --- /dev/null +++ b/docs/src/details/integration/renderers/eve.rst @@ -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 `__. +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 diff --git a/docs/src/details/integration/renderers/index.rst b/docs/src/details/integration/renderers/index.rst index 25b49a6e5e..149cf4bc13 100644 --- a/docs/src/details/integration/renderers/index.rst +++ b/docs/src/details/integration/renderers/index.rst @@ -8,6 +8,7 @@ Renderers and GPUs sw arm2d espressif_ppa + eve nema_gfx nxp_pxp nxp_vglite_gpu diff --git a/lv_conf_template.h b/lv_conf_template.h index 9b7061096a..0e84d3745e 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -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 *=======================*/ diff --git a/lvgl.h b/lvgl.h index cae4f9ea37..d41a484de5 100644 --- a/lvgl.h +++ b/lvgl.h @@ -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" diff --git a/scripts/code-format.cfg b/scripts/code-format.cfg index 53a3a8749b..3caae375bf 100644 --- a/scripts/code-format.cfg +++ b/scripts/code-format.cfg @@ -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 diff --git a/src/core/lv_global.h b/src/core/lv_global.h index 6043dac0f0..119bc80f71 100644 --- a/src/core/lv_global.h +++ b/src/core/lv_global.h @@ -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; diff --git a/src/draw/eve/lv_draw_eve.c b/src/draw/eve/lv_draw_eve.c new file mode 100644 index 0000000000..03a635035c --- /dev/null +++ b/src/draw/eve/lv_draw_eve.c @@ -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*/ diff --git a/src/draw/eve/lv_draw_eve.h b/src/draw/eve/lv_draw_eve.h new file mode 100644 index 0000000000..003638ad4f --- /dev/null +++ b/src/draw/eve/lv_draw_eve.h @@ -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 */ diff --git a/src/draw/eve/lv_draw_eve_arc.c b/src/draw/eve/lv_draw_eve_arc.c new file mode 100644 index 0000000000..f359f78e0c --- /dev/null +++ b/src/draw/eve/lv_draw_eve_arc.c @@ -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*/ diff --git a/src/draw/eve/lv_draw_eve_fill.c b/src/draw/eve/lv_draw_eve_fill.c new file mode 100644 index 0000000000..d0221a711f --- /dev/null +++ b/src/draw/eve/lv_draw_eve_fill.c @@ -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*/ + diff --git a/src/draw/eve/lv_draw_eve_image.c b/src/draw/eve/lv_draw_eve_image.c new file mode 100644 index 0000000000..223512768f --- /dev/null +++ b/src/draw/eve/lv_draw_eve_image.c @@ -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*/ diff --git a/src/draw/eve/lv_draw_eve_letter.c b/src/draw/eve/lv_draw_eve_letter.c new file mode 100644 index 0000000000..f65d40dab7 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_letter.c @@ -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*/ + diff --git a/src/draw/eve/lv_draw_eve_line.c b/src/draw/eve/lv_draw_eve_line.c new file mode 100644 index 0000000000..c38357e285 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_line.c @@ -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*/ diff --git a/src/draw/eve/lv_draw_eve_private.h b/src/draw/eve/lv_draw_eve_private.h new file mode 100644 index 0000000000..0decd03c5e --- /dev/null +++ b/src/draw/eve/lv_draw_eve_private.h @@ -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*/ diff --git a/src/draw/eve/lv_draw_eve_ram_g.c b/src/draw/eve/lv_draw_eve_ram_g.c new file mode 100644 index 0000000000..1ad544cd69 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_ram_g.c @@ -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*/ + diff --git a/src/draw/eve/lv_draw_eve_ram_g.h b/src/draw/eve/lv_draw_eve_ram_g.h new file mode 100644 index 0000000000..ec6ae75352 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_ram_g.h @@ -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 */ diff --git a/src/draw/eve/lv_draw_eve_target.h b/src/draw/eve/lv_draw_eve_target.h new file mode 100644 index 0000000000..90e938bb37 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_target.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*/ diff --git a/src/draw/eve/lv_draw_eve_triangle.c b/src/draw/eve/lv_draw_eve_triangle.c new file mode 100644 index 0000000000..b48411f59e --- /dev/null +++ b/src/draw/eve/lv_draw_eve_triangle.c @@ -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*/ + + diff --git a/src/draw/eve/lv_eve.c b/src/draw/eve/lv_eve.c new file mode 100644 index 0000000000..16f8ddaba7 --- /dev/null +++ b/src/draw/eve/lv_eve.c @@ -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*/ diff --git a/src/draw/eve/lv_eve.h b/src/draw/eve/lv_eve.h new file mode 100644 index 0000000000..e341b0e6ef --- /dev/null +++ b/src/draw/eve/lv_eve.h @@ -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 */ diff --git a/src/drivers/display/ft81x/lv_ft81x.h b/src/drivers/display/ft81x/lv_ft81x.h index 0995d4a47d..05899ee029 100644 --- a/src/drivers/display/ft81x/lv_ft81x.h +++ b/src/drivers/display/ft81x/lv_ft81x.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 diff --git a/src/drivers/draw/eve/lv_draw_eve_display.c b/src/drivers/draw/eve/lv_draw_eve_display.c new file mode 100644 index 0000000000..e7285b50e0 --- /dev/null +++ b/src/drivers/draw/eve/lv_draw_eve_display.c @@ -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*/ diff --git a/src/drivers/draw/eve/lv_draw_eve_display.h b/src/drivers/draw/eve/lv_draw_eve_display.h new file mode 100644 index 0000000000..d2ee5c4bdf --- /dev/null +++ b/src/drivers/draw/eve/lv_draw_eve_display.h @@ -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*/ diff --git a/src/drivers/draw/eve/lv_draw_eve_display_defines.h b/src/drivers/draw/eve/lv_draw_eve_display_defines.h new file mode 100644 index 0000000000..1d2efff155 --- /dev/null +++ b/src/drivers/draw/eve/lv_draw_eve_display_defines.h @@ -0,0 +1,1207 @@ +/** + * @file lv_draw_eve_display_defines.h + * + */ + +#ifndef LV_DRAW_EVE_DISPLAY_DEFINES_H +#define LV_DRAW_EVE_DISPLAY_DEFINES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE + +/********************* + * DEFINES + *********************/ + +/* Memory */ +#define LV_EVE_EVE_RAM_G ((uint32_t) 0x00000000UL) +#define LV_EVE_EVE_ROM_CHIPID ((uint32_t) 0x000C0000UL) +#define LV_EVE_EVE_ROM_FONT ((uint32_t) 0x001E0000UL) +#define LV_EVE_EVE_ROM_FONTROOT ((uint32_t) 0x002FFFFCUL) +#define LV_EVE_EVE_RAM_DL ((uint32_t) 0x00300000UL) +#define LV_EVE_EVE_RAM_REG ((uint32_t) 0x00302000UL) +#define LV_EVE_EVE_RAM_CMD ((uint32_t) 0x00308000UL) + +/* Memory buffer sizes */ +#define LV_EVE_EVE_RAM_G_SIZE ((uint32_t) 1024U*1024UL) +#define LV_EVE_EVE_CMDFIFO_SIZE ((uint32_t) 4U*1024UL) +#define LV_EVE_EVE_RAM_DL_SIZE ((uint32_t) 8U*1024UL) + +/* diplay list list commands, most need OR's arguments */ +#define LV_EVE_DL_DISPLAY ((uint32_t) 0x00000000UL) +#define LV_EVE_DL_BITMAP_SOURCE ((uint32_t) 0x01000000UL) +#define LV_EVE_DL_CLEAR_COLOR_RGB ((uint32_t) 0x02000000UL) +#define LV_EVE_DL_TAG ((uint32_t) 0x03000000UL) +#define LV_EVE_DL_COLOR_RGB ((uint32_t) 0x04000000UL) +#define LV_EVE_DL_BITMAP_HANDLE ((uint32_t) 0x05000000UL) +#define LV_EVE_DL_CELL ((uint32_t) 0x06000000UL) +#define LV_EVE_DL_BITMAP_LAYOUT ((uint32_t) 0x07000000UL) +#define LV_EVE_DL_BITMAP_SIZE ((uint32_t) 0x08000000UL) +#define LV_EVE_DL_ALPHA_FUNC ((uint32_t) 0x09000000UL) +#define LV_EVE_DL_STENCIL_FUNC ((uint32_t) 0x0A000000UL) +#define LV_EVE_DL_BLEND_FUNC ((uint32_t) 0x0B000000UL) +#define LV_EVE_DL_STENCIL_OP ((uint32_t) 0x0C000000UL) +#define LV_EVE_DL_POINT_SIZE ((uint32_t) 0x0D000000UL) +#define LV_EVE_DL_LINE_WIDTH ((uint32_t) 0x0E000000UL) +#define LV_EVE_DL_CLEAR_COLOR_A ((uint32_t) 0x0F000000UL) +#define LV_EVE_DL_COLOR_A ((uint32_t) 0x10000000UL) +#define LV_EVE_DL_CLEAR_STENCIL ((uint32_t) 0x11000000UL) +#define LV_EVE_DL_CLEAR_TAG ((uint32_t) 0x12000000UL) +#define LV_EVE_DL_STENCIL_MASK ((uint32_t) 0x13000000UL) +#define LV_EVE_DL_TAG_MASK ((uint32_t) 0x14000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_A ((uint32_t) 0x15000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_B ((uint32_t) 0x16000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_C ((uint32_t) 0x17000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_D ((uint32_t) 0x18000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_E ((uint32_t) 0x19000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_F ((uint32_t) 0x1A000000UL) +#define LV_EVE_DL_SCISSOR_XY ((uint32_t) 0x1B000000UL) +#define LV_EVE_DL_SCISSOR_SIZE ((uint32_t) 0x1C000000UL) +#define LV_EVE_DL_CALL ((uint32_t) 0x1D000000UL) +#define LV_EVE_DL_JUMP ((uint32_t) 0x1E000000UL) +#define LV_EVE_DL_BEGIN ((uint32_t) 0x1F000000UL) +#define LV_EVE_DL_COLOR_MASK ((uint32_t) 0x20000000UL) +#define LV_EVE_DL_END ((uint32_t) 0x21000000UL) +#define LV_EVE_DL_SAVE_CONTEXT ((uint32_t) 0x22000000UL) +#define LV_EVE_DL_RESTORE_CONTEXT ((uint32_t) 0x23000000UL) +#define LV_EVE_DL_RETURN ((uint32_t) 0x24000000UL) +#define LV_EVE_DL_MACRO ((uint32_t) 0x25000000UL) +#define LV_EVE_DL_CLEAR ((uint32_t) 0x26000000UL) +#define LV_EVE_DL_VERTEX_FORMAT ((uint32_t) 0x27000000UL) +#define LV_EVE_DL_BITMAP_LAYOUT_H ((uint32_t) 0x28000000UL) +#define LV_EVE_DL_BITMAP_SIZE_H ((uint32_t) 0x29000000UL) +#define LV_EVE_DL_PALETTE_SOURCE ((uint32_t) 0x2A000000UL) +#define LV_EVE_DL_VERTEX_TRANSLATE_X ((uint32_t) 0x2B000000UL) +#define LV_EVE_DL_VERTEX_TRANSLATE_Y ((uint32_t) 0x2C000000UL) +#define LV_EVE_DL_NOP ((uint32_t) 0x2D000000UL) + +#define LV_EVE_DL_VERTEX2F ((uint32_t) 0x40000000UL) +#define LV_EVE_DL_VERTEX2II ((uint32_t) 0x80000000UL) + +#define LV_EVE_CLR_COL ((uint8_t) 0x4U) +#define LV_EVE_CLR_STN ((uint8_t) 0x2U) +#define LV_EVE_CLR_TAG ((uint8_t) 0x1U) + +/* Host commands */ +#define LV_EVE_EVE_ACTIVE ((uint8_t) 0x00U) /* place EVE in active state */ +#define LV_EVE_EVE_STANDBY ((uint8_t) 0x41U) /* place EVE in Standby (clk running) */ +#define LV_EVE_EVE_SLEEP ((uint8_t) 0x42U) /* place EVE in Sleep (clk off) */ +#define LV_EVE_EVE_CLKEXT ((uint8_t) 0x44U) /* select external clock source */ +#define LV_EVE_EVE_CLKINT ((uint8_t) 0x48U) /* select internal clock source, not a valid option for BT817 / BT818 */ +#define LV_EVE_EVE_PWRDOWN ((uint8_t) 0x50U) /* place EVE in Power Down (core off) */ +#define LV_EVE_EVE_CLKSEL ((uint8_t) 0x61U) /* configure system clock */ +#define LV_EVE_EVE_RST_PULSE ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define LV_EVE_EVE_CORERST ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define LV_EVE_EVE_PINDRIVE ((uint8_t) 0x70U) /* setup drive strength for various pins */ +#define LV_EVE_EVE_PIN_PD_STATE ((uint8_t) 0x71U) /* setup how pins behave during power down */ + +/* Graphic command defines */ +#define LV_EVE_EVE_NEVER ((uint8_t) 0UL) +#define LV_EVE_EVE_LESS ((uint8_t) 1UL) +#define LV_EVE_EVE_LEQUAL ((uint8_t) 2UL) +#define LV_EVE_EVE_GREATER ((uint8_t) 3UL) +#define LV_EVE_EVE_GEQUAL ((uint8_t) 4UL) +#define LV_EVE_EVE_EQUAL ((uint8_t) 5UL) +#define LV_EVE_EVE_NOTEQUAL ((uint8_t) 6UL) +#define LV_EVE_EVE_ALWAYS ((uint8_t) 7UL) + +/* Bitmap formats */ +#define LV_EVE_EVE_ARGB1555 ((uint8_t) 0UL) +#define LV_EVE_EVE_L1 ((uint8_t) 1UL) +#define LV_EVE_EVE_L4 ((uint8_t) 2UL) +#define LV_EVE_EVE_L8 ((uint8_t) 3UL) +#define LV_EVE_EVE_RGB332 ((uint8_t) 4UL) +#define LV_EVE_EVE_ARGB2 ((uint8_t) 5UL) +#define LV_EVE_EVE_ARGB4 ((uint8_t) 6UL) +#define LV_EVE_EVE_RGB565 ((uint8_t) 7UL) +#define LV_EVE_EVE_PALETTED ((uint8_t) 8UL) +#define LV_EVE_EVE_TEXT8X8 ((uint8_t) 9UL) +#define LV_EVE_EVE_TEXTVGA ((uint8_t) 10UL) +#define LV_EVE_EVE_BARGRAPH ((uint8_t) 11UL) + +/* Bitmap filter types */ +#define LV_EVE_EVE_NEAREST ((uint8_t) 0UL) +#define LV_EVE_EVE_BILINEAR ((uint8_t) 1UL) + +/* Bitmap wrap types */ +#define LV_EVE_EVE_BORDER ((uint8_t) 0UL) +#define LV_EVE_EVE_REPEAT ((uint8_t) 1UL) + +/* Stencil defines */ +#define LV_EVE_EVE_KEEP ((uint8_t) 1UL) +#define LV_EVE_EVE_REPLACE ((uint8_t) 2UL) +#define LV_EVE_EVE_INCR ((uint8_t) 3UL) +#define LV_EVE_EVE_DECR ((uint8_t) 4UL) +#define LV_EVE_EVE_INVERT ((uint8_t) 5UL) + +/* Graphics display list swap defines */ +#define LV_EVE_EVE_DLSWAP_DONE ((uint8_t) 0UL) +#define LV_EVE_EVE_DLSWAP_LINE ((uint8_t) 1UL) +#define LV_EVE_EVE_DLSWAP_FRAME ((uint8_t) 2UL) + +/* Interrupt bits */ +#define LV_EVE_EVE_INT_SWAP ((uint8_t) 0x01) +#define LV_EVE_EVE_INT_TOUCH ((uint8_t) 0x02) +#define LV_EVE_EVE_INT_TAG ((uint8_t) 0x04) +#define LV_EVE_EVE_INT_SOUND ((uint8_t) 0x08) +#define LV_EVE_EVE_INT_PLAYBACK ((uint8_t) 0x10) +#define LV_EVE_EVE_INT_CMDEMPTY ((uint8_t) 0x20) +#define LV_EVE_EVE_INT_CMDFLAG ((uint8_t) 0x40) +#define LV_EVE_EVE_INT_CONVCOMPLETE ((uint8_t) 0x80) + +/* Touch mode */ +#define LV_EVE_EVE_TMODE_OFF ((uint8_t) 0U) +#define LV_EVE_EVE_TMODE_ONESHOT ((uint8_t) 1U) +#define LV_EVE_EVE_TMODE_FRAME ((uint8_t) 2U) +#define LV_EVE_EVE_TMODE_CONTINUOUS ((uint8_t) 3U) + +/* Alpha blending */ +#define LV_EVE_EVE_ZERO ((uint32_t) 0UL) +#define LV_EVE_EVE_ONE ((uint32_t) 1UL) +#define LV_EVE_EVE_SRC_ALPHA ((uint32_t) 2UL) +#define LV_EVE_EVE_DST_ALPHA ((uint32_t) 3UL) +#define LV_EVE_EVE_ONE_MINUS_SRC_ALPHA ((uint32_t) 4UL) +#define LV_EVE_EVE_ONE_MINUS_DST_ALPHA ((uint32_t) 5UL) + +/* Graphics primitives */ +#define LV_EVE_EVE_BITMAPS ((uint32_t) 1UL) +#define LV_EVE_EVE_POINTS ((uint32_t) 2UL) +#define LV_EVE_EVE_LINES ((uint32_t) 3UL) +#define LV_EVE_EVE_LINE_STRIP ((uint32_t) 4UL) +#define LV_EVE_EVE_EDGE_STRIP_R ((uint32_t) 5UL) +#define LV_EVE_EVE_EDGE_STRIP_L ((uint32_t) 6UL) +#define LV_EVE_EVE_EDGE_STRIP_A ((uint32_t) 7UL) +#define LV_EVE_EVE_EDGE_STRIP_B ((uint32_t) 8UL) +#define LV_EVE_EVE_RECTS ((uint32_t) 9UL) +#define LV_EVE_EVE_INT_G8 ((uint32_t) 18UL) +#define LV_EVE_EVE_INT_L8C ((uint32_t) 12UL) +#define LV_EVE_EVE_INT_VGA ((uint32_t) 13UL) +#define LV_EVE_EVE_PALETTED565 ((uint32_t) 14UL) +#define LV_EVE_EVE_PALETTED4444 ((uint32_t) 15UL) +#define LV_EVE_EVE_PALETTED8 ((uint32_t) 16UL) +#define LV_EVE_EVE_L2 ((uint32_t) 17UL) + +/* Widget command options */ +#define LV_EVE_EVE_OPT_MONO ((uint16_t) 1U) +#define LV_EVE_EVE_OPT_NODL ((uint16_t) 2U) +#define LV_EVE_EVE_OPT_FLAT ((uint16_t) 256U) +#define LV_EVE_EVE_OPT_CENTERX ((uint16_t) 512U) +#define LV_EVE_EVE_OPT_CENTERY ((uint16_t) 1024U) +#define LV_EVE_EVE_OPT_CENTER (LV_EVE_EVE_OPT_CENTERX | LV_EVE_EVE_OPT_CENTERY) +#define LV_EVE_EVE_OPT_NOBACK ((uint16_t) 4096U) +#define LV_EVE_EVE_OPT_NOTICKS ((uint16_t) 8192U) +#define LV_EVE_EVE_OPT_NOHM ((uint16_t) 16384U) +#define LV_EVE_EVE_OPT_NOPOINTER ((uint16_t) 16384U) +#define LV_EVE_EVE_OPT_NOSECS ((uint16_t) 32768U) +#define LV_EVE_EVE_OPT_NOHANDS ((uint16_t) 49152U) +#define LV_EVE_EVE_OPT_RIGHTX ((uint16_t) 2048U) +#define LV_EVE_EVE_OPT_SIGNED ((uint16_t) 256U) + +#define LV_EVE_EVE_OPT_MEDIAFIFO ((uint16_t) 16U) +#define LV_EVE_EVE_OPT_FULLSCREEN ((uint16_t) 8U) +#define LV_EVE_EVE_OPT_NOTEAR ((uint16_t) 4U) +#define LV_EVE_EVE_OPT_SOUND ((uint16_t) 32U) + +/* ADC */ +#define LV_EVE_EVE_ADC_DIFFERENTIAL ((uint32_t) 1UL) +#define LV_EVE_EVE_ADC_SINGLE_ENDED ((uint32_t) 0UL) + +/* Fonts */ +#define LV_EVE_EVE_NUMCHAR_PERFONT ((uint32_t) 128UL) /* number of font characters per bitmap handle */ +#define LV_EVE_EVE_FONT_TABLE_SIZE ((uint32_t) 148UL) /* size of the font table - utilized for loopup by the graphics engine */ +#define LV_EVE_EVE_FONT_TABLE_POINTER ((uint32_t) 0xFFFFCUL) /* pointer to the inbuilt font tables starting from bitmap handle 16 */ + +/* Audio sample type defines */ +#define LV_EVE_EVE_LINEAR_SAMPLES ((uint32_t) 0UL) /* 8bit signed samples */ +#define LV_EVE_EVE_ULAW_SAMPLES ((uint32_t) 1UL) /* 8bit ulaw samples */ +#define LV_EVE_EVE_ADPCM_SAMPLES ((uint32_t) 2UL) /* 4bit ima adpcm samples */ + +/* Synthesized sound */ +#define LV_EVE_EVE_SILENCE ((uint8_t) 0x00U) +#define LV_EVE_EVE_SQUAREWAVE ((uint8_t) 0x01U) +#define LV_EVE_EVE_SINEWAVE ((uint8_t) 0x02U) +#define LV_EVE_EVE_SAWTOOTH ((uint8_t) 0x03U) +#define LV_EVE_EVE_TRIANGLE ((uint8_t) 0x04U) +#define LV_EVE_EVE_BEEPING ((uint8_t) 0x05U) +#define LV_EVE_EVE_ALARM ((uint8_t) 0x06U) +#define LV_EVE_EVE_WARBLE ((uint8_t) 0x07U) +#define LV_EVE_EVE_CAROUSEL ((uint8_t) 0x08U) +#define LV_EVE_EVE_PIPS(n) ((uint8_t) (0x0FU + (n))) +#define LV_EVE_EVE_HARP ((uint8_t) 0x40U) +#define LV_EVE_EVE_XYLOPHONE ((uint8_t) 0x41U) +#define LV_EVE_EVE_TUBA ((uint8_t) 0x42U) +#define LV_EVE_EVE_GLOCKENSPIEL ((uint8_t) 0x43U) +#define LV_EVE_EVE_ORGAN ((uint8_t) 0x44U) +#define LV_EVE_EVE_TRUMPET ((uint8_t) 0x45U) +#define LV_EVE_EVE_PIANO ((uint8_t) 0x46U) +#define LV_EVE_EVE_CHIMES ((uint8_t) 0x47U) +#define LV_EVE_EVE_MUSICBOX ((uint8_t) 0x48U) +#define LV_EVE_EVE_BELL ((uint8_t) 0x49U) +#define LV_EVE_EVE_CLICK ((uint8_t) 0x50U) +#define LV_EVE_EVE_SWITCH ((uint8_t) 0x51U) +#define LV_EVE_EVE_COWBELL ((uint8_t) 0x52U) +#define LV_EVE_EVE_NOTCH ((uint8_t) 0x53U) +#define LV_EVE_EVE_HIHAT ((uint8_t) 0x54U) +#define LV_EVE_EVE_KICKDRUM ((uint8_t) 0x55U) +#define LV_EVE_EVE_POP ((uint8_t) 0x56U) +#define LV_EVE_EVE_CLACK ((uint8_t) 0x57U) +#define LV_EVE_EVE_CHACK ((uint8_t) 0x58U) +#define LV_EVE_EVE_MUTE ((uint8_t) 0x60U) +#define LV_EVE_EVE_UNMUTE ((uint8_t) 0x61U) + +/* Synthesized sound frequencies, midi note */ +#define LV_EVE_EVE_MIDI_A0 ((uint8_t) 21U) +#define LV_EVE_EVE_MIDI_A_0 ((uint8_t) 22U) +#define LV_EVE_EVE_MIDI_B0 ((uint8_t) 23U) +#define LV_EVE_EVE_MIDI_C1 ((uint8_t) 24U) +#define LV_EVE_EVE_MIDI_C_1 ((uint8_t) 25U) +#define LV_EVE_EVE_MIDI_D1 ((uint8_t) 26U) +#define LV_EVE_EVE_MIDI_D_1 ((uint8_t) 27U) +#define LV_EVE_EVE_MIDI_E1 ((uint8_t) 28U) +#define LV_EVE_EVE_MIDI_F1 ((uint8_t) 29U) +#define LV_EVE_EVE_MIDI_F_1 ((uint8_t) 30U) +#define LV_EVE_EVE_MIDI_G1 ((uint8_t) 31U) +#define LV_EVE_EVE_MIDI_G_1 ((uint8_t) 32U) +#define LV_EVE_EVE_MIDI_A1 ((uint8_t) 33U) +#define LV_EVE_EVE_MIDI_A_1 ((uint8_t) 34U) +#define LV_EVE_EVE_MIDI_B1 ((uint8_t) 35U) +#define LV_EVE_EVE_MIDI_C2 ((uint8_t) 36U) +#define LV_EVE_EVE_MIDI_C_2 ((uint8_t) 37U) +#define LV_EVE_EVE_MIDI_D2 ((uint8_t) 38U) +#define LV_EVE_EVE_MIDI_D_2 ((uint8_t) 39U) +#define LV_EVE_EVE_MIDI_E2 ((uint8_t) 40U) +#define LV_EVE_EVE_MIDI_F2 ((uint8_t) 41U) +#define LV_EVE_EVE_MIDI_F_2 ((uint8_t) 42U) +#define LV_EVE_EVE_MIDI_G2 ((uint8_t) 43U) +#define LV_EVE_EVE_MIDI_G_2 ((uint8_t) 44U) +#define LV_EVE_EVE_MIDI_A2 ((uint8_t) 45U) +#define LV_EVE_EVE_MIDI_A_2 ((uint8_t) 46U) +#define LV_EVE_EVE_MIDI_B2 ((uint8_t) 47U) +#define LV_EVE_EVE_MIDI_C3 ((uint8_t) 48U) +#define LV_EVE_EVE_MIDI_C_3 ((uint8_t) 49U) +#define LV_EVE_EVE_MIDI_D3 ((uint8_t) 50U) +#define LV_EVE_EVE_MIDI_D_3 ((uint8_t) 51U) +#define LV_EVE_EVE_MIDI_E3 ((uint8_t) 52U) +#define LV_EVE_EVE_MIDI_F3 ((uint8_t) 53U) +#define LV_EVE_EVE_MIDI_F_3 ((uint8_t) 54U) +#define LV_EVE_EVE_MIDI_G3 ((uint8_t) 55U) +#define LV_EVE_EVE_MIDI_G_3 ((uint8_t) 56U) +#define LV_EVE_EVE_MIDI_A3 ((uint8_t) 57U) +#define LV_EVE_EVE_MIDI_A_3 ((uint8_t) 58U) +#define LV_EVE_EVE_MIDI_B3 ((uint8_t) 59U) +#define LV_EVE_EVE_MIDI_C4 ((uint8_t) 60U) +#define LV_EVE_EVE_MIDI_C_4 ((uint8_t) 61U) +#define LV_EVE_EVE_MIDI_D4 ((uint8_t) 62U) +#define LV_EVE_EVE_MIDI_D_4 ((uint8_t) 63U) +#define LV_EVE_EVE_MIDI_E4 ((uint8_t) 64U) +#define LV_EVE_EVE_MIDI_F4 ((uint8_t) 65U) +#define LV_EVE_EVE_MIDI_F_4 ((uint8_t) 66U) +#define LV_EVE_EVE_MIDI_G4 ((uint8_t) 67U) +#define LV_EVE_EVE_MIDI_G_4 ((uint8_t) 68U) +#define LV_EVE_EVE_MIDI_A4 ((uint8_t) 69U) +#define LV_EVE_EVE_MIDI_A_4 ((uint8_t) 70U) +#define LV_EVE_EVE_MIDI_B4 ((uint8_t) 71U) +#define LV_EVE_EVE_MIDI_C5 ((uint8_t) 72U) +#define LV_EVE_EVE_MIDI_C_5 ((uint8_t) 73U) +#define LV_EVE_EVE_MIDI_D5 ((uint8_t) 74U) +#define LV_EVE_EVE_MIDI_D_5 ((uint8_t) 75U) +#define LV_EVE_EVE_MIDI_E5 ((uint8_t) 76U) +#define LV_EVE_EVE_MIDI_F5 ((uint8_t) 77U) +#define LV_EVE_EVE_MIDI_F_5 ((uint8_t) 78U) +#define LV_EVE_EVE_MIDI_G5 ((uint8_t) 79U) +#define LV_EVE_EVE_MIDI_G_5 ((uint8_t) 80U) +#define LV_EVE_EVE_MIDI_A5 ((uint8_t) 81U) +#define LV_EVE_EVE_MIDI_A_5 ((uint8_t) 82U) +#define LV_EVE_EVE_MIDI_B5 ((uint8_t) 83U) +#define LV_EVE_EVE_MIDI_C6 ((uint8_t) 84U) +#define LV_EVE_EVE_MIDI_C_6 ((uint8_t) 85U) +#define LV_EVE_EVE_MIDI_D6 ((uint8_t) 86U) +#define LV_EVE_EVE_MIDI_D_6 ((uint8_t) 87U) +#define LV_EVE_EVE_MIDI_E6 ((uint8_t) 88U) +#define LV_EVE_EVE_MIDI_F6 ((uint8_t) 89U) +#define LV_EVE_EVE_MIDI_F_6 ((uint8_t) 90U) +#define LV_EVE_EVE_MIDI_G6 ((uint8_t) 91U) +#define LV_EVE_EVE_MIDI_G_6 ((uint8_t) 92U) +#define LV_EVE_EVE_MIDI_A6 ((uint8_t) 93U) +#define LV_EVE_EVE_MIDI_A_6 ((uint8_t) 94U) +#define LV_EVE_EVE_MIDI_B6 ((uint8_t) 95U) +#define LV_EVE_EVE_MIDI_C7 ((uint8_t) 96U) +#define LV_EVE_EVE_MIDI_C_7 ((uint8_t) 97U) +#define LV_EVE_EVE_MIDI_D7 ((uint8_t) 98U) +#define LV_EVE_EVE_MIDI_D_7 ((uint8_t) 99U) +#define LV_EVE_EVE_MIDI_E7 ((uint8_t) 100U) +#define LV_EVE_EVE_MIDI_F7 ((uint8_t) 101U) +#define LV_EVE_EVE_MIDI_F_7 ((uint8_t) 102U) +#define LV_EVE_EVE_MIDI_G7 ((uint8_t) 103U) +#define LV_EVE_EVE_MIDI_G_7 ((uint8_t) 104U) +#define LV_EVE_EVE_MIDI_A7 ((uint8_t) 105U) +#define LV_EVE_EVE_MIDI_A_7 ((uint8_t) 106U) +#define LV_EVE_EVE_MIDI_B7 ((uint8_t) 107U) +#define LV_EVE_EVE_MIDI_C8 ((uint8_t) 108U) + +/* GPIO bits */ +#define LV_EVE_EVE_GPIO0 ((uint8_t) 0U) +#define LV_EVE_EVE_GPIO1 ((uint8_t) 1U) /* default gpio pin for audio shutdown, 1 - enable, 0 - disable */ +#define LV_EVE_EVE_GPIO7 ((uint8_t) 7U) /* default gpio pin for display enable, 1 - enable, 0 - disable */ + +/* Display rotation */ +#define LV_EVE_EVE_DISPLAY_0 ((uint8_t) 0U) /* 0 degrees rotation */ +#define LV_EVE_EVE_DISPLAY_180 ((uint8_t) 1U) /* 180 degrees rotation */ + +/* Commands */ +#define LV_EVE_CMD_APPEND ((uint32_t) 0xFFFFFF1EUL) +#define LV_EVE_CMD_BGCOLOR ((uint32_t) 0xFFFFFF09UL) +#define LV_EVE_CMD_BUTTON ((uint32_t) 0xFFFFFF0DUL) +#define LV_EVE_CMD_CALIBRATE ((uint32_t) 0xFFFFFF15UL) +#define LV_EVE_CMD_CLOCK ((uint32_t) 0xFFFFFF14UL) +#define LV_EVE_CMD_COLDSTART ((uint32_t) 0xFFFFFF32UL) +#define LV_EVE_CMD_DIAL ((uint32_t) 0xFFFFFF2DUL) +#define LV_EVE_CMD_DLSTART ((uint32_t) 0xFFFFFF00UL) +#define LV_EVE_CMD_FGCOLOR ((uint32_t) 0xFFFFFF0AUL) +#define LV_EVE_CMD_GAUGE ((uint32_t) 0xFFFFFF13UL) +#define LV_EVE_CMD_GETMATRIX ((uint32_t) 0xFFFFFF33UL) +#define LV_EVE_CMD_GETPROPS ((uint32_t) 0xFFFFFF25UL) +#define LV_EVE_CMD_GETPTR ((uint32_t) 0xFFFFFF23UL) +#define LV_EVE_CMD_GRADCOLOR ((uint32_t) 0xFFFFFF34UL) +#define LV_EVE_CMD_GRADIENT ((uint32_t) 0xFFFFFF0BUL) +#define LV_EVE_CMD_INFLATE ((uint32_t) 0xFFFFFF22UL) +#define LV_EVE_CMD_INTERRUPT ((uint32_t) 0xFFFFFF02UL) +#define LV_EVE_CMD_KEYS ((uint32_t) 0xFFFFFF0EUL) +#define LV_EVE_CMD_LOADIDENTITY ((uint32_t) 0xFFFFFF26UL) +#define LV_EVE_CMD_LOADIMAGE ((uint32_t) 0xFFFFFF24UL) +#define LV_EVE_CMD_LOGO ((uint32_t) 0xFFFFFF31UL) +#define LV_EVE_CMD_MEDIAFIFO ((uint32_t) 0xFFFFFF39UL) +#define LV_EVE_CMD_MEMCPY ((uint32_t) 0xFFFFFF1DUL) +#define LV_EVE_CMD_MEMCRC ((uint32_t) 0xFFFFFF18UL) +#define LV_EVE_CMD_MEMSET ((uint32_t) 0xFFFFFF1BUL) +#define LV_EVE_CMD_MEMWRITE ((uint32_t) 0xFFFFFF1AUL) +#define LV_EVE_CMD_MEMZERO ((uint32_t) 0xFFFFFF1CUL) +#define LV_EVE_CMD_NUMBER ((uint32_t) 0xFFFFFF2EUL) +#define LV_EVE_CMD_PLAYVIDEO ((uint32_t) 0xFFFFFF3AUL) +#define LV_EVE_CMD_PROGRESS ((uint32_t) 0xFFFFFF0FUL) +#define LV_EVE_CMD_REGREAD ((uint32_t) 0xFFFFFF19UL) +#define LV_EVE_CMD_ROMFONT ((uint32_t) 0xFFFFFF3FUL) +#define LV_EVE_CMD_ROTATE ((uint32_t) 0xFFFFFF29UL) +#define LV_EVE_CMD_SCALE ((uint32_t) 0xFFFFFF28UL) +#define LV_EVE_CMD_SCREENSAVER ((uint32_t) 0xFFFFFF2FUL) +#define LV_EVE_CMD_SCROLLBAR ((uint32_t) 0xFFFFFF11UL) +#define LV_EVE_CMD_SETBASE ((uint32_t) 0xFFFFFF38UL) +#define LV_EVE_CMD_SETBITMAP ((uint32_t) 0xFFFFFF43UL) +#define LV_EVE_CMD_SETFONT ((uint32_t) 0xFFFFFF2BUL) +#define LV_EVE_CMD_SETFONT2 ((uint32_t) 0xFFFFFF3BUL) +#define LV_EVE_CMD_SETMATRIX ((uint32_t) 0xFFFFFF2AUL) +#define LV_EVE_CMD_SETROTATE ((uint32_t) 0xFFFFFF36UL) +#define LV_EVE_CMD_SETSCRATCH ((uint32_t) 0xFFFFFF3CUL) +#define LV_EVE_CMD_SKETCH ((uint32_t) 0xFFFFFF30UL) +#define LV_EVE_CMD_SLIDER ((uint32_t) 0xFFFFFF10UL) +#define LV_EVE_CMD_SNAPSHOT ((uint32_t) 0xFFFFFF1FUL) +#define LV_EVE_CMD_SNAPSHOT2 ((uint32_t) 0xFFFFFF37UL) +#define LV_EVE_CMD_SPINNER ((uint32_t) 0xFFFFFF16UL) +#define LV_EVE_CMD_STOP ((uint32_t) 0xFFFFFF17UL) +#define LV_EVE_CMD_SWAP ((uint32_t) 0xFFFFFF01UL) +#define LV_EVE_CMD_TEXT ((uint32_t) 0xFFFFFF0CUL) +#define LV_EVE_CMD_TOGGLE ((uint32_t) 0xFFFFFF12UL) +#define LV_EVE_CMD_TRACK ((uint32_t) 0xFFFFFF2CUL) +#define LV_EVE_CMD_TRANSLATE ((uint32_t) 0xFFFFFF27UL) +#define LV_EVE_CMD_VIDEOFRAME ((uint32_t) 0xFFFFFF41UL) +#define LV_EVE_CMD_VIDEOSTART ((uint32_t) 0xFFFFFF40UL) + +/* Registers */ +#define LV_EVE_REG_ANA_COMP ((uint32_t) 0x00302184UL) /* only listed in datasheet */ +#define LV_EVE_REG_BIST_EN ((uint32_t) 0x00302174UL) /* only listed in datasheet */ +#define LV_EVE_REG_CLOCK ((uint32_t) 0x00302008UL) +#define LV_EVE_REG_CMDB_SPACE ((uint32_t) 0x00302574UL) +#define LV_EVE_REG_CMDB_WRITE ((uint32_t) 0x00302578UL) +#define LV_EVE_REG_CMD_DL ((uint32_t) 0x00302100UL) +#define LV_EVE_REG_CMD_READ ((uint32_t) 0x003020f8UL) +#define LV_EVE_REG_CMD_WRITE ((uint32_t) 0x003020fcUL) +#define LV_EVE_REG_CPURESET ((uint32_t) 0x00302020UL) +#define LV_EVE_REG_CSPREAD ((uint32_t) 0x00302068UL) +#define LV_EVE_REG_CTOUCH_EXTENDED ((uint32_t) 0x00302108UL) +#define LV_EVE_REG_CTOUCH_TOUCH0_XY ((uint32_t) 0x00302124UL) /* only listed in datasheet */ +#define LV_EVE_REG_CTOUCH_TOUCH4_X ((uint32_t) 0x0030216cUL) +#define LV_EVE_REG_CTOUCH_TOUCH4_Y ((uint32_t) 0x00302120UL) +#define LV_EVE_REG_CTOUCH_TOUCH1_XY ((uint32_t) 0x0030211cUL) +#define LV_EVE_REG_CTOUCH_TOUCH2_XY ((uint32_t) 0x0030218cUL) +#define LV_EVE_REG_CTOUCH_TOUCH3_XY ((uint32_t) 0x00302190UL) +#define LV_EVE_REG_TOUCH_CONFIG ((uint32_t) 0x00302168UL) +#define LV_EVE_REG_DATESTAMP ((uint32_t) 0x00302564UL) /* only listed in datasheet */ +#define LV_EVE_REG_DITHER ((uint32_t) 0x00302060UL) +#define LV_EVE_REG_DLSWAP ((uint32_t) 0x00302054UL) +#define LV_EVE_REG_FRAMES ((uint32_t) 0x00302004UL) +#define LV_EVE_REG_FREQUENCY ((uint32_t) 0x0030200cUL) +#define LV_EVE_REG_GPIO ((uint32_t) 0x00302094UL) +#define LV_EVE_REG_GPIOX ((uint32_t) 0x0030209cUL) +#define LV_EVE_REG_GPIOX_DIR ((uint32_t) 0x00302098UL) +#define LV_EVE_REG_GPIO_DIR ((uint32_t) 0x00302090UL) +#define LV_EVE_REG_HCYCLE ((uint32_t) 0x0030202cUL) +#define LV_EVE_REG_HOFFSET ((uint32_t) 0x00302030UL) +#define LV_EVE_REG_HSIZE ((uint32_t) 0x00302034UL) +#define LV_EVE_REG_HSYNC0 ((uint32_t) 0x00302038UL) +#define LV_EVE_REG_HSYNC1 ((uint32_t) 0x0030203cUL) +#define LV_EVE_REG_ID ((uint32_t) 0x00302000UL) +#define LV_EVE_REG_INT_EN ((uint32_t) 0x003020acUL) +#define LV_EVE_REG_INT_FLAGS ((uint32_t) 0x003020a8UL) +#define LV_EVE_REG_INT_MASK ((uint32_t) 0x003020b0UL) +#define LV_EVE_REG_MACRO_0 ((uint32_t) 0x003020d8UL) +#define LV_EVE_REG_MACRO_1 ((uint32_t) 0x003020dcUL) +#define LV_EVE_REG_MEDIAFIFO_READ ((uint32_t) 0x00309014UL) /* only listed in programmers guide */ +#define LV_EVE_REG_MEDIAFIFO_WRITE ((uint32_t) 0x00309018UL) /* only listed in programmers guide */ +#define LV_EVE_REG_OUTBITS ((uint32_t) 0x0030205cUL) +#define LV_EVE_REG_PCLK ((uint32_t) 0x00302070UL) +#define LV_EVE_REG_PCLK_POL ((uint32_t) 0x0030206cUL) +#define LV_EVE_REG_PLAY ((uint32_t) 0x0030208cUL) +#define LV_EVE_REG_PLAYBACK_FORMAT ((uint32_t) 0x003020c4UL) +#define LV_EVE_REG_PLAYBACK_FREQ ((uint32_t) 0x003020c0UL) +#define LV_EVE_REG_PLAYBACK_LENGTH ((uint32_t) 0x003020b8UL) +#define LV_EVE_REG_PLAYBACK_LOOP ((uint32_t) 0x003020c8UL) +#define LV_EVE_REG_PLAYBACK_PLAY ((uint32_t) 0x003020ccUL) +#define LV_EVE_REG_PLAYBACK_READPTR ((uint32_t) 0x003020bcUL) +#define LV_EVE_REG_PLAYBACK_START ((uint32_t) 0x003020b4UL) +#define LV_EVE_REG_PWM_DUTY ((uint32_t) 0x003020d4UL) +#define LV_EVE_REG_PWM_HZ ((uint32_t) 0x003020d0UL) +#define LV_EVE_REG_RENDERMODE ((uint32_t) 0x00302010UL) /* only listed in datasheet */ +#define LV_EVE_REG_ROTATE ((uint32_t) 0x00302058UL) +#define LV_EVE_REG_SNAPFORMAT ((uint32_t) 0x0030201cUL) /* only listed in datasheet */ +#define LV_EVE_REG_SNAPSHOT ((uint32_t) 0x00302018UL) /* only listed in datasheet */ +#define LV_EVE_REG_SNAPY ((uint32_t) 0x00302014UL) /* only listed in datasheet */ +#define LV_EVE_REG_SOUND ((uint32_t) 0x00302088UL) +#define LV_EVE_REG_SPI_WIDTH ((uint32_t) 0x00302188UL) /* listed with false offset in programmers guide V1.1 */ +#define LV_EVE_REG_SWIZZLE ((uint32_t) 0x00302064UL) +#define LV_EVE_REG_TAG ((uint32_t) 0x0030207cUL) +#define LV_EVE_REG_TAG_X ((uint32_t) 0x00302074UL) +#define LV_EVE_REG_TAG_Y ((uint32_t) 0x00302078UL) +#define LV_EVE_REG_TAP_CRC ((uint32_t) 0x00302024UL) /* only listed in datasheet */ +#define LV_EVE_REG_TAP_MASK ((uint32_t) 0x00302028UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_ADC_MODE ((uint32_t) 0x00302108UL) +#define LV_EVE_REG_TOUCH_CHARGE ((uint32_t) 0x0030210cUL) +#define LV_EVE_REG_TOUCH_DIRECT_XY ((uint32_t) 0x0030218cUL) +#define LV_EVE_REG_TOUCH_DIRECT_Z1Z2 ((uint32_t) 0x00302190UL) +#define LV_EVE_REG_TOUCH_MODE ((uint32_t) 0x00302104UL) +#define LV_EVE_REG_TOUCH_OVERSAMPLE ((uint32_t) 0x00302114UL) +#define LV_EVE_REG_TOUCH_RAW_XY ((uint32_t) 0x0030211cUL) +#define LV_EVE_REG_TOUCH_RZ ((uint32_t) 0x00302120UL) +#define LV_EVE_REG_TOUCH_RZTHRESH ((uint32_t) 0x00302118UL) +#define LV_EVE_REG_TOUCH_SCREEN_XY ((uint32_t) 0x00302124UL) +#define LV_EVE_REG_TOUCH_SETTLE ((uint32_t) 0x00302110UL) +#define LV_EVE_REG_TOUCH_TAG ((uint32_t) 0x0030212cUL) +#define LV_EVE_REG_TOUCH_TAG1 ((uint32_t) 0x00302134UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG1_XY ((uint32_t) 0x00302130UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG2 ((uint32_t) 0x0030213cUL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG2_XY ((uint32_t) 0x00302138UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG3 ((uint32_t) 0x00302144UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG3_XY ((uint32_t) 0x00302140UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG4 ((uint32_t) 0x0030214cUL)/* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG4_XY ((uint32_t) 0x00302148UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG_XY ((uint32_t) 0x00302128UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_A ((uint32_t) 0x00302150UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_B ((uint32_t) 0x00302154UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_C ((uint32_t) 0x00302158UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_D ((uint32_t) 0x0030215cUL) +#define LV_EVE_REG_TOUCH_TRANSFORM_E ((uint32_t) 0x00302160UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_F ((uint32_t) 0x00302164UL) +#define LV_EVE_REG_TRACKER ((uint32_t) 0x00309000UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_1 ((uint32_t) 0x00309004UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_2 ((uint32_t) 0x00309008UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_3 ((uint32_t) 0x0030900cUL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_4 ((uint32_t) 0x00309010UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRIM ((uint32_t) 0x00302180UL) +#define LV_EVE_REG_VCYCLE ((uint32_t) 0x00302040UL) +#define LV_EVE_REG_VOFFSET ((uint32_t) 0x00302044UL) +#define LV_EVE_REG_VOL_PB ((uint32_t) 0x00302080UL) +#define LV_EVE_REG_VOL_SOUND ((uint32_t) 0x00302084UL) +#define LV_EVE_REG_VSIZE ((uint32_t) 0x00302048UL) +#define LV_EVE_REG_VSYNC0 ((uint32_t) 0x0030204cUL) +#define LV_EVE_REG_VSYNC1 ((uint32_t) 0x00302050UL) + + +/* Macros for static display list generation */ + +//#define LV_EVE_ALPHA_FUNC(func,ref) ((LV_EVE_DL_ALPHA_FUNC) | (((func) & 7UL) << 8U) | ((ref) & 0xFFUL)) +/** + * @brief Set the alpha test function. + * + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_ALPHA_FUNC(uint8_t func, uint8_t ref) +{ + uint32_t const funcv = ((uint32_t) func & 7U) << 8U; + return (LV_EVE_DL_ALPHA_FUNC | funcv | ref); +} + +//#define LV_EVE_BITMAP_HANDLE(handle) ((LV_EVE_DL_BITMAP_HANDLE) | ((handle) & 0x1FUL)) +/** + * @brief Set the bitmap handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_HANDLE(uint8_t handle) +{ + return (LV_EVE_DL_BITMAP_HANDLE | ((handle) & 0x1FUL)); +} + +//#define LV_EVE_BITMAP_LAYOUT(format,linestride,height) ((LV_EVE_DL_BITMAP_LAYOUT) | (((format) & 0x1FUL) << 19U) | (((linestride) & 0x3FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_LAYOUT(uint8_t format, uint16_t linestride, uint16_t height) +{ + uint32_t const formatv = ((uint32_t) format & 0x1FUL) << 19U; + uint32_t const linestridev = ((uint32_t) linestride & 0x3FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (LV_EVE_DL_BITMAP_LAYOUT | formatv | linestridev | heightv); +} + +//#define LV_EVE_BITMAP_SIZE(filter,wrapx,wrapy,width,height) ((LV_EVE_DL_BITMAP_SIZE) | (((filter) & 1UL) << 20U) | (((wrapx) & 1UL) << 19U) | (((wrapy) & 1UL) << 18U) | (((width) & 0x1FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SIZE(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) +{ + uint32_t const filterv = (filter & 0x1UL) << 20U; + uint32_t const wrapxv = (wrapx & 0x1UL) << 19U; + uint32_t const wrapyv = (wrapy & 0x1UL) << 18U; + uint32_t const widthv = (width & 0x1FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (LV_EVE_DL_BITMAP_SIZE | filterv | wrapxv | wrapyv | widthv | heightv); +} + +//#define LV_EVE_BITMAP_LAYOUT_H(linestride,height) ((LV_EVE_DL_BITMAP_LAYOUT_H) | (((((linestride) & 0xC00U) >> 10U)&3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of the source bitmap memory format and layout for the current handle. + * @param linestride 12-bit value specified to BITMAP_LAYOUT + * @param height 11-bit value specified to BITMAP_LAYOUT + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_LAYOUT_H(uint16_t linestride, uint16_t height) +{ + uint32_t const linestridev = (uint32_t)((((linestride & 0xC00U) >> 10U) & 3UL) << 2U); + uint32_t const heightv = (uint32_t)(((height & 0x600U) >> 9U) & 3UL); + return (LV_EVE_DL_BITMAP_LAYOUT_H | linestridev | heightv); +} + +//#define LV_EVE_BITMAP_SIZE_H(width,height) ((LV_EVE_DL_BITMAP_SIZE_H) | (((((width) & 0x600U) >> 9U) & 3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of bitmaps dimension for the current handle. + * @param linestride 11-bit value of bitmap width, the 2 most significant bits are used + * @param height 11-bit value of bitmap width, the 2 most significant bits are used + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SIZE_H(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t)((((width & 0x600U) >> 9U) & 3UL) << 2U); + uint32_t const heightv = (uint32_t)(((height & 0x600U) >> 9U) & 3UL); + return ((LV_EVE_DL_BITMAP_SIZE_H) | widthv | heightv); +} + +//#define LV_EVE_BITMAP_SOURCE(addr) ((LV_EVE_DL_BITMAP_SOURCE) | ((addr) & 0x3FFFFFUL)) +/** + * @brief Set the source address of bitmap data in RAM_G or flash memory. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SOURCE(uint32_t addr) +{ + return (LV_EVE_DL_BITMAP_SOURCE | (addr & 0x3FFFFFUL)); +} + +#if LV_DRAW_EVE_EVE_GENERATION < 3 /* only define these for FT81x */ +//#define LV_EVE_BITMAP_TRANSFORM_A(a) ((LV_EVE_DL_BITMAP_TRANSFORM_A) | ((a) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_A(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_A | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_B(b) ((LV_EVE_DL_BITMAP_TRANSFORM_B) | ((b) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_B(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_B | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_D(d) ((LV_EVE_DL_BITMAP_TRANSFORM_D) | ((d) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_D(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_D | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_E(e) ((LV_EVE_DL_BITMAP_TRANSFORM_E) | ((e) & 0x1FFFFUL)) +/** + * @brief Set he E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_E(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_E | (val & 0x1FFFFUL)); +} + +#endif + +//#define LV_EVE_BITMAP_TRANSFORM_C(c) ((LV_EVE_DL_BITMAP_TRANSFORM_C) | ((c) & 0x1FFFFUL)) +/** + * @brief Set the C coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_C(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_C | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_F(f) ((LV_EVE_DL_BITMAP_TRANSFORM_F) | ((f) & 0x1FFFFUL)) +/** + * @brief Set the F coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_F(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_F | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BLEND_FUNC(src,dst) ((LV_EVE_DL_BLEND_FUNC) | (((src) & 7UL) << 3U) | ((dst) & 7UL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BLEND_FUNC(uint8_t src, uint8_t dst) +{ + uint32_t const srcv = (uint32_t)((src & 7UL) << 3U); + uint32_t const dstv = (uint32_t)(dst & 7UL); + return (LV_EVE_DL_BLEND_FUNC | srcv | dstv); +} + +//#define LV_EVE_CALL(dest) ((LV_EVE_DL_CALL) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CALL(uint16_t dest) +{ + return (LV_EVE_DL_CALL | (dest & 0x7FFUL)); +} + +//#define LV_EVE_JUMP(dest) ((LV_EVE_DL_JUMP) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_JUMP(uint16_t dest) +{ + return (LV_EVE_DL_JUMP | (dest & 0x7FFUL)); +} + +//#define LV_EVE_CELL(cell) ((LV_EVE_DL_CELL) | ((cell) & 0x7FUL)) +/** + * @brief Set the bitmap cell number for the VERTEX2F command. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CELL(uint8_t cell) +{ + return (LV_EVE_DL_CELL | (cell & 0x7FUL)); +} + +//#define LV_EVE_CLEAR(c,s,t) ((LV_EVE_DL_CLEAR) | (((c) & 1UL) << 2U) | (((s) & 1UL) << 1U) | ((t) & 1UL)) +/** + * @brief Clear buffers to preset values. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR(uint8_t color, uint8_t stencil, uint8_t tag) +{ + uint32_t const colorv = (color & 1UL) << 2U; + uint32_t const stencilv = (stencil & 1UL) << 1U; + uint32_t const tagv = (tag & 1UL); + return (LV_EVE_DL_CLEAR | colorv | stencilv | tagv); +} + +//#define LV_EVE_CLEAR_COLOR_A(alpha) ((LV_EVE_DL_CLEAR_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set clear value for the alpha channel. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_COLOR_A(uint8_t alpha) +{ + return (LV_EVE_DL_CLEAR_COLOR_A | alpha); +} + +//#define LV_EVE_CLEAR_COLOR_RGB(red,green,blue) ((LV_EVE_DL_CLEAR_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set clear values for red, green and blue channels. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (LV_EVE_DL_CLEAR_COLOR_RGB | redv | greenv | bluev); +} + +//#define LV_EVE_CLEAR_STENCIL(s) ((LV_EVE_DL_CLEAR_STENCIL) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the stencil buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_STENCIL(uint8_t val) +{ + return (LV_EVE_DL_CLEAR_STENCIL | val); +} + +//#define LV_EVE_CLEAR_TAG(s) ((LV_EVE_DL_CLEAR_TAG) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_TAG(uint8_t val) +{ + return (LV_EVE_DL_CLEAR_TAG | val); +} + +//#define LV_EVE_COLOR_A(alpha) ((LV_EVE_DL_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set the current color alpha. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_COLOR_A(uint8_t alpha) +{ + return (LV_EVE_DL_COLOR_A | alpha); +} + +//#define LV_EVE_COLOR_MASK(r,g,b,a) ((LV_EVE_DL_COLOR_MASK) | (((r) & 1UL) << 3U) | (((g) & 1UL) << 2U) | (((b) & 1UL) << 1U) | ((a) & 1UL)) +/** + * @brief Enable or disable writing of color components. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_COLOR_MASK(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 1UL) << 3U); + uint32_t const greenv = ((green & 1UL) << 2U); + uint32_t const bluev = ((blue & 1UL) << 1U); + uint32_t const alphav = (alpha & 1UL); + return (LV_EVE_DL_COLOR_MASK | redv | greenv | bluev | alphav); +} + +//#define LV_EVE_COLOR_RGB(red,green,blue) ((LV_EVE_DL_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set the current color red, green and blue. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (LV_EVE_DL_COLOR_RGB | redv | greenv | bluev); +} + +//#define LV_EVE_LINE_WIDTH(width) ((LV_EVE_DL_LINE_WIDTH) | (((uint32_t) (width)) & 0xFFFUL)) +/** + * @brief Set the width of lines to be drawn with primitive LINES in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_LINE_WIDTH(uint16_t width) +{ + return (LV_EVE_DL_LINE_WIDTH | (width & 0xFFFUL)); +} + +//#define LV_EVE_MACRO(m) ((LV_EVE_DL_MACRO) | ((m) & 1UL)) +/** + * @brief Execute a single command from a macro register. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_MACRO(uint8_t macro) +{ + return (LV_EVE_DL_MACRO | (macro & 0x1UL)); +} + +//#define LV_EVE_PALETTE_SOURCE(addr) ((LV_EVE_DL_PALETTE_SOURCE) | ((addr) & 0x3FFFFF3UL)) +/** + * @brief Set the base address of the palette. + * @note 2-byte alignment is required if pixel format is PALETTE4444 or PALETTE565. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_PALETTE_SOURCE(uint32_t addr) +{ + return (LV_EVE_DL_PALETTE_SOURCE | (addr & 0x3FFFFFUL)); +} + +//#define LV_EVE_POINT_SIZE(size) ((LV_EVE_DL_POINT_SIZE) | ((size) & 0x1FFFUL)) +/** + * @brief Set the radius of points to be drawn with primitive POINTS in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_POINT_SIZE(uint16_t size) +{ + return (LV_EVE_DL_POINT_SIZE | (size & 0x1FFFUL)); +} + +//#define LV_EVE_SCISSOR_SIZE(width,height) ((LV_EVE_DL_SCISSOR_SIZE) | (((width) & 0xFFFUL) << 12U) | ((height) & 0xFFFUL)) +/** + * @brief Set the size of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2048 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_SCISSOR_SIZE(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t)((width & 0xFFFUL) << 12U); + uint32_t const heightv = (uint32_t)(height & 0xFFFUL); + return (LV_EVE_DL_SCISSOR_SIZE | widthv | heightv); +} + +//#define LV_EVE_SCISSOR_XY(x,y) ((LV_EVE_DL_SCISSOR_XY) | (((x) & 0x7FFUL) << 11U) | ((y) & 0x7FFUL)) +/** + * @brief Set the top left corner of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_SCISSOR_XY(uint16_t xc0, uint16_t yc0) +{ + uint32_t const xc0v = (uint32_t)((xc0 & 0x7FFUL) << 11U); + uint32_t const yc0v = (uint32_t)(yc0 & 0x7FFUL); + return (LV_EVE_DL_SCISSOR_XY | xc0v | yc0v); +} + +//#define LV_EVE_STENCIL_FUNC(func,ref,mask) ((LV_EVE_DL_STENCIL_FUNC) | (((func) & 7UL) << 16U) | (((ref) & 0xFFUL) << 8U)|((mask) & 0xFFUL)) +/** + * @brief Set function and reference value for stencil testing. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_STENCIL_FUNC(uint8_t func, uint8_t ref, uint8_t mask) +{ + uint32_t const funcv = (uint32_t)((func & 7UL) << 16U); + uint32_t const refv = (uint32_t)((ref & 0xFFUL) << 8U); + uint32_t const maskv = (uint32_t)(mask & 0xFFUL); + return (LV_EVE_DL_STENCIL_FUNC | funcv | refv | maskv); +} + +//#define LV_EVE_STENCIL_MASK(mask) ((LV_EVE_DL_STENCIL_MASK) | ((mask) & 0xFFUL)) +/** + * @brief Control the writing of individual bits in the stencil planes. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_STENCIL_MASK(uint8_t mask) +{ + return (LV_EVE_DL_STENCIL_MASK | mask); +} + +//#define LV_EVE_STENCIL_OP(sfail,spass) ((LV_EVE_DL_STENCIL_OP) | (((sfail) & 7UL) << 3U) | ((spass) & 7UL)) +/** + * @brief Set stencil test actions. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_STENCIL_OP(uint8_t sfail, uint8_t spass) +{ + uint32_t const sfailv = (uint32_t)((sfail & 0x07UL) << 3U); + uint32_t const spassv = (uint32_t)(spass & 0x07UL); + return (LV_EVE_DL_STENCIL_OP | sfailv | spassv); +} + +//#define LV_EVE_TAG(s) ((LV_EVE_DL_TAG) | ((s) & 0xFFUL)) +/** + * @brief Attach the tag value for the following graphics objects drawn on the screen. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_TAG(uint8_t tagval) +{ + return (LV_EVE_DL_TAG | tagval); +} + +//#define LV_EVE_TAG_MASK(mask) ((LV_EVE_DL_TAG_MASK) | ((mask) & 1UL)) +/** + * @brief Control the writing of the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_TAG_MASK(uint8_t mask) +{ + return (LV_EVE_DL_TAG_MASK | ((mask) & 1UL)); +} + +//#define LV_EVE_VERTEX2F(x,y) ((LV_EVE_DL_VERTEX2F) | ((((uint32_t) (x)) & 0x7FFFUL) << 15U) | (((uint32_t) (y)) & 0x7FFFUL)) +/** + * @brief Set coordinates for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX2F(int16_t xc0, int16_t yc0) +{ + uint32_t const xc0v = ((((uint32_t)((uint16_t) xc0)) & 0x7FFFUL) << 15U); + uint32_t const yc0v = (((uint32_t)((uint16_t) yc0)) & 0x7FFFUL); + return (LV_EVE_DL_VERTEX2F | xc0v | yc0v); +} + +//#define LV_EVE_VERTEX2II(x,y,handle,cell) ((LV_EVE_DL_VERTEX2II) | (((x) & 0x1FFUL) << 21U) | (((y) & 0x1FFUL) << 12U) | (((handle) & 0x1FUL) << 7U) | ((cell) & 0x7FUL)) +/** + * @brief Set coordinates, bitmap-handle and cell-number for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX2II(uint16_t xc0, uint16_t yc0, uint8_t handle, uint8_t cell) +{ + uint32_t const xc0v = ((((uint32_t) xc0) & 0x1FFUL) << 21U); + uint32_t const yc0v = ((((uint32_t) yc0) & 0x1FFUL) << 12U); + uint32_t const handlev = ((((uint32_t) handle) & 0x1FUL) << 7U); + uint32_t const cellv = (((uint32_t) cell) & 0x7FUL); + return (LV_EVE_DL_VERTEX2II | xc0v | yc0v | handlev | cellv); +} + +//#define LV_EVE_VERTEX_FORMAT(frac) ((LV_EVE_DL_VERTEX_FORMAT) | ((frac) & 7UL)) +/** + * @brief Set the precision of VERTEX2F coordinates. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX_FORMAT(uint8_t frac) +{ + return (LV_EVE_DL_VERTEX_FORMAT | ((frac) & 7UL)); +} + +//#define LV_EVE_VERTEX_TRANSLATE_X(x) ((LV_EVE_DL_VERTEX_TRANSLATE_X) | ((x) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations X translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX_TRANSLATE_X(int32_t xco) +{ + return (LV_EVE_DL_VERTEX_TRANSLATE_X | (((uint32_t) xco) & 0x1FFFFUL)); +} + +//#define LV_EVE_VERTEX_TRANSLATE_Y(y) ((LV_EVE_DL_VERTEX_TRANSLATE_Y) | ((y) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations Y translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX_TRANSLATE_Y(int32_t yco) +{ + return (LV_EVE_DL_VERTEX_TRANSLATE_Y | (((uint32_t) yco) & 0x1FFFFUL)); +} + +/* #define LV_EVE_BEGIN(prim) ((LV_EVE_DL_BEGIN) | ((prim) & 15UL)) */ /* use define LV_EVE_DL_BEGIN */ +/* #define LV_EVE_DISPLAY() ((LV_EVE_DL_DISPLAY)) */ /* use define LV_EVE_DL_DISPLAY */ +/* #define LV_EVE_END() ((LV_EVE_DL_END)) */ /* use define LV_EVE_DL_END */ +/* #define LV_EVE_RESTORE_CONTEXT() ((LV_EVE_DL_RESTORE_CONTEXT)) */ /* use define LV_EVE_DL_RESTORE_CONTEXT */ +/* #define LV_EVE_RETURN() ((LV_EVE_DL_RETURN)) */ /* use define LV_EVE_DL_RETURN */ +/* #define LV_EVE_SAVE_CONTEXT() ((LV_EVE_DL_SAVE_CONTEXT)) */ /* use define LV_EVE_DL_SAVE_CONTEXT */ +/* #define LV_EVE_NOP() ((LV_EVE_DL_NOP)) */ + +/* ########## EVE Generation 3: BT815 / BT816 definitions ########## */ + +#if LV_DRAW_EVE_EVE_GENERATION > 2 + +#define LV_EVE_EVE_GLFORMAT ((uint32_t) 31UL) /* used with BITMAP_LAYOUT to indicate bitmap-format is specified by BITMAP_EXT_FORMAT */ + +#define LV_EVE_DL_BITMAP_EXT_FORMAT ((uint32_t) 0x2E000000UL) /* requires OR'd arguments */ +#define LV_EVE_DL_BITMAP_SWIZZLE ((uint32_t) 0x2F000000UL) +/* #define LV_EVE_DL_INT_FRR ((uint32_t) 0x30000000UL) */ /* ESE displays "Internal: flash read result" - undocumented display list command */ + +/* Extended Bitmap formats */ +#define LV_EVE_EVE_ASTC_4X4 ((uint32_t) 37808UL) +#define LV_EVE_EVE_ASTC_5X4 ((uint32_t) 37809UL) +#define LV_EVE_EVE_ASTC_5X5 ((uint32_t) 37810UL) +#define LV_EVE_EVE_ASTC_6X5 ((uint32_t) 37811UL) +#define LV_EVE_EVE_ASTC_6X6 ((uint32_t) 37812UL) +#define LV_EVE_EVE_ASTC_8X5 ((uint32_t) 37813UL) +#define LV_EVE_EVE_ASTC_8X6 ((uint32_t) 37814UL) +#define LV_EVE_EVE_ASTC_8X8 ((uint32_t) 37815UL) +#define LV_EVE_EVE_ASTC_10X5 ((uint32_t) 37816UL) +#define LV_EVE_EVE_ASTC_10X6 ((uint32_t) 37817UL) +#define LV_EVE_EVE_ASTC_10X8 ((uint32_t) 37818UL) +#define LV_EVE_EVE_ASTC_10X10 ((uint32_t) 37819UL) +#define LV_EVE_EVE_ASTC_12X10 ((uint32_t) 37820UL) +#define LV_EVE_EVE_ASTC_12X12 ((uint32_t) 37821UL) + +#define LV_EVE_EVE_RAM_ERR_REPORT ((uint32_t) 0x309800UL) /* max 128 bytes null terminated string */ +#define LV_EVE_EVE_RAM_FLASH ((uint32_t) 0x800000UL) +#define LV_EVE_EVE_RAM_FLASH_POSTBLOB ((uint32_t) 0x801000UL) + +#define LV_EVE_EVE_OPT_FLASH ((uint16_t) 64U) +#define LV_EVE_EVE_OPT_OVERLAY ((uint16_t) 128U) +#define LV_EVE_EVE_OPT_FORMAT ((uint16_t) 4096U) +#define LV_EVE_EVE_OPT_FILL ((uint16_t) 8192U) + +/* Commands for BT815 / BT816 */ +#define LV_EVE_CMD_BITMAP_TRANSFORM ((uint32_t) 0xFFFFFF21UL) +#define LV_EVE_CMD_SYNC ((uint32_t) 0xFFFFFF42UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_SYNC) */ +#define LV_EVE_CMD_FLASHERASE ((uint32_t) 0xFFFFFF44UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHERASE) */ +#define LV_EVE_CMD_FLASHWRITE ((uint32_t) 0xFFFFFF45UL) +#define LV_EVE_CMD_FLASHREAD ((uint32_t) 0xFFFFFF46UL) +#define LV_EVE_CMD_FLASHUPDATE ((uint32_t) 0xFFFFFF47UL) +#define LV_EVE_CMD_FLASHDETACH ((uint32_t) 0xFFFFFF48UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHDETACH) */ +#define LV_EVE_CMD_FLASHATTACH ((uint32_t) 0xFFFFFF49UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHATTACH) */ +#define LV_EVE_CMD_FLASHFAST ((uint32_t) 0xFFFFFF4AUL) +#define LV_EVE_CMD_FLASHSPIDESEL ((uint32_t) 0xFFFFFF4BUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHSPIDESEL) */ +#define LV_EVE_CMD_FLASHSPITX ((uint32_t) 0xFFFFFF4CUL) +#define LV_EVE_CMD_FLASHSPIRX ((uint32_t) 0xFFFFFF4DUL) +#define LV_EVE_CMD_FLASHSOURCE ((uint32_t) 0xFFFFFF4EUL) +#define LV_EVE_CMD_CLEARCACHE ((uint32_t) 0xFFFFFF4FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_CLEARCACHE) */ +#define LV_EVE_CMD_INFLATE2 ((uint32_t) 0xFFFFFF50UL) +#define LV_EVE_CMD_ROTATEAROUND ((uint32_t) 0xFFFFFF51UL) +#define LV_EVE_CMD_RESETFONTS ((uint32_t) 0xFFFFFF52UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RESETFONTS) */ +#define LV_EVE_CMD_ANIMSTART ((uint32_t) 0xFFFFFF53UL) +#define LV_EVE_CMD_ANIMSTOP ((uint32_t) 0xFFFFFF54UL) +#define LV_EVE_CMD_ANIMXY ((uint32_t) 0xFFFFFF55UL) +#define LV_EVE_CMD_ANIMDRAW ((uint32_t) 0xFFFFFF56UL) +#define LV_EVE_CMD_GRADIENTA ((uint32_t) 0xFFFFFF57UL) +#define LV_EVE_CMD_FILLWIDTH ((uint32_t) 0xFFFFFF58UL) +#define LV_EVE_CMD_APPENDF ((uint32_t) 0xFFFFFF59UL) +#define LV_EVE_CMD_ANIMFRAME ((uint32_t) 0xFFFFFF5AUL) +#define LV_EVE_CMD_VIDEOSTARTF ((uint32_t) 0xFFFFFF5FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_VIDEOSTARTF) */ + +/* Registers for BT815 / BT816 */ +#define LV_EVE_REG_ADAPTIVE_FRAMERATE ((uint32_t) 0x0030257cUL) +#define LV_EVE_REG_PLAYBACK_PAUSE ((uint32_t) 0x003025ecUL) +#define LV_EVE_REG_FLASH_STATUS ((uint32_t) 0x003025f0UL) +#define LV_EVE_REG_FLASH_SIZE ((uint32_t) 0x00309024UL) +#define LV_EVE_REG_PLAY_CONTROL ((uint32_t) 0x0030914eUL) +#define LV_EVE_REG_COPRO_PATCH_PTR ((uint32_t) 0x00309162UL) + +/* Macros for BT815 / BT816 */ + +//#define LV_EVE_BITMAP_EXT_FORMAT(format) ((LV_EVE_DL_BITMAP_EXT_FORMAT) | ((format) & 0xFFFFUL)) +/** + * @brief Set the extended format of the bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_EXT_FORMAT(uint16_t format) +{ + return (LV_EVE_DL_BITMAP_EXT_FORMAT | format); +} + +//#define LV_EVE_BITMAP_SWIZZLE(r,g,b,a) ((LV_EVE_DL_BITMAP_SWIZZLE) | (((r) & 7UL) << 9U) | (((g) & 7UL) << 6U) | (((b) & 7UL) << 3U) | ((a) & 7UL)) +/** + * @brief Set the source for the red, green, blue and alpha channels of a bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SWIZZLE(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 7UL) << 9U); + uint32_t const greenv = ((green & 7UL) << 6U); + uint32_t const bluev = ((blue & 7UL) << 3U); + uint32_t const alphav = (alpha & 7UL); + return (LV_EVE_DL_BITMAP_SWIZZLE | redv | greenv | bluev | alphav); +} + +//#define LV_EVE_BITMAP_TRANSFORM_A_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_A) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_A(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_A | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_B_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_B) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_B(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_B | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_D_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_D) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_D(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_D | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_E_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_E) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_E(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_E | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_A(a) LV_EVE_BITMAP_TRANSFORM_A_EXT(0UL,(a)) +//#define LV_EVE_BITMAP_TRANSFORM_B(b) LV_EVE_BITMAP_TRANSFORM_B_EXT(0UL,(b)) +//#define LV_EVE_BITMAP_TRANSFORM_D(d) LV_EVE_BITMAP_TRANSFORM_D_EXT(0UL,(d)) +//#define LV_EVE_BITMAP_TRANSFORM_E(e) LV_EVE_BITMAP_TRANSFORM_E_EXT(0UL,(e)) + +#endif /* LV_DRAW_EVE_EVE_GENERATION > 2 */ + +/* ########## EVE Generation 4: BT817 / BT818 definitions ########## */ + +#if LV_DRAW_EVE_EVE_GENERATION > 3 + +/* Commands for BT817 / BT818 */ +#define LV_EVE_CMD_ANIMFRAMERAM ((uint32_t) 0xFFFFFF6DUL) +#define LV_EVE_CMD_ANIMSTARTRAM ((uint32_t) 0xFFFFFF6EUL) +#define LV_EVE_CMD_APILEVEL ((uint32_t) 0xFFFFFF63UL) +#define LV_EVE_CMD_CALIBRATESUB ((uint32_t) 0xFFFFFF60UL) +#define LV_EVE_CMD_CALLLIST ((uint32_t) 0xFFFFFF67UL) +#define LV_EVE_CMD_ENDLIST ((uint32_t) 0xFFFFFF69UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_ENDLIST) */ +#define LV_EVE_CMD_FLASHPROGRAM ((uint32_t) 0xFFFFFF70UL) +#define LV_EVE_CMD_FONTCACHE ((uint32_t) 0xFFFFFF6BUL) +#define LV_EVE_CMD_FONTCACHEQUERY ((uint32_t) 0xFFFFFF6CUL) +#define LV_EVE_CMD_GETIMAGE ((uint32_t) 0xFFFFFF64UL) +#define LV_EVE_CMD_HSF ((uint32_t) 0xFFFFFF62UL) +#define LV_EVE_CMD_LINETIME ((uint32_t) 0xFFFFFF5EUL) +#define LV_EVE_CMD_NEWLIST ((uint32_t) 0xFFFFFF68UL) +#define LV_EVE_CMD_PCLKFREQ ((uint32_t) 0xFFFFFF6AUL) +#define LV_EVE_CMD_RETURN ((uint32_t) 0xFFFFFF66UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RETURN) */ +#define LV_EVE_CMD_RUNANIM ((uint32_t) 0xFFFFFF6FUL) +#define LV_EVE_CMD_TESTCARD ((uint32_t) 0xFFFFFF61UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_TESTCARD) */ +#define LV_EVE_CMD_WAIT ((uint32_t) 0xFFFFFF65UL) + +/* Registers for BT817 / BT818 */ +#define LV_EVE_REG_UNDERRUN ((uint32_t) 0x0030260cUL) +#define LV_EVE_REG_AH_HCYCLE_MAX ((uint32_t) 0x00302610UL) +#define LV_EVE_REG_PCLK_FREQ ((uint32_t) 0x00302614UL) +#define LV_EVE_REG_PCLK_2X ((uint32_t) 0x00302618UL) +#define LV_EVE_REG_ANIM_ACTIVE ((uint32_t) 0x0030902CUL) + +#endif /* LV_DRAW_EVE_EVE_GENERATION > 3 */ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_EVE_DISPLAY_DEFINES_H*/ diff --git a/src/drivers/lv_drivers.h b/src/drivers/lv_drivers.h index 0850108132..fb5b240082 100644 --- a/src/drivers/lv_drivers.h +++ b/src/drivers/lv_drivers.h @@ -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" diff --git a/src/libs/FT800-FT813/EVE.h b/src/libs/FT800-FT813/EVE.h new file mode 100644 index 0000000000..ebce3687f7 --- /dev/null +++ b/src/libs/FT800-FT813/EVE.h @@ -0,0 +1,1257 @@ +/* +@file EVE.h +@brief Contains FT80x/FT81x/BT81x API definitions +@version 5.0 +@date 2024-01-28 +@author Rudolph Riedel + +@section LICENSE + +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. + +@section History + +5.0 +- started to add BT817 / BT818 defines +- cleanup: removed FT80x defines +- replaced BT81X_ENABLE with "EVE_GEN > 2" +- removed FT81X_ENABLE as FT81x already is the lowest supported chip revision now +- added more BT817 / BT818 defines +- removed undocumented registers and commands +- merged FT80x and FT81x definitions as FT81x is baseline now +- removed the history from before 4.0 +- fixed typo: REG_AH_CYCLE_MAX -> REG_AH_HCYCLE_MAX +- re-arranged the host commands, removed EVE_CLKINT for BT817/BT818, + removed FT80x EVE_CLK36M and EVE_CLK48M +- added EVE_OPT_OVERLAY +- removed the 4.0 history +- fixed some MISRA-C issues +- removed macro BEGIN(prim) - use (DL_BEGIN | EVE_BITMAPS) for example +- removed macro END() - use define DL_END +- removed macro RESTORE_CONTEXT() - use define DL_RESTORE_CONTEXT +- removed macro RETURN() - use define DL_RETURN +- removed macro SAVE_CONTEXT() - use define DL_SAVE_CONTEXT +- basic maintenance: checked for violations of white space and indent rules +- more linter fixes +- changed EVE_COMPRESSED_RGBA_ASTC_nxn_KHR to EVE_ASTC_nXn to fix linter + warnings and used the opportunity to make these shorter +- added DL_COLOR_A as alternative to the COLOR_A macro +- added defines for all DL_ display list commands +- cleaned up the macros +- fix: changed DL_CLEAR_RGB to DL_CLEAR_COLOR_RGB + as this is what the programming guide uses +- fix: renamed EVE_ROM_FONT_ADDR to EVE_ROM_FONTROOT +- added #ifdef __cplusplus / extern "C" to allow + adding EVE_ functions to C++ code +- fix: typo REG_COPRO_PATCH_DTR -> REG_COPRO_PATCH_PTR +- started to convert the function-like macros to static inline functions to be + a little friendlier towards C++ in regards of type-safety +- added type-casts to all simple macros +- converted some more function-like macros to static inline functions +- converted the rest of the function-like macros to static inline functions +- fix: forgot to comment out the EVE2 BITMAP_TRANSFORM_E when converting it to an inline function + +*/ + +#ifndef EVE_H +#define EVE_H + +#include "EVE_target.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "EVE_config.h" +#include "EVE_commands.h" + +/* Memory */ +#define EVE_RAM_G ((uint32_t) 0x00000000UL) +#define EVE_ROM_CHIPID ((uint32_t) 0x000C0000UL) +#define EVE_ROM_FONT ((uint32_t) 0x001E0000UL) +#define EVE_ROM_FONTROOT ((uint32_t) 0x002FFFFCUL) +#define EVE_RAM_DL ((uint32_t) 0x00300000UL) +#define EVE_RAM_REG ((uint32_t) 0x00302000UL) +#define EVE_RAM_CMD ((uint32_t) 0x00308000UL) + +/* Memory buffer sizes */ +#define EVE_RAM_G_SIZE ((uint32_t) 1024U*1024UL) +#define EVE_CMDFIFO_SIZE ((uint32_t) 4U*1024UL) +#define EVE_RAM_DL_SIZE ((uint32_t) 8U*1024UL) + +/* diplay list list commands, most need OR's arguments */ +#define DL_DISPLAY ((uint32_t) 0x00000000UL) +#define DL_BITMAP_SOURCE ((uint32_t) 0x01000000UL) +#define DL_CLEAR_COLOR_RGB ((uint32_t) 0x02000000UL) +#define DL_TAG ((uint32_t) 0x03000000UL) +#define DL_COLOR_RGB ((uint32_t) 0x04000000UL) +#define DL_BITMAP_HANDLE ((uint32_t) 0x05000000UL) +#define DL_CELL ((uint32_t) 0x06000000UL) +#define DL_BITMAP_LAYOUT ((uint32_t) 0x07000000UL) +#define DL_BITMAP_SIZE ((uint32_t) 0x08000000UL) +#define DL_ALPHA_FUNC ((uint32_t) 0x09000000UL) +#define DL_STENCIL_FUNC ((uint32_t) 0x0A000000UL) +#define DL_BLEND_FUNC ((uint32_t) 0x0B000000UL) +#define DL_STENCIL_OP ((uint32_t) 0x0C000000UL) +#define DL_POINT_SIZE ((uint32_t) 0x0D000000UL) +#define DL_LINE_WIDTH ((uint32_t) 0x0E000000UL) +#define DL_CLEAR_COLOR_A ((uint32_t) 0x0F000000UL) +#define DL_COLOR_A ((uint32_t) 0x10000000UL) +#define DL_CLEAR_STENCIL ((uint32_t) 0x11000000UL) +#define DL_CLEAR_TAG ((uint32_t) 0x12000000UL) +#define DL_STENCIL_MASK ((uint32_t) 0x13000000UL) +#define DL_TAG_MASK ((uint32_t) 0x14000000UL) +#define DL_BITMAP_TRANSFORM_A ((uint32_t) 0x15000000UL) +#define DL_BITMAP_TRANSFORM_B ((uint32_t) 0x16000000UL) +#define DL_BITMAP_TRANSFORM_C ((uint32_t) 0x17000000UL) +#define DL_BITMAP_TRANSFORM_D ((uint32_t) 0x18000000UL) +#define DL_BITMAP_TRANSFORM_E ((uint32_t) 0x19000000UL) +#define DL_BITMAP_TRANSFORM_F ((uint32_t) 0x1A000000UL) +#define DL_SCISSOR_XY ((uint32_t) 0x1B000000UL) +#define DL_SCISSOR_SIZE ((uint32_t) 0x1C000000UL) +#define DL_CALL ((uint32_t) 0x1D000000UL) +#define DL_JUMP ((uint32_t) 0x1E000000UL) +#define DL_BEGIN ((uint32_t) 0x1F000000UL) +#define DL_COLOR_MASK ((uint32_t) 0x20000000UL) +#define DL_END ((uint32_t) 0x21000000UL) +#define DL_SAVE_CONTEXT ((uint32_t) 0x22000000UL) +#define DL_RESTORE_CONTEXT ((uint32_t) 0x23000000UL) +#define DL_RETURN ((uint32_t) 0x24000000UL) +#define DL_MACRO ((uint32_t) 0x25000000UL) +#define DL_CLEAR ((uint32_t) 0x26000000UL) +#define DL_VERTEX_FORMAT ((uint32_t) 0x27000000UL) +#define DL_BITMAP_LAYOUT_H ((uint32_t) 0x28000000UL) +#define DL_BITMAP_SIZE_H ((uint32_t) 0x29000000UL) +#define DL_PALETTE_SOURCE ((uint32_t) 0x2A000000UL) +#define DL_VERTEX_TRANSLATE_X ((uint32_t) 0x2B000000UL) +#define DL_VERTEX_TRANSLATE_Y ((uint32_t) 0x2C000000UL) +#define DL_NOP ((uint32_t) 0x2D000000UL) + +#define DL_VERTEX2F ((uint32_t) 0x40000000UL) +#define DL_VERTEX2II ((uint32_t) 0x80000000UL) + +#define CLR_COL ((uint8_t) 0x4U) +#define CLR_STN ((uint8_t) 0x2U) +#define CLR_TAG ((uint8_t) 0x1U) + +/* Host commands */ +#define EVE_ACTIVE ((uint8_t) 0x00U) /* place EVE in active state */ +#define EVE_STANDBY ((uint8_t) 0x41U) /* place EVE in Standby (clk running) */ +#define EVE_SLEEP ((uint8_t) 0x42U) /* place EVE in Sleep (clk off) */ +#define EVE_CLKEXT ((uint8_t) 0x44U) /* select external clock source */ +#define EVE_CLKINT ((uint8_t) 0x48U) /* select internal clock source, not a valid option for BT817 / BT818 */ +#define EVE_PWRDOWN ((uint8_t) 0x50U) /* place EVE in Power Down (core off) */ +#define EVE_CLKSEL ((uint8_t) 0x61U) /* configure system clock */ +#define EVE_RST_PULSE ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define EVE_CORERST ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define EVE_PINDRIVE ((uint8_t) 0x70U) /* setup drive strength for various pins */ +#define EVE_PIN_PD_STATE ((uint8_t) 0x71U) /* setup how pins behave during power down */ + +/* Graphic command defines */ +#define EVE_NEVER ((uint8_t) 0UL) +#define EVE_LESS ((uint8_t) 1UL) +#define EVE_LEQUAL ((uint8_t) 2UL) +#define EVE_GREATER ((uint8_t) 3UL) +#define EVE_GEQUAL ((uint8_t) 4UL) +#define EVE_EQUAL ((uint8_t) 5UL) +#define EVE_NOTEQUAL ((uint8_t) 6UL) +#define EVE_ALWAYS ((uint8_t) 7UL) + +/* Bitmap formats */ +#define EVE_ARGB1555 ((uint8_t) 0UL) +#define EVE_L1 ((uint8_t) 1UL) +#define EVE_L4 ((uint8_t) 2UL) +#define EVE_L8 ((uint8_t) 3UL) +#define EVE_RGB332 ((uint8_t) 4UL) +#define EVE_ARGB2 ((uint8_t) 5UL) +#define EVE_ARGB4 ((uint8_t) 6UL) +#define EVE_RGB565 ((uint8_t) 7UL) +#define EVE_PALETTED ((uint8_t) 8UL) +#define EVE_TEXT8X8 ((uint8_t) 9UL) +#define EVE_TEXTVGA ((uint8_t) 10UL) +#define EVE_BARGRAPH ((uint8_t) 11UL) + +/* Bitmap filter types */ +#define EVE_NEAREST ((uint8_t) 0UL) +#define EVE_BILINEAR ((uint8_t) 1UL) + +/* Bitmap wrap types */ +#define EVE_BORDER ((uint8_t) 0UL) +#define EVE_REPEAT ((uint8_t) 1UL) + +/* Stencil defines */ +#define EVE_KEEP ((uint8_t) 1UL) +#define EVE_REPLACE ((uint8_t) 2UL) +#define EVE_INCR ((uint8_t) 3UL) +#define EVE_DECR ((uint8_t) 4UL) +#define EVE_INVERT ((uint8_t) 5UL) + +/* Graphics display list swap defines */ +#define EVE_DLSWAP_DONE ((uint8_t) 0UL) +#define EVE_DLSWAP_LINE ((uint8_t) 1UL) +#define EVE_DLSWAP_FRAME ((uint8_t) 2UL) + +/* Interrupt bits */ +#define EVE_INT_SWAP ((uint8_t) 0x01) +#define EVE_INT_TOUCH ((uint8_t) 0x02) +#define EVE_INT_TAG ((uint8_t) 0x04) +#define EVE_INT_SOUND ((uint8_t) 0x08) +#define EVE_INT_PLAYBACK ((uint8_t) 0x10) +#define EVE_INT_CMDEMPTY ((uint8_t) 0x20) +#define EVE_INT_CMDFLAG ((uint8_t) 0x40) +#define EVE_INT_CONVCOMPLETE ((uint8_t) 0x80) + +/* Touch mode */ +#define EVE_TMODE_OFF ((uint8_t) 0U) +#define EVE_TMODE_ONESHOT ((uint8_t) 1U) +#define EVE_TMODE_FRAME ((uint8_t) 2U) +#define EVE_TMODE_CONTINUOUS ((uint8_t) 3U) + +/* Alpha blending */ +#define EVE_ZERO ((uint32_t) 0UL) +#define EVE_ONE ((uint32_t) 1UL) +#define EVE_SRC_ALPHA ((uint32_t) 2UL) +#define EVE_DST_ALPHA ((uint32_t) 3UL) +#define EVE_ONE_MINUS_SRC_ALPHA ((uint32_t) 4UL) +#define EVE_ONE_MINUS_DST_ALPHA ((uint32_t) 5UL) + +/* Graphics primitives */ +#define EVE_BITMAPS ((uint32_t) 1UL) +#define EVE_POINTS ((uint32_t) 2UL) +#define EVE_LINES ((uint32_t) 3UL) +#define EVE_LINE_STRIP ((uint32_t) 4UL) +#define EVE_EDGE_STRIP_R ((uint32_t) 5UL) +#define EVE_EDGE_STRIP_L ((uint32_t) 6UL) +#define EVE_EDGE_STRIP_A ((uint32_t) 7UL) +#define EVE_EDGE_STRIP_B ((uint32_t) 8UL) +#define EVE_RECTS ((uint32_t) 9UL) +#define EVE_INT_G8 ((uint32_t) 18UL) +#define EVE_INT_L8C ((uint32_t) 12UL) +#define EVE_INT_VGA ((uint32_t) 13UL) +#define EVE_PALETTED565 ((uint32_t) 14UL) +#define EVE_PALETTED4444 ((uint32_t) 15UL) +#define EVE_PALETTED8 ((uint32_t) 16UL) +#define EVE_L2 ((uint32_t) 17UL) + +/* Widget command options */ +#define EVE_OPT_MONO ((uint16_t) 1U) +#define EVE_OPT_NODL ((uint16_t) 2U) +#define EVE_OPT_FLAT ((uint16_t) 256U) +#define EVE_OPT_CENTERX ((uint16_t) 512U) +#define EVE_OPT_CENTERY ((uint16_t) 1024U) +#define EVE_OPT_CENTER (EVE_OPT_CENTERX | EVE_OPT_CENTERY) +#define EVE_OPT_NOBACK ((uint16_t) 4096U) +#define EVE_OPT_NOTICKS ((uint16_t) 8192U) +#define EVE_OPT_NOHM ((uint16_t) 16384U) +#define EVE_OPT_NOPOINTER ((uint16_t) 16384U) +#define EVE_OPT_NOSECS ((uint16_t) 32768U) +#define EVE_OPT_NOHANDS ((uint16_t) 49152U) +#define EVE_OPT_RIGHTX ((uint16_t) 2048U) +#define EVE_OPT_SIGNED ((uint16_t) 256U) + +#define EVE_OPT_MEDIAFIFO ((uint16_t) 16U) +#define EVE_OPT_FULLSCREEN ((uint16_t) 8U) +#define EVE_OPT_NOTEAR ((uint16_t) 4U) +#define EVE_OPT_SOUND ((uint16_t) 32U) + +/* ADC */ +#define EVE_ADC_DIFFERENTIAL ((uint32_t) 1UL) +#define EVE_ADC_SINGLE_ENDED ((uint32_t) 0UL) + +/* Fonts */ +#define EVE_NUMCHAR_PERFONT ((uint32_t) 128UL) /* number of font characters per bitmap handle */ +#define EVE_FONT_TABLE_SIZE ((uint32_t) 148UL) /* size of the font table - utilized for loopup by the graphics engine */ +#define EVE_FONT_TABLE_POINTER ((uint32_t) 0xFFFFCUL) /* pointer to the inbuilt font tables starting from bitmap handle 16 */ + +/* Audio sample type defines */ +#define EVE_LINEAR_SAMPLES ((uint32_t) 0UL) /* 8bit signed samples */ +#define EVE_ULAW_SAMPLES ((uint32_t) 1UL) /* 8bit ulaw samples */ +#define EVE_ADPCM_SAMPLES ((uint32_t) 2UL) /* 4bit ima adpcm samples */ + +/* Synthesized sound */ +#define EVE_SILENCE ((uint8_t) 0x00U) +#define EVE_SQUAREWAVE ((uint8_t) 0x01U) +#define EVE_SINEWAVE ((uint8_t) 0x02U) +#define EVE_SAWTOOTH ((uint8_t) 0x03U) +#define EVE_TRIANGLE ((uint8_t) 0x04U) +#define EVE_BEEPING ((uint8_t) 0x05U) +#define EVE_ALARM ((uint8_t) 0x06U) +#define EVE_WARBLE ((uint8_t) 0x07U) +#define EVE_CAROUSEL ((uint8_t) 0x08U) +#define EVE_PIPS(n) ((uint8_t) (0x0FU + (n))) +#define EVE_HARP ((uint8_t) 0x40U) +#define EVE_XYLOPHONE ((uint8_t) 0x41U) +#define EVE_TUBA ((uint8_t) 0x42U) +#define EVE_GLOCKENSPIEL ((uint8_t) 0x43U) +#define EVE_ORGAN ((uint8_t) 0x44U) +#define EVE_TRUMPET ((uint8_t) 0x45U) +#define EVE_PIANO ((uint8_t) 0x46U) +#define EVE_CHIMES ((uint8_t) 0x47U) +#define EVE_MUSICBOX ((uint8_t) 0x48U) +#define EVE_BELL ((uint8_t) 0x49U) +#define EVE_CLICK ((uint8_t) 0x50U) +#define EVE_SWITCH ((uint8_t) 0x51U) +#define EVE_COWBELL ((uint8_t) 0x52U) +#define EVE_NOTCH ((uint8_t) 0x53U) +#define EVE_HIHAT ((uint8_t) 0x54U) +#define EVE_KICKDRUM ((uint8_t) 0x55U) +#define EVE_POP ((uint8_t) 0x56U) +#define EVE_CLACK ((uint8_t) 0x57U) +#define EVE_CHACK ((uint8_t) 0x58U) +#define EVE_MUTE ((uint8_t) 0x60U) +#define EVE_UNMUTE ((uint8_t) 0x61U) + +/* Synthesized sound frequencies, midi note */ +#define EVE_MIDI_A0 ((uint8_t) 21U) +#define EVE_MIDI_A_0 ((uint8_t) 22U) +#define EVE_MIDI_B0 ((uint8_t) 23U) +#define EVE_MIDI_C1 ((uint8_t) 24U) +#define EVE_MIDI_C_1 ((uint8_t) 25U) +#define EVE_MIDI_D1 ((uint8_t) 26U) +#define EVE_MIDI_D_1 ((uint8_t) 27U) +#define EVE_MIDI_E1 ((uint8_t) 28U) +#define EVE_MIDI_F1 ((uint8_t) 29U) +#define EVE_MIDI_F_1 ((uint8_t) 30U) +#define EVE_MIDI_G1 ((uint8_t) 31U) +#define EVE_MIDI_G_1 ((uint8_t) 32U) +#define EVE_MIDI_A1 ((uint8_t) 33U) +#define EVE_MIDI_A_1 ((uint8_t) 34U) +#define EVE_MIDI_B1 ((uint8_t) 35U) +#define EVE_MIDI_C2 ((uint8_t) 36U) +#define EVE_MIDI_C_2 ((uint8_t) 37U) +#define EVE_MIDI_D2 ((uint8_t) 38U) +#define EVE_MIDI_D_2 ((uint8_t) 39U) +#define EVE_MIDI_E2 ((uint8_t) 40U) +#define EVE_MIDI_F2 ((uint8_t) 41U) +#define EVE_MIDI_F_2 ((uint8_t) 42U) +#define EVE_MIDI_G2 ((uint8_t) 43U) +#define EVE_MIDI_G_2 ((uint8_t) 44U) +#define EVE_MIDI_A2 ((uint8_t) 45U) +#define EVE_MIDI_A_2 ((uint8_t) 46U) +#define EVE_MIDI_B2 ((uint8_t) 47U) +#define EVE_MIDI_C3 ((uint8_t) 48U) +#define EVE_MIDI_C_3 ((uint8_t) 49U) +#define EVE_MIDI_D3 ((uint8_t) 50U) +#define EVE_MIDI_D_3 ((uint8_t) 51U) +#define EVE_MIDI_E3 ((uint8_t) 52U) +#define EVE_MIDI_F3 ((uint8_t) 53U) +#define EVE_MIDI_F_3 ((uint8_t) 54U) +#define EVE_MIDI_G3 ((uint8_t) 55U) +#define EVE_MIDI_G_3 ((uint8_t) 56U) +#define EVE_MIDI_A3 ((uint8_t) 57U) +#define EVE_MIDI_A_3 ((uint8_t) 58U) +#define EVE_MIDI_B3 ((uint8_t) 59U) +#define EVE_MIDI_C4 ((uint8_t) 60U) +#define EVE_MIDI_C_4 ((uint8_t) 61U) +#define EVE_MIDI_D4 ((uint8_t) 62U) +#define EVE_MIDI_D_4 ((uint8_t) 63U) +#define EVE_MIDI_E4 ((uint8_t) 64U) +#define EVE_MIDI_F4 ((uint8_t) 65U) +#define EVE_MIDI_F_4 ((uint8_t) 66U) +#define EVE_MIDI_G4 ((uint8_t) 67U) +#define EVE_MIDI_G_4 ((uint8_t) 68U) +#define EVE_MIDI_A4 ((uint8_t) 69U) +#define EVE_MIDI_A_4 ((uint8_t) 70U) +#define EVE_MIDI_B4 ((uint8_t) 71U) +#define EVE_MIDI_C5 ((uint8_t) 72U) +#define EVE_MIDI_C_5 ((uint8_t) 73U) +#define EVE_MIDI_D5 ((uint8_t) 74U) +#define EVE_MIDI_D_5 ((uint8_t) 75U) +#define EVE_MIDI_E5 ((uint8_t) 76U) +#define EVE_MIDI_F5 ((uint8_t) 77U) +#define EVE_MIDI_F_5 ((uint8_t) 78U) +#define EVE_MIDI_G5 ((uint8_t) 79U) +#define EVE_MIDI_G_5 ((uint8_t) 80U) +#define EVE_MIDI_A5 ((uint8_t) 81U) +#define EVE_MIDI_A_5 ((uint8_t) 82U) +#define EVE_MIDI_B5 ((uint8_t) 83U) +#define EVE_MIDI_C6 ((uint8_t) 84U) +#define EVE_MIDI_C_6 ((uint8_t) 85U) +#define EVE_MIDI_D6 ((uint8_t) 86U) +#define EVE_MIDI_D_6 ((uint8_t) 87U) +#define EVE_MIDI_E6 ((uint8_t) 88U) +#define EVE_MIDI_F6 ((uint8_t) 89U) +#define EVE_MIDI_F_6 ((uint8_t) 90U) +#define EVE_MIDI_G6 ((uint8_t) 91U) +#define EVE_MIDI_G_6 ((uint8_t) 92U) +#define EVE_MIDI_A6 ((uint8_t) 93U) +#define EVE_MIDI_A_6 ((uint8_t) 94U) +#define EVE_MIDI_B6 ((uint8_t) 95U) +#define EVE_MIDI_C7 ((uint8_t) 96U) +#define EVE_MIDI_C_7 ((uint8_t) 97U) +#define EVE_MIDI_D7 ((uint8_t) 98U) +#define EVE_MIDI_D_7 ((uint8_t) 99U) +#define EVE_MIDI_E7 ((uint8_t) 100U) +#define EVE_MIDI_F7 ((uint8_t) 101U) +#define EVE_MIDI_F_7 ((uint8_t) 102U) +#define EVE_MIDI_G7 ((uint8_t) 103U) +#define EVE_MIDI_G_7 ((uint8_t) 104U) +#define EVE_MIDI_A7 ((uint8_t) 105U) +#define EVE_MIDI_A_7 ((uint8_t) 106U) +#define EVE_MIDI_B7 ((uint8_t) 107U) +#define EVE_MIDI_C8 ((uint8_t) 108U) + +/* GPIO bits */ +#define EVE_GPIO0 ((uint8_t) 0U) +#define EVE_GPIO1 ((uint8_t) 1U) /* default gpio pin for audio shutdown, 1 - enable, 0 - disable */ +#define EVE_GPIO7 ((uint8_t) 7U) /* default gpio pin for display enable, 1 - enable, 0 - disable */ + +/* Display rotation */ +#define EVE_DISPLAY_0 ((uint8_t) 0U) /* 0 degrees rotation */ +#define EVE_DISPLAY_180 ((uint8_t) 1U) /* 180 degrees rotation */ + +/* Commands */ +#define CMD_APPEND ((uint32_t) 0xFFFFFF1EUL) +#define CMD_BGCOLOR ((uint32_t) 0xFFFFFF09UL) +#define CMD_BUTTON ((uint32_t) 0xFFFFFF0DUL) +#define CMD_CALIBRATE ((uint32_t) 0xFFFFFF15UL) +#define CMD_CLOCK ((uint32_t) 0xFFFFFF14UL) +#define CMD_COLDSTART ((uint32_t) 0xFFFFFF32UL) +#define CMD_DIAL ((uint32_t) 0xFFFFFF2DUL) +#define CMD_DLSTART ((uint32_t) 0xFFFFFF00UL) +#define CMD_FGCOLOR ((uint32_t) 0xFFFFFF0AUL) +#define CMD_GAUGE ((uint32_t) 0xFFFFFF13UL) +#define CMD_GETMATRIX ((uint32_t) 0xFFFFFF33UL) +#define CMD_GETPROPS ((uint32_t) 0xFFFFFF25UL) +#define CMD_GETPTR ((uint32_t) 0xFFFFFF23UL) +#define CMD_GRADCOLOR ((uint32_t) 0xFFFFFF34UL) +#define CMD_GRADIENT ((uint32_t) 0xFFFFFF0BUL) +#define CMD_INFLATE ((uint32_t) 0xFFFFFF22UL) +#define CMD_INTERRUPT ((uint32_t) 0xFFFFFF02UL) +#define CMD_KEYS ((uint32_t) 0xFFFFFF0EUL) +#define CMD_LOADIDENTITY ((uint32_t) 0xFFFFFF26UL) +#define CMD_LOADIMAGE ((uint32_t) 0xFFFFFF24UL) +#define CMD_LOGO ((uint32_t) 0xFFFFFF31UL) +#define CMD_MEDIAFIFO ((uint32_t) 0xFFFFFF39UL) +#define CMD_MEMCPY ((uint32_t) 0xFFFFFF1DUL) +#define CMD_MEMCRC ((uint32_t) 0xFFFFFF18UL) +#define CMD_MEMSET ((uint32_t) 0xFFFFFF1BUL) +#define CMD_MEMWRITE ((uint32_t) 0xFFFFFF1AUL) +#define CMD_MEMZERO ((uint32_t) 0xFFFFFF1CUL) +#define CMD_NUMBER ((uint32_t) 0xFFFFFF2EUL) +#define CMD_PLAYVIDEO ((uint32_t) 0xFFFFFF3AUL) +#define CMD_PROGRESS ((uint32_t) 0xFFFFFF0FUL) +#define CMD_REGREAD ((uint32_t) 0xFFFFFF19UL) +#define CMD_ROMFONT ((uint32_t) 0xFFFFFF3FUL) +#define CMD_ROTATE ((uint32_t) 0xFFFFFF29UL) +#define CMD_SCALE ((uint32_t) 0xFFFFFF28UL) +#define CMD_SCREENSAVER ((uint32_t) 0xFFFFFF2FUL) +#define CMD_SCROLLBAR ((uint32_t) 0xFFFFFF11UL) +#define CMD_SETBASE ((uint32_t) 0xFFFFFF38UL) +#define CMD_SETBITMAP ((uint32_t) 0xFFFFFF43UL) +#define CMD_SETFONT ((uint32_t) 0xFFFFFF2BUL) +#define CMD_SETFONT2 ((uint32_t) 0xFFFFFF3BUL) +#define CMD_SETMATRIX ((uint32_t) 0xFFFFFF2AUL) +#define CMD_SETROTATE ((uint32_t) 0xFFFFFF36UL) +#define CMD_SETSCRATCH ((uint32_t) 0xFFFFFF3CUL) +#define CMD_SKETCH ((uint32_t) 0xFFFFFF30UL) +#define CMD_SLIDER ((uint32_t) 0xFFFFFF10UL) +#define CMD_SNAPSHOT ((uint32_t) 0xFFFFFF1FUL) +#define CMD_SNAPSHOT2 ((uint32_t) 0xFFFFFF37UL) +#define CMD_SPINNER ((uint32_t) 0xFFFFFF16UL) +#define CMD_STOP ((uint32_t) 0xFFFFFF17UL) +#define CMD_SWAP ((uint32_t) 0xFFFFFF01UL) +#define CMD_TEXT ((uint32_t) 0xFFFFFF0CUL) +#define CMD_TOGGLE ((uint32_t) 0xFFFFFF12UL) +#define CMD_TRACK ((uint32_t) 0xFFFFFF2CUL) +#define CMD_TRANSLATE ((uint32_t) 0xFFFFFF27UL) +#define CMD_VIDEOFRAME ((uint32_t) 0xFFFFFF41UL) +#define CMD_VIDEOSTART ((uint32_t) 0xFFFFFF40UL) + +/* Registers */ +#define REG_ANA_COMP ((uint32_t) 0x00302184UL) /* only listed in datasheet */ +#define REG_BIST_EN ((uint32_t) 0x00302174UL) /* only listed in datasheet */ +#define REG_CLOCK ((uint32_t) 0x00302008UL) +#define REG_CMDB_SPACE ((uint32_t) 0x00302574UL) +#define REG_CMDB_WRITE ((uint32_t) 0x00302578UL) +#define REG_CMD_DL ((uint32_t) 0x00302100UL) +#define REG_CMD_READ ((uint32_t) 0x003020f8UL) +#define REG_CMD_WRITE ((uint32_t) 0x003020fcUL) +#define REG_CPURESET ((uint32_t) 0x00302020UL) +#define REG_CSPREAD ((uint32_t) 0x00302068UL) +#define REG_CTOUCH_EXTENDED ((uint32_t) 0x00302108UL) +#define REG_CTOUCH_TOUCH0_XY ((uint32_t) 0x00302124UL) /* only listed in datasheet */ +#define REG_CTOUCH_TOUCH4_X ((uint32_t) 0x0030216cUL) +#define REG_CTOUCH_TOUCH4_Y ((uint32_t) 0x00302120UL) +#define REG_CTOUCH_TOUCH1_XY ((uint32_t) 0x0030211cUL) +#define REG_CTOUCH_TOUCH2_XY ((uint32_t) 0x0030218cUL) +#define REG_CTOUCH_TOUCH3_XY ((uint32_t) 0x00302190UL) +#define REG_TOUCH_CONFIG ((uint32_t) 0x00302168UL) +#define REG_DATESTAMP ((uint32_t) 0x00302564UL) /* only listed in datasheet */ +#define REG_DITHER ((uint32_t) 0x00302060UL) +#define REG_DLSWAP ((uint32_t) 0x00302054UL) +#define REG_FRAMES ((uint32_t) 0x00302004UL) +#define REG_FREQUENCY ((uint32_t) 0x0030200cUL) +#define REG_GPIO ((uint32_t) 0x00302094UL) +#define REG_GPIOX ((uint32_t) 0x0030209cUL) +#define REG_GPIOX_DIR ((uint32_t) 0x00302098UL) +#define REG_GPIO_DIR ((uint32_t) 0x00302090UL) +#define REG_HCYCLE ((uint32_t) 0x0030202cUL) +#define REG_HOFFSET ((uint32_t) 0x00302030UL) +#define REG_HSIZE ((uint32_t) 0x00302034UL) +#define REG_HSYNC0 ((uint32_t) 0x00302038UL) +#define REG_HSYNC1 ((uint32_t) 0x0030203cUL) +#define REG_ID ((uint32_t) 0x00302000UL) +#define REG_INT_EN ((uint32_t) 0x003020acUL) +#define REG_INT_FLAGS ((uint32_t) 0x003020a8UL) +#define REG_INT_MASK ((uint32_t) 0x003020b0UL) +#define REG_MACRO_0 ((uint32_t) 0x003020d8UL) +#define REG_MACRO_1 ((uint32_t) 0x003020dcUL) +#define REG_MEDIAFIFO_READ ((uint32_t) 0x00309014UL) /* only listed in programmers guide */ +#define REG_MEDIAFIFO_WRITE ((uint32_t) 0x00309018UL) /* only listed in programmers guide */ +#define REG_OUTBITS ((uint32_t) 0x0030205cUL) +#define REG_PCLK ((uint32_t) 0x00302070UL) +#define REG_PCLK_POL ((uint32_t) 0x0030206cUL) +#define REG_PLAY ((uint32_t) 0x0030208cUL) +#define REG_PLAYBACK_FORMAT ((uint32_t) 0x003020c4UL) +#define REG_PLAYBACK_FREQ ((uint32_t) 0x003020c0UL) +#define REG_PLAYBACK_LENGTH ((uint32_t) 0x003020b8UL) +#define REG_PLAYBACK_LOOP ((uint32_t) 0x003020c8UL) +#define REG_PLAYBACK_PLAY ((uint32_t) 0x003020ccUL) +#define REG_PLAYBACK_READPTR ((uint32_t) 0x003020bcUL) +#define REG_PLAYBACK_START ((uint32_t) 0x003020b4UL) +#define REG_PWM_DUTY ((uint32_t) 0x003020d4UL) +#define REG_PWM_HZ ((uint32_t) 0x003020d0UL) +#define REG_RENDERMODE ((uint32_t) 0x00302010UL) /* only listed in datasheet */ +#define REG_ROTATE ((uint32_t) 0x00302058UL) +#define REG_SNAPFORMAT ((uint32_t) 0x0030201cUL) /* only listed in datasheet */ +#define REG_SNAPSHOT ((uint32_t) 0x00302018UL) /* only listed in datasheet */ +#define REG_SNAPY ((uint32_t) 0x00302014UL) /* only listed in datasheet */ +#define REG_SOUND ((uint32_t) 0x00302088UL) +#define REG_SPI_WIDTH ((uint32_t) 0x00302188UL) /* listed with false offset in programmers guide V1.1 */ +#define REG_SWIZZLE ((uint32_t) 0x00302064UL) +#define REG_TAG ((uint32_t) 0x0030207cUL) +#define REG_TAG_X ((uint32_t) 0x00302074UL) +#define REG_TAG_Y ((uint32_t) 0x00302078UL) +#define REG_TAP_CRC ((uint32_t) 0x00302024UL) /* only listed in datasheet */ +#define REG_TAP_MASK ((uint32_t) 0x00302028UL) /* only listed in datasheet */ +#define REG_TOUCH_ADC_MODE ((uint32_t) 0x00302108UL) +#define REG_TOUCH_CHARGE ((uint32_t) 0x0030210cUL) +#define REG_TOUCH_DIRECT_XY ((uint32_t) 0x0030218cUL) +#define REG_TOUCH_DIRECT_Z1Z2 ((uint32_t) 0x00302190UL) +#define REG_TOUCH_MODE ((uint32_t) 0x00302104UL) +#define REG_TOUCH_OVERSAMPLE ((uint32_t) 0x00302114UL) +#define REG_TOUCH_RAW_XY ((uint32_t) 0x0030211cUL) +#define REG_TOUCH_RZ ((uint32_t) 0x00302120UL) +#define REG_TOUCH_RZTHRESH ((uint32_t) 0x00302118UL) +#define REG_TOUCH_SCREEN_XY ((uint32_t) 0x00302124UL) +#define REG_TOUCH_SETTLE ((uint32_t) 0x00302110UL) +#define REG_TOUCH_TAG ((uint32_t) 0x0030212cUL) +#define REG_TOUCH_TAG1 ((uint32_t) 0x00302134UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG1_XY ((uint32_t) 0x00302130UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG2 ((uint32_t) 0x0030213cUL) /* only listed in datasheet */ +#define REG_TOUCH_TAG2_XY ((uint32_t) 0x00302138UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG3 ((uint32_t) 0x00302144UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG3_XY ((uint32_t) 0x00302140UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG4 ((uint32_t) 0x0030214cUL)/* only listed in datasheet */ +#define REG_TOUCH_TAG4_XY ((uint32_t) 0x00302148UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG_XY ((uint32_t) 0x00302128UL) +#define REG_TOUCH_TRANSFORM_A ((uint32_t) 0x00302150UL) +#define REG_TOUCH_TRANSFORM_B ((uint32_t) 0x00302154UL) +#define REG_TOUCH_TRANSFORM_C ((uint32_t) 0x00302158UL) +#define REG_TOUCH_TRANSFORM_D ((uint32_t) 0x0030215cUL) +#define REG_TOUCH_TRANSFORM_E ((uint32_t) 0x00302160UL) +#define REG_TOUCH_TRANSFORM_F ((uint32_t) 0x00302164UL) +#define REG_TRACKER ((uint32_t) 0x00309000UL) /* only listed in programmers guide */ +#define REG_TRACKER_1 ((uint32_t) 0x00309004UL) /* only listed in programmers guide */ +#define REG_TRACKER_2 ((uint32_t) 0x00309008UL) /* only listed in programmers guide */ +#define REG_TRACKER_3 ((uint32_t) 0x0030900cUL) /* only listed in programmers guide */ +#define REG_TRACKER_4 ((uint32_t) 0x00309010UL) /* only listed in programmers guide */ +#define REG_TRIM ((uint32_t) 0x00302180UL) +#define REG_VCYCLE ((uint32_t) 0x00302040UL) +#define REG_VOFFSET ((uint32_t) 0x00302044UL) +#define REG_VOL_PB ((uint32_t) 0x00302080UL) +#define REG_VOL_SOUND ((uint32_t) 0x00302084UL) +#define REG_VSIZE ((uint32_t) 0x00302048UL) +#define REG_VSYNC0 ((uint32_t) 0x0030204cUL) +#define REG_VSYNC1 ((uint32_t) 0x00302050UL) + + +/* Macros for static display list generation */ + +//#define ALPHA_FUNC(func,ref) ((DL_ALPHA_FUNC) | (((func) & 7UL) << 8U) | ((ref) & 0xFFUL)) +/** + * @brief Set the alpha test function. + * + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t ALPHA_FUNC(uint8_t func, uint8_t ref) +{ + uint32_t const funcv = ((uint32_t) func & 7U) << 8U; + return (DL_ALPHA_FUNC | funcv | ref); +} + +//#define BITMAP_HANDLE(handle) ((DL_BITMAP_HANDLE) | ((handle) & 0x1FUL)) +/** + * @brief Set the bitmap handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_HANDLE(uint8_t handle) +{ + return (DL_BITMAP_HANDLE | ((handle) & 0x1FUL)); +} + +//#define BITMAP_LAYOUT(format,linestride,height) ((DL_BITMAP_LAYOUT) | (((format) & 0x1FUL) << 19U) | (((linestride) & 0x3FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_LAYOUT(uint8_t format, uint16_t linestride, uint16_t height) +{ + uint32_t const formatv = ((uint32_t) format & 0x1FUL) << 19U; + uint32_t const linestridev = ((uint32_t) linestride & 0x3FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (DL_BITMAP_LAYOUT | formatv | linestridev | heightv); +} + +//#define BITMAP_SIZE(filter,wrapx,wrapy,width,height) ((DL_BITMAP_SIZE) | (((filter) & 1UL) << 20U) | (((wrapx) & 1UL) << 19U) | (((wrapy) & 1UL) << 18U) | (((width) & 0x1FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SIZE(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) +{ + uint32_t const filterv = (filter & 0x1UL) << 20U; + uint32_t const wrapxv = (wrapx & 0x1UL) << 19U; + uint32_t const wrapyv = (wrapy & 0x1UL) << 18U; + uint32_t const widthv = (width & 0x1FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (DL_BITMAP_SIZE | filterv | wrapxv | wrapyv | widthv | heightv); +} + +//#define BITMAP_LAYOUT_H(linestride,height) ((DL_BITMAP_LAYOUT_H) | (((((linestride) & 0xC00U) >> 10U)&3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of the source bitmap memory format and layout for the current handle. + * @param linestride 12-bit value specified to BITMAP_LAYOUT + * @param height 11-bit value specified to BITMAP_LAYOUT + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_LAYOUT_H(uint16_t linestride, uint16_t height) +{ + uint32_t const linestridev = (uint32_t) ((((linestride & 0xC00U) >> 10U) &3UL) << 2U); + uint32_t const heightv = (uint32_t) (((height & 0x600U) >> 9U) & 3UL); + return (DL_BITMAP_LAYOUT_H | linestridev | heightv); +} + +//#define BITMAP_SIZE_H(width,height) ((DL_BITMAP_SIZE_H) | (((((width) & 0x600U) >> 9U) & 3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of bitmaps dimension for the current handle. + * @param linestride 11-bit value of bitmap width, the 2 most significant bits are used + * @param height 11-bit value of bitmap width, the 2 most significant bits are used + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SIZE_H(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t) ((((width & 0x600U) >> 9U) & 3UL) << 2U); + uint32_t const heightv = (uint32_t) (((height & 0x600U) >> 9U) & 3UL); + return ((DL_BITMAP_SIZE_H) | widthv | heightv); +} + +//#define BITMAP_SOURCE(addr) ((DL_BITMAP_SOURCE) | ((addr) & 0x3FFFFFUL)) +/** + * @brief Set the source address of bitmap data in RAM_G or flash memory. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SOURCE(uint32_t addr) +{ + return (DL_BITMAP_SOURCE | (addr & 0x3FFFFFUL)); +} + +#if EVE_GEN < 3 /* only define these for FT81x */ +//#define BITMAP_TRANSFORM_A(a) ((DL_BITMAP_TRANSFORM_A) | ((a) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_A(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_A | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_B(b) ((DL_BITMAP_TRANSFORM_B) | ((b) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_B(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_B | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_D(d) ((DL_BITMAP_TRANSFORM_D) | ((d) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_D(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_D | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_E(e) ((DL_BITMAP_TRANSFORM_E) | ((e) & 0x1FFFFUL)) +/** + * @brief Set he E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_E(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_E | (val & 0x1FFFFUL)); +} + +#endif + +//#define BITMAP_TRANSFORM_C(c) ((DL_BITMAP_TRANSFORM_C) | ((c) & 0x1FFFFUL)) +/** + * @brief Set the C coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_C(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_C | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_F(f) ((DL_BITMAP_TRANSFORM_F) | ((f) & 0x1FFFFUL)) +/** + * @brief Set the F coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_F(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_F | (val & 0x1FFFFUL)); +} + +//#define BLEND_FUNC(src,dst) ((DL_BLEND_FUNC) | (((src) & 7UL) << 3U) | ((dst) & 7UL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BLEND_FUNC(uint8_t src, uint8_t dst) +{ + uint32_t const srcv = (uint32_t) ((src & 7UL) << 3U); + uint32_t const dstv = (uint32_t) (dst & 7UL); + return (DL_BLEND_FUNC | srcv | dstv); +} + +//#define CALL(dest) ((DL_CALL) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CALL(uint16_t dest) +{ + return (DL_CALL | (dest & 0x7FFUL)); +} + +//#define JUMP(dest) ((DL_JUMP) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t JUMP(uint16_t dest) +{ + return (DL_JUMP | (dest & 0x7FFUL)); +} + +//#define CELL(cell) ((DL_CELL) | ((cell) & 0x7FUL)) +/** + * @brief Set the bitmap cell number for the VERTEX2F command. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CELL(uint8_t cell) +{ + return (DL_CELL | (cell & 0x7FUL)); +} + +//#define CLEAR(c,s,t) ((DL_CLEAR) | (((c) & 1UL) << 2U) | (((s) & 1UL) << 1U) | ((t) & 1UL)) +/** + * @brief Clear buffers to preset values. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR(uint8_t color, uint8_t stencil, uint8_t tag) +{ + uint32_t const colorv = (color & 1UL) << 2U; + uint32_t const stencilv = (stencil & 1UL) << 1U; + uint32_t const tagv = (tag & 1UL); + return (DL_CLEAR | colorv | stencilv | tagv); +} + +//#define CLEAR_COLOR_A(alpha) ((DL_CLEAR_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set clear value for the alpha channel. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_COLOR_A(uint8_t alpha) +{ + return (DL_CLEAR_COLOR_A | alpha); +} + +//#define CLEAR_COLOR_RGB(red,green,blue) ((DL_CLEAR_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set clear values for red, green and blue channels. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (DL_CLEAR_COLOR_RGB | redv | greenv | bluev); +} + +//#define CLEAR_STENCIL(s) ((DL_CLEAR_STENCIL) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the stencil buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_STENCIL(uint8_t val) +{ + return (DL_CLEAR_STENCIL | val); +} + +//#define CLEAR_TAG(s) ((DL_CLEAR_TAG) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_TAG(uint8_t val) +{ + return (DL_CLEAR_TAG | val); +} + +//#define COLOR_A(alpha) ((DL_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set the current color alpha. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t COLOR_A(uint8_t alpha) +{ + return (DL_COLOR_A | alpha); +} + +//#define COLOR_MASK(r,g,b,a) ((DL_COLOR_MASK) | (((r) & 1UL) << 3U) | (((g) & 1UL) << 2U) | (((b) & 1UL) << 1U) | ((a) & 1UL)) +/** + * @brief Enable or disable writing of color components. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t COLOR_MASK(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 1UL) << 3U); + uint32_t const greenv = ((green & 1UL) << 2U); + uint32_t const bluev = ((blue & 1UL) << 1U); + uint32_t const alphav = (alpha & 1UL); + return (DL_COLOR_MASK | redv | greenv | bluev | alphav); +} + +//#define COLOR_RGB(red,green,blue) ((DL_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set the current color red, green and blue. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (DL_COLOR_RGB | redv | greenv | bluev); +} + +//#define LINE_WIDTH(width) ((DL_LINE_WIDTH) | (((uint32_t) (width)) & 0xFFFUL)) +/** + * @brief Set the width of lines to be drawn with primitive LINES in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LINE_WIDTH(uint16_t width) +{ + return (DL_LINE_WIDTH | (width & 0xFFFUL)); +} + +//#define MACRO(m) ((DL_MACRO) | ((m) & 1UL)) +/** + * @brief Execute a single command from a macro register. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t MACRO(uint8_t macro) +{ + return (DL_MACRO | (macro & 0x1UL)); +} + +//#define PALETTE_SOURCE(addr) ((DL_PALETTE_SOURCE) | ((addr) & 0x3FFFFF3UL)) +/** + * @brief Set the base address of the palette. + * @note 2-byte alignment is required if pixel format is PALETTE4444 or PALETTE565. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t PALETTE_SOURCE(uint32_t addr) +{ + return (DL_PALETTE_SOURCE | (addr & 0x3FFFFFUL)); +} + +//#define POINT_SIZE(size) ((DL_POINT_SIZE) | ((size) & 0x1FFFUL)) +/** + * @brief Set the radius of points to be drawn with primitive POINTS in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t POINT_SIZE(uint16_t size) +{ + return (DL_POINT_SIZE | (size & 0x1FFFUL)); +} + +//#define SCISSOR_SIZE(width,height) ((DL_SCISSOR_SIZE) | (((width) & 0xFFFUL) << 12U) | ((height) & 0xFFFUL)) +/** + * @brief Set the size of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2048 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t SCISSOR_SIZE(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t) ((width & 0xFFFUL) << 12U); + uint32_t const heightv = (uint32_t) (height & 0xFFFUL); + return (DL_SCISSOR_SIZE | widthv | heightv); +} + +//#define SCISSOR_XY(x,y) ((DL_SCISSOR_XY) | (((x) & 0x7FFUL) << 11U) | ((y) & 0x7FFUL)) +/** + * @brief Set the top left corner of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t SCISSOR_XY(uint16_t xc0, uint16_t yc0) +{ + uint32_t const xc0v = (uint32_t) ((xc0 & 0x7FFUL) << 11U); + uint32_t const yc0v = (uint32_t) (yc0 & 0x7FFUL); + return (DL_SCISSOR_XY | xc0v | yc0v); +} + +//#define STENCIL_FUNC(func,ref,mask) ((DL_STENCIL_FUNC) | (((func) & 7UL) << 16U) | (((ref) & 0xFFUL) << 8U)|((mask) & 0xFFUL)) +/** + * @brief Set function and reference value for stencil testing. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t STENCIL_FUNC(uint8_t func, uint8_t ref, uint8_t mask) +{ + uint32_t const funcv = (uint32_t) ((func & 7UL) << 16U); + uint32_t const refv = (uint32_t) ((ref & 0xFFUL) << 8U); + uint32_t const maskv = (uint32_t) (mask & 0xFFUL); + return (DL_STENCIL_FUNC | funcv | refv | maskv); +} + +//#define STENCIL_MASK(mask) ((DL_STENCIL_MASK) | ((mask) & 0xFFUL)) +/** + * @brief Control the writing of individual bits in the stencil planes. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t STENCIL_MASK(uint8_t mask) +{ + return (DL_STENCIL_MASK | mask); +} + +//#define STENCIL_OP(sfail,spass) ((DL_STENCIL_OP) | (((sfail) & 7UL) << 3U) | ((spass) & 7UL)) +/** + * @brief Set stencil test actions. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t STENCIL_OP(uint8_t sfail, uint8_t spass) +{ + uint32_t const sfailv = (uint32_t) ((sfail & 0x07UL) << 3U); + uint32_t const spassv = (uint32_t) (spass & 0x07UL); + return (DL_STENCIL_OP | sfailv | spassv); +} + +//#define TAG(s) ((DL_TAG) | ((s) & 0xFFUL)) +/** + * @brief Attach the tag value for the following graphics objects drawn on the screen. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t TAG(uint8_t tagval) +{ + return (DL_TAG | tagval); +} + +//#define TAG_MASK(mask) ((DL_TAG_MASK) | ((mask) & 1UL)) +/** + * @brief Control the writing of the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t TAG_MASK(uint8_t mask) +{ + return (DL_TAG_MASK | ((mask) & 1UL)); +} + +//#define VERTEX2F(x,y) ((DL_VERTEX2F) | ((((uint32_t) (x)) & 0x7FFFUL) << 15U) | (((uint32_t) (y)) & 0x7FFFUL)) +/** + * @brief Set coordinates for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX2F(int16_t xc0, int16_t yc0) +{ + uint32_t const xc0v = ((((uint32_t) ((uint16_t) xc0)) & 0x7FFFUL) << 15U); + uint32_t const yc0v = (((uint32_t) ((uint16_t) yc0)) & 0x7FFFUL); + return (DL_VERTEX2F | xc0v | yc0v); +} + +//#define VERTEX2II(x,y,handle,cell) ((DL_VERTEX2II) | (((x) & 0x1FFUL) << 21U) | (((y) & 0x1FFUL) << 12U) | (((handle) & 0x1FUL) << 7U) | ((cell) & 0x7FUL)) +/** + * @brief Set coordinates, bitmap-handle and cell-number for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX2II(uint16_t xc0, uint16_t yc0, uint8_t handle, uint8_t cell) +{ + uint32_t const xc0v = ((((uint32_t) xc0) & 0x1FFUL) << 21U); + uint32_t const yc0v = ((((uint32_t) yc0) & 0x1FFUL) << 12U); + uint32_t const handlev = ((((uint32_t) handle) & 0x1FUL) << 7U); + uint32_t const cellv = (((uint32_t) cell) & 0x7FUL); + return (DL_VERTEX2II | xc0v | yc0v | handlev | cellv); +} + +//#define VERTEX_FORMAT(frac) ((DL_VERTEX_FORMAT) | ((frac) & 7UL)) +/** + * @brief Set the precision of VERTEX2F coordinates. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX_FORMAT(uint8_t frac) +{ + return (DL_VERTEX_FORMAT | ((frac) & 7UL)); +} + +//#define VERTEX_TRANSLATE_X(x) ((DL_VERTEX_TRANSLATE_X) | ((x) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations X translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX_TRANSLATE_X(int32_t xco) +{ + return (DL_VERTEX_TRANSLATE_X | (((uint32_t) xco) & 0x1FFFFUL)); +} + +//#define VERTEX_TRANSLATE_Y(y) ((DL_VERTEX_TRANSLATE_Y) | ((y) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations Y translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX_TRANSLATE_Y(int32_t yco) +{ + return (DL_VERTEX_TRANSLATE_Y | (((uint32_t) yco) & 0x1FFFFUL)); +} + +/* #define BEGIN(prim) ((DL_BEGIN) | ((prim) & 15UL)) */ /* use define DL_BEGIN */ +/* #define DISPLAY() ((DL_DISPLAY)) */ /* use define DL_DISPLAY */ +/* #define END() ((DL_END)) */ /* use define DL_END */ +/* #define RESTORE_CONTEXT() ((DL_RESTORE_CONTEXT)) */ /* use define DL_RESTORE_CONTEXT */ +/* #define RETURN() ((DL_RETURN)) */ /* use define DL_RETURN */ +/* #define SAVE_CONTEXT() ((DL_SAVE_CONTEXT)) */ /* use define DL_SAVE_CONTEXT */ +/* #define NOP() ((DL_NOP)) */ + +/* ########## EVE Generation 3: BT815 / BT816 definitions ########## */ + +#if EVE_GEN > 2 + +#define EVE_GLFORMAT ((uint32_t) 31UL) /* used with BITMAP_LAYOUT to indicate bitmap-format is specified by BITMAP_EXT_FORMAT */ + +#define DL_BITMAP_EXT_FORMAT ((uint32_t) 0x2E000000UL) /* requires OR'd arguments */ +#define DL_BITMAP_SWIZZLE ((uint32_t) 0x2F000000UL) +/* #define DL_INT_FRR ((uint32_t) 0x30000000UL) */ /* ESE displays "Internal: flash read result" - undocumented display list command */ + +/* Extended Bitmap formats */ +#define EVE_ASTC_4X4 ((uint32_t) 37808UL) +#define EVE_ASTC_5X4 ((uint32_t) 37809UL) +#define EVE_ASTC_5X5 ((uint32_t) 37810UL) +#define EVE_ASTC_6X5 ((uint32_t) 37811UL) +#define EVE_ASTC_6X6 ((uint32_t) 37812UL) +#define EVE_ASTC_8X5 ((uint32_t) 37813UL) +#define EVE_ASTC_8X6 ((uint32_t) 37814UL) +#define EVE_ASTC_8X8 ((uint32_t) 37815UL) +#define EVE_ASTC_10X5 ((uint32_t) 37816UL) +#define EVE_ASTC_10X6 ((uint32_t) 37817UL) +#define EVE_ASTC_10X8 ((uint32_t) 37818UL) +#define EVE_ASTC_10X10 ((uint32_t) 37819UL) +#define EVE_ASTC_12X10 ((uint32_t) 37820UL) +#define EVE_ASTC_12X12 ((uint32_t) 37821UL) + +#define EVE_RAM_ERR_REPORT ((uint32_t) 0x309800UL) /* max 128 bytes null terminated string */ +#define EVE_RAM_FLASH ((uint32_t) 0x800000UL) +#define EVE_RAM_FLASH_POSTBLOB ((uint32_t) 0x801000UL) + +#define EVE_OPT_FLASH ((uint16_t) 64U) +#define EVE_OPT_OVERLAY ((uint16_t) 128U) +#define EVE_OPT_FORMAT ((uint16_t) 4096U) +#define EVE_OPT_FILL ((uint16_t) 8192U) + +/* Commands for BT815 / BT816 */ +#define CMD_BITMAP_TRANSFORM ((uint32_t) 0xFFFFFF21UL) +#define CMD_SYNC ((uint32_t) 0xFFFFFF42UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_SYNC) */ +#define CMD_FLASHERASE ((uint32_t) 0xFFFFFF44UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHERASE) */ +#define CMD_FLASHWRITE ((uint32_t) 0xFFFFFF45UL) +#define CMD_FLASHREAD ((uint32_t) 0xFFFFFF46UL) +#define CMD_FLASHUPDATE ((uint32_t) 0xFFFFFF47UL) +#define CMD_FLASHDETACH ((uint32_t) 0xFFFFFF48UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHDETACH) */ +#define CMD_FLASHATTACH ((uint32_t) 0xFFFFFF49UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHATTACH) */ +#define CMD_FLASHFAST ((uint32_t) 0xFFFFFF4AUL) +#define CMD_FLASHSPIDESEL ((uint32_t) 0xFFFFFF4BUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHSPIDESEL) */ +#define CMD_FLASHSPITX ((uint32_t) 0xFFFFFF4CUL) +#define CMD_FLASHSPIRX ((uint32_t) 0xFFFFFF4DUL) +#define CMD_FLASHSOURCE ((uint32_t) 0xFFFFFF4EUL) +#define CMD_CLEARCACHE ((uint32_t) 0xFFFFFF4FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_CLEARCACHE) */ +#define CMD_INFLATE2 ((uint32_t) 0xFFFFFF50UL) +#define CMD_ROTATEAROUND ((uint32_t) 0xFFFFFF51UL) +#define CMD_RESETFONTS ((uint32_t) 0xFFFFFF52UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RESETFONTS) */ +#define CMD_ANIMSTART ((uint32_t) 0xFFFFFF53UL) +#define CMD_ANIMSTOP ((uint32_t) 0xFFFFFF54UL) +#define CMD_ANIMXY ((uint32_t) 0xFFFFFF55UL) +#define CMD_ANIMDRAW ((uint32_t) 0xFFFFFF56UL) +#define CMD_GRADIENTA ((uint32_t) 0xFFFFFF57UL) +#define CMD_FILLWIDTH ((uint32_t) 0xFFFFFF58UL) +#define CMD_APPENDF ((uint32_t) 0xFFFFFF59UL) +#define CMD_ANIMFRAME ((uint32_t) 0xFFFFFF5AUL) +#define CMD_VIDEOSTARTF ((uint32_t) 0xFFFFFF5FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_VIDEOSTARTF) */ + +/* Registers for BT815 / BT816 */ +#define REG_ADAPTIVE_FRAMERATE ((uint32_t) 0x0030257cUL) +#define REG_PLAYBACK_PAUSE ((uint32_t) 0x003025ecUL) +#define REG_FLASH_STATUS ((uint32_t) 0x003025f0UL) +#define REG_FLASH_SIZE ((uint32_t) 0x00309024UL) +#define REG_PLAY_CONTROL ((uint32_t) 0x0030914eUL) +#define REG_COPRO_PATCH_PTR ((uint32_t) 0x00309162UL) + +/* Macros for BT815 / BT816 */ + +//#define BITMAP_EXT_FORMAT(format) ((DL_BITMAP_EXT_FORMAT) | ((format) & 0xFFFFUL)) +/** + * @brief Set the extended format of the bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_EXT_FORMAT(uint16_t format) +{ + return (DL_BITMAP_EXT_FORMAT | format); +} + +//#define BITMAP_SWIZZLE(r,g,b,a) ((DL_BITMAP_SWIZZLE) | (((r) & 7UL) << 9U) | (((g) & 7UL) << 6U) | (((b) & 7UL) << 3U) | ((a) & 7UL)) +/** + * @brief Set the source for the red, green, blue and alpha channels of a bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SWIZZLE(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 7UL) << 9U); + uint32_t const greenv = ((green & 7UL) << 6U); + uint32_t const bluev = ((blue & 7UL) << 3U); + uint32_t const alphav = (alpha & 7UL); + return (DL_BITMAP_SWIZZLE | redv | greenv | bluev | alphav); +} + +//#define BITMAP_TRANSFORM_A_EXT(p,v) ((DL_BITMAP_TRANSFORM_A) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_A(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_A | prcv | valv); +} + +//#define BITMAP_TRANSFORM_B_EXT(p,v) ((DL_BITMAP_TRANSFORM_B) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_B(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_B | prcv | valv); +} + +//#define BITMAP_TRANSFORM_D_EXT(p,v) ((DL_BITMAP_TRANSFORM_D) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_D(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_D | prcv | valv); +} + +//#define BITMAP_TRANSFORM_E_EXT(p,v) ((DL_BITMAP_TRANSFORM_E) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_E(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_E | prcv | valv); +} + +//#define BITMAP_TRANSFORM_A(a) BITMAP_TRANSFORM_A_EXT(0UL,(a)) +//#define BITMAP_TRANSFORM_B(b) BITMAP_TRANSFORM_B_EXT(0UL,(b)) +//#define BITMAP_TRANSFORM_D(d) BITMAP_TRANSFORM_D_EXT(0UL,(d)) +//#define BITMAP_TRANSFORM_E(e) BITMAP_TRANSFORM_E_EXT(0UL,(e)) + +#endif /* EVE_GEN > 2 */ + +/* ########## EVE Generation 4: BT817 / BT818 definitions ########## */ + +#if EVE_GEN > 3 + +/* Commands for BT817 / BT818 */ +#define CMD_ANIMFRAMERAM ((uint32_t) 0xFFFFFF6DUL) +#define CMD_ANIMSTARTRAM ((uint32_t) 0xFFFFFF6EUL) +#define CMD_APILEVEL ((uint32_t) 0xFFFFFF63UL) +#define CMD_CALIBRATESUB ((uint32_t) 0xFFFFFF60UL) +#define CMD_CALLLIST ((uint32_t) 0xFFFFFF67UL) +#define CMD_ENDLIST ((uint32_t) 0xFFFFFF69UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_ENDLIST) */ +#define CMD_FLASHPROGRAM ((uint32_t) 0xFFFFFF70UL) +#define CMD_FONTCACHE ((uint32_t) 0xFFFFFF6BUL) +#define CMD_FONTCACHEQUERY ((uint32_t) 0xFFFFFF6CUL) +#define CMD_GETIMAGE ((uint32_t) 0xFFFFFF64UL) +#define CMD_HSF ((uint32_t) 0xFFFFFF62UL) +#define CMD_LINETIME ((uint32_t) 0xFFFFFF5EUL) +#define CMD_NEWLIST ((uint32_t) 0xFFFFFF68UL) +#define CMD_PCLKFREQ ((uint32_t) 0xFFFFFF6AUL) +#define CMD_RETURN ((uint32_t) 0xFFFFFF66UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RETURN) */ +#define CMD_RUNANIM ((uint32_t) 0xFFFFFF6FUL) +#define CMD_TESTCARD ((uint32_t) 0xFFFFFF61UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_TESTCARD) */ +#define CMD_WAIT ((uint32_t) 0xFFFFFF65UL) + +/* Registers for BT817 / BT818 */ +#define REG_UNDERRUN ((uint32_t) 0x0030260cUL) +#define REG_AH_HCYCLE_MAX ((uint32_t) 0x00302610UL) +#define REG_PCLK_FREQ ((uint32_t) 0x00302614UL) +#define REG_PCLK_2X ((uint32_t) 0x00302618UL) +#define REG_ANIM_ACTIVE ((uint32_t) 0x0030902CUL) + +#endif /* EVE_GEN > 3 */ + +#ifdef __cplusplus +} +#endif + +#endif /* EVE_H */ diff --git a/src/libs/FT800-FT813/EVE_commands.c b/src/libs/FT800-FT813/EVE_commands.c new file mode 100644 index 0000000000..351bd3c7ac --- /dev/null +++ b/src/libs/FT800-FT813/EVE_commands.c @@ -0,0 +1,3936 @@ +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE +/* +@file EVE_commands.c +@brief contains FT8xx / BT8xx functions +@version 5.0 +@date 2023-12-29 +@author Rudolph Riedel + +@section info + +At least for Arm Cortex-M0 and Cortex-M4 I have fastest execution with -O2. +The c-standard is C99. + + +@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_cmd_pclkfreq() +- put back writing of REG_CSSPREAD as it needs to be deactivated for higher frequencies +- added the configuration of the second PLL for the pixel clock in BT817/BT818 to EVE_init() in case the display config +has EVE_PCLK_FREQ defined +- 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() +- split all display-list commands into two functions: EVE_cmd_XXX() and EVE_cmd_XXX_burst() +- switched from using EVE_RAM_CMD + cmdOffset to REG_CMDB_WRITE +- as a side effect from switching to REG_CMDB_WRITE, every coprocessor command is automatically executed now +- renamed EVE_LIB_GetProps() back to EVE_cmd_getprops() since it does not do anything special to justify a special name +- added helper function EVE_memWrite_sram_buffer() +- added EVE_cmd_bitmap_transform() and EVE_cmd_bitmap_transform_burst() +- added zero-pointer protection to commands using block_transfer() +- added EVE_cmd_playvideo() +- changed EVE_cmd_setfont() to a display-list command and added EVE_cmd_setfont_burst() +- changed EVE_cmd_setfont2() to a display-list command and added EVE_cmd_setfont2_burst() +- added 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 EVE_cmd_fontcache() and EVE_cmd_fontcachequery() +- added EVE_cmd_calibratesub() +- added EVE_cmd_animframeram(), EVE_cmd_animframeram_burst(), EVE_cmd_animstartram(), EVE_cmd_animstartram_burst() +- added EVE_cmd_apilevel(), EVE_cmd_apilevel_burst() +- added EVE_cmd_calllist(), EVE_cmd_calllist_burst() +- added EVE_cmd_hsf(), EVE_cmd_hsf_burst() +- added EVE_cmd_linetime() +- added EVE_cmd_newlist(), EVE_cmd_newlist_burst() +- added EVE_cmd_runanim(), EVE_cmd_runanim_burst() +- added a safeguard to EVE_start_cmd_burst() to protect it from overlapping transfers with DMA and segmented lists +- used spi_transmit_32() to shorten this file by around 600 lines with no functional change +- removed the history from before 4.0 +- removed a couple of spi_transmit_32() calls from EVE_cmd_getptr() to make it work again +- Bugfix: EVE_cmd_setfont2_burst() was using CMD_SETFONT instead of CMD_SETFONT2 +- removed a check for cmd_burst from EVE_cmd_getimage() as it is in the group of commands that are not used for display +lists +- moved EVE_cmd_newlist() to the group of commands that are not used for display lists +- removed EVE_cmd_newlist_burst() +- renamed spi_flash_write() to private_block_write() and made it static +- renamed EVE_write_string() to private_string_write() and made it static +- made EVE_start_command() static +- Bugfix: ESP8266 needs 32 bit alignment for 32 bit pointers, + changed private_string_write() for burst-mode to read 8-bit values +- Bugfix: somehow messed up private_string_write() for burst-mode + but only for 8-Bit controllers +- changed EVE_memRead8(), EVE_memRead16() and EVE_memRead32() to use + spi_transmit_32() for the initial address+zero byte transfer + This speeds up ESP32/ESP8266 by several us, has no measureable effect + for ATSAMD51 and is a little slower for AVR. +- Bugfix: not sure why but setting private_block_write() to static broke it, without "static" it works +- Bugfix: EVE_cmd_flashspirx() was using CMD_FLASHREAD +- fixed a warning in EVE_init() when compiling for EVE4 +- renamed internal function EVE_begin_cmd() to eve_begin_cmd() and made it static +- changed all the EVE_start_command() calls to eve_begin_cmd() calls following the report on Github from + Michael Wachs that these are identical - they weren't prior to V5 +- removed EVE_start_command() +- Bugfix: EVE_init() was only checking the first two bits of REG_CPURESET and ignored the bit for the audio-engine, not +an issue but not correct either. +- fixed a few clang-tidy warnings +- fixed a few cppcheck warnings +- fixed a few CERT warnings +- converted all TABs to SPACEs +- made EVE_TOUCH_RZTHRESH in EVE_init() optional to a) remove it from EVE_config.h and b) make it configureable +externally +- changed EVE_init() to write 1200U to REG_TOUCH_RZTHRESH if EVE_TOUCH_RZTHRESH is not defined +- changed EVE_init() to return E_OK = 0x00 in case of success and more meaningfull values in case of failure +- changed EVE_busy() to return EVE_IS_BUSY if EVE is busy and E_OK = 0x00 if EVE is not busy - no real change in +functionality +- 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 +- changed EVE_init_flash() to return E_OK in case of success and more meaningfull values in case of failure +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available +- minor cleanup, less break and else statements +- added the burst code back into all the functions for which there is a _burst version, this allows to use the version +without the traling _burst in the name when exceution speed is not an issue - e.g. with all targets supporting DMA +- removed the 4.0 history +- added the optional parameter EVE_ROTATE as define to EVE_init() to allow for screen rotation during init + thanks for the idea to AndrejValand on Github! +- added the optional parameter EVE_BACKLIGHT_PWM to EVE_init() to allow setting the backlight during init +- modified EVE_calibrate_manual() to work better with bar type displays +- fixed a large number of MISRA-C issues - mostly more casts for explicit type conversion and more brackets +- 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 +- 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() +- more minor tweaks and fixes to make the static analyzer happy +- changed the burst variant of private_string_write() back to the older and faster version +- refactoring of EVE_init() to single return +- added prototype for EVE_write_display_parameters() +- added EVE_memRead_sram_buffer() +- Bugfix issue #81: neither DISP or the pixel clock are enabled for EVE4 configurations not using EVE_PCLK_FREQ. + thanks for the report to grados73 on Github! +- added a few support lines for the Gameduino GD3X to EVE_init() +- switched from using CMD_PCLKFREQ to writing to REG_PCLK_FREQ directly +- added define EVE_SET_REG_PCLK_2X to set REG_PCLK_2X to 1 when necessary +- Bugfix: EVE_init() did not set the audio engine to "mute" as intended, but to "silent" +- Bugfix: EVE_busy() returns E_NOT_OK now on coprocessor faults. + thanks for the report to Z0ld3n on Github! +- Fix: reworked EVE_busy() to return EVE_FAULT_RECOVERED on deteced coprocessor faults, + removed the flash commands from the fault recovery sequence as these are project specific. +- added EVE_get_and_reset_fault_state() to check if EVE_busy() triggered a fault recovery +- added notes on how to use to EVE_cmd_setfont2() and EVE_cmd_romfont() +- new optional parameter in EVE_init(): EVE_BACKLIGHT_FREQ +- fixed a couple of minor issues from static code analysis +- reworked the burst part of private_string_write() to be less complex +- renamed chipid references to regid as suggested by #93 on github +- Bugfix: broke transfers of buffers larger than 3840 when fixing issues from static code analysis +- changed a number of function parameters from signed to unsigned following the + updated BT81x series programming guide V2.4 +- did another linter pass and fixed some things +- started to improve the embedded documentation +- added more documentation +- removed EVE_cmd_hsf_burst() + +*/ + +#include "EVE_commands.h" + +/* EVE Memory Commands - used with EVE_memWritexx and EVE_memReadxx */ +#define MEM_WRITE 0x80U /* EVE Host Memory Write */ +/* #define MEM_READ 0x00U */ /* EVE Host Memory Read */ + +/* define NULL if it not already is */ +#ifndef NULL +#include +#endif + +static volatile uint8_t cmd_burst = 0U; /* flag to indicate cmd-burst is active */ +static volatile uint8_t fault_recovered = E_OK; /* flag to indicate if EVE_busy triggered a fault recovery */ + +/* ################################################################## + helper functions +##################################################################### */ + +/** + * @brief Send a host command. + */ +void EVE_cmdWrite(uint8_t const command, uint8_t const parameter) +{ + EVE_cs_set(); + spi_transmit(command); + spi_transmit(parameter); + spi_transmit(0U); + EVE_cs_clear(); +} + +/** + * @brief Implementation of rd8() function, reads 8 bits. + */ +uint8_t EVE_memRead8(uint32_t const ft_address) +{ + uint8_t data; + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + data = spi_receive(0U); /* read data byte by sending another dummy byte */ + EVE_cs_clear(); + return (data); +} + +/** + * @brief Implementation of rd16() function, reads 16 bits. + */ +uint16_t EVE_memRead16(uint32_t const ft_address) +{ + uint16_t data; + + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + uint8_t const lowbyte = spi_receive(0U); /* read low byte */ + uint8_t const hibyte = spi_receive(0U); /* read high byte */ + data = ((uint16_t) hibyte * 256U) | lowbyte; + EVE_cs_clear(); + return (data); +} + +/** + * @brief Implementation of rd32() function, reads 32 bits. + */ +uint32_t EVE_memRead32(uint32_t const ft_address) +{ + uint32_t data; + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + data = ((uint32_t) spi_receive(0U)); /* read low byte */ + data = ((uint32_t) spi_receive(0U) << 8U) | data; + data = ((uint32_t) spi_receive(0U) << 16U) | data; + data = ((uint32_t) spi_receive(0U) << 24U) | data; /* read high byte */ + EVE_cs_clear(); + return (data); +} + +/** + * @brief Implementation of wr8() function, writes 8 bits. + */ +void EVE_memWrite8(uint32_t const ft_address, uint8_t const ft_data) +{ + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); + spi_transmit((uint8_t) (ft_address >> 8U)); + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); + spi_transmit(ft_data); + EVE_cs_clear(); +} + +/** + * @brief Implementation of wr16() function, writes 16 bits. + */ +void EVE_memWrite16(uint32_t const ft_address, uint16_t const ft_data) +{ + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); /* send Memory Write plus high address byte */ + spi_transmit((uint8_t) (ft_address >> 8U)); /* send middle address byte */ + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); /* send low address byte */ + spi_transmit((uint8_t) (ft_data & 0x00ffU)); /* send data low byte */ + spi_transmit((uint8_t) (ft_data >> 8U)); /* send data high byte */ + EVE_cs_clear(); +} + +/** + * @brief Implementation of wr32() function, writes 32 bits. + */ +void EVE_memWrite32(uint32_t const ft_address, uint32_t const ft_data) +{ + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); /* send Memory Write plus high address byte */ + spi_transmit((uint8_t) (ft_address >> 8U)); /* send middle address byte */ + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); /* send low address byte */ + spi_transmit_32(ft_data); + EVE_cs_clear(); +} + +/** + * @brief Helper function, write a block of memory from the FLASH of the host controller to EVE. + */ +void EVE_memWrite_flash_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len) +{ + if (p_data != NULL) + { + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); + spi_transmit((uint8_t) (ft_address >> 8U)); + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); + + // uint32_t length = (len + 3U) & (~3U); + + for (uint32_t count = 0U; count < len; count++) + { + spi_transmit(fetch_flash_byte(&p_data[count])); + } + + EVE_cs_clear(); + } +} + +/** + * @brief Helper function, write a block of memory from the SRAM of the host controller to EVE. + */ +void EVE_memWrite_sram_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len) +{ + if (p_data != NULL) + { + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); + spi_transmit((uint8_t) (ft_address >> 8U)); + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); + + // uint32_t length = (len + 3U) & (~3U); + + for (uint32_t count = 0U; count < len; count++) + { + spi_transmit(p_data[count]); + } + + EVE_cs_clear(); + } +} + +/** + * @brief Helper function, read a block of memory from EVE to the SRAM of the host controller. + */ +void EVE_memRead_sram_buffer(uint32_t const ft_address, uint8_t *p_data, uint32_t const len) +{ + if (p_data != NULL) + { + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + + for (uint32_t count = 0U; count < len; count++) + { + p_data[count] = spi_receive(0U); /* read data byte by sending another dummy byte */ + } + + EVE_cs_clear(); + } +} + +static void CoprocessorFaultRecover(void) +{ +#if EVE_GEN > 2 + uint16_t copro_patch_pointer; + copro_patch_pointer = EVE_memRead16(REG_COPRO_PATCH_PTR); +#endif + + EVE_memWrite8(REG_CPURESET, 1U); /* hold coprocessor engine in the reset condition */ + EVE_memWrite16(REG_CMD_READ, 0U); /* set REG_CMD_READ to 0 */ + EVE_memWrite16(REG_CMD_WRITE, 0U); /* set REG_CMD_WRITE to 0 */ + EVE_memWrite16(REG_CMD_DL, 0U); /* reset REG_CMD_DL to 0 as required by the BT81x programming guide, should not hurt FT8xx */ + +#if EVE_GEN > 2 + EVE_memWrite16(REG_COPRO_PATCH_PTR, copro_patch_pointer); + + /* restore REG_PCLK in case it was set to zero by an error */ +#if (EVE_GEN > 3) && (defined EVE_PCLK_FREQ) + EVE_memWrite16(REG_PCLK_FREQ, (uint16_t) EVE_PCLK_FREQ); + EVE_memWrite8(REG_PCLK, 1U); /* enable extsync mode */ +#else + EVE_memWrite8(REG_PCLK, EVE_PCLK); +#endif + +#endif + EVE_memWrite8(REG_CPURESET, 0U); /* set REG_CPURESET to 0 to restart the coprocessor engine*/ + DELAY_MS(10U); /* just to be safe */ +} + +/** + * @brief Check if the coprocessor completed executing the current command list. + * @return - E_OK - if EVE is not busy (no DMA transfer active and REG_CMDB_SPACE has the value 0xffc, meaning the CMD-FIFO is empty + * @return - EVE_IS_BUSY - if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc + * @return - EVE_FIFO_HALF_EMPTY - if no DMA transfer is active and REG_CMDB_SPACE shows more than 2048 bytes available + * @return - E_NOT_OK - if there was a coprocessor fault and the recovery sequence was executed + * @note - if there is a coprocessor fault the external flash is not reinitialized by EVE_busy() + */ +uint8_t EVE_busy(void) +{ + uint16_t space; + uint8_t ret = EVE_IS_BUSY; + +#if defined (EVE_DMA) + if (0 == EVE_dma_busy) + { +#endif + + space = EVE_memRead16(REG_CMDB_SPACE); + + /* (REG_CMDB_SPACE & 0x03) != 0 -> we have a coprocessor fault */ + if ((space & 3U) != 0U) /* we have a coprocessor fault, make EVE play with us again */ + { + ret = EVE_FAULT_RECOVERED; + fault_recovered = EVE_FAULT_RECOVERED; /* save fault recovery state */ + CoprocessorFaultRecover(); + } + else + { + if (0xffcU == space) + { + ret = E_OK; + } + else if (space > 0x800U) + { + ret = EVE_FIFO_HALF_EMPTY; + } + else + { + ret = EVE_IS_BUSY; + } + } + +#if defined (EVE_DMA) + } +#endif + + return (ret); +} + +/** + * @brief Helper function to check if EVE_busy() tried to recover from a coprocessor fault. + * The internal fault indicator is cleared so it could be set by EVE_busy() again. + * @return - EVE_FAULT_RECOVERED - if EVE_busy() detected a coprocessor fault + * @return - E_OK - if EVE_busy() did not detect a coprocessor fault + */ +uint8_t EVE_get_and_reset_fault_state(void) +{ + uint8_t ret = E_OK; + + if (EVE_FAULT_RECOVERED == fault_recovered) + { + ret = EVE_FAULT_RECOVERED; + fault_recovered = E_OK; + } + return (ret); +} + +/** + * @brief Helper function, wait for the coprocessor to complete the FIFO queue. + */ +void EVE_execute_cmd(void) +{ + while (EVE_busy() != E_OK) + { + } +} + +/* begin a coprocessor command, this is used for non-display-list and non-burst-mode commands.*/ +static void eve_begin_cmd(uint32_t command) +{ + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ + spi_transmit_32(command); +} + +void private_block_write(const uint8_t *p_data, uint16_t len); /* prototype to comply with MISRA */ + +void private_block_write(const uint8_t *p_data, uint16_t len) +{ + uint8_t padding; + + padding = (uint8_t) (len & 3U); /* 0, 1, 2 or 3 */ + padding = 4U - padding; /* 4, 3, 2 or 1 */ + padding &= 3U; /* 3, 2 or 1 */ + + for (uint16_t count = 0U; count < len; count++) + { + spi_transmit(fetch_flash_byte(&p_data[count])); + } + + while (padding > 0U) + { + spi_transmit(0U); + padding--; + } +} + +void block_transfer(const uint8_t *p_data, uint32_t len); /* prototype to comply with MISRA */ + +void block_transfer(const uint8_t *p_data, uint32_t len) +{ + uint32_t bytes_left; + uint32_t offset = 0U; + + bytes_left = len; + while (bytes_left > 0U) + { + uint32_t block_len; + + block_len = (bytes_left > 3840UL) ? 3840UL : bytes_left; + + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ + private_block_write(&p_data[offset], (uint16_t) block_len); + EVE_cs_clear(); + offset += block_len; + bytes_left -= block_len; + EVE_execute_cmd(); + } +} + +/* ################################################################## + coprocessor commands that are not used in displays lists, + these are not to be used with burst transfers +################################################################### */ + +/* BT817 / BT818 */ +#if EVE_GEN > 3 + +/** + * @brief Write "num" bytes from src in RAM_G to the previously erased external flash of a BT81x at address dest. + * @note - dest must be 4096-byte aligned, src must be 4-byte aligned, num must be a multiple of 4096 + * @note - EVE will not do anything if the alignment requirements are not met + * @note - the address ptr is relative to the flash so the first address is 0x000000 not 0x800000 + * @note - this looks exactly the same as EVE_cmd_flashupdate() but it needs the flash to be empty + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashprogram(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHPROGRAM); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Enable the font cache. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_fontcache(uint32_t font, uint32_t ptr, uint32_t num) +{ + eve_begin_cmd(CMD_FONTCACHE); + spi_transmit_32(font); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Queries the capacity and utilization of the font cache. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_fontcachequery(uint32_t *p_total, uint32_t *p_used) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_FONTCACHEQUERY); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + + if (p_total != NULL) + { + *p_total = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL)); + } + if (p_used != NULL) + { + *p_used = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL)); + } +} + +/** + * @brief Returns all the attributes of the bitmap made by the previous CMD_LOADIMAGE, CMD_PLAYVIDEO, CMD_VIDEOSTART or CMD_VIDEOSTARTF. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_getimage(uint32_t *p_source, uint32_t *p_fmt, uint32_t *p_width, uint32_t *p_height, uint32_t *p_palette) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_GETIMAGE); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + + if (p_palette != NULL) + { + *p_palette = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL)); + } + if (p_height != NULL) + { + *p_height = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL)); + } + if (p_width != NULL) + { + *p_width = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 12UL) & 0xfffUL)); + } + if (p_fmt != NULL) + { + *p_fmt = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 16UL) & 0xfffUL)); + } + if (p_source != NULL) + { + *p_source = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 20UL) & 0xfffUL)); + } +} + +/** + * @brief Undocumented command. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_linetime(uint32_t dest) +{ + eve_begin_cmd(CMD_LINETIME); + spi_transmit_32(dest); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Starts the compilation of a command list into RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_newlist(uint32_t adr) +{ + eve_begin_cmd(CMD_NEWLIST); + spi_transmit_32(adr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Sets REG_PCLK_FREQ to generate the closest possible frequency to the one requested. + * @return - the frequency achieved or zero if no frequency was found + * @note - When using this command, the flash BLOB is required. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_pclkfreq(uint32_t ftarget, int32_t rounding) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_PCLKFREQ); + spi_transmit_32(ftarget); + spi_transmit_32((uint32_t) rounding); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief Waits for a specified number of microseconds. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_wait(uint32_t usec) +{ + eve_begin_cmd(CMD_WAIT); + spi_transmit_32(usec); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +#endif /* EVE_GEN > 3 */ + +/* BT815 / BT816 */ +#if EVE_GEN > 2 + +/** + * @brief Clears the graphics engine’s internal flash cache. + * @note - This function includes clearing out the display list. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_clearcache(void) +{ + EVE_cmd_dl(CMD_DLSTART); + EVE_cmd_dl(CMD_SWAP); + EVE_execute_cmd(); + + EVE_cmd_dl(CMD_DLSTART); + EVE_cmd_dl(CMD_SWAP); + EVE_execute_cmd(); + + EVE_cmd_dl(CMD_CLEARCACHE); + EVE_execute_cmd(); +} + +/** + * @brief Re-connect to the attached SPI flash storage. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashattach(void) +{ + eve_begin_cmd(CMD_FLASHATTACH); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Dis-connect from the attached SPI flash storage. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashdetach(void) +{ + eve_begin_cmd(CMD_FLASHDETACH); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Erases the attached SPI flash storage. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flasherase(void) +{ + eve_begin_cmd(CMD_FLASHERASE); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Drive the attached SPI flash storage in full-speed mode, if possible. + * @return - Zero on success, error code on failure + * @note - When using this command, the flash BLOB is required. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_flashfast(void) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_FLASHFAST); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief De-asserts the SPI CS signal of the attached SPI flash storage. + * @note - Only works when the attached SPI flash storage has been detached. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashspidesel(void) +{ + eve_begin_cmd(CMD_FLASHSPIDESEL); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Copies "num" bytes from "src" in attached SPI flash storage to "dest" in RAM_G. + * @note - src must be 64-byte aligned, dest must be 4-byte aligned, num must be a multiple of 4 + * @note - EVE will not do anything if the alignment requirements are not met + * @note - The src pointer is relative to the flash so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashread(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHREAD); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Set the source address for flash data loaded by the CMD_LOADIMAGE, CMD_PLAYVIDEO, CMD_VIDEOSTARTF and CMD_INFLATE2 commands with the OPT_FLASH option. + * @note - Address must be 64-byte aligned. + * @note - EVE will not do anything if the alignment requirements are not met. + * @note - The pointer is relative to the flash, so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashsource(uint32_t ptr) +{ + eve_begin_cmd(CMD_FLASHSOURCE); + spi_transmit_32(ptr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Receives bytes from the flash SPI interface and writes them to main memory. + * @note - Only works when the attached SPI flash storage has been detached. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashspirx(uint32_t dest, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHSPIRX); + spi_transmit_32(dest); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Transmits bytes over the flash SPI interface. + * @note - Only works when the attached SPI flash storage has been detached. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashspitx(uint32_t num, const uint8_t *p_data) +{ + eve_begin_cmd(CMD_FLASHSPITX); + spi_transmit_32(num); + EVE_cs_clear(); + block_transfer(p_data, num); +} + +/** + * @brief Write "num" bytes from src in RAM_G to the attached SPI flash storage at address dest. + * @note - dest must be 4096-byte aligned, src must be 4-byte aligned, num must be a multiple of 4096 + * @note - EVE will not do anything if the alignment requirements are not met. + * @note - The address ptr is relative to the flash so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashupdate(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHUPDATE); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Write "num" bytes to the attached SPI flash storage at address dest. + * @note - dest must be 256-byte aligned, num must be a multiple of 256 + * @note - EVE will not do anything if the alignment requirements are not met. + * @note - The address ptr is relative to the flash so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashwrite(uint32_t ptr, uint32_t num, const uint8_t *p_data) +{ + eve_begin_cmd(CMD_FLASHWRITE); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + if (p_data != NULL) + { + block_transfer(p_data, num); + } +} + +/** + * @brief Decompress data into RAM_G. + * @note - The data must be correct and complete. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_inflate2(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len) +{ + eve_begin_cmd(CMD_INFLATE2); + spi_transmit_32(ptr); + spi_transmit_32(options); + EVE_cs_clear(); + + if (0UL == options) /* direct data, not by Media-FIFO or Flash */ + { + if (p_data != NULL) + { + block_transfer(p_data, len); + } + } +} + +#endif /* EVE_GEN > 2 */ + +/** + * @brief Returns the source address and size of the bitmap loaded by the previous CMD_LOADIMAGE. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_getprops(uint32_t *p_pointer, uint32_t *p_width, uint32_t *p_height) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_GETPROPS); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + + if (p_pointer != NULL) + { + *p_pointer = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 12UL) & 0xfffUL)); + } + if (p_width != NULL) + { + *p_width = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL)); + } + if (p_height != NULL) + { + *p_height = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL)); + } +} + +/** + * @brief Returns the next address after a CMD_INFLATE and other commands. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_getptr(void) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_GETPTR); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief Decompress data into RAM_G. + * @note - The data must be correct and complete. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_inflate(uint32_t ptr, const uint8_t *p_data, uint32_t len) +{ + eve_begin_cmd(CMD_INFLATE); + spi_transmit_32(ptr); + EVE_cs_clear(); + if (p_data != NULL) + { + block_transfer(p_data, len); + } +} + +/** + * @brief Trigger interrupt INT_CMDFLAG. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_interrupt(uint32_t msec) +{ + eve_begin_cmd(CMD_INTERRUPT); + spi_transmit_32(msec); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Loads and decodes a JPEG/PNG image into RAM_G. + * @note - Decoding PNG images takes significantly more time than decoding JPEG images. + * @note - In doubt use the EVE Asset Builder to check if PNG/JPEG files are compatible. + * @note - If the image is in PNG format, the top 42kiB of RAM_G will be overwritten. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_loadimage(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len) +{ + eve_begin_cmd(CMD_LOADIMAGE); + spi_transmit_32(ptr); + spi_transmit_32(options); + EVE_cs_clear(); + +#if EVE_GEN > 2 + if ((0UL == (options & EVE_OPT_MEDIAFIFO)) && + (0UL == (options & EVE_OPT_FLASH))) /* direct data, neither by Media-FIFO or from Flash */ +#else + if (0UL == (options & EVE_OPT_MEDIAFIFO)) /* direct data, not by Media-FIFO */ +#endif + { + if (p_data != NULL) + { + block_transfer(p_data, len); + } + } +} + +/** + * @brief Set up a streaming media FIFO in RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_mediafifo(uint32_t ptr, uint32_t size) +{ + eve_begin_cmd(CMD_MEDIAFIFO); + spi_transmit_32(ptr); + spi_transmit_32(size); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Copy a block of RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_MEMCPY); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Compute a CRC-32 for RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_memcrc(uint32_t ptr, uint32_t num) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_MEMCRC); + spi_transmit_32(ptr); + spi_transmit_32(num); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief Fill RAM_G with a byte value. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_memset(uint32_t ptr, uint8_t value, uint32_t num) +{ + eve_begin_cmd(CMD_MEMSET); + spi_transmit_32(ptr); + spi_transmit_32((uint32_t)value); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Write bytes into RAM_G using the coprocessor. + * @note - Commented out, just use one of the EVE_memWrite* helper functions to directly write to EVEs memory. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +/* +void EVE_cmd_memwrite(uint32_t dest, uint32_t num, const uint8_t *p_data) +{ + eve_begin_cmd(CMD_MEMWRITE); + spi_transmit_32(dest); + spi_transmit_32(num); + + num = (num + 3U) & (~3U); + + for (uint32_t count = 0U; count 2 + if ((0UL == (options & EVE_OPT_MEDIAFIFO)) && + (0UL == (options & EVE_OPT_FLASH))) /* direct data, neither by Media-FIFO or from Flash */ +#else + if (0UL == (options & EVE_OPT_MEDIAFIFO)) /* direct data, not by Media-FIFO */ +#endif + { + if (p_data != NULL) + { + block_transfer(p_data, len); + } + } +} + +/** + * @brief Rotate the screen and set up transform matrix accordingly. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_setrotate(uint32_t rotation) +{ + eve_begin_cmd(CMD_SETROTATE); + spi_transmit_32(rotation); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Take a snapshot of the current screen. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_snapshot(uint32_t ptr) +{ + eve_begin_cmd(CMD_SNAPSHOT); + spi_transmit_32(ptr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Take a snapshot of part of the current screen with format option. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_snapshot2(uint32_t fmt, uint32_t ptr, int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt) +{ + eve_begin_cmd(CMD_SNAPSHOT2); + spi_transmit_32(fmt); + spi_transmit_32(ptr); + + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Track touches for a graphics object. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_track(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t tag) +{ + eve_begin_cmd(CMD_TRACK); + + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + + spi_transmit((uint8_t) (tag)); + spi_transmit((uint8_t) (tag >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Load the next frame of a video. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_videoframe(uint32_t dest, uint32_t result_ptr) +{ + eve_begin_cmd(CMD_VIDEOFRAME); + spi_transmit_32(dest); + spi_transmit_32(result_ptr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/* ################################################################## + patching and initialization +#################################################################### */ + +#if EVE_GEN > 2 + +/** + * @brief EVE flash initialization for BT81x, switches the FLASH attached to a BT81x to full-speed mode + * @return Returns E_OK in case of success, EVE_FAIL_FLASH_STATUS_INIT if the status remains init, + * EVE_FAIL_FLASH_STATUS_DETACHED if no flash chip was found, a number of different values for failures with + * cmd_flashfast and E_NOT_OK if a not supported status is returned in REG_FLASH_STATUS. + */ +uint8_t EVE_init_flash(void) +{ + uint8_t timeout = 0U; + uint8_t status; + uint8_t ret_val = E_NOT_OK; + + status = EVE_memRead8(REG_FLASH_STATUS); /* should be 0x02 - FLASH_STATUS_BASIC, power-up is done and the attached flash is detected */ + + /* we are somehow still in init, give it a litte more time, this should never happen */ + while (EVE_FLASH_STATUS_INIT == status) + { + status = EVE_memRead8(REG_FLASH_STATUS); + DELAY_MS(1U); + timeout++; + if (timeout > 100U) /* 100ms and still in init, lets call quits now and exit with an error */ + { + ret_val = EVE_FAIL_FLASH_STATUS_INIT; + break; + } + } + + /* no flash was found during init, no flash present or the detection failed, give it another try */ + if (EVE_FLASH_STATUS_DETACHED == status) + { + EVE_cmd_dl(CMD_FLASHATTACH); + EVE_execute_cmd(); + status = EVE_memRead8(REG_FLASH_STATUS); + if (status != 2U) /* still not in FLASH_STATUS_BASIC, time to give up */ + { + ret_val = EVE_FAIL_FLASH_STATUS_DETACHED; + } + } + + /* flash detected and ready for action, move it up to FLASH_STATUS_FULL */ + if (EVE_FLASH_STATUS_BASIC == status) + { + uint32_t result; + + result = EVE_cmd_flashfast(); + + switch (result) + { + case 0x0000UL: + ret_val = E_OK; + break; + + case 0xE001UL: + ret_val = EVE_FAIL_FLASHFAST_NOT_SUPPORTED; + break; + + case 0xE002UL: + ret_val = EVE_FAIL_FLASHFAST_NO_HEADER_DETECTED; + break; + + case 0xE003UL: + ret_val = EVE_FAIL_FLASHFAST_SECTOR0_FAILED; + break; + + case 0xE004UL: + ret_val = EVE_FAIL_FLASHFAST_BLOB_MISMATCH; + break; + + case 0xE005UL: + ret_val = EVE_FAIL_FLASHFAST_SPEED_TEST; + break; + + default: /* we have an unknown error, so just return failure */ + ret_val = E_NOT_OK; + break; + } + } + + if (EVE_FLASH_STATUS_FULL == status) /* we are already there, why has this function been called? */ + { + ret_val = E_OK; + } + + return (ret_val); +} + +#endif /* EVE_GEN > 2 */ + +#if EVE_GEN < 3 +#if defined (__AVR__) +#include +#else +#define PROGMEM +#endif +#endif + +void use_gt911(void); + +void use_gt911(void) +{ +#if EVE_GEN > 2 + EVE_memWrite16(REG_TOUCH_CONFIG, 0x05d0U); /* switch to Goodix touch controller */ +#else + +/* FT811 / FT813 binary-blob from FTDIs AN_336 to patch the touch-engine for Goodix GT911 / GT9271 touch controllers */ +const uint8_t eve_gt911_data[1184U] PROGMEM = +{ + 26, 255, 255, 255, 32, 32, 48, 0, 4, 0, 0, 0, 2, 0, 0, 0, 34, 255, 255, 255, 0, 176, 48, + 0, 120, 218, 237, 84, 221, 111, 84, 69, 20, 63, 51, 179, 93, 160, 148, 101, 111, 76, 5, 44, 141, 123, + 111, 161, 11, 219, 154, 16, 9, 16, 17, 229, 156, 75, 26, 11, 13, 21, 227, 3, 16, 252, 184, 179, 45, + 219, 143, 45, 41, 125, 144, 72, 67, 100, 150, 71, 189, 113, 18, 36, 17, 165, 100, 165, 198, 16, 32, 17, + 149, 196, 240, 128, 161, 16, 164, 38, 54, 240, 0, 209, 72, 130, 15, 38, 125, 48, 66, 82, 30, 76, 19, + 31, 172, 103, 46, 139, 24, 255, 4, 227, 157, 204, 156, 51, 115, 102, 206, 231, 239, 220, 5, 170, 94, 129, + 137, 75, 194, 216, 98, 94, 103, 117, 115, 121, 76, 131, 177, 125, 89, 125, 82, 123, 60, 243, 58, 142, 242, + 204, 185, 243, 188, 118, 156, 227, 155, 203, 238, 238, 195, 251, 205, 229, 71, 92, 28, 169, 190, 184, 84, 143, + 113, 137, 53, 244, 103, 181, 237, 87, 253, 113, 137, 233, 48, 12, 198, 165, 181, 104, 139, 25, 84, 253, 155, + 114, 74, 191, 0, 54, 138, 163, 12, 62, 131, 207, 129, 23, 217, 34, 91, 31, 128, 65, 246, 163, 175, 213, + 8, 147, 213, 107, 35, 203, 94, 108, 3, 111, 40, 171, 83, 24, 15, 165, 177, 222, 116, 97, 23, 188, 140, + 206, 150, 42, 102, 181, 87, 78, 86, 182, 170, 134, 215, 241, 121, 26, 243, 252, 2, 76, 115, 217, 139, 222, + 206, 173, 136, 132, 81, 61, 35, 185, 39, 113, 23, 46, 199, 76, 178, 54, 151, 183, 224, 0, 40, 189, 28, + 149, 182, 58, 131, 79, 152, 30, 76, 34, 98, 234, 162, 216, 133, 141, 102, 39, 170, 40, 192, 101, 53, 201, + 146, 191, 37, 77, 44, 177, 209, 74, 211, 5, 206, 187, 5, 6, 216, 47, 53, 96, 123, 22, 50, 103, 251, + 192, 84, 17, 74, 227, 185, 56, 106, 51, 91, 161, 96, 182, 163, 48, 171, 141, 139, 65, 152, 66, 66, 11, + 102, 43, 158, 75, 36, 80, 147, 184, 147, 139, 112, 17, 235, 216, 103, 111, 239, 245, 92, 10, 175, 194, 40, + 44, 58, 125, 5, 59, 112, 50, 103, 245, 4, 78, 192, 5, 156, 194, 51, 60, 191, 134, 75, 110, 173, 237, + 46, 192, 121, 156, 192, 115, 184, 218, 120, 67, 63, 115, 46, 11, 102, 10, 97, 232, 50, 235, 114, 182, 148, + 118, 178, 41, 188, 12, 135, 77, 202, 124, 12, 96, 238, 35, 161, 234, 189, 129, 23, 249, 212, 139, 230, 25, + 53, 48, 205, 52, 93, 163, 117, 53, 154, 170, 81, 85, 163, 178, 70, 69, 66, 167, 241, 14, 46, 241, 1, + 226, 136, 152, 179, 197, 59, 184, 148, 254, 49, 132, 48, 15, 176, 137, 192, 76, 131, 196, 105, 104, 162, 86, + 81, 160, 165, 255, 26, 173, 162, 137, 86, 145, 210, 183, 192, 55, 175, 194, 211, 60, 91, 120, 230, 184, 174, + 27, 41, 131, 155, 40, 224, 29, 87, 179, 232, 16, 55, 55, 7, 165, 147, 81, 23, 165, 49, 101, 54, 224, + 75, 180, 81, 108, 18, 29, 226, 69, 225, 110, 175, 224, 42, 212, 25, 47, 130, 193, 110, 234, 192, 215, 252, + 56, 74, 162, 24, 46, 251, 174, 54, 106, 68, 245, 14, 9, 155, 160, 22, 120, 207, 104, 240, 29, 90, 178, + 140, 28, 24, 220, 47, 166, 112, 61, 251, 208, 192, 111, 56, 239, 238, 93, 255, 251, 62, 99, 32, 193, 75, + 61, 190, 235, 123, 229, 110, 218, 194, 85, 79, 225, 59, 98, 20, 238, 227, 235, 220, 11, 221, 149, 25, 180, + 116, 194, 159, 111, 96, 192, 24, 213, 59, 139, 179, 156, 215, 69, 230, 19, 24, 35, 135, 117, 206, 171, 206, + 162, 67, 129, 234, 61, 235, 11, 104, 103, 84, 64, 223, 167, 254, 40, 163, 101, 92, 84, 43, 150, 46, 249, + 219, 205, 7, 116, 11, 91, 104, 61, 57, 75, 223, 8, 48, 25, 28, 119, 252, 222, 113, 49, 86, 249, 74, + 180, 211, 156, 181, 61, 215, 168, 157, 7, 251, 199, 150, 242, 250, 91, 58, 132, 94, 121, 7, 53, 151, 139, + 98, 6, 165, 153, 69, 214, 32, 110, 211, 100, 101, 31, 89, 45, 81, 98, 23, 205, 205, 197, 209, 109, 186, + 198, 35, 141, 191, 249, 25, 60, 132, 223, 153, 251, 98, 20, 239, 146, 139, 20, 217, 250, 41, 250, 137, 58, + 177, 90, 57, 79, 51, 108, 233, 20, 253, 194, 187, 49, 222, 205, 114, 141, 96, 48, 175, 219, 107, 54, 111, + 138, 22, 154, 103, 108, 79, 58, 252, 179, 178, 79, 164, 195, 2, 153, 36, 39, 170, 199, 201, 167, 197, 85, + 106, 8, 59, 177, 81, 46, 56, 2, 230, 75, 114, 17, 55, 112, 188, 65, 208, 137, 77, 114, 10, 115, 55, + 58, 208, 197, 173, 122, 87, 6, 140, 110, 42, 208, 124, 163, 70, 108, 241, 104, 18, 245, 98, 214, 187, 134, + 53, 42, 221, 22, 182, 133, 211, 116, 148, 177, 194, 209, 192, 85, 90, 199, 58, 55, 203, 2, 229, 19, 137, + 187, 161, 228, 154, 112, 203, 145, 125, 244, 188, 220, 118, 228, 41, 201, 181, 41, 195, 144, 215, 183, 51, 80, + 250, 21, 217, 16, 217, 200, 235, 109, 227, 188, 122, 218, 142, 60, 170, 224, 112, 240, 184, 130, 229, 224, 113, + 5, 223, 148, 163, 80, 165, 183, 130, 187, 132, 116, 64, 238, 161, 85, 220, 115, 139, 205, 98, 227, 244, 29, + 102, 125, 7, 37, 243, 123, 223, 11, 26, 92, 63, 243, 116, 61, 191, 138, 123, 244, 160, 84, 186, 74, 31, + 5, 174, 247, 119, 135, 199, 248, 253, 135, 242, 97, 102, 145, 190, 144, 14, 85, 238, 221, 231, 193, 158, 48, + 205, 25, 120, 248, 15, 220, 29, 158, 9, 70, 185, 30, 103, 229, 33, 254, 23, 237, 160, 172, 62, 193, 90, + 222, 224, 232, 14, 200, 56, 90, 104, 142, 227, 120, 110, 6, 21, 211, 203, 65, 150, 99, 151, 220, 247, 87, + 164, 50, 159, 49, 239, 234, 58, 142, 0, 109, 108, 123, 18, 79, 227, 36, 100, 248, 222, 205, 96, 127, 120, + 26, 171, 228, 69, 63, 36, 17, 252, 200, 17, 116, 242, 187, 227, 88, 143, 247, 2, 75, 191, 6, 130, 59, + 188, 11, 55, 240, 31, 243, 122, 152, 226, 183, 207, 154, 73, 188, 39, 219, 43, 105, 222, 87, 41, 143, 141, + 140, 175, 73, 112, 184, 252, 61, 184, 16, 90, 250, 35, 168, 82, 119, 176, 57, 116, 94, 200, 150, 22, 190, + 179, 44, 104, 12, 235, 84, 149, 102, 252, 89, 154, 193, 99, 228, 106, 242, 125, 248, 64, 194, 255, 223, 127, + 242, 83, 11, 255, 2, 70, 214, 226, 128, 0, 0 +}; + + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ + private_block_write(eve_gt911_data, sizeof(eve_gt911_data)); + EVE_cs_clear(); + EVE_execute_cmd(); + + EVE_memWrite8(REG_TOUCH_OVERSAMPLE, 0x0fU); /* setup oversample to 0x0f as "hidden" in binary-blob for AN_336 */ + EVE_memWrite16(REG_TOUCH_CONFIG, 0x05D0U); /* write magic cookie as requested by AN_336 */ + + /* specific to the EVE2 modules from Matrix-Orbital we have to use GPIO3 to reset GT911 */ + EVE_memWrite16(REG_GPIOX_DIR, 0x8008U); /* Reset-Value is 0x8000, adding 0x08 sets GPIO3 to output, default-value + for REG_GPIOX is 0x8000 -> Low output on GPIO3 */ + DELAY_MS(1U); /* wait more than 100us */ + EVE_memWrite8(REG_CPURESET, 0U); /* clear all resets */ + DELAY_MS(110U); /* wait more than 55ms - does not work with multitouch, for some reason a minimum delay of 108ms is + required */ + EVE_memWrite16(REG_GPIOX_DIR, 0x8000U); /* setting GPIO3 back to input */ +#endif +} + +/** + * @brief Waits for either reading REG_ID with a value of 0x7c, indicating that + * an EVE chip is present and ready to communicate, or untill a timeout of 400ms has passed. + * @return Returns E_OK in case of success, EVE_FAIL_REGID_TIMEOUT if the + * value of 0x7c could not be read. + */ +static uint8_t wait_regid(void) +{ + uint8_t ret = EVE_FAIL_REGID_TIMEOUT; + uint8_t regid = 0U; + + for (uint16_t timeout = 0U; timeout < 400U; timeout++) + { + DELAY_MS(1U); + + regid = EVE_memRead8(REG_ID); + if (0x7cU == regid) /* EVE is up and running */ + { + ret = E_OK; + break; + } + } + + return (ret); +} + +/** + * @brief Waits for either REG_CPURESET to indicate that the audio, touch and + * coprocessor units finished their respective reset cycles, + * or untill a timeout of 50ms has passed. + * @return Returns E_OK in case of success, EVE_FAIL_RESET_TIMEOUT if either the + * audio, touch or coprocessor unit indicate a fault by not returning from reset. + */ +static uint8_t wait_reset(void) +{ + uint8_t ret = EVE_FAIL_RESET_TIMEOUT; + uint8_t reset = 0U; + + for (uint16_t timeout = 0U; timeout < 50U; timeout++) + { + DELAY_MS(1U); + + reset = EVE_memRead8(REG_CPURESET) & 7U; + if (0U == reset) /* EVE reports all units running */ + { + ret = E_OK; + break; + } + } + + return (ret); +} + +/** + * @brief Writes all parameters defined for the display selected in EVE_config.h. + * to the corresponding registers. + * It is used by EVE_init() and can be used to refresh the register values if needed. + */ +void EVE_write_display_parameters(void) +{ + /* Initialize Display */ + EVE_memWrite16(REG_HSIZE, EVE_HSIZE); /* active display width */ + EVE_memWrite16(REG_HCYCLE, EVE_HCYCLE); /* total number of clocks per line, incl front/back porch */ + EVE_memWrite16(REG_HOFFSET, EVE_HOFFSET); /* start of active line */ + EVE_memWrite16(REG_HSYNC0, EVE_HSYNC0); /* start of horizontal sync pulse */ + EVE_memWrite16(REG_HSYNC1, EVE_HSYNC1); /* end of horizontal sync pulse */ + EVE_memWrite16(REG_VSIZE, EVE_VSIZE); /* active display height */ + EVE_memWrite16(REG_VCYCLE, EVE_VCYCLE); /* total number of lines per screen, including pre/post */ + EVE_memWrite16(REG_VOFFSET, EVE_VOFFSET); /* start of active screen */ + EVE_memWrite16(REG_VSYNC0, EVE_VSYNC0); /* start of vertical sync pulse */ + EVE_memWrite16(REG_VSYNC1, EVE_VSYNC1); /* end of vertical sync pulse */ + EVE_memWrite8(REG_SWIZZLE, EVE_SWIZZLE); /* FT8xx output to LCD - pin order */ + EVE_memWrite8(REG_PCLK_POL, EVE_PCLKPOL); /* LCD data is clocked in on this PCLK edge */ + EVE_memWrite8(REG_CSPREAD, EVE_CSPREAD); /* helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */ + + /* configure Touch */ + EVE_memWrite8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS); /* enable touch */ +#if defined (EVE_TOUCH_RZTHRESH) + EVE_memWrite16(REG_TOUCH_RZTHRESH, EVE_TOUCH_RZTHRESH); /* configure the sensitivity of resistive touch */ +#else + EVE_memWrite16(REG_TOUCH_RZTHRESH, 1200U); /* set a reasonable default value if none is given */ +#endif + +#if defined (EVE_ROTATE) + EVE_memWrite8(REG_ROTATE, EVE_ROTATE & 7U); /* bit0 = invert, bit2 = portrait, bit3 = mirrored */ + /* reset default value is 0x0 - not inverted, landscape, not mirrored */ +#endif +} + +static void enable_pixel_clock(void) +{ + EVE_memWrite8(REG_GPIO, 0x80U); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIO_DIR by default */ + +#if (EVE_GEN > 3) && (defined EVE_PCLK_FREQ) + EVE_memWrite16(REG_PCLK_FREQ, (uint16_t) EVE_PCLK_FREQ); + +#if defined (EVE_SET_REG_PCLK_2X) + EVE_memWrite8(REG_PCLK_2X, 1U); +#endif + + EVE_memWrite8(REG_PCLK, 1U); /* enable extsync mode */ +#else + EVE_memWrite8(REG_PCLK, EVE_PCLK); /* start clocking data to the LCD panel */ +#endif +} + +/** + * @brief Initializes EVE according to the selected configuration from EVE_config.h. + * @return E_OK in case of success + * @note - Has to be executed with the SPI setup to 11 MHz or less as required by FT8xx / BT8xx! + * @note - Additional settings can be made through extra macros. + * @note - EVE_TOUCH_RZTHRESH - configure the sensitivity of resistive touch, defaults to 1200. + * @note - EVE_ROTATE - set the screen rotation: bit0 = invert, bit1 = portrait, bit2 = mirrored. + * @note - needs a set of calibration values for the selected rotation since this rotates before calibration! + * @note - EVE_BACKLIGHT_FREQ - configure the backlight frequency, default is not writing it which results in 250Hz. + * @note - EVE_BACKLIGHT_PWM - configure the backlight pwm, defaults to 0x20 / 25%. + */ +uint8_t EVE_init(void) +{ + uint8_t ret; + + EVE_pdn_set(); + DELAY_MS(6U); /* minimum time for power-down is 5ms */ + EVE_pdn_clear(); + DELAY_MS(21U); /* minimum time to allow from rising PD_N to first access is 20ms */ + +#if defined (EVE_GD3X) + EVE_cmdWrite(EVE_RST_PULSE,0U); /* reset, only required for warm-start if PowerDown line is not used */ +#endif + + if(EVE_HAS_CRYSTAL) { + EVE_cmdWrite(EVE_CLKEXT, 0U); /* setup EVE for external clock */ + } + else { + EVE_cmdWrite(EVE_CLKINT, 0U); /* setup EVE for internal clock */ + } + +#if EVE_GEN > 2 + EVE_cmdWrite(EVE_CLKSEL, 0x46U); /* set clock to 72 MHz */ +#endif + + EVE_cmdWrite(EVE_ACTIVE, 0U); /* start EVE */ + DELAY_MS(40U); /* give EVE a moment of silence to power up */ + + ret = wait_regid(); + if (E_OK == ret) + { + ret = wait_reset(); + if (E_OK == ret) + { +/* tell EVE that we changed the frequency from default to 72MHz for BT8xx */ +#if EVE_GEN > 2 + EVE_memWrite32(REG_FREQUENCY, 72000000UL); +#endif + +/* we have a display with a Goodix GT911 / GT9271 touch-controller on it, + so we patch our FT811 or FT813 according to AN_336 or setup a BT815 / BT817 accordingly */ + if(EVE_HAS_GT911) { + use_gt911(); + } + +#if defined (EVE_ADAM101) + EVE_memWrite8(REG_PWM_DUTY, 0x80U); /* turn off backlight for Glyn ADAM101 module, it uses inverted values */ +#else + EVE_memWrite8(REG_PWM_DUTY, 0U); /* turn off backlight for any other module */ +#endif + EVE_write_display_parameters(); + + /* disable Audio for now */ + EVE_memWrite8(REG_VOL_PB, 0U); /* turn recorded audio volume down, reset-default is 0xff */ + EVE_memWrite8(REG_VOL_SOUND, 0U); /* turn synthesizer volume down, reset-default is 0xff */ + EVE_memWrite16(REG_SOUND, EVE_MUTE); /* set synthesizer to mute */ + + /* write a basic display-list to get things started */ + EVE_memWrite32(EVE_RAM_DL, DL_CLEAR_COLOR_RGB); + EVE_memWrite32(EVE_RAM_DL + 4U, (DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG)); + EVE_memWrite32(EVE_RAM_DL + 8U, DL_DISPLAY); /* end of display list */ + EVE_memWrite32(REG_DLSWAP, EVE_DLSWAP_FRAME); + /* nothing is being displayed yet... the pixel clock is still 0x00 */ + +#if defined (EVE_GD3X) + EVE_memWrite16(REG_OUTBITS,0x01B6U); /* the GD3X is only using 6 bits per color */ +#endif + + enable_pixel_clock(); + + EVE_memWrite16(REG_PWM_HZ, EVE_BACKLIGHT_FREQ); /* set backlight frequency to configured value */ + + EVE_memWrite8(REG_PWM_DUTY, EVE_BACKLIGHT_PWM); /* set backlight pwm to user requested level */ + DELAY_MS(1U); + EVE_execute_cmd(); /* just to be safe, wait for EVE to not be busy */ + +#if defined (EVE_DMA) + EVE_init_dma(); /* prepare DMA */ +#endif + } + } + + return (ret); +} + +/* ################################################################## + functions for display lists +##################################################################### */ + +/** + * @brief Begin a sequence of commands or prepare a DMA transfer if applicable. + * @note - Needs to be used with EVE_end_cmd_burst(). + * @note - Do not use any functions in the sequence that do not address the command-fifo as for example any of EVE_mem...() functions. + * @note - Do not use any of the functions that do not support burst-mode. + */ +void EVE_start_cmd_burst(void) +{ +#if defined (EVE_DMA) + if (EVE_dma_busy) + { + EVE_execute_cmd(); /* this is a safe-guard to protect segmented display-list building with DMA from overlapping */ + } +#endif + + cmd_burst = 42U; + +#if defined (EVE_DMA) + EVE_dma_buffer[0U] = 0x7825B000UL; /* REG_CMDB_WRITE + MEM_WRITE low mid hi 00 */ +// ((uint8_t) (ft_address >> 16U) | MEM_WRITE) | (ft_address & 0x0000ff00UL) | ((uint8_t) (ft_address) << 16U); +// EVE_dma_buffer[0U] = EVE_dma_buffer[0U] << 8U; + EVE_dma_buffer_index = 1U; +#else + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ +#endif +} + +/** + * @brief End a sequence of commands or trigger a prepared DMA transfer if applicable. + * @note - Needs to be used with EVE_start_cmd_burst(). + */ +void EVE_end_cmd_burst(void) +{ + cmd_burst = 0U; + +#if defined (EVE_DMA) + EVE_start_dma_transfer(); /* begin DMA transfer */ +#else + EVE_cs_clear(); +#endif +} + +/* write a string to coprocessor memory in context of a command: */ +/* no chip-select, just plain SPI-transfers */ +static void private_string_write(const char *p_text) +{ + /* treat the array as bunch of bytes */ + const uint8_t *const p_bytes = (const uint8_t *)p_text; + + if (0U == cmd_burst) + { + uint8_t textindex = 0U; + uint8_t padding; + + /* either leave on Zero or when the string is too long */ + while ((textindex < 249U) && (p_bytes[textindex] != 0U)) + { + spi_transmit(p_bytes[textindex]); + textindex++; + } + + /* transmit at least one 0x00 byte */ + /* and up to four if the string happens to be 4-byte aligned already */ + padding = textindex & 3U; /* 0, 1, 2 or 3 */ + padding = 4U - padding; /* 4, 3, 2 or 1 */ + + while (padding > 0U) + { + spi_transmit(0U); + padding--; + } + } + else /* we are in burst mode, so every transfer is 32 bits */ + { + for (uint8_t textindex = 0U; textindex < 249U; textindex += 4U) + { + uint32_t calc = 0U; + + for (uint8_t index = 0U; index < 4U; index++) + { + uint8_t data; + + data = p_bytes[textindex + index]; + + if (0U == data) + { + spi_transmit_burst(calc); + return; /* MISRA 2012 rule 15.5 (advisory) violation */ + } + + calc += ((uint32_t)data) << (index * 8U); + } + + spi_transmit_burst(calc); + } + + spi_transmit_burst(0U); /* executed when the line is too long */ + } +} + +/* BT817 / BT818 */ +#if EVE_GEN > 3 + +/** + * @brief Render one frame in RAM_G of an animation. + */ +void EVE_cmd_animframeram(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMFRAMERAM); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit_32(aoptr); + spi_transmit_32(frame); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMFRAMERAM); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); + } +} + +/** + * @brief Render one frame in RAM_G of an animation, only works in burst-mode. + */ +void EVE_cmd_animframeram_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, + uint32_t frame) +{ + spi_transmit_burst(CMD_ANIMFRAMERAM); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); +} + +/** + * @brief Start an animation in RAM_G. + */ +void EVE_cmd_animstartram(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMSTARTRAM); + spi_transmit_32((uint32_t) chnl); + spi_transmit_32(aoptr); + spi_transmit_32(loop); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMSTARTRAM); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); + } +} + +/** + * @brief Start an animation in RAM_G, only works in burst-mode. + */ +void EVE_cmd_animstartram_burst(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + spi_transmit_burst(CMD_ANIMSTARTRAM); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); +} + +/** + * @brief Sets the API level used by the coprocessor. + */ +void EVE_cmd_apilevel(uint32_t level) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_APILEVEL); + spi_transmit_32(level); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_APILEVEL); + spi_transmit_burst(level); + } +} + +/** + * @brief Sets the API level used by the coprocessor, only works in burst-mode. + */ +void EVE_cmd_apilevel_burst(uint32_t level) +{ + spi_transmit_burst(CMD_APILEVEL); + spi_transmit_burst(level); +} + +/** + * @brief Execute the touch screen calibration routine for a sub-window. + * @note - Does not support burst-mode. + */ +void EVE_cmd_calibratesub(uint16_t xc0, uint16_t yc0, uint16_t width, uint16_t height) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CALIBRATESUB); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (width)); + spi_transmit((uint8_t) (width >> 8U)); + spi_transmit((uint8_t) (height)); + spi_transmit((uint8_t) (height >> 8U)); + EVE_cs_clear(); + } +} + +/** + * @brief Calls a command list in RAM_G. + */ +void EVE_cmd_calllist(uint32_t adr) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CALLLIST); + spi_transmit_32(adr); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_CALLLIST); + spi_transmit_burst(adr); + } +} + +/** + * @brief Calls a command list in RAM_G, only works in burst-mode. + */ +void EVE_cmd_calllist_burst(uint32_t adr) +{ + spi_transmit_burst(CMD_CALLLIST); + spi_transmit_burst(adr); +} + +/** + * @brief Setup the Horizontal Scan out Filter for non-square pixel LCD support. + * @note - Does not support burst-mode. + */ +void EVE_cmd_hsf(uint32_t hsf) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_HSF); + spi_transmit_32(hsf); + EVE_cs_clear(); + } +} + +/** + * @brief Play/run animations until complete. + */ +void EVE_cmd_runanim(uint32_t waitmask, uint32_t play) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_RUNANIM); + spi_transmit_32(waitmask); + spi_transmit_32(play); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_RUNANIM); + spi_transmit_burst(waitmask); + spi_transmit_burst(play); + } +} + +/** + * @brief Play/run animations until complete, only works in burst-mode. + */ +void EVE_cmd_runanim_burst(uint32_t waitmask, uint32_t play) +{ + spi_transmit_burst(CMD_RUNANIM); + spi_transmit_burst(waitmask); + spi_transmit_burst(play); +} + +#endif /* EVE_GEN > 3 */ + +/* BT815 / BT816 */ +#if EVE_GEN > 2 + +/** + * @brief Draw one or more active animations. + */ +void EVE_cmd_animdraw(int32_t chnl) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMDRAW); + spi_transmit_32((uint32_t) chnl); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMDRAW); + spi_transmit_burst((uint32_t) chnl); + } +} + +/** + * @brief Draw one or more active animations, only works in burst-mode. + */ +void EVE_cmd_animdraw_burst(int32_t chnl) +{ + spi_transmit_burst(CMD_ANIMDRAW); + spi_transmit_burst((uint32_t) chnl); +} + +/** + * @brief Draw the specified frame of an animation. + */ +void EVE_cmd_animframe(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMFRAME); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit_32(aoptr); + spi_transmit_32(frame); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMFRAME); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); + } +} + +/** + * @brief Draw the specified frame of an animation, only works in burst-mode. + */ +void EVE_cmd_animframe_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, + uint32_t frame) +{ + spi_transmit_burst(CMD_ANIMFRAME); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); +} + +/** + * @brief Start an animation. + */ +void EVE_cmd_animstart(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMSTART); + spi_transmit_32((uint32_t) chnl); + spi_transmit_32(aoptr); + spi_transmit_32(loop); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMSTART); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); + } +} + +/** + * @brief Start an animation, only works in burst-mode. + */ +void EVE_cmd_animstart_burst(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + spi_transmit_burst(CMD_ANIMSTART); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); +} + +/** + * @brief Stops one or more active animations. + */ +void EVE_cmd_animstop(int32_t chnl) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMSTOP); + spi_transmit_32((uint32_t) chnl); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMSTOP); + spi_transmit_burst((uint32_t) chnl); + } +} + +/** + * @brief Stops one or more active animations, only works in burst-mode. + */ +void EVE_cmd_animstop_burst(int32_t chnl) +{ + spi_transmit_burst(CMD_ANIMSTOP); + spi_transmit_burst((uint32_t) chnl); +} + +/** + * @brief Sets the coordinates of an animation. + */ +void EVE_cmd_animxy(int32_t chnl, int16_t xc0, int16_t yc0) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMXY); + spi_transmit_32((uint32_t) chnl); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMXY); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + } +} + +/** + * @brief Sets the coordinates of an animation, only works in burst-mode. + */ +void EVE_cmd_animxy_burst(int32_t chnl, int16_t xc0, int16_t yc0) +{ + spi_transmit_burst(CMD_ANIMXY); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); +} + +/** + * @brief Append flash data to the display list. + */ +void EVE_cmd_appendf(uint32_t ptr, uint32_t num) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_APPENDF); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_APPENDF); + spi_transmit_burst(ptr); + spi_transmit_burst(num); + } +} + +/** + * @brief Append flash data to the display list, only works in burst-mode. + */ +void EVE_cmd_appendf_burst(uint32_t ptr, uint32_t num) +{ + spi_transmit_burst(CMD_APPENDF); + spi_transmit_burst(ptr); + spi_transmit_burst(num); +} + +/** + * @brief Computes a bitmap transform and appends commands BITMAP_TRANSFORM_A...BITMAP_TRANSFORM_F to the display list. + */ +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) +{ + uint16_t ret_val = 0U; + + if (0U == cmd_burst) + { + uint16_t cmdoffset; + + eve_begin_cmd(CMD_BITMAP_TRANSFORM); + spi_transmit_32((uint32_t) xc0); + spi_transmit_32((uint32_t) yc0); + spi_transmit_32((uint32_t) xc1); + spi_transmit_32((uint32_t) yc1); + spi_transmit_32((uint32_t) xc2); + spi_transmit_32((uint32_t) yc2); + spi_transmit_32((uint32_t) tx0); + spi_transmit_32((uint32_t) ty0); + spi_transmit_32((uint32_t) tx1); + spi_transmit_32((uint32_t) ty1); + spi_transmit_32((uint32_t) tx2); + spi_transmit_32((uint32_t) ty2); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + ret_val = (uint16_t) EVE_memRead32(EVE_RAM_CMD + cmdoffset); + } + else /* note: the result parameter is ignored in burst mode */ + { + spi_transmit_burst(CMD_BITMAP_TRANSFORM); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst((uint32_t) xc1); + spi_transmit_burst((uint32_t) yc1); + spi_transmit_burst((uint32_t) xc2); + spi_transmit_burst((uint32_t) yc2); + spi_transmit_burst((uint32_t) tx0); + spi_transmit_burst((uint32_t) ty0); + spi_transmit_burst((uint32_t) tx1); + spi_transmit_burst((uint32_t) ty1); + spi_transmit_burst((uint32_t) tx2); + spi_transmit_burst((uint32_t) ty2); + spi_transmit_burst(0UL); + } + return (ret_val); +} + +/** + * @brief Computes a bitmap transform and appends commands BITMAP_TRANSFORM_A...BITMAP_TRANSFORM_F to the display list. + * @note - Only works in burst-mode, the result parameter is ignored. + */ +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) +{ + spi_transmit_burst(CMD_BITMAP_TRANSFORM); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst((uint32_t) xc1); + spi_transmit_burst((uint32_t) yc1); + spi_transmit_burst((uint32_t) xc2); + spi_transmit_burst((uint32_t) yc2); + spi_transmit_burst((uint32_t) tx0); + spi_transmit_burst((uint32_t) ty0); + spi_transmit_burst((uint32_t) tx1); + spi_transmit_burst((uint32_t) ty1); + spi_transmit_burst((uint32_t) tx2); + spi_transmit_burst((uint32_t) ty2); + spi_transmit_burst(0UL); +} + +/** + * @brief Sets the pixel fill width for CMD_TEXT,CMD_BUTTON,CMD_BUTTON with the OPT_FILL option. + */ +void EVE_cmd_fillwidth(uint32_t pixel) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_FILLWIDTH); + spi_transmit_32(pixel); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_FILLWIDTH); + spi_transmit_burst(pixel); + } +} + +/** + * @brief Sets the pixel fill width for CMD_TEXT,CMD_BUTTON,CMD_BUTTON with the OPT_FILL option. + * @note - Only works in burst-mode. + */ +void EVE_cmd_fillwidth_burst(uint32_t pixel) +{ + spi_transmit_burst(CMD_FILLWIDTH); + spi_transmit_burst(pixel); +} + +/** + * @brief Draw a smooth color gradient with transparency. + */ +void EVE_cmd_gradienta(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GRADIENTA); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit_32(argb0); + spi_transmit((uint8_t) ((uint16_t) xc1)); + spi_transmit((uint8_t) (((uint16_t) xc1) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc1)); + spi_transmit((uint8_t) (((uint16_t) yc1) >> 8U)); + spi_transmit_32(argb1); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GRADIENTA); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(argb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(argb1); + } +} + +/** + * @brief Draw a smooth color gradient with transparency, only works in burst-mode. + */ +void EVE_cmd_gradienta_burst(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1) +{ + spi_transmit_burst(CMD_GRADIENTA); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(argb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(argb1); +} + +/** + * @brief Apply a rotation and scale around a specified coordinate. + */ +void EVE_cmd_rotatearound(int32_t xc0, int32_t yc0, uint32_t angle, int32_t scale) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ROTATEAROUND); + spi_transmit_32((uint32_t) xc0); + spi_transmit_32((uint32_t) yc0); + spi_transmit_32(angle & 0xFFFFUL); + spi_transmit_32((uint32_t) scale); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ROTATEAROUND); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst(angle & 0xFFFFUL); + spi_transmit_burst((uint32_t) scale); + } +} + +/** + * @brief Apply a rotation and scale around a specified coordinate, only works in burst-mode. + */ +void EVE_cmd_rotatearound_burst(int32_t xc0, int32_t yc0, uint32_t angle, + int32_t scale) +{ + spi_transmit_burst(CMD_ROTATEAROUND); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst(angle & 0xFFFFUL); + spi_transmit_burst((uint32_t) scale); +} + +/** + * @brief Draw a button with a label, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in p_arguments[] + */ +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[]) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_BUTTON); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_32(p_arguments[counter]); + } + } + } + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + ((uint32_t) hgt << 16U)); + spi_transmit_burst(((uint32_t) font) + ((uint32_t) options << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } + } +} + +/** + * @brief Draw a button with a label, varargs version, only works in burst-mode. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in 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[]) +{ + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + ((uint32_t) hgt << 16U)); + spi_transmit_burst(((uint32_t) font) + ((uint32_t) options << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } +} + +/** + * @brief Draw a text string, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in 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[]) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TEXT); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_32(p_arguments[counter]); + } + } + } + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } + } +} + +/** + * @brief Draw a text string, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in 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[]) +{ + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } +} + +/** + * @brief Draw a toggle switch with labels, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in 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[]) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TOGGLE); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (state)); + spi_transmit((uint8_t) (state >> 8U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_32(p_arguments[counter]); + } + } + } + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } + } +} + +/** + * @brief Draw a toggle switch with labels, varargs version, only works in burst-mode. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in 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[]) +{ + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } +} + +#endif /* EVE_GEN > 2 */ + +/** + * @brief Generic function for display-list and coprocessor commands with no arguments, only works in burst-mode. + * @note - EVE_cmd_dl(CMD_DLSTART); + * @note - EVE_cmd_dl(CMD_SWAP); + * @note - EVE_cmd_dl(CMD_SCREENSAVER); + * @note - EVE_cmd_dl(VERTEX2F(0,0)); + * @note - EVE_cmd_dl(DL_BEGIN | EVE_RECTS); + */ +void EVE_cmd_dl(uint32_t command) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(command); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(command); + } +} + +/** + * @brief Generic function for display-list and coprocessor commands with no arguments, only works in burst-mode. + */ +void EVE_cmd_dl_burst(uint32_t command) +{ + spi_transmit_burst(command); +} + +/** + * @brief Appends commands from RAM_G to the display list. + */ +void EVE_cmd_append(uint32_t ptr, uint32_t num) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_APPEND); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_APPEND); + spi_transmit_burst(ptr); + spi_transmit_burst(num); + } +} + +/** + * @brief Appends commands from RAM_G to the display list, only works in burst-mode. + */ +void EVE_cmd_append_burst(uint32_t ptr, uint32_t num) +{ + spi_transmit_burst(CMD_APPEND); + spi_transmit_burst(ptr); + spi_transmit_burst(num); +} + +/** + * @brief Set the background color. + */ +void EVE_cmd_bgcolor(uint32_t color) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_BGCOLOR); + spi_transmit((uint8_t) (color)); + spi_transmit((uint8_t) (color >> 8U)); + spi_transmit((uint8_t) (color >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_BGCOLOR); + spi_transmit_burst(color); + } +} + +/** + * @brief Set the background color, only works in burst-mode. + */ +void EVE_cmd_bgcolor_burst(uint32_t color) +{ + spi_transmit_burst(CMD_BGCOLOR); + spi_transmit_burst(color); +} + +/** + * @brief Draw a button with a label. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_BUTTON); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a button with a label, only works in burst-mode. + */ +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) +{ + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Execute the touch screen calibration routine. + * @note - does not support burst-mode + */ +void EVE_cmd_calibrate(void) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CALIBRATE); + spi_transmit_32(0UL); + EVE_cs_clear(); + } +} + +/** + * @brief Draw an analog clock. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CLOCK); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rad)); + spi_transmit((uint8_t) (rad >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (hours)); + spi_transmit((uint8_t) (hours >> 8U)); + spi_transmit((uint8_t) (mins)); + spi_transmit((uint8_t) (mins >> 8U)); + spi_transmit((uint8_t) (secs)); + spi_transmit((uint8_t) (secs >> 8U)); + spi_transmit((uint8_t) (msecs)); + spi_transmit((uint8_t) (msecs >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_CLOCK); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) hours) + (((uint32_t) mins) << 16U)); + spi_transmit_burst(((uint32_t) secs) + (((uint32_t) msecs) << 16U)); + } +} + +/** + * @brief Draw an analog clock, only works in burst-mode. + */ +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) +{ + spi_transmit_burst(CMD_CLOCK); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) hours) + (((uint32_t) mins) << 16U)); + spi_transmit_burst(((uint32_t) secs) + (((uint32_t) msecs) << 16U)); +} + +/** + * @brief Draw a rotary dial control. + */ +void EVE_cmd_dial(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t val) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_DIAL); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rad)); + spi_transmit((uint8_t) (rad >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_DIAL); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(val); + } +} + +/** + * @brief Draw a rotary dial control, only works in burst-mode. + */ +void EVE_cmd_dial_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, + uint16_t val) +{ + spi_transmit_burst(CMD_DIAL); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(val); +} + +/** + * @brief Set the foreground color. + */ +void EVE_cmd_fgcolor(uint32_t color) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_FGCOLOR); + spi_transmit((uint8_t) (color)); + spi_transmit((uint8_t) (color >> 8U)); + spi_transmit((uint8_t) (color >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_FGCOLOR); + spi_transmit_burst(color); + } +} + +/** + * @brief Set the foreground color, only works in burst-mode. + */ +void EVE_cmd_fgcolor_burst(uint32_t color) +{ + spi_transmit_burst(CMD_FGCOLOR); + spi_transmit_burst(color); +} + +/** + * @brief Draw a gauge. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GAUGE); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rad)); + spi_transmit((uint8_t) (rad >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (major)); + spi_transmit((uint8_t) (major >> 8U)); + spi_transmit((uint8_t) (minor)); + spi_transmit((uint8_t) (minor >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GAUGE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) major) + (((uint32_t) minor) << 16U)); + spi_transmit_burst(((uint32_t) val) + (((uint32_t) range) << 16U)); + } +} + +/** + * @brief Draw a gauge, only works in burst-mode. + */ +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) +{ + spi_transmit_burst(CMD_GAUGE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) major) + (((uint32_t) minor) << 16U)); + spi_transmit_burst(((uint32_t) val) + (((uint32_t) range) << 16U)); +} + +/** + * @brief Retrieves the current matrix within the context of the coprocessor engine. + * @note - waits for completion and reads values from RAM_CMD after completion + * @note - can not be used with cmd-burst + */ +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) +{ + if (0U == cmd_burst) + { + uint16_t cmdoffset; + uint32_t address; + + eve_begin_cmd(CMD_GETMATRIX); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); + + if (p_f != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL); + *p_f = (int32_t) EVE_memRead32(address); + } + if (p_e != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL); + *p_e = (int32_t) EVE_memRead32(address); + } + if (p_d != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 12UL) & 0xfffUL); + *p_d = (int32_t) EVE_memRead32(address); + } + if (p_c != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 16UL) & 0xfffUL); + *p_c = (int32_t) EVE_memRead32(address); + } + if (p_b != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 20UL) & 0xfffUL); + *p_b = (int32_t) EVE_memRead32(address); + } + if (p_a != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 24UL) & 0xfffUL); + *p_a = (int32_t) EVE_memRead32(address); + } + } +} + +/** + * @brief Set up the highlight color used in 3D effects for CMD_BUTTON and CMD_KEYS. + */ +void EVE_cmd_gradcolor(uint32_t color) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GRADCOLOR); + spi_transmit((uint8_t) (color)); + spi_transmit((uint8_t) (color >> 8U)); + spi_transmit((uint8_t) (color >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GRADCOLOR); + spi_transmit_burst(color); + } +} + +/** + * @brief Set up the highlight color used in 3D effects for CMD_BUTTON and CMD_KEYS, only works in burst-mode. + */ +void EVE_cmd_gradcolor_burst(uint32_t color) +{ + spi_transmit_burst(CMD_GRADCOLOR); + spi_transmit_burst(color); +} + +/** + * @brief Draw a smooth color gradient. + */ +void EVE_cmd_gradient(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, + int16_t yc1, uint32_t rgb1) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GRADIENT); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rgb0)); + spi_transmit((uint8_t) (rgb0 >> 8U)); + spi_transmit((uint8_t) (rgb0 >> 16U)); + spi_transmit(0U); + spi_transmit((uint8_t) ((uint16_t) xc1)); + spi_transmit((uint8_t) (((uint16_t) xc1) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc1)); + spi_transmit((uint8_t) (((uint16_t) yc1) >> 8U)); + spi_transmit((uint8_t) (rgb1)); + spi_transmit((uint8_t) (rgb1 >> 8U)); + spi_transmit((uint8_t) (rgb1 >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GRADIENT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(rgb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(rgb1); + } +} + +/** + * @brief Draw a smooth color gradient, only works in burst-mode. + */ +void EVE_cmd_gradient_burst(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, + int16_t yc1, uint32_t rgb1) +{ + spi_transmit_burst(CMD_GRADIENT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(rgb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(rgb1); +} + +/** + * @brief Draw a row of key buttons with labels. + * @note - The tag value of each button is set to the ASCII value of its label. + * @note - Does not work with UTF-8. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_KEYS); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_KEYS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a row of key buttons with labels, only works in burst-mode. + * @note - The tag value of each button is set to the ASCII value of its label. + * @note - Does not work with UTF-8. + */ +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) +{ + spi_transmit_burst(CMD_KEYS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Draw a number. + */ +void EVE_cmd_number(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, int32_t number) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_NUMBER); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit_32((uint32_t) number); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_NUMBER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + spi_transmit_burst((uint32_t) number); + } +} + +/** + * @brief Draw a number, only works in burst-mode. + */ +void EVE_cmd_number_burst(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, int32_t number) +{ + spi_transmit_burst(CMD_NUMBER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + spi_transmit_burst((uint32_t) number); +} + +/** + * @brief Draw a progress bar. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_PROGRESS); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_PROGRESS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); + } +} + +/** + * @brief Draw a progress bar, only works in burst-mode. + */ +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) +{ + spi_transmit_burst(CMD_PROGRESS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); +} + +/** + * @brief Load a ROM font into bitmap handle. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_romfont(uint32_t font, uint32_t romslot) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ROMFONT); + spi_transmit_32(font); + spi_transmit_32(romslot); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ROMFONT); + spi_transmit_burst(font); + spi_transmit_burst(romslot); + } +} + +/** + * @brief Load a ROM font into bitmap handle, only works in burst-mode. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_romfont_burst(uint32_t font, uint32_t romslot) +{ + spi_transmit_burst(CMD_ROMFONT); + spi_transmit_burst(font); + spi_transmit_burst(romslot); +} + +/** + * @brief Apply a rotation to the current matrix. + */ +void EVE_cmd_rotate(uint32_t angle) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ROTATE); + spi_transmit_32(angle & 0xFFFFUL); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ROTATE); + spi_transmit_burst(angle & 0xFFFFUL); + } +} + +/** + * @brief Apply a rotation to the current matrix, only works in burst-mode. + */ +void EVE_cmd_rotate_burst(uint32_t angle) +{ + spi_transmit_burst(CMD_ROTATE); + spi_transmit_burst(angle & 0xFFFFUL); +} + +/** + * @brief Apply a scale to the current matrix. + */ +void EVE_cmd_scale(int32_t scx, int32_t scy) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SCALE); + spi_transmit_32((uint32_t) scx); + spi_transmit_32((uint32_t) scy); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SCALE); + spi_transmit_burst((uint32_t) scx); + spi_transmit_burst((uint32_t) scy); + } +} + +/** + * @brief Apply a scale to the current matrix, only works in burst-mode. + */ +void EVE_cmd_scale_burst(int32_t scx, int32_t scy) +{ + spi_transmit_burst(CMD_SCALE); + spi_transmit_burst((uint32_t) scx); + spi_transmit_burst((uint32_t) scy); +} + +/** + * @brief Draw a scroll bar. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SCROLLBAR); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (size)); + spi_transmit((uint8_t) (size >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SCROLLBAR); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst(((uint32_t) size) + (((uint32_t) range) << 16U)); + } +} + +/** + * @brief Draw a scroll bar, only works in burst-mode. + */ +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) +{ + spi_transmit_burst(CMD_SCROLLBAR); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst(((uint32_t) size) + (((uint32_t) range) << 16U)); +} + +/** + * @brief Set the base for number output. + */ +void EVE_cmd_setbase(uint32_t base) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETBASE); + spi_transmit_32(base); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETBASE); + spi_transmit_burst(base); + } +} + +/** + * @brief Set the base for number output, only works in burst-mode. + */ +void EVE_cmd_setbase_burst(uint32_t base) +{ + spi_transmit_burst(CMD_SETBASE); + spi_transmit_burst(base); +} + +/** + * @brief Generate the corresponding display list commands for given bitmap information. + */ +void EVE_cmd_setbitmap(uint32_t addr, uint16_t fmt, uint16_t width, + uint16_t height) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETBITMAP); + spi_transmit_32(addr); + spi_transmit((uint8_t) (fmt)); + spi_transmit((uint8_t) (fmt >> 8U)); + spi_transmit((uint8_t) (width)); + spi_transmit((uint8_t) (width >> 8U)); + spi_transmit((uint8_t) (height)); + spi_transmit((uint8_t) (height >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETBITMAP); + spi_transmit_burst(addr); + spi_transmit_burst(((uint32_t) fmt) + (((uint32_t) width) << 16U)); + spi_transmit_burst((uint32_t) height); + } +} + +/** + * @brief Generate the corresponding display list commands for given bitmap information, only works in burst-mode. + */ +void EVE_cmd_setbitmap_burst(uint32_t addr, uint16_t fmt, uint16_t width, + uint16_t height) +{ + spi_transmit_burst(CMD_SETBITMAP); + spi_transmit_burst(addr); + spi_transmit_burst(((uint32_t) fmt) + (((uint32_t) width) << 16U)); + spi_transmit_burst((uint32_t) height); +} + +/** + * @brief Register one custom font into the coprocessor engine. + * @note - does not set up the bitmap parameters of the font + */ +void EVE_cmd_setfont(uint32_t font, uint32_t ptr) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETFONT); + spi_transmit_32(font); + spi_transmit_32(ptr); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETFONT); + spi_transmit_burst(font); + spi_transmit_burst(ptr); + } +} + +/** + * @brief Register one custom font into the coprocessor engine, only works in burst-mode. + * @note - does not set up the bitmap parameters of the font + */ +void EVE_cmd_setfont_burst(uint32_t font, uint32_t ptr) +{ + spi_transmit_burst(CMD_SETFONT); + spi_transmit_burst(font); + spi_transmit_burst(ptr); +} + +/** + * @brief Set up a custom for use by the coprocessor engine. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_setfont2(uint32_t font, uint32_t ptr, uint32_t firstchar) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETFONT2); + spi_transmit_32(font); + spi_transmit_32(ptr); + spi_transmit_32(firstchar); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETFONT2); + spi_transmit_burst(font); + spi_transmit_burst(ptr); + spi_transmit_burst(firstchar); + } +} + +/** + * @brief Set up a custom for use by the coprocessor engine, only works in burst-mode. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_setfont2_burst(uint32_t font, uint32_t ptr, uint32_t firstchar) +{ + spi_transmit_burst(CMD_SETFONT2); + spi_transmit_burst(font); + spi_transmit_burst(ptr); + spi_transmit_burst(firstchar); +} + +/** + * @brief Set the scratch bitmap for widget use. + */ +void EVE_cmd_setscratch(uint32_t handle) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETSCRATCH); + spi_transmit_32(handle); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETSCRATCH); + spi_transmit_burst(handle); + } +} + +/** + * @brief Set the scratch bitmap for widget use, only works in burst-mode. + */ +void EVE_cmd_setscratch_burst(uint32_t handle) +{ + spi_transmit_burst(CMD_SETSCRATCH); + spi_transmit_burst(handle); +} + +/** + * @brief Start a continuous sketch update. + */ +void EVE_cmd_sketch(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint32_t ptr, uint16_t format) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SKETCH); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) wid)); + spi_transmit((uint8_t) (((uint16_t) wid) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) hgt)); + spi_transmit((uint8_t) (((uint16_t) hgt) >> 8U)); + spi_transmit_32(ptr); + spi_transmit((uint8_t) (format)); + spi_transmit((uint8_t) (format >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SKETCH); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) ((uint16_t) wid)) + (((uint32_t) ((uint16_t) hgt)) << 16U)); + spi_transmit_burst(ptr); + spi_transmit_burst((uint32_t) format); + } +} + +/** + * @brief Start a continuous sketch update, only works in burst-mode. + */ +void EVE_cmd_sketch_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint32_t ptr, uint16_t format) +{ + spi_transmit_burst(CMD_SKETCH); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) ((uint16_t) wid)) + (((uint32_t) ((uint16_t) hgt)) << 16U)); + spi_transmit_burst(ptr); + spi_transmit_burst((uint32_t) format); +} + +/** + * @brief Draw a slider. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SLIDER); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SLIDER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); + } +} + +/** + * @brief Draw a slider, only works in burst-mode. + */ +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) +{ + spi_transmit_burst(CMD_SLIDER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); +} + +/** + * @brief Start an animated spinner. + */ +void EVE_cmd_spinner(int16_t xc0, int16_t yc0, uint16_t style, uint16_t scale) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SPINNER); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (style)); + spi_transmit((uint8_t) (style >> 8U)); + spi_transmit((uint8_t) (scale)); + spi_transmit((uint8_t) (scale >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SPINNER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) style) + (((uint32_t) scale) << 16U)); + } +} + +/** + * @brief Start an animated spinner, only works in burst-mode. + */ +void EVE_cmd_spinner_burst(int16_t xc0, int16_t yc0, uint16_t style, + uint16_t scale) +{ + spi_transmit_burst(CMD_SPINNER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) style) + (((uint32_t) scale) << 16U)); +} + +/** + * @brief Draw a text string. + */ +void EVE_cmd_text(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, + const char *p_text) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TEXT); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a text string, only works in burst-mode. + */ +void EVE_cmd_text_burst(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, const char *p_text) +{ + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Draw a toggle switch with labels. + */ +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) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TOGGLE); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (state)); + spi_transmit((uint8_t) (state >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a toggle switch with labels, only works in burst-mode. + */ +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) +{ + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Apply a translation to the current matrix. + */ +void EVE_cmd_translate(int32_t tr_x, int32_t tr_y) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TRANSLATE); + spi_transmit_32((uint32_t) tr_x); + spi_transmit_32((uint32_t) tr_y); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TRANSLATE); + spi_transmit_burst((uint32_t) tr_x); + spi_transmit_burst((uint32_t) tr_y); + } +} + +/** + * @brief Apply a translation to the current matrix, only works in burst-mode. + */ +void EVE_cmd_translate_burst(int32_t tr_x, int32_t tr_y) +{ + spi_transmit_burst(CMD_TRANSLATE); + spi_transmit_burst((uint32_t) tr_x); + spi_transmit_burst((uint32_t) tr_y); +} + +/** + * @brief Set the current color red, green and blue. + */ +void EVE_color_rgb(uint32_t color) +{ + EVE_cmd_dl(DL_COLOR_RGB | (color & 0x00ffffffUL)); +} + +/** + * @brief Set the current color red, green and blue, only works in burst-mode. + */ +void EVE_color_rgb_burst(uint32_t color) +{ + spi_transmit_burst(DL_COLOR_RGB | (color & 0x00ffffffUL)); +} + +/** + * @brief Set the current color alpha, green and blue. + */ +void EVE_color_a(uint8_t alpha) +{ + EVE_cmd_dl(DL_COLOR_A | ((uint32_t) alpha)); +} + +/** + * @brief Set the current color alpha, green and blue, only works in burst-mode. + */ +void EVE_color_a_burst(uint8_t alpha) +{ + spi_transmit_burst(DL_COLOR_A | ((uint32_t) alpha)); +} + + +/* ################################################################## + special purpose functions +##################################################################### */ + +/* This is meant to be called outside display-list building. */ +/* This function displays an interactive calibration screen, calculates the calibration values */ +/* and writes the new values to the touch matrix registers of EVE.*/ +/* Unlike the built-in cmd_calibrate() of EVE this also works with displays that are cut down from larger ones like + * EVE2-38A / EVE2-38G. */ +/* The dimensions are needed as parameter as EVE_VSIZE for the EVE2-38 is 272 but the visible size is only 116. */ +/* So the call would be EVE_calibrate_manual(EVE_HSIZE, 116); for the EVE2-38A and EVE2-38G while for most other + * displays */ +/* using EVE_calibrate_manual(EVE_VSIZE, EVE_VSIZE) would work - but for normal displays the built-in cmd_calibrate + * would work as expected anyways */ +/* This code was taken from the MatrixOrbital EVE2-Library on Github, adapted and modified */ +void EVE_calibrate_manual(uint16_t width, uint16_t height) +{ + int32_t display_x[3U]; + int32_t display_y[3U]; + int32_t touch_x[3U]; + int32_t touch_y[3U]; + uint32_t touch_value; + int32_t tmp; + int32_t divi; + int32_t trans_matrix[6U]; + uint8_t count = 0U; + uint8_t calc = 0U; + uint32_t calc32 = 0U; + char num[4U]; + uint8_t touch_lock = 1U; + + /* these values determine where your calibration points will be drawn on your display */ + display_x[0U] = (int32_t) width / 6; + display_y[0U] = (int32_t) height / 6; + + display_x[1U] = (int32_t) width - ((int32_t) width / 8); + display_y[1U] = (int32_t) height / 2; + + display_x[2U] = (int32_t) width / 2; + display_y[2U] = (int32_t) height - ((int32_t) height / 8); + + while (count < 3U) + { + EVE_cmd_dl(CMD_DLSTART); + EVE_cmd_dl(DL_CLEAR_COLOR_RGB); + EVE_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); + EVE_cmd_dl(DL_VERTEX_FORMAT); /* set to 0 - reduce precision for VERTEX2F to 1 pixel instead of 1/16 pixel default */ + + /* draw Calibration Point on screen */ + EVE_cmd_dl(DL_COLOR_RGB | 0x0000ffUL); + EVE_cmd_dl(POINT_SIZE(15U * 16U)); + EVE_cmd_dl((DL_BEGIN | EVE_POINTS)); + + int16_t xc0; + int16_t yc0; + + xc0 = (int16_t) display_x[count]; + yc0 = (int16_t) display_y[count]; + EVE_cmd_dl(VERTEX2F(xc0, yc0)); + EVE_cmd_dl(DL_END); + EVE_cmd_dl(DL_COLOR_RGB | 0xffffffUL); + EVE_cmd_text((int16_t) width / 2, 20, 26U, EVE_OPT_CENTER, "tap on the dot"); + calc = count + 0x31U; + num[0U] = (char) calc; + num[1U] = (char) 0U; /* null terminated string of one character */ + EVE_cmd_text((int16_t) display_x[count], (int16_t) display_y[count], 27U, EVE_OPT_CENTER, num); + + EVE_cmd_dl(DL_DISPLAY); + EVE_cmd_dl(CMD_SWAP); + EVE_execute_cmd(); + + for (;;) + { + touch_value = EVE_memRead32(REG_TOUCH_DIRECT_XY); /* read for any new touch tag inputs */ + + if (touch_lock != 0U) + { + if ((touch_value & 0x80000000UL) != 0UL) /* check if we have no touch */ + { + touch_lock = 0U; + } + } + else + { + if (0UL == (touch_value & 0x80000000UL)) /* check if a touch is detected */ + { + calc32 = ((touch_value >> 16U) & 0x03FFUL); + touch_x[count] = (int32_t) calc32; /* raw Touchscreen X coordinate */ + calc32 = touch_value & 0x03FFUL; + touch_y[count] = (int32_t) calc32; /* raw Touchscreen Y coordinate */ + touch_lock = 1U; + count++; + break; /* leave for (;;) */ + } + } + } + } + + divi = ((touch_x[0U] - touch_x[2U]) * (touch_y[1U] - touch_y[2U])) - ((touch_x[1U] - touch_x[2U]) * (touch_y[0U] - touch_y[2U])); + + tmp = (((display_x[0U] - display_x[2U]) * (touch_y[1U] - touch_y[2U])) - + ((display_x[1U] - display_x[2U]) * (touch_y[0U] - touch_y[2U]))); + trans_matrix[0U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = (((touch_x[0U] - touch_x[2U]) * (display_x[1U] - display_x[2U])) - + ((display_x[0U] - display_x[2U]) * (touch_x[1U] - touch_x[2U]))); + trans_matrix[1U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = ((touch_y[0U] * (((touch_x[2U] * display_x[1U]) - (touch_x[1U] * display_x[2U])))) + + (touch_y[1U] * (((touch_x[0U] * display_x[2U]) - (touch_x[2U] * display_x[0U])))) + + (touch_y[2U] * (((touch_x[1U] * display_x[0U]) - (touch_x[0U] * display_x[1U]))))); + trans_matrix[2U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = (((display_y[0U] - display_y[2U]) * (touch_y[1U] - touch_y[2U])) - + ((display_y[1U] - display_y[2U]) * (touch_y[0U] - touch_y[2U]))); + trans_matrix[3U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = (((touch_x[0U] - touch_x[2U]) * (display_y[1U] - display_y[2U])) - + ((display_y[0U] - display_y[2U]) * (touch_x[1U] - touch_x[2U]))); + trans_matrix[4U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = ((touch_y[0U] * (((touch_x[2U] * display_y[1U]) - (touch_x[1U] * display_y[2U])))) + + (touch_y[1U] * (((touch_x[0U] * display_y[2U]) - (touch_x[2U] * display_y[0U])))) + + (touch_y[2U] * (((touch_x[1U] * display_y[0U]) - (touch_x[0U] * display_y[1U]))))); + trans_matrix[5U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + EVE_memWrite32(REG_TOUCH_TRANSFORM_A, (uint32_t) trans_matrix[0U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_B, (uint32_t) trans_matrix[1U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_C, (uint32_t) trans_matrix[2U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_D, (uint32_t) trans_matrix[3U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_E, (uint32_t) trans_matrix[4U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_F, (uint32_t) trans_matrix[5U]); +} + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/libs/FT800-FT813/EVE_commands.h b/src/libs/FT800-FT813/EVE_commands.h new file mode 100644 index 0000000000..144d7ed38f --- /dev/null +++ b/src/libs/FT800-FT813/EVE_commands.h @@ -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 */ diff --git a/src/libs/FT800-FT813/EVE_config.h b/src/libs/FT800-FT813/EVE_config.h new file mode 100644 index 0000000000..0d51e63353 --- /dev/null +++ b/src/libs/FT800-FT813/EVE_config.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 */ diff --git a/src/libs/FT800-FT813/EVE_supplemental.c b/src/libs/FT800-FT813/EVE_supplemental.c new file mode 100644 index 0000000000..988b62c739 --- /dev/null +++ b/src/libs/FT800-FT813/EVE_supplemental.c @@ -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 +#endif + +#if defined (__AVR__) +#include +#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*/ diff --git a/src/libs/FT800-FT813/EVE_suppplemental.h b/src/libs/FT800-FT813/EVE_suppplemental.h new file mode 100644 index 0000000000..c55a8dc9cd --- /dev/null +++ b/src/libs/FT800-FT813/EVE_suppplemental.h @@ -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 */ diff --git a/src/libs/FT800-FT813/EVE_target.h b/src/libs/FT800-FT813/EVE_target.h new file mode 100644 index 0000000000..802d944831 --- /dev/null +++ b/src/libs/FT800-FT813/EVE_target.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_ */ diff --git a/src/libs/FT800-FT813/LICENSE b/src/libs/FT800-FT813/LICENSE new file mode 100644 index 0000000000..a6ab28bb71 --- /dev/null +++ b/src/libs/FT800-FT813/LICENSE @@ -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. diff --git a/src/libs/FT800-FT813/README.md b/src/libs/FT800-FT813/README.md new file mode 100644 index 0000000000..211acb1eba --- /dev/null +++ b/src/libs/FT800-FT813/README.md @@ -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 diff --git a/src/lv_api_map_v9_2.h b/src/lv_api_map_v9_2.h index 1c754a845b..1339452361 100644 --- a/src/lv_api_map_v9_2.h +++ b/src/lv_api_map_v9_2.h @@ -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 diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 9b6083f32d..f5191bc485 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -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 *=======================*/ diff --git a/src/lv_conf_kconfig.h b/src/lv_conf_kconfig.h index 78f9596878..3a8d5d10bf 100644 --- a/src/lv_conf_kconfig.h +++ b/src/lv_conf_kconfig.h @@ -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 diff --git a/src/lv_init.c b/src/lv_init.c index 141c402f4a..ed580d71ae 100644 --- a/src/lv_init.c +++ b/src/lv_init.c @@ -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*/ diff --git a/src/misc/lv_types.h b/src/misc/lv_types.h index 7bb7a6aea8..43fef09164 100644 --- a/src/misc/lv_types.h +++ b/src/misc/lv_types.h @@ -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__*/ /**********************