diff --git a/lv_core/lv_indev.c b/lv_core/lv_indev.c index 8a5facd5f..64ffc4be5 100644 --- a/lv_core/lv_indev.c +++ b/lv_core/lv_indev.c @@ -161,7 +161,7 @@ void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group) * @param indev pointer to an input device * @param group point to a group */ -void lv_indev_set_button_points(lv_indev_t * indev, lv_point_t * points) +void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points) { if(indev->driver.type == LV_INDEV_TYPE_BUTTON) indev->btn_points = points; } diff --git a/lv_core/lv_indev.h b/lv_core/lv_indev.h index 68cab9a92..19b047ce2 100644 --- a/lv_core/lv_indev.h +++ b/lv_core/lv_indev.h @@ -89,7 +89,7 @@ void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group); * @param indev pointer to an input device * @param group point to a group */ -void lv_indev_set_button_points(lv_indev_t *indev, lv_point_t *points); +void lv_indev_set_button_points(lv_indev_t *indev, const lv_point_t *points); /** * Set feedback callback for indev. diff --git a/lv_hal/lv_hal_indev.h b/lv_hal/lv_hal_indev.h index c244da46c..214b02754 100644 --- a/lv_hal/lv_hal_indev.h +++ b/lv_hal/lv_hal_indev.h @@ -115,7 +115,7 @@ typedef struct _lv_indev_t { union { struct _lv_obj_t *cursor; /*Cursor for LV_INPUT_TYPE_POINTER*/ struct _lv_group_t *group; /*Keypad destination group*/ - lv_point_t * btn_points; /*Array points assigned to the button ()screen will be pressed here by the buttons*/ + const lv_point_t * btn_points; /*Array points assigned to the button ()screen will be pressed here by the buttons*/ }; struct _lv_indev_t *next; diff --git a/lv_porting/lv_port_disp_templ.c b/lv_porting/lv_port_disp_templ.c new file mode 100644 index 000000000..18e676372 --- /dev/null +++ b/lv_porting/lv_port_disp_templ.c @@ -0,0 +1,185 @@ +/** + * @file lv_port_disp_templ.c + * + */ + + /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/ +#if 0 + +/********************* + * INCLUDES + *********************/ +#include "lv_port_disp_templ.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void disp_init(void); + +static void disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p); +static void disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p); +static void disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color); +#if USE_LV_GPU +static void mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa); +static void mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color); +#endif + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_port_disp_init(void) +{ + /*------------------------- + * Initialize your display + * -----------------------*/ + disp_init(); + + /*----------------------------------- + * Register the display in LittlevGL + *----------------------------------*/ + + lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + + /*Set up the functions to access to your display*/ + + /*Used in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/ + disp_drv.disp_flush = disp_flush; + + /*Used in unbuffered mode (LV_VDB_SIZE == 0 in lv_conf.h)*/ + disp_drv.disp_fill = disp_fill; + + /*Used in unbuffered mode (LV_VDB_SIZE == 0 in lv_conf.h)*/ + disp_drv.disp_map = disp_map; + +#if USE_LV_GPU + /*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/ + + /*Blend two color array using opacity*/ + disp_drv.mem_blend = mem_blend; + + /*Fill a memory array with a color*/ + disp_drv.mem_fill = mem_fill; +#endif + + /*Finally register the driver*/ + lv_disp_drv_register(&disp_drv); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/* Initialize your display and the required peripherals. */ +static void disp_init(void) +{ + /*You code here*/ +} + +/* Flush the content of the internal buffer the specific area on the display + * You can use DMA or any hardware acceleration to do this operation in the background but + * 'lv_flush_ready()' has to be called when finished + * This function is required only when LV_VDB_SIZE != 0 in lv_conf.h*/ +static void disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p) +{ + /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/ + + int32_t x; + int32_t y; + for(y = y1; y <= y2; y++) { + for(x = x1; x <= x2; x++) { + /* Put a pixel to the display. For example: */ + /* put_px(x, y, *color_p)*/ + color_p++; + } + } + + /* IMPORTANT!!! + * Inform the graphics library that you are ready with the flushing*/ + lv_flush_ready(); +} + + +/* Write a pixel array (called 'map') to the a specific area on the display + * This function is required only when LV_VDB_SIZE == 0 in lv_conf.h*/ +static void disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p) +{ + /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/ + + int32_t x; + int32_t y; + for(y = y1; y <= y2; y++) { + for(x = x1; x <= x2; x++) { + /* Put a pixel to the display. For example: */ + /* put_px(x, y, *color_p)*/ + color_p++; + } + } +} + + +/* Write a pixel array (called 'map') to the a specific area on the display + * This function is required only when LV_VDB_SIZE == 0 in lv_conf.h*/ +static void disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color) +{ + /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/ + + int32_t x; + int32_t y; + for(y = y1; y <= y2; y++) { + for(x = x1; x <= x2; x++) { + /* Put a pixel to the display. For example: */ + /* put_px(x, y, *color)*/ + } + } + + (void)color; /*Just to avid warnings*/ +} + +/*OPTIONAL: GPU INTERFACE*/ +#if USE_LV_GPU + +/* If your MCU has hardware accelerator (GPU) then you can use it to blend to memories using opacity + * It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/ +static void mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa) +{ + /*It's an example code which should be done by your GPU*/ + + uint32_t i; + for(i = 0; i < length; i++) { + dest[i] = lv_color_mix(dest[i], src[i], opa); + } +} + +/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color + * It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/ +static void mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color) +{ + /*It's an example code which should be done by your GPU*/ + + uint32_t i; + for(i = 0; i < length; i++) { + dest[i] = color; + } +} + +#endif /*USE_LV_GPU*/ + +#endif diff --git a/lv_porting/lv_port_disp_templ.h b/lv_porting/lv_port_disp_templ.h new file mode 100644 index 000000000..abf5b9e51 --- /dev/null +++ b/lv_porting/lv_port_disp_templ.h @@ -0,0 +1,44 @@ +/** + * @file lv_port_disp_templ.h + * + */ + + /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/ +#if 0 + +#ifndef LV_PORT_DISP_TEMPL_H +#define LV_PORT_DISP_TEMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_PORT_DISP_TEMPL_H*/ + +#endif /*Disable/Enable content*/ diff --git a/lv_porting/lv_port_fs_templ.c b/lv_porting/lv_port_fs_templ.c new file mode 100644 index 000000000..e69de29bb diff --git a/lv_porting/lv_port_fs_templ.h b/lv_porting/lv_port_fs_templ.h new file mode 100644 index 000000000..a2805fb8a --- /dev/null +++ b/lv_porting/lv_port_fs_templ.h @@ -0,0 +1,44 @@ +/** + * @file lv_port_fs_templ.h + * + */ + + /*Copy this file as "lv_port_fs.c" and set this value to "1" to enable content*/ +#if 0 + +#ifndef LV_PORT_FS_TEMPL_H +#define LV_PORT_FS_TEMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_PORT_FS_TEMPL_H*/ + +#endif /*Disable/Enable content*/ diff --git a/lv_porting/lv_port_indev_templ.c b/lv_porting/lv_port_indev_templ.c new file mode 100644 index 000000000..9c76edc4d --- /dev/null +++ b/lv_porting/lv_port_indev_templ.c @@ -0,0 +1,424 @@ +/** + * @file lv_port_indev_templ.c + * + */ + + /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/ +#if 0 + +/********************* + * INCLUDES + *********************/ +#include "lv_port_indev_templ.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void touchpad_init(void); +static bool touchpad_read(lv_indev_data_t * data); +static bool touchpad_is_pressed(void); +static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y); + +static void mouse_init(void); +static bool mouse_read(lv_indev_data_t * data); +static bool mouse_is_pressed(void); +static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y); + +static void keypad_init(void); +static bool keypad_read(lv_indev_data_t * data); +static uint32_t keypad_get_key(void); + +static void encoder_init(void); +static bool encoder_read(lv_indev_data_t * data); +static void encoder_handler(void); + +static void button_init(void); +static bool button_read(lv_indev_data_t * data); +static int8_t button_get_pressed_id(void); +static bool button_is_pressed(uint8_t id); + +/********************** + * STATIC VARIABLES + **********************/ +lv_indev_t * indev_touchpad; +lv_indev_t * indev_mouse; +lv_indev_t * indev_keypad; +lv_indev_t * indev_encoder; +lv_indev_t * indev_button; + +static int32_t encoder_diff; +static lv_indev_state_t encoder_state; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_port_indev_init(void) +{ + /* Here you will find example implementation of input devices supported by LittelvGL: + * - Touchpad + * - Mouse (with cursor support) + * - Keypad (supports GUI usage only with key) + * - Encoder (supports GUI usage only with: left, right, push) + * - Button (external buttons to press points on the screen) + * + * The `..._read()` function are only examples. + * You should shape them according to your hardware + */ + + + lv_indev_drv_t indev_drv; + + /*------------------ + * Touchpad + * -----------------*/ + + /*Initialize your touchpad if you have*/ + touchpad_init(); + + /*Register a touchpad input device*/ + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read = touchpad_read; + indev_touchpad = lv_indev_drv_register(&indev_drv); + + /*------------------ + * Mouse + * -----------------*/ + + /*Initialize your touchpad if you have*/ + mouse_init(); + + /*Register a mouse input device*/ + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read = mouse_read; + indev_mouse = lv_indev_drv_register(&indev_drv); + + /*Set cursor. For simplicity set a HOME symbol now.*/ + lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act(), NULL); + lv_img_set_src(mouse_cursor, SYMBOL_HOME); + lv_indev_set_cursor(indev_mouse, mouse_cursor); + + /*------------------ + * Keypad + * -----------------*/ + + /*Initialize your keypad or keyboard if you have*/ + keypad_init(); + + /*Register a keypad input device*/ + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_KEYPAD; + indev_drv.read = keypad_read; + indev_keypad = lv_indev_drv_register(&indev_drv); + + /* Later you should create group(s) with `lv_group_t * group = lv_group_create()`, + * add objects to the group with `lv_group_add_obj(group, obj)` + * and assign this input device to group to navigate in it: + * `lv_indev_set_group(indev_keypad, group);` */ + + /*------------------ + * Encoder + * -----------------*/ + + /*Initialize your encoder if you have*/ + encoder_init(); + + /*Register a encoder input device*/ + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_KEYPAD; + indev_drv.read = encoder_read; + indev_encoder = lv_indev_drv_register(&indev_drv); + + /* Later you should create group(s) with `lv_group_t * group = lv_group_create()`, + * add objects to the group with `lv_group_add_obj(group, obj)` + * and assign this input device to group to navigate in it: + * `lv_indev_set_group(indev_keypad, group);` */ + + /*------------------ + * Button + * -----------------*/ + + /*Initialize your button if you have*/ + button_init(); + + /*Register a button input device*/ + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_BUTTON; + indev_drv.read = button_read; + indev_button = lv_indev_drv_register(&indev_drv); + + /*Assign buttons to points on the screen*/ + static const lv_point_t btn_points[2] = { + {10, 10}, /*Button 0 -> x:10; y:10*/ + {40, 100}, /*Button 1 -> x:40; y:100*/ + }; + lv_indev_set_button_points(indev_button, btn_points); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + + + +/*------------------ + * Touchpad + * -----------------*/ + +/*Initialize your touchpad*/ +static void touchpad_init(void) +{ + /*Your code comes here*/ +} + +/* Will be called by the library to read the touchpad */ +static bool touchpad_read(lv_indev_data_t * data) +{ + static lv_coord_t last_x = 0; + static lv_coord_t last_y = 0; + + /*Save the pressed coordinates and the state*/ + if(touchpad_is_pressed()) { + touchpad_get_xy(&last_x, &last_y); + data->state = LV_INDEV_STATE_PR; + } else { + data->state = LV_INDEV_STATE_REL; + } + + /*Set the last pressed coordinates*/ + data->point.x = last_x; + data->point.y = last_y; + + /*Return `false` because we are not buffering and no more data to read*/ + return false; +} + +/*Return true is the touchpad is pressed*/ +static bool touchpad_is_pressed(void) +{ + /*Your code comes here*/ + + return false; +} + +/*Get the x and y coordinates if the touchpad is pressed*/ +static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) +{ + /*Your code comes here*/ + + (*x) = 0; + (*y) = 0; +} + + +/*------------------ + * Mouse + * -----------------*/ + +/* Initialize your mouse */ +static void mouse_init(void) +{ + /*Your code comes here*/ +} + +/* Will be called by the library to read the mouse */ +static bool mouse_read(lv_indev_data_t * data) +{ + /*Get the current x and y coordinates*/ + mouse_get_xy(&data->point.x, &data->point.y); + + /*Get whether the mouse button is pressed or released*/ + if(mouse_is_pressed()) { + data->state = LV_INDEV_STATE_PR; + } else { + data->state = LV_INDEV_STATE_REL; + } + + /*Return `false` because we are not buffering and no more data to read*/ + return false; +} + +/*Return true is the mouse button is pressed*/ +static bool mouse_is_pressed(void) +{ + /*Your code comes here*/ + + return false; +} + +/*Get the x and y coordinates if the mouse is pressed*/ +static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y) +{ + /*Your code comes here*/ + + (*x) = 0; + (*y) = 0; +} + +/*------------------ + * Keypad + * -----------------*/ + +/* Initialize your keypad */ +static void keypad_init(void) +{ + /*Your code comes here*/ +} + +/* Will be called by the library to read the mouse */ +static bool keypad_read(lv_indev_data_t * data) +{ + static uint32_t last_key = 0; + + /*Get the current x and y coordinates*/ + mouse_get_xy(&data->point.x, &data->point.y); + + /*Get whether the a key is pressed and save the pressed key*/ + uint32_t act_key = keypad_get_key(); + if(act_key != 0) { + data->state = LV_INDEV_STATE_PR; + + /*Translate the keys to LittlevGL control characters according to your key definitions*/ + switch(act_key) { + case 1: + act_key = LV_GROUP_KEY_NEXT; + break; + case 2: + act_key = LV_GROUP_KEY_PREV; + break; + case 3: + act_key = LV_GROUP_KEY_LEFT; + break; + case 4: + act_key = LV_GROUP_KEY_RIGHT; + break; + case 5: + act_key = LV_GROUP_KEY_ENTER; + break; + } + + last_key = act_key; + } else { + data->state = LV_INDEV_STATE_REL; + } + + data->key = last_key; + + /*Return `false` because we are not buffering and no more data to read*/ + return false; +} + +/*Get the currently being pressed key. 0 if no key is pressed*/ +static uint32_t keypad_get_key(void) +{ + /*Your code comes here*/ + + return 0; +} + +/*------------------ + * Encoder + * -----------------*/ + +/* Initialize your keypad */ +static void encoder_init(void) +{ + /*Your code comes here*/ +} + +/* Will be called by the library to read the encoder */ +static bool encoder_read(lv_indev_data_t * data) +{ + + data->enc_diff = encoder_diff; + data->state = encoder_state; + + /*Return `false` because we are not buffering and no more data to read*/ + return false; +} + +/*Call this function in an interrupt to process encoder events (turn, press)*/ +static void encoder_handler(void) +{ + /*Your code comes here*/ + + encoder_diff += 0; + encoder_state = LV_INDEV_STATE_REL; +} + + +/*------------------ + * Button + * -----------------*/ + +/* Initialize your buttons */ +static void button_init(void) +{ + /*Your code comes here*/ +} + +/* Will be called by the library to read the button */ +static bool button_read(lv_indev_data_t * data) +{ + + static uint8_t last_btn = 0; + + /*Get the pressed button's ID*/ + int8_t btn_act = button_get_pressed_id(); + + if(btn_act >= 0) { + data->state = LV_INDEV_STATE_PR; + last_btn = btn_act; + } else { + data->state = LV_INDEV_STATE_REL; + } + + /*Save the last pressed button's ID*/ + data->btn = last_btn; + + /*Return `false` because we are not buffering and no more data to read*/ + return false; +} + +/*Get ID (0, 1, 2 ..) of the pressed button*/ +static int8_t button_get_pressed_id(void) +{ + uint8_t i; + + /*Check to buttons see which is being pressed (assume there are 2 buttons)*/ + for(i = 0; i < 2; i++) { + /*Return the pressed button's ID*/ + if(button_is_pressed(i)) { + return i; + } + } + + /*No button pressed*/ + return -1; +} + +/*Test if `id` button is pressed or not*/ +static bool button_is_pressed(uint8_t id) +{ + + /*Your code comes here*/ + + return false; +} + +#endif diff --git a/lv_porting/lv_port_indev_templ.h b/lv_porting/lv_port_indev_templ.h new file mode 100644 index 000000000..491d5249a --- /dev/null +++ b/lv_porting/lv_port_indev_templ.h @@ -0,0 +1,45 @@ + +/** + * @file lv_port_indev_templ.h + * + */ + + /*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/ +#if 0 + +#ifndef LV_PORT_INDEV_TEMPL_H +#define LV_PORT_INDEV_TEMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_PORT_INDEV_TEMPL_H*/ + +#endif /*Disable/Enable content*/