forked from xuos/xiuos
fix i2c error, add senser interface.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
SRC_FILES := lv_init.c lv_demo.c lv_demo_calendar.c
|
||||
SRC_FILES += lv_sensor_info.c lv_sensor_update_info.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
## lv_sensor_update_info
|
||||
用于在触摸屏上显示传感器的各项数据
|
||||
|
||||
更新显示数据可在线程中使用`bool sensor_update_val(double val, enum sensor_type st)`(保障线程安全)
|
||||
- `val`: 传感器数值;
|
||||
- `st`:检测值类型(如氧气、臭氧);
|
||||
- `st`类型为`enum sensor_type`,该枚举类型在lv_sensor_info.h中给出;
|
||||
- 该函数的使用方法可参考lv_sensor_info_update_demo.c;
|
||||
- 请勿直接修改lvgl table;
|
||||
``` C
|
||||
enum sensor_type {
|
||||
O3 = 0, // 臭氧
|
||||
CO2, // 二氧化碳
|
||||
SO2, // 二氧化硫
|
||||
NO2, // 二氧化氮
|
||||
N2, // 氨气
|
||||
TVOC,
|
||||
FORMALDEHYDE, // 甲醛
|
||||
ALCOHOL, // 乙醇
|
||||
METHANE, // 甲烷
|
||||
O2, // 氧气
|
||||
AQS,
|
||||
PM, // PM1.0/2.5
|
||||
TEMPERATURE, // 温度
|
||||
HUMIDITY, // 湿度
|
||||
WIND_SPEED, // 风速
|
||||
WIND_DIRECTION, //风向
|
||||
PRESURE, // 压力
|
||||
NOISE // 噪音
|
||||
};
|
||||
```
|
||||
@@ -3,19 +3,20 @@
|
||||
#include "lv_demo_calendar.h"
|
||||
#include <transform.h>
|
||||
|
||||
extern void lv_example_chart_2(void);
|
||||
extern void lv_example_img_1(void);
|
||||
extern void lv_example_img_2(void);
|
||||
extern void lv_example_img_3(void);
|
||||
extern void lv_example_img_4(void);
|
||||
extern void lv_example_line_1(void);
|
||||
extern void lv_example_aoteman(void);
|
||||
// extern void lv_example_chart_2(void);
|
||||
// extern void lv_example_img_1(void);
|
||||
// extern void lv_example_img_2(void);
|
||||
// extern void lv_example_img_3(void);
|
||||
// extern void lv_example_img_4(void);
|
||||
// extern void lv_example_line_1(void);
|
||||
// extern void lv_example_aoteman(void);
|
||||
void* lvgl_thread(void *parameter)
|
||||
{
|
||||
/* display demo; you may replace with your LVGL application at here */
|
||||
lv_demo_calendar();
|
||||
// lv_example_img_1();
|
||||
// lv_example_chart_2();
|
||||
// lv_example_table_1();
|
||||
// lv_example_line_1();
|
||||
// lv_example_aoteman();
|
||||
/* handle the tasks of LVGL */
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "lv_sensor_info.h"
|
||||
|
||||
static void draw_part_event_cb(lv_event_t* e) {
|
||||
lv_obj_t* obj = lv_event_get_target(e);
|
||||
lv_obj_draw_part_dsc_t* dsc = lv_event_get_param(e);
|
||||
/*If the cells are drawn...*/
|
||||
if(dsc->part == LV_PART_ITEMS) {
|
||||
uint32_t row = dsc->id / lv_table_get_col_cnt(obj);
|
||||
uint32_t col = dsc->id - row * lv_table_get_col_cnt(obj);
|
||||
/*Make the texts in the first cell center aligned*/
|
||||
if(row == 0) {
|
||||
dsc->label_dsc->align = LV_TEXT_ALIGN_CENTER;
|
||||
dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_BLUE), dsc->rect_dsc->bg_color, LV_OPA_20);
|
||||
dsc->rect_dsc->bg_opa = LV_OPA_COVER;
|
||||
}
|
||||
/*In the first column align the texts to the right*/
|
||||
else if(col == 0) {
|
||||
dsc->label_dsc->flag = LV_TEXT_ALIGN_CENTER;
|
||||
}
|
||||
/*Make every 2nd row grayish*/
|
||||
if((row != 0 && row % 2) == 0) {
|
||||
dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_GREY), dsc->rect_dsc->bg_color, LV_OPA_10);
|
||||
dsc->rect_dsc->bg_opa = LV_OPA_COVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* Double2Str(char* buf, double value) {
|
||||
sprintf(buf,"%.8f",value);//保留8位小数,不够补0
|
||||
int index = 0;
|
||||
int len = strlen(buf);
|
||||
for(int i = len-1;i>0;i--)
|
||||
{
|
||||
if(buf[i] == '0')
|
||||
continue;
|
||||
else {
|
||||
if (buf[i] == '.') index = i;
|
||||
else index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[index] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
lv_obj_t* lv_ssr_tb;
|
||||
|
||||
void lv_sensor_info(void) {
|
||||
lv_ssr_tb = lv_table_create(lv_scr_act());
|
||||
// lv_obj_remove_style(lv_ssr_tb, NULL, LV_PART_ITEMS | LV_STATE_PRESSED);
|
||||
|
||||
for (uint32_t i = 0; i < NR_VAL_PERLINE; ++i) {
|
||||
lv_table_set_cell_value(lv_ssr_tb, 0, 2 * i, "检测量");
|
||||
lv_table_set_cell_value(lv_ssr_tb, 0, 2 * i + 1, "数值");
|
||||
}
|
||||
|
||||
// fill name
|
||||
uint32_t filled_pos = 0;
|
||||
uint32_t cur_line_tmp = 0;
|
||||
LV_FONT_DECLARE(lvgl_font_chinese);
|
||||
while (filled_pos < nr_sensors) {
|
||||
cur_line_tmp = 1 + (filled_pos / NR_VAL_PERLINE);
|
||||
for (uint32_t i = 0; i < NR_VAL_PERLINE; ++i) {
|
||||
if (filled_pos >= nr_sensors) { break; }
|
||||
lv_table_set_cell_value(lv_ssr_tb, cur_line_tmp, 2 * i, sensor_names[filled_pos++]);
|
||||
}
|
||||
}
|
||||
lv_obj_set_style_text_font(lv_ssr_tb, &lvgl_font_chinese, 0);
|
||||
|
||||
for (uint32_t i = 0; i < 2 * NR_VAL_PERLINE; ++i) {
|
||||
if (i % 2 == 0) {
|
||||
lv_table_set_col_width(lv_ssr_tb, i, 75);
|
||||
}
|
||||
else {
|
||||
lv_table_set_col_width(lv_ssr_tb, i, 85);
|
||||
}
|
||||
}
|
||||
|
||||
// fill val
|
||||
filled_pos = 0;
|
||||
// init val
|
||||
for (uint32_t i = 0; i < nr_sensors; ++i) { lv_sensor_vals[i] = 0; }
|
||||
char buf[10];
|
||||
snprintf(buf, 9, "%.1f", 0);
|
||||
while (filled_pos < nr_sensors) {
|
||||
for (uint32_t i = 0; i < NR_VAL_PERLINE; ++i) {
|
||||
if (filled_pos >= nr_sensors) { break; }
|
||||
lv_table_set_cell_value_fmt(lv_ssr_tb, 1 + (filled_pos / NR_VAL_PERLINE),
|
||||
1 + 2 * i, "%s %s", buf, seneor_denominations[filled_pos++]);
|
||||
}
|
||||
}
|
||||
|
||||
lv_obj_set_size(lv_ssr_tb, 480, 272);
|
||||
|
||||
lv_obj_set_height(lv_ssr_tb, 272);
|
||||
lv_obj_center(lv_ssr_tb);
|
||||
|
||||
/*Add an event callback to to apply some custom drawing*/
|
||||
lv_obj_add_event_cb(lv_ssr_tb, draw_part_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
|
||||
}
|
||||
|
||||
void* lvgl_thd_show_sensor_info(void *parameter)
|
||||
{
|
||||
lv_sensor_info();
|
||||
PrivMutexCreate(&ssr_val_lock, 0);
|
||||
while (1)
|
||||
{
|
||||
lv_task_handler();
|
||||
|
||||
sensor_update_table();
|
||||
}
|
||||
}
|
||||
|
||||
pthread_t lvgl_task;
|
||||
static int lvgl_show_sensor_info(void)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = 25;
|
||||
attr.stacksize = 4096;
|
||||
|
||||
PrivTaskCreate(&lvgl_task, &attr, lvgl_thd_show_sensor_info, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),lvgl_show_sensor_info, lvgl_show_sensor_info, lvgl_show_sensor_info );
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef __LVGL_SENSOR_INFO_H__
|
||||
#define __LVGL_SENSOR_INFO_H__
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <string.h>
|
||||
|
||||
#define nr_sensors 18
|
||||
extern lv_obj_t* lv_ssr_tb;
|
||||
pthread_mutex_t ssr_val_lock;
|
||||
|
||||
#define NR_VAL_PERLINE 3
|
||||
|
||||
static char* sensor_names[nr_sensors] = {
|
||||
"臭氧", "二氧化碳", "二氧化硫", "二氧化氮", "氨气",
|
||||
"TVOC", "甲醛", "乙醇", "甲烷", "氧气", "AQS", "PM1.0/2.5/10",
|
||||
"温度", "湿度",
|
||||
"风速", "风向", "气压", "噪音"
|
||||
};
|
||||
|
||||
static char* seneor_denominations[nr_sensors] = {
|
||||
"ppb", "ppm", "ppb", "ppb", "ppm",
|
||||
"ppm", "ppm", "ppm", "%VOL", "%VOL", "ug/m³", "ug/m³",
|
||||
"°C", "%RH", "m/s", "m/s", "mbar", "dB(A)"
|
||||
};
|
||||
|
||||
static double lv_sensor_vals[nr_sensors];
|
||||
|
||||
enum sensor_type {
|
||||
O3 = 0, // 臭氧
|
||||
CO2, // 二氧化碳
|
||||
SO2, // 二氧化硫
|
||||
NO2, // 二氧化氮
|
||||
N2, // 氨气
|
||||
TVOC,
|
||||
FORMALDEHYDE, // 甲醛
|
||||
ALCOHOL, // 乙醇
|
||||
METHANE, // 甲烷
|
||||
O2, // 氧气
|
||||
AQS,
|
||||
PM, // PM1.0/2.5
|
||||
TEMPERATURE, // 温度
|
||||
HUMIDITY, // 湿度
|
||||
WIND_SPEED, // 风速
|
||||
WIND_DIRECTION, //风向
|
||||
PRESURE, // 压力
|
||||
NOISE // 噪音
|
||||
};
|
||||
|
||||
void lv_sensor_info(void);
|
||||
bool sensor_update_val(double, enum sensor_type);
|
||||
char* Double2Str(char* buf, double value);
|
||||
void sensor_update_table();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "lv_sensor_info.h"
|
||||
|
||||
void* lvgl_thd_sensor_info_update_demo(void *parameter)
|
||||
{
|
||||
double val = 0;
|
||||
while (1)
|
||||
{
|
||||
sensor_update_val(val + 0.1, O3);
|
||||
sensor_update_val(val, CO2);
|
||||
sensor_update_val(val + 0.2, NO2);
|
||||
sensor_update_val(val - 0.1, SO2);
|
||||
sensor_update_val(val + 0.3, AQS);
|
||||
sensor_update_val(val - 0.3, O2);
|
||||
sensor_update_val(val + 0.3, TEMPERATURE);
|
||||
val += 0.3;
|
||||
PrivTaskDelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_t lvgl_task;
|
||||
static int lvgl_sensor_info_update_demo(void)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = 25;
|
||||
attr.stacksize = 4096;
|
||||
|
||||
PrivTaskCreate(&lvgl_task, &attr, lvgl_thd_sensor_info_update_demo, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),lvgl_sensor_info_update_demo, lvgl_sensor_info_update_demo, lvgl_sensor_info_update_demo );
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "lv_sensor_info.h"
|
||||
|
||||
uint32_t lv_ssr_map_idx(enum sensor_type st) {
|
||||
uint32_t idx;
|
||||
switch (st) {
|
||||
case O3: {idx = 0; break;}
|
||||
case CO2: {idx = 1; break;}
|
||||
case SO2: {idx = 2; break;}
|
||||
case NO2: {idx = 3; break;}
|
||||
case N2: {idx = 4; break;}
|
||||
case TVOC: {idx = 5; break;}
|
||||
case FORMALDEHYDE: {idx = 6; break;}
|
||||
case ALCOHOL: {idx = 7; break;}
|
||||
case METHANE: {idx = 8; break;}
|
||||
case O2: {idx = 9; break;}
|
||||
case AQS: {idx = 10; break;}
|
||||
case PM: {idx = 11; break;}
|
||||
case TEMPERATURE: {idx = 12; break;}
|
||||
case HUMIDITY: {idx = 13; break;}
|
||||
case WIND_SPEED: {idx = 14; break;}
|
||||
case WIND_DIRECTION: {idx = 15; break;}
|
||||
case PRESURE: {idx = 16; break;}
|
||||
case NOISE: {idx = 17; break;}
|
||||
default: {idx = -1; break;}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool sensor_update_val(double val, enum sensor_type st) {
|
||||
uint32_t idx = lv_ssr_map_idx(st);
|
||||
if (idx >= nr_sensors || lv_ssr_tb == NULL) { return false; }
|
||||
PrivMutexObtain(&ssr_val_lock);
|
||||
lv_sensor_vals[idx] = val;
|
||||
PrivMutexAbandon(&ssr_val_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief update cell vals in lv_ssr_tb,
|
||||
* note that this function can only be called in lv_ssr_tb control thread
|
||||
*
|
||||
*/
|
||||
void sensor_update_table() {
|
||||
uint32_t filled_pos = 0;
|
||||
char buf[10] = { 0 };
|
||||
PrivMutexObtain(&ssr_val_lock);
|
||||
while (filled_pos < nr_sensors) {
|
||||
for (uint32_t i = 0; i < NR_VAL_PERLINE; ++i) {
|
||||
if (filled_pos >= nr_sensors) { break; }
|
||||
snprintf(buf, 9, "%.1f", lv_sensor_vals[filled_pos]);
|
||||
lv_table_set_cell_value_fmt(lv_ssr_tb, 1 + (filled_pos / NR_VAL_PERLINE),
|
||||
1 + 2 * i, "%s %s", buf, seneor_denominations[filled_pos++]);
|
||||
}
|
||||
}
|
||||
PrivMutexAbandon(&ssr_val_lock);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
// #include <user_api.h>
|
||||
#include <transform.h>
|
||||
|
||||
|
||||
|
||||
extern int FrameworkInit();
|
||||
extern void ApplicationOtaTaskInit(void);
|
||||
int main(void)
|
||||
@@ -24,7 +26,12 @@ int main(void)
|
||||
#ifdef APPLICATION_OTA
|
||||
ApplicationOtaTaskInit();
|
||||
#endif
|
||||
return 0;
|
||||
// while (1) {
|
||||
// ShowTask();
|
||||
// ShowMemory();
|
||||
// PrivTaskDelay(1500);
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
// int cppmain(void);
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@
|
||||
*=========================*/
|
||||
|
||||
/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
|
||||
#define LV_MEM_CUSTOM 1
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
|
||||
# define LV_MEM_SIZE (32U * 1024U) /*[bytes]*/
|
||||
# define LV_MEM_SIZE (64U * 1024U) /*[bytes]*/
|
||||
|
||||
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
|
||||
# define LV_MEM_ADR 0 /*0: unused*/
|
||||
@@ -78,10 +78,10 @@
|
||||
*====================*/
|
||||
|
||||
/*Default display refresh period. LVG will redraw changed areas with this period time*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 100 /*[ms]*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 1 /*[ms]*/
|
||||
|
||||
/*Input device read period in milliseconds*/
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/
|
||||
#define LV_INDEV_DEF_READ_PERIOD 1 /*[ms]*/
|
||||
|
||||
/*Use a custom tick source that tells the elapsed time in milliseconds.
|
||||
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
|
||||
@@ -187,7 +187,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
|
||||
/*1: Print the log with 'printf';
|
||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
||||
# define LV_LOG_PRINTF 0
|
||||
# define LV_LOG_PRINTF 1
|
||||
|
||||
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
|
||||
# define LV_LOG_TRACE_MEM 1
|
||||
@@ -229,7 +229,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
|
||||
/*1: Show the used memory and the memory fragmentation in the left bottom corner
|
||||
* Requires LV_MEM_CUSTOM = 0*/
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#define LV_USE_MEM_MONITOR 1
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.mk
|
||||
# include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.mk
|
||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/porting/porting.mk
|
||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra/extra.mk
|
||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core/lv_core.mk
|
||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/lv_draw.mk
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* @file lv_port_disp_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
|
||||
#if 1
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_disp_template.h"
|
||||
#include "../lvgl.h"
|
||||
|
||||
static int lcd_fd = 0;
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void disp_init(void);
|
||||
|
||||
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
|
||||
// const lv_area_t * fill_area, lv_color_t color);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_port_disp_init(void)
|
||||
{
|
||||
/*-------------------------
|
||||
* Initialize your display
|
||||
* -----------------------*/
|
||||
disp_init();
|
||||
|
||||
/*-----------------------------
|
||||
* Create a buffer for drawing
|
||||
*----------------------------*/
|
||||
|
||||
/**
|
||||
* LVGL requires a buffer where it internally draws the widgets.
|
||||
* Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
|
||||
* The buffer has to be greater than 1 display row
|
||||
*
|
||||
* There are 3 buffering configurations:
|
||||
* 1. Create ONE buffer:
|
||||
* LVGL will draw the display's content here and writes it to your display
|
||||
*
|
||||
* 2. Create TWO buffer:
|
||||
* LVGL will draw the display's content to a buffer and writes it your display.
|
||||
* You should use DMA to write the buffer's content to the display.
|
||||
* It will enable LVGL to draw the next part of the screen to the other buffer while
|
||||
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
|
||||
*
|
||||
* 3. Double buffering
|
||||
* Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
|
||||
* This way LVGL will always provide the whole rendered screen in `flush_cb`
|
||||
* and you only need to change the frame buffer's address.
|
||||
*/
|
||||
|
||||
/* Example for 1) */
|
||||
// static lv_disp_draw_buf_t draw_buf_dsc_1;
|
||||
// static lv_color_t buf_1[MY_DISP_HOR_RES * 1]; /*A buffer for 10 rows*/
|
||||
// lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 1); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 2) */
|
||||
static lv_disp_draw_buf_t draw_buf_dsc_2;
|
||||
static lv_color_t buf_2_1[MY_DISP_HOR_RES *10]; /*A buffer for 10 rows*/
|
||||
static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; /*An other buffer for 10 rows*/
|
||||
lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 3) also set disp_drv.full_refresh = 1 below*/
|
||||
// static lv_disp_draw_buf_t draw_buf_dsc_3;
|
||||
// static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*A screen sized buffer*/
|
||||
// static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*An other screen sized buffer*/
|
||||
// lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * LV_VER_RES_MAX); /*Initialize the display buffer*/
|
||||
|
||||
/*-----------------------------------
|
||||
* Register the display in LVGL
|
||||
*----------------------------------*/
|
||||
|
||||
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
|
||||
/*Set up the functions to access to your display*/
|
||||
|
||||
/*Set the resolution of the display*/
|
||||
disp_drv.hor_res = MY_DISP_HOR_RES;
|
||||
disp_drv.ver_res = MY_DISP_VER_RES;
|
||||
|
||||
/*Used to copy the buffer's content to the display*/
|
||||
disp_drv.flush_cb = disp_flush;
|
||||
|
||||
/*Set a display buffer*/
|
||||
disp_drv.draw_buf = &draw_buf_dsc_2;
|
||||
|
||||
/*Required for Example 3)*/
|
||||
//disp_drv.full_refresh = 1
|
||||
|
||||
/* Fill a memory array with a color if you have GPU.
|
||||
* Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
|
||||
* But if you have a different GPU you can use with this callback.*/
|
||||
//disp_drv.gpu_fill_cb = gpu_fill;
|
||||
|
||||
/*Finally register the driver*/
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/*Initialize your display and the required peripherals.*/
|
||||
static void disp_init(void)
|
||||
{
|
||||
lcd_fd = PrivOpen(PRIV_LCD_DEV,O_RDWR);
|
||||
printf("lcd fd = %d\n",lcd_fd);
|
||||
/*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_disp_flush_ready()' has to be called when finished.*/
|
||||
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
|
||||
LcdWriteParam disp_info;
|
||||
/*Put a pixel to the display. For example:*/
|
||||
|
||||
memset(&disp_info,0,sizeof(LcdWriteParam));
|
||||
if(area && color_p)
|
||||
{
|
||||
disp_info.type = 1;
|
||||
// printf("wwg debug\n");
|
||||
disp_info.pixel_info.x_startpos = area->x1;
|
||||
disp_info.pixel_info.x_endpos = area->x2;
|
||||
disp_info.pixel_info.y_startpos = area->y1;
|
||||
disp_info.pixel_info.y_endpos = area->y2;
|
||||
disp_info.pixel_info.pixel_color = color_p;
|
||||
// printf("x1:%d x2:%d y1 %d y2 %d\n",disp_info.pixel_info.x_startpos,disp_info.pixel_info.x_endpos,disp_info.pixel_info.y_startpos,disp_info.pixel_info.y_endpos);
|
||||
PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam));
|
||||
}
|
||||
|
||||
|
||||
// int32_t x;
|
||||
// int32_t y;
|
||||
// for(y = area->y1; y <= area->y2; y++) {
|
||||
// for(x = area->x1; x <= area->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_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
/*OPTIONAL: GPU INTERFACE*/
|
||||
|
||||
/*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
|
||||
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
|
||||
// const lv_area_t * fill_area, lv_color_t color)
|
||||
//{
|
||||
// /*It's an example code which should be done by your GPU*/
|
||||
// int32_t x, y;
|
||||
// dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
|
||||
//
|
||||
// for(y = fill_area->y1; y <= fill_area->y2; y++) {
|
||||
// for(x = fill_area->x1; x <= fill_area->x2; x++) {
|
||||
// dest_buf[x] = color;
|
||||
// }
|
||||
// dest_buf+=dest_width; /*Go to the next line*/
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
#else /*Enable this file at the top*/
|
||||
|
||||
/*This dummy typedef exists purely to silence -Wpedantic.*/
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file lv_port_disp_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_disp.h" 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*/
|
||||
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* @file lv_port_fs_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_fs.c" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_fs_template.h"
|
||||
#include "../../lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void fs_init(void);
|
||||
|
||||
static void * fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
|
||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p);
|
||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
|
||||
static lv_fs_res_t fs_size(lv_fs_drv_t * drv, void * file_p, uint32_t * size_p);
|
||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
|
||||
|
||||
static void * fs_dir_open(lv_fs_drv_t * drv, const char *path);
|
||||
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn);
|
||||
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * rddir_p);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_port_fs_init(void)
|
||||
{
|
||||
/*----------------------------------------------------
|
||||
* Initialize your storage device and File System
|
||||
* -------------------------------------------------*/
|
||||
fs_init();
|
||||
|
||||
/*---------------------------------------------------
|
||||
* Register the file system interface in LVGL
|
||||
*--------------------------------------------------*/
|
||||
|
||||
/*Add a simple drive to open images*/
|
||||
static lv_fs_drv_t fs_drv;
|
||||
lv_fs_drv_init(&fs_drv);
|
||||
|
||||
/*Set up fields...*/
|
||||
fs_drv.letter = 'P';
|
||||
fs_drv.open_cb = fs_open;
|
||||
fs_drv.close_cb = fs_close;
|
||||
fs_drv.read_cb = fs_read;
|
||||
fs_drv.write_cb = fs_write;
|
||||
fs_drv.seek_cb = fs_seek;
|
||||
fs_drv.tell_cb = fs_tell;
|
||||
|
||||
fs_drv.dir_close_cb = fs_dir_close;
|
||||
fs_drv.dir_open_cb = fs_dir_open;
|
||||
fs_drv.dir_read_cb = fs_dir_read;
|
||||
|
||||
lv_fs_drv_register(&fs_drv);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/*Initialize your Storage device and File system.*/
|
||||
static void fs_init(void)
|
||||
{
|
||||
/*E.g. for FatFS initialize the SD card and FatFS itself*/
|
||||
|
||||
/*You code here*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
|
||||
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
|
||||
* @return a file descriptor or NULL on error
|
||||
*/
|
||||
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
void * f = NULL;
|
||||
|
||||
if(mode == LV_FS_MODE_WR)
|
||||
{
|
||||
/*Open a file for write*/
|
||||
f = ... /*Add your code here*/
|
||||
}
|
||||
else if(mode == LV_FS_MODE_RD)
|
||||
{
|
||||
/*Open a file for read*/
|
||||
f = ... /*Add your code here*/
|
||||
}
|
||||
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
|
||||
{
|
||||
/*Open a file for read and write*/
|
||||
f = ... /*Add your code here*/
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close an opened file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a file_t variable. (opened with fs_open)
|
||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/*Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from an opened file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a file_t variable.
|
||||
* @param buf pointer to a memory block where to store the read data
|
||||
* @param btr number of Bytes To Read
|
||||
* @param br the real number of read bytes (Byte Read)
|
||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/*Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write into a file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a file_t variable
|
||||
* @param buf pointer to a buffer with the bytes to write
|
||||
* @param btr Bytes To Write
|
||||
* @param br the number of real written bytes (Bytes Written). NULL if unused.
|
||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/*Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read write pointer. Also expand the file size if necessary.
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a file_t variable. (opened with fs_open )
|
||||
* @param pos the new position of read write pointer
|
||||
* @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t
|
||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/*Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* Give the position of the read write pointer
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a file_t variable.
|
||||
* @param pos_p pointer to to store the result
|
||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/*Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a 'lv_fs_dir_t' variable for directory reading
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param path path to a directory
|
||||
* @return pointer to the directory read descriptor or NULL on error
|
||||
*/
|
||||
static void * fs_dir_open(lv_fs_drv_t * drv, const char *path)
|
||||
{
|
||||
void * dir = NULL;
|
||||
/*Add your code here*/
|
||||
dir = ... /*Add your code here*/
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the next filename form a directory.
|
||||
* The name of the directories will begin with '/'
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
|
||||
* @param fn pointer to a buffer to store the filename
|
||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char *fn)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/*Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the directory reading
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
|
||||
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * rddir_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/*Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#else /*Enable this file at the top*/
|
||||
|
||||
/*This dummy typedef exists purely to silence -Wpedantic.*/
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file lv_port_fs_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_fs.h" 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*/
|
||||
@@ -0,0 +1,521 @@
|
||||
/**
|
||||
* @file lv_port_indev_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
|
||||
#if 1
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_indev_template.h"
|
||||
#include "../lvgl.h"
|
||||
|
||||
#include <dev_touch.h>
|
||||
|
||||
static int touch_fd = 0;
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_USE_INDEV_TOUCHPAD 0x1u
|
||||
#define LV_USE_INDEV_MOUSE 0x2u
|
||||
#define LV_USE_INDEV_KEYPAD 0x4u
|
||||
#define LV_USE_INDEV_ENCODER 0x8u
|
||||
#define LV_USE_INDEV_BUTTUN 0x10u
|
||||
|
||||
#define PRESS_FAILED_LIMIT 15
|
||||
#define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD ///< modify this DEFINE to enable the indev device. e.g #define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD | LV_USE_INDEV_KEYPAD
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
||||
static void touchpad_init(void);
|
||||
static void touchpad_read(lv_indev_drv_t * indev_drv, 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 bool touchpad_is_pressed(struct TouchDataStandard* touch_data_ptr);
|
||||
static void touchpad_get_xy(struct TouchDataStandard* touch_data_ptr,
|
||||
lv_coord_t* x, lv_coord_t* y);
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
||||
static void mouse_init(void);
|
||||
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static bool mouse_is_pressed(void);
|
||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
||||
static void keypad_init(void);
|
||||
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static uint32_t keypad_get_key(void);
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||
static void encoder_init(void);
|
||||
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static void encoder_handler(void);
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
||||
static void button_init(void);
|
||||
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static int8_t button_get_pressed_id(void);
|
||||
static bool button_is_pressed(uint8_t id);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
||||
lv_indev_t * indev_touchpad;
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
||||
lv_indev_t * indev_mouse;
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
||||
lv_indev_t * indev_keypad;
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||
lv_indev_t * indev_encoder;
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
||||
lv_indev_t * indev_button;
|
||||
#endif
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
static lv_indev_drv_t indev_drv;
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
||||
/*------------------
|
||||
* 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_cb = touchpad_read;
|
||||
indev_touchpad = lv_indev_drv_register(&indev_drv);
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
||||
/*------------------
|
||||
* 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_cb = 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());
|
||||
lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
|
||||
lv_indev_set_cursor(indev_mouse, mouse_cursor);
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
||||
/*------------------
|
||||
* 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_cb = 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);`*/
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||
/*------------------
|
||||
* 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_ENCODER;
|
||||
indev_drv.read_cb = 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_encoder, group);`*/
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
||||
/*------------------
|
||||
* 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_cb = 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);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
||||
/*------------------
|
||||
* Touchpad
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your touchpad*/
|
||||
static void touchpad_init(void)
|
||||
{
|
||||
touch_fd = PrivOpen(PRIV_TOUCH_DEV,O_RDWR);
|
||||
if(touch_fd >= 0) {
|
||||
printf("touch fd = %d\n",touch_fd);
|
||||
} else {
|
||||
printf("open %s touch fd = %d failed.\n",PRIV_TOUCH_DEV,touch_fd);
|
||||
}
|
||||
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
// static struct TouchDataStandard touch_data;
|
||||
|
||||
/*Will be called by the library to read the touchpad*/
|
||||
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
static lv_coord_t last_x = 0;
|
||||
static lv_coord_t last_y = 0;
|
||||
|
||||
static struct TouchDataStandard touch_data;
|
||||
|
||||
/*Save the pressed coordinates and the state*/
|
||||
if (touchpad_is_pressed(&touch_data)) {
|
||||
touchpad_get_xy(&touch_data, &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 true is the touchpad is pressed*/
|
||||
// static bool touchpad_is_pressed(void)
|
||||
// {
|
||||
// int ret;
|
||||
// /*Your code comes here*/
|
||||
// // memset(&touch_data, 0 ,sizeof(TouchDataParam));
|
||||
// memset(&touch_data, 0 ,sizeof(struct TouchDataStandard));
|
||||
// ret = PrivRead(touch_fd, &touch_data, 1);
|
||||
// if (ret && touch_data.x >= 0 && touch_data.x < MY_INDEV_X
|
||||
// && touch_data.y >= 0 && touch_data.y < MY_INDEV_Y)
|
||||
// {
|
||||
// // printf("touch x %d touch y %d\n",touch_data.x,touch_data.y);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
|
||||
uint32_t press_failed_cnt = 0;
|
||||
static bool touchpad_is_pressed(struct TouchDataStandard* touch_data_ptr)
|
||||
{
|
||||
int ret;
|
||||
/*Your code comes here*/
|
||||
memset(touch_data_ptr, 0 ,sizeof(struct TouchDataStandard));
|
||||
ret = PrivRead(touch_fd, touch_data_ptr, 1);
|
||||
if (ret && touch_data_ptr->x > 0 && touch_data_ptr->x < MY_INDEV_X
|
||||
&& touch_data_ptr->y > 0 && touch_data_ptr->y < MY_INDEV_Y)
|
||||
{
|
||||
press_failed_cnt = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
press_failed_cnt++;
|
||||
if (press_failed_cnt >= PRESS_FAILED_LIMIT) {
|
||||
PrivClose(touch_fd);
|
||||
touchpad_init();
|
||||
press_failed_cnt = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Get the x and y coordinates if the touchpad is pressed*/
|
||||
static void touchpad_get_xy(struct TouchDataStandard* touch_data_ptr,
|
||||
lv_coord_t* x, lv_coord_t* y) {
|
||||
/*Your code comes here*/
|
||||
|
||||
(*x) = touch_data_ptr->x;
|
||||
(*y) = touch_data_ptr->y;
|
||||
}
|
||||
|
||||
// static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
|
||||
// {
|
||||
// /*Your code comes here*/
|
||||
|
||||
// (*x) = touch_data.x;
|
||||
// (*y) = touch_data.y;
|
||||
// }
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
||||
/*------------------
|
||||
* Mouse
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your mouse*/
|
||||
static void mouse_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/*Will be called by the library to read the mouse*/
|
||||
static void mouse_read(lv_indev_drv_t * indev_drv, 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 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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
||||
/*------------------
|
||||
* Keypad
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your keypad*/
|
||||
static void keypad_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/*Will be called by the library to read the mouse*/
|
||||
static void keypad_read(lv_indev_drv_t * indev_drv, 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 LVGL control characters according to your key definitions*/
|
||||
switch(act_key) {
|
||||
case 1:
|
||||
act_key = LV_KEY_NEXT;
|
||||
break;
|
||||
case 2:
|
||||
act_key = LV_KEY_PREV;
|
||||
break;
|
||||
case 3:
|
||||
act_key = LV_KEY_LEFT;
|
||||
break;
|
||||
case 4:
|
||||
act_key = LV_KEY_RIGHT;
|
||||
break;
|
||||
case 5:
|
||||
act_key = LV_KEY_ENTER;
|
||||
break;
|
||||
}
|
||||
|
||||
last_key = act_key;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
data->key = last_key;
|
||||
}
|
||||
|
||||
/*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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||
/*------------------
|
||||
* Encoder
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your keypad*/
|
||||
static void encoder_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/*Will be called by the library to read the encoder*/
|
||||
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
|
||||
data->enc_diff = encoder_diff;
|
||||
data->state = encoder_state;
|
||||
}
|
||||
|
||||
/*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;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
||||
/*------------------
|
||||
* Button
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your buttons*/
|
||||
static void button_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/*Will be called by the library to read the button*/
|
||||
static void button_read(lv_indev_drv_t * indev_drv, 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_id = last_btn;
|
||||
}
|
||||
|
||||
/*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
|
||||
#else /*Enable this file at the top*/
|
||||
|
||||
/*This dummy typedef exists purely to silence -Wpedantic.*/
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
/**
|
||||
* @file lv_port_indev_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_indev.h" 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*/
|
||||
@@ -0,0 +1 @@
|
||||
SRC_FILES := $(shell find -L $(LVGL_DIR)/$(LVGL_DIR_NAME)/porting -name \*.c)
|
||||
+1123
File diff suppressed because it is too large
Load Diff
@@ -98,10 +98,10 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void)
|
||||
/*Run all timer from the list*/
|
||||
lv_timer_t * next;
|
||||
do {
|
||||
timer_deleted = false;
|
||||
timer_created = false;
|
||||
timer_deleted = false;
|
||||
timer_created = false;
|
||||
LV_GC_ROOT(_lv_timer_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll));
|
||||
while(LV_GC_ROOT(_lv_timer_act)) {
|
||||
while (LV_GC_ROOT(_lv_timer_act)) {
|
||||
/*The timer might be deleted if it runs only once ('repeat_count = 1')
|
||||
*So get next element until the current is surely valid*/
|
||||
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_timer_ll), LV_GC_ROOT(_lv_timer_act));
|
||||
@@ -113,11 +113,11 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LV_GC_ROOT(_lv_timer_act) = next; /*Load the next timer*/
|
||||
}
|
||||
} while(LV_GC_ROOT(_lv_timer_act));
|
||||
|
||||
|
||||
uint32_t time_till_next = LV_NO_TIMER_READY;
|
||||
next = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll));
|
||||
while(next) {
|
||||
@@ -310,8 +310,8 @@ static bool lv_timer_exec(lv_timer_t * timer)
|
||||
if(timer->repeat_count > 0) timer->repeat_count--;
|
||||
timer->last_run = lv_tick_get();
|
||||
TIMER_TRACE("calling timer callback: %p", *((void **)&timer->timer_cb));
|
||||
if(timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer);
|
||||
TIMER_TRACE("timer callback %p finished", *((void **)&timer->timer_cb));
|
||||
if (timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer);
|
||||
TIMER_TRACE("timer callback %p finished", *((void**)&timer->timer_cb));
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
exec = true;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint16_t row, uint16_t col, con
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
LV_ASSERT_NULL(fmt);
|
||||
|
||||
lv_table_t * table = (lv_table_t *)obj;
|
||||
lv_table_t* table = (lv_table_t*)obj;
|
||||
if(col >= table->col_cnt) {
|
||||
LV_LOG_WARN("lv_table_set_cell_value: invalid column");
|
||||
return;
|
||||
@@ -183,9 +183,11 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint16_t row, uint16_t col, con
|
||||
/*Refresh the row height*/
|
||||
lv_coord_t cell_left = lv_obj_get_style_pad_left(obj, LV_PART_ITEMS);
|
||||
lv_coord_t cell_right = lv_obj_get_style_pad_right(obj, LV_PART_ITEMS);
|
||||
lv_coord_t cell_top = lv_obj_get_style_pad_top(obj, LV_PART_ITEMS);
|
||||
lv_coord_t cell_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_ITEMS);
|
||||
|
||||
// lv_coord_t cell_top = lv_obj_get_style_pad_top(obj, LV_PART_ITEMS);
|
||||
lv_coord_t cell_top = 3;
|
||||
// lv_coord_t cell_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_ITEMS);
|
||||
lv_coord_t cell_bottom = 3;
|
||||
|
||||
lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_ITEMS);
|
||||
lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_ITEMS);
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_ITEMS);
|
||||
|
||||
Reference in New Issue
Block a user