forked from xuos/xiuos
				
			fix i2c error, add senser interface.
This commit is contained in:
		
							parent
							
								
									0a629fc69d
								
							
						
					
					
						commit
						c014727e2c
					
				|  | @ -1,3 +1,4 @@ | ||||||
| SRC_FILES := lv_init.c lv_demo.c lv_demo_calendar.c  | 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 | 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 "lv_demo_calendar.h" | ||||||
| #include <transform.h> | #include <transform.h> | ||||||
| 
 | 
 | ||||||
| extern void lv_example_chart_2(void); | // extern void lv_example_chart_2(void);
 | ||||||
| extern void lv_example_img_1(void); | // extern void lv_example_img_1(void);
 | ||||||
| extern void lv_example_img_2(void); | // extern void lv_example_img_2(void);
 | ||||||
| extern void lv_example_img_3(void); | // extern void lv_example_img_3(void);
 | ||||||
| extern void lv_example_img_4(void); | // extern void lv_example_img_4(void);
 | ||||||
| extern void lv_example_line_1(void); | // extern void lv_example_line_1(void);
 | ||||||
| extern void lv_example_aoteman(void); | // extern void lv_example_aoteman(void);
 | ||||||
| void* lvgl_thread(void *parameter) | void* lvgl_thread(void *parameter) | ||||||
| { | { | ||||||
|     /* display demo; you may replace with your LVGL application at here */ |     /* display demo; you may replace with your LVGL application at here */ | ||||||
|     lv_demo_calendar(); |     lv_demo_calendar(); | ||||||
|     // lv_example_img_1();
 |     // lv_example_img_1();
 | ||||||
|     // lv_example_chart_2();
 |     // lv_example_chart_2();
 | ||||||
|  |     // lv_example_table_1();
 | ||||||
|     // lv_example_line_1();
 |     // lv_example_line_1();
 | ||||||
|     // lv_example_aoteman();
 |     // lv_example_aoteman();
 | ||||||
|     /* handle the tasks of LVGL */ |     /* 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 <user_api.h>
 | ||||||
| #include <transform.h> | #include <transform.h> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| extern int FrameworkInit(); | extern int FrameworkInit(); | ||||||
| extern void ApplicationOtaTaskInit(void); | extern void ApplicationOtaTaskInit(void); | ||||||
| int main(void) | int main(void) | ||||||
|  | @ -24,6 +26,11 @@ int main(void) | ||||||
| #ifdef APPLICATION_OTA | #ifdef APPLICATION_OTA | ||||||
| 	ApplicationOtaTaskInit(); | 	ApplicationOtaTaskInit(); | ||||||
| #endif | #endif | ||||||
|  |     // while (1) {
 | ||||||
|  |     //     ShowTask();
 | ||||||
|  |     //     ShowMemory();
 | ||||||
|  |     //     PrivTaskDelay(1500);
 | ||||||
|  |     // }
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| // int cppmain(void);
 | // int cppmain(void);
 | ||||||
|  |  | ||||||
|  | @ -46,10 +46,10 @@ | ||||||
|  *=========================*/ |  *=========================*/ | ||||||
| 
 | 
 | ||||||
| /*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/ | /*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 | #if LV_MEM_CUSTOM == 0 | ||||||
| /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/ | /*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.*/ | /*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*/ | #  define LV_MEM_ADR 0     /*0: unused*/ | ||||||
|  | @ -78,10 +78,10 @@ | ||||||
|  *====================*/ |  *====================*/ | ||||||
| 
 | 
 | ||||||
| /*Default display refresh period. LVG will redraw changed areas with this period time*/ | /*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*/ | /*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.
 | /*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()`)*/ |  *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';
 | /*1: Print the log with 'printf';
 | ||||||
|  *0: User need to register a callback with `lv_log_register_print_cb()`*/ |  *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*/ | /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ | ||||||
| #  define LV_LOG_TRACE_MEM        1 | #  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
 | /*1: Show the used memory and the memory fragmentation in the left bottom corner
 | ||||||
|  * Requires LV_MEM_CUSTOM = 0*/ |  * Requires LV_MEM_CUSTOM = 0*/ | ||||||
| #define LV_USE_MEM_MONITOR 0 | #define LV_USE_MEM_MONITOR 1 | ||||||
| #if LV_USE_PERF_MONITOR | #if LV_USE_PERF_MONITOR | ||||||
| #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT | #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT | ||||||
| #endif | #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/extra/extra.mk | ||||||
| include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core/lv_core.mk | include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core/lv_core.mk | ||||||
| include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/lv_draw.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) | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -101,7 +101,7 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) | ||||||
|         timer_deleted = false; |         timer_deleted = false; | ||||||
|         timer_created = false; |         timer_created = false; | ||||||
|         LV_GC_ROOT(_lv_timer_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll)); |         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')
 |             /*The timer might be deleted if it runs only once ('repeat_count = 1')
 | ||||||
|              *So get next element until the current is surely valid*/ |              *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)); |             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; |                     break; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             LV_GC_ROOT(_lv_timer_act) = next; /*Load the next timer*/ |             LV_GC_ROOT(_lv_timer_act) = next; /*Load the next timer*/ | ||||||
|         } |         } | ||||||
|     } while(LV_GC_ROOT(_lv_timer_act)); |     } while(LV_GC_ROOT(_lv_timer_act)); | ||||||
| 
 | 
 | ||||||
|  |      | ||||||
|     uint32_t time_till_next = LV_NO_TIMER_READY; |     uint32_t time_till_next = LV_NO_TIMER_READY; | ||||||
|     next = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll)); |     next = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll)); | ||||||
|     while(next) { |     while(next) { | ||||||
|  | @ -310,8 +310,8 @@ static bool lv_timer_exec(lv_timer_t * timer) | ||||||
|         if(timer->repeat_count > 0) timer->repeat_count--; |         if(timer->repeat_count > 0) timer->repeat_count--; | ||||||
|         timer->last_run = lv_tick_get(); |         timer->last_run = lv_tick_get(); | ||||||
|         TIMER_TRACE("calling timer callback: %p", *((void **)&timer->timer_cb)); |         TIMER_TRACE("calling timer callback: %p", *((void **)&timer->timer_cb)); | ||||||
|         if(timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer); |         if (timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer); | ||||||
|         TIMER_TRACE("timer callback %p finished", *((void **)&timer->timer_cb)); |         TIMER_TRACE("timer callback %p finished", *((void**)&timer->timer_cb)); | ||||||
|         LV_ASSERT_MEM_INTEGRITY(); |         LV_ASSERT_MEM_INTEGRITY(); | ||||||
|         exec = true; |         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_OBJ(obj, MY_CLASS); | ||||||
|     LV_ASSERT_NULL(fmt); |     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) { |     if(col >= table->col_cnt) { | ||||||
|         LV_LOG_WARN("lv_table_set_cell_value: invalid column"); |         LV_LOG_WARN("lv_table_set_cell_value: invalid column"); | ||||||
|         return; |         return; | ||||||
|  | @ -183,8 +183,10 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint16_t row, uint16_t col, con | ||||||
|     /*Refresh the row height*/ |     /*Refresh the row height*/ | ||||||
|     lv_coord_t cell_left = lv_obj_get_style_pad_left(obj, LV_PART_ITEMS); |     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_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_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 = 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 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); |     lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_ITEMS); | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ Modification: | ||||||
| 
 | 
 | ||||||
| static I2cBusParam i2c_bus_param = | static I2cBusParam i2c_bus_param = | ||||||
| { | { | ||||||
|     I2C_SDA_FUNC_GPIO, |     _FUNC_GPIO, | ||||||
|     I2C_SCL_FUNC_GPIO, |     I2C_SCL_FUNC_GPIO, | ||||||
| }; | }; | ||||||
| static BusType pin; | static BusType pin; | ||||||
|  |  | ||||||
|  | @ -1256,7 +1256,7 @@ status_t LPI2C_MasterTransferNonBlocking(LPI2C_Type *base, | ||||||
| 
 | 
 | ||||||
|     /* Return an error if the bus is already in use not by us. */ |     /* Return an error if the bus is already in use not by us. */ | ||||||
|     result = LPI2C_CheckForBusyBus(base); |     result = LPI2C_CheckForBusyBus(base); | ||||||
|     if (result) |     if (result != kStatus_Success) | ||||||
|     { |     { | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <xs_isr.h> | #include <xs_isr.h> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /*******************************************************************************
 | /*******************************************************************************
 | ||||||
|  * Definitions |  * Definitions | ||||||
|  ******************************************************************************/ |  ******************************************************************************/ | ||||||
|  | @ -982,6 +984,8 @@ void LPI2C_MasterTransferCreateHandle(LPI2C_Type *base, | ||||||
|     EnableIRQ(kLpi2cIrqs[instance]); |     EnableIRQ(kLpi2cIrqs[instance]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | uint32_t failed_times = 0; | ||||||
| /*!
 | /*!
 | ||||||
|  * @brief Execute states until FIFOs are exhausted. |  * @brief Execute states until FIFOs are exhausted. | ||||||
|  * @param handle Master nonblocking driver handle. |  * @param handle Master nonblocking driver handle. | ||||||
|  | @ -1018,6 +1022,13 @@ static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_han | ||||||
| 
 | 
 | ||||||
|     /* Get fifo counts and compute room in tx fifo. */ |     /* Get fifo counts and compute room in tx fifo. */ | ||||||
|     LPI2C_MasterGetFifoCounts(base, &rxCount, &txCount); |     LPI2C_MasterGetFifoCounts(base, &rxCount, &txCount); | ||||||
|  |     if (txCount == 0 && rxCount == 0) { | ||||||
|  |         failed_times++; | ||||||
|  |         if (failed_times > 100) { | ||||||
|  |             handle->state = kStopState; | ||||||
|  |             failed_times = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|     txCount = txFifoSize - txCount; |     txCount = txFifoSize - txCount; | ||||||
| 
 | 
 | ||||||
|     while (!state_complete) |     while (!state_complete) | ||||||
|  | @ -1148,6 +1159,7 @@ static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_han | ||||||
|                 if (status & kLPI2C_MasterStopDetectFlag) |                 if (status & kLPI2C_MasterStopDetectFlag) | ||||||
|                 { |                 { | ||||||
|                     *isDone = true; |                     *isDone = true; | ||||||
|  |                     failed_times = 0; | ||||||
|                 } |                 } | ||||||
|                 state_complete = true; |                 state_complete = true; | ||||||
|                 break; |                 break; | ||||||
|  | @ -1372,6 +1384,7 @@ void LPI2C_MasterTransferAbort(LPI2C_Type *base, lpi2c_master_handle_t *handle) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /*!
 | /*!
 | ||||||
|  * brief Reusable routine to handle master interrupts. |  * brief Reusable routine to handle master interrupts. | ||||||
|  * note This function does not need to be called unless you are reimplementing the |  * note This function does not need to be called unless you are reimplementing the | ||||||
|  | @ -2113,9 +2126,7 @@ void LPI2C0_DriverIRQHandler(void) | ||||||
| /* Implementation of LPI2C1 handler named in startup code. */ | /* Implementation of LPI2C1 handler named in startup code. */ | ||||||
| void LPI2C1_DriverIRQHandler(int irqn, void *arg) | void LPI2C1_DriverIRQHandler(int irqn, void *arg) | ||||||
| { | { | ||||||
|     DisableIRQ(LPI2C1_IRQn); |  | ||||||
|     LPI2C_CommonIRQHandler(LPI2C1, 1); |     LPI2C_CommonIRQHandler(LPI2C1, 1); | ||||||
|     EnableIRQ(LPI2C1_IRQn); |  | ||||||
| } | } | ||||||
| DECLARE_HW_IRQ(LPI2C1_IRQn, LPI2C1_DriverIRQHandler, NONE); | DECLARE_HW_IRQ(LPI2C1_IRQn, LPI2C1_DriverIRQHandler, NONE); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -27,7 +27,6 @@ | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| typedef struct Stm32I2c | typedef struct Stm32I2c | ||||||
| { | { | ||||||
|     LPI2C_Type* base; |     LPI2C_Type* base; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,476 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2015, Freescale Semiconductor, Inc. | ||||||
|  |  * Copyright 2016-2017 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  *  | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*************************************************
 | ||||||
|  | File name: fsl_port | ||||||
|  | Description:  | ||||||
|  | Others: take for references | ||||||
|  |                 https://github.com/open-isa-org/open-isa.org
 | ||||||
|  | History:  | ||||||
|  | 1. Date: 2022-02-16 | ||||||
|  | Author: AIIT XUOS Lab | ||||||
|  | Modification:   | ||||||
|  | *************************************************/ | ||||||
|  | 
 | ||||||
|  | #ifndef _FSL_PORT_H_ | ||||||
|  | #define _FSL_PORT_H_ | ||||||
|  | 
 | ||||||
|  | #include "fsl_common.h" | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @addtogroup port | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @name Driver version */ | ||||||
|  | /*@{*/ | ||||||
|  | /*! Version 2.0.2. */ | ||||||
|  | #define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) | ||||||
|  | /*@}*/ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE | ||||||
|  | /*! @brief Internal resistor pull feature selection */ | ||||||
|  | enum _port_pull | ||||||
|  | { | ||||||
|  |     kPORT_PullDisable = 0U, /*!< Internal pull-up/down resistor is disabled. */ | ||||||
|  |     kPORT_PullDown = 2U,    /*!< Internal pull-down resistor is enabled. */ | ||||||
|  |     kPORT_PullUp = 3U,      /*!< Internal pull-up resistor is enabled. */ | ||||||
|  | }; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE | ||||||
|  | /*! @brief Slew rate selection */ | ||||||
|  | enum _port_slew_rate | ||||||
|  | { | ||||||
|  |     kPORT_FastSlewRate = 0U, /*!< Fast slew rate is configured. */ | ||||||
|  |     kPORT_SlowSlewRate = 1U, /*!< Slow slew rate is configured. */ | ||||||
|  | }; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN | ||||||
|  | /*! @brief Open Drain feature enable/disable */ | ||||||
|  | enum _port_open_drain_enable | ||||||
|  | { | ||||||
|  |     kPORT_OpenDrainDisable = 0U, /*!< Open drain output is disabled. */ | ||||||
|  |     kPORT_OpenDrainEnable = 1U,  /*!< Open drain output is enabled. */ | ||||||
|  | }; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER | ||||||
|  | /*! @brief Passive filter feature enable/disable */ | ||||||
|  | enum _port_passive_filter_enable | ||||||
|  | { | ||||||
|  |     kPORT_PassiveFilterDisable = 0U, /*!< Passive input filter is disabled. */ | ||||||
|  |     kPORT_PassiveFilterEnable = 1U,  /*!< Passive input filter is enabled. */ | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH | ||||||
|  | /*! @brief Configures the drive strength. */ | ||||||
|  | enum _port_drive_strength | ||||||
|  | { | ||||||
|  |     kPORT_LowDriveStrength = 0U,  /*!< Low-drive strength is configured. */ | ||||||
|  |     kPORT_HighDriveStrength = 1U, /*!< High-drive strength is configured. */ | ||||||
|  | }; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK | ||||||
|  | /*! @brief Unlock/lock the pin control register field[15:0] */ | ||||||
|  | enum _port_lock_register | ||||||
|  | { | ||||||
|  |     kPORT_UnlockRegister = 0U, /*!< Pin Control Register fields [15:0] are not locked. */ | ||||||
|  |     kPORT_LockRegister = 1U,   /*!< Pin Control Register fields [15:0] are locked. */ | ||||||
|  | }; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH | ||||||
|  | /*! @brief Pin mux selection */ | ||||||
|  | typedef enum _port_mux | ||||||
|  | { | ||||||
|  |     kPORT_PinDisabledOrAnalog = 0U, /*!< Corresponding pin is disabled, but is used as an analog pin. */ | ||||||
|  |     kPORT_MuxAsGpio = 1U,           /*!< Corresponding pin is configured as GPIO. */ | ||||||
|  |     kPORT_MuxAlt2 = 2U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt3 = 3U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt4 = 4U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt5 = 5U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt6 = 6U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt7 = 7U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt8 = 8U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt9 = 9U,             /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt10 = 10U,           /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt11 = 11U,           /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt12 = 12U,           /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt13 = 13U,           /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt14 = 14U,           /*!< Chip-specific */ | ||||||
|  |     kPORT_MuxAlt15 = 15U,           /*!< Chip-specific */ | ||||||
|  | } port_mux_t; | ||||||
|  | #endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Configures the interrupt generation condition. */ | ||||||
|  | typedef enum _port_interrupt | ||||||
|  | { | ||||||
|  |     kPORT_InterruptOrDMADisabled = 0x0U, /*!< Interrupt/DMA request is disabled. */ | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_DMA_REQUEST) && FSL_FEATURE_PORT_HAS_DMA_REQUEST | ||||||
|  |     kPORT_DMARisingEdge = 0x1U,  /*!< DMA request on rising edge. */ | ||||||
|  |     kPORT_DMAFallingEdge = 0x2U, /*!< DMA request on falling edge. */ | ||||||
|  |     kPORT_DMAEitherEdge = 0x3U,  /*!< DMA request on either edge. */ | ||||||
|  | #endif | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_IRQC_FLAG) && FSL_FEATURE_PORT_HAS_IRQC_FLAG | ||||||
|  |     kPORT_FlagRisingEdge = 0x05U,  /*!< Flag sets on rising edge. */ | ||||||
|  |     kPORT_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */ | ||||||
|  |     kPORT_FlagEitherEdge = 0x07U,  /*!< Flag sets on either edge. */ | ||||||
|  | #endif | ||||||
|  |     kPORT_InterruptLogicZero = 0x8U,   /*!< Interrupt when logic zero. */ | ||||||
|  |     kPORT_InterruptRisingEdge = 0x9U,  /*!< Interrupt on rising edge. */ | ||||||
|  |     kPORT_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */ | ||||||
|  |     kPORT_InterruptEitherEdge = 0xBU,  /*!< Interrupt on either edge. */ | ||||||
|  |     kPORT_InterruptLogicOne = 0xCU,    /*!< Interrupt when logic one. */ | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER | ||||||
|  |     kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */ | ||||||
|  |     kPORT_ActiveLowTriggerOutputEnable = 0xEU,  /*!< Enable active low-trigger output. */ | ||||||
|  | #endif | ||||||
|  | } port_interrupt_t; | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER | ||||||
|  | /*! @brief Digital filter clock source selection */ | ||||||
|  | typedef enum _port_digital_filter_clock_source | ||||||
|  | { | ||||||
|  |     kPORT_BusClock = 0U, /*!< Digital filters are clocked by the bus clock. */ | ||||||
|  |     kPORT_LpoClock = 1U, /*!< Digital filters are clocked by the 1 kHz LPO clock. */ | ||||||
|  | } port_digital_filter_clock_source_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief PORT digital filter feature configuration definition */ | ||||||
|  | typedef struct _port_digital_filter_config | ||||||
|  | { | ||||||
|  |     uint32_t digitalFilterWidth;                    /*!< Set digital filter width */ | ||||||
|  |     port_digital_filter_clock_source_t clockSource; /*!< Set digital filter clockSource */ | ||||||
|  | } port_digital_filter_config_t; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH | ||||||
|  | /*! @brief PORT pin configuration structure */ | ||||||
|  | typedef struct _port_pin_config | ||||||
|  | { | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE | ||||||
|  |     uint16_t pullSelect : 2; /*!< No-pull/pull-down/pull-up select */ | ||||||
|  | #else | ||||||
|  |     uint16_t : 2; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE | ||||||
|  |     uint16_t slewRate : 1; /*!< Fast/slow slew rate Configure */ | ||||||
|  | #else | ||||||
|  |     uint16_t : 1; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */ | ||||||
|  | 
 | ||||||
|  |     uint16_t : 1; | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER | ||||||
|  |     uint16_t passiveFilterEnable : 1; /*!< Passive filter enable/disable */ | ||||||
|  | #else | ||||||
|  |     uint16_t : 1; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_PASSIVE_FILTER */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN | ||||||
|  |     uint16_t openDrainEnable : 1; /*!< Open drain enable/disable */ | ||||||
|  | #else | ||||||
|  |     uint16_t : 1; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH | ||||||
|  |     uint16_t driveStrength : 1; /*!< Fast/slow drive strength configure */ | ||||||
|  | #else | ||||||
|  |     uint16_t : 1; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     uint16_t : 1; | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && (FSL_FEATURE_PORT_PCR_MUX_WIDTH == 3) | ||||||
|  |     uint16_t mux : 3; /*!< Pin mux Configure */ | ||||||
|  |     uint16_t : 4; | ||||||
|  | #elif defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && (FSL_FEATURE_PORT_PCR_MUX_WIDTH == 4) | ||||||
|  |     uint16_t mux : 4; /*!< Pin mux Configure */ | ||||||
|  |     uint16_t : 3; | ||||||
|  | #else | ||||||
|  |     uint16_t : 7, | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK | ||||||
|  |     uint16_t lockRegister : 1; /*!< Lock/unlock the PCR field[15:0] */ | ||||||
|  | #else | ||||||
|  |     uint16_t : 1; | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ | ||||||
|  | } port_pin_config_t; | ||||||
|  | #endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * API | ||||||
|  | ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH | ||||||
|  | /*! @name Configuration */ | ||||||
|  | /*@{*/ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Sets the port PCR register. | ||||||
|  |  * | ||||||
|  |  * This is an example to define an input pin or output pin PCR configuration. | ||||||
|  |  * @code | ||||||
|  |  * // Define a digital input pin PCR configuration
 | ||||||
|  |  * port_pin_config_t config = { | ||||||
|  |  *      kPORT_PullUp, | ||||||
|  |  *      kPORT_FastSlewRate, | ||||||
|  |  *      kPORT_PassiveFilterDisable, | ||||||
|  |  *      kPORT_OpenDrainDisable, | ||||||
|  |  *      kPORT_LowDriveStrength, | ||||||
|  |  *      kPORT_MuxAsGpio, | ||||||
|  |  *      kPORT_UnLockRegister, | ||||||
|  |  * }; | ||||||
|  |  * @endcode | ||||||
|  |  * | ||||||
|  |  * @param base   PORT peripheral base pointer. | ||||||
|  |  * @param pin    PORT pin number. | ||||||
|  |  * @param config PORT PCR register configuration structure. | ||||||
|  |  */ | ||||||
|  | static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config) | ||||||
|  | { | ||||||
|  |     assert(config); | ||||||
|  |     uint32_t addr = (uint32_t)&base->PCR[pin]; | ||||||
|  |     *(volatile uint16_t *)(addr) = *((const uint16_t *)config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Sets the port PCR register for multiple pins. | ||||||
|  |  * | ||||||
|  |  * This is an example to define input pins or output pins PCR configuration. | ||||||
|  |  * @code | ||||||
|  |  * // Define a digital input pin PCR configuration
 | ||||||
|  |  * port_pin_config_t config = { | ||||||
|  |  *      kPORT_PullUp , | ||||||
|  |  *      kPORT_PullEnable, | ||||||
|  |  *      kPORT_FastSlewRate, | ||||||
|  |  *      kPORT_PassiveFilterDisable, | ||||||
|  |  *      kPORT_OpenDrainDisable, | ||||||
|  |  *      kPORT_LowDriveStrength, | ||||||
|  |  *      kPORT_MuxAsGpio, | ||||||
|  |  *      kPORT_UnlockRegister, | ||||||
|  |  * }; | ||||||
|  |  * @endcode | ||||||
|  |  * | ||||||
|  |  * @param base   PORT peripheral base pointer. | ||||||
|  |  * @param mask   PORT pin number macro. | ||||||
|  |  * @param config PORT PCR register configuration structure. | ||||||
|  |  */ | ||||||
|  | static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config) | ||||||
|  | { | ||||||
|  |     assert(config); | ||||||
|  | 
 | ||||||
|  |     uint16_t pcrl = *((const uint16_t *)config); | ||||||
|  | 
 | ||||||
|  |     if (mask & 0xffffU) | ||||||
|  |     { | ||||||
|  |         base->GPCLR = ((mask & 0xffffU) << 16) | pcrl; | ||||||
|  |     } | ||||||
|  |     if (mask >> 16) | ||||||
|  |     { | ||||||
|  |         base->GPCHR = (mask & 0xffff0000U) | pcrl; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_MULTIPLE_IRQ_CONFIG) && FSL_FEATURE_PORT_HAS_MULTIPLE_IRQ_CONFIG | ||||||
|  | /*!
 | ||||||
|  |  * @brief Sets the port interrupt configuration in PCR register for multiple pins. | ||||||
|  |  * | ||||||
|  |  * @param base   PORT peripheral base pointer. | ||||||
|  |  * @param mask   PORT pin number macro. | ||||||
|  |  * @param config  PORT pin interrupt configuration. | ||||||
|  |  *        - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled. | ||||||
|  |  *        - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit). | ||||||
|  |  *        - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit). | ||||||
|  |  *        - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit). | ||||||
|  |  *        - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit). | ||||||
|  |  *        - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit). | ||||||
|  |  *        - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit). | ||||||
|  |  *        - #kPORT_InterruptLogicZero  : Interrupt when logic zero. | ||||||
|  |  *        - #kPORT_InterruptRisingEdge : Interrupt on rising edge. | ||||||
|  |  *        - #kPORT_InterruptFallingEdge: Interrupt on falling edge. | ||||||
|  |  *        - #kPORT_InterruptEitherEdge : Interrupt on either edge. | ||||||
|  |  *        - #kPORT_InterruptLogicOne   : Interrupt when logic one. | ||||||
|  |  *        - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit). | ||||||
|  |  *        - #kPORT_ActiveLowTriggerOutputEnable  : Enable active low-trigger output (if the trigger states exit).. | ||||||
|  |  */ | ||||||
|  | static inline void PORT_SetMultipleInterruptPinsConfig(PORT_Type *base, uint32_t mask, port_interrupt_t config) | ||||||
|  | { | ||||||
|  |     assert(config); | ||||||
|  | 
 | ||||||
|  |     if (mask & 0xffffU) | ||||||
|  |     { | ||||||
|  |         base->GICLR = (config << 16) | (mask & 0xffffU); | ||||||
|  |     } | ||||||
|  |     if (mask >> 16) | ||||||
|  |     { | ||||||
|  |         base->GICHR = (config << 16) | (mask & 0xffff0000U); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Configures the pin muxing. | ||||||
|  |  * | ||||||
|  |  * @param base  PORT peripheral base pointer. | ||||||
|  |  * @param pin   PORT pin number. | ||||||
|  |  * @param mux   pin muxing slot selection. | ||||||
|  |  *        - #kPORT_PinDisabledOrAnalog: Pin disabled or work in analog function. | ||||||
|  |  *        - #kPORT_MuxAsGpio          : Set as GPIO. | ||||||
|  |  *        - #kPORT_MuxAlt2            : chip-specific. | ||||||
|  |  *        - #kPORT_MuxAlt3            : chip-specific. | ||||||
|  |  *        - #kPORT_MuxAlt4            : chip-specific. | ||||||
|  |  *        - #kPORT_MuxAlt5            : chip-specific. | ||||||
|  |  *        - #kPORT_MuxAlt6            : chip-specific. | ||||||
|  |  *        - #kPORT_MuxAlt7            : chip-specific. | ||||||
|  |  * @Note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because | ||||||
|  |  *         the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux is | ||||||
|  |  *         reset to zero : kPORT_PinDisabledOrAnalog). | ||||||
|  |  *        This function is recommended to use to reset the pin mux | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux) | ||||||
|  | { | ||||||
|  |     base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux); | ||||||
|  | } | ||||||
|  | #endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin. | ||||||
|  |  * | ||||||
|  |  * @param base  PORT peripheral base pointer. | ||||||
|  |  * @param mask  PORT pin number macro. | ||||||
|  |  */ | ||||||
|  | static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable) | ||||||
|  | { | ||||||
|  |     if (enable == true) | ||||||
|  |     { | ||||||
|  |         base->DFER |= mask; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         base->DFER &= ~mask; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Sets the digital filter in one port, each bit of the 32-bit register represents one pin. | ||||||
|  |  * | ||||||
|  |  * @param base   PORT peripheral base pointer. | ||||||
|  |  * @param config PORT digital filter configuration structure. | ||||||
|  |  */ | ||||||
|  | static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digital_filter_config_t *config) | ||||||
|  | { | ||||||
|  |     assert(config); | ||||||
|  | 
 | ||||||
|  |     base->DFCR = PORT_DFCR_CS(config->clockSource); | ||||||
|  |     base->DFWR = PORT_DFWR_FILT(config->digitalFilterWidth); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ | ||||||
|  | 
 | ||||||
|  | /*@}*/ | ||||||
|  | 
 | ||||||
|  | /*! @name Interrupt */ | ||||||
|  | /*@{*/ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Configures the port pin interrupt/DMA request. | ||||||
|  |  * | ||||||
|  |  * @param base    PORT peripheral base pointer. | ||||||
|  |  * @param pin     PORT pin number. | ||||||
|  |  * @param config  PORT pin interrupt configuration. | ||||||
|  |  *        - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled. | ||||||
|  |  *        - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit). | ||||||
|  |  *        - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit). | ||||||
|  |  *        - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit). | ||||||
|  |  *        - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit). | ||||||
|  |  *        - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit). | ||||||
|  |  *        - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit). | ||||||
|  |  *        - #kPORT_InterruptLogicZero  : Interrupt when logic zero. | ||||||
|  |  *        - #kPORT_InterruptRisingEdge : Interrupt on rising edge. | ||||||
|  |  *        - #kPORT_InterruptFallingEdge: Interrupt on falling edge. | ||||||
|  |  *        - #kPORT_InterruptEitherEdge : Interrupt on either edge. | ||||||
|  |  *        - #kPORT_InterruptLogicOne   : Interrupt when logic one. | ||||||
|  |  *        - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit). | ||||||
|  |  *        - #kPORT_ActiveLowTriggerOutputEnable  : Enable active low-trigger output (if the trigger states exit). | ||||||
|  |  */ | ||||||
|  | static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config) | ||||||
|  | { | ||||||
|  |     base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH | ||||||
|  | /*!
 | ||||||
|  |  * @brief Configures the port pin drive strength. | ||||||
|  |  * | ||||||
|  |  * @param base    PORT peripheral base pointer. | ||||||
|  |  * @param pin     PORT pin number. | ||||||
|  |  * @param config  PORT pin drive strength | ||||||
|  |  *        - #kPORT_LowDriveStrength = 0U - Low-drive strength is configured. | ||||||
|  |  *        - #kPORT_HighDriveStrength = 1U - High-drive strength is configured. | ||||||
|  |  */ | ||||||
|  | static inline void PORT_SetPinDriveStrength(PORT_Type* base, uint32_t pin, uint8_t strength) | ||||||
|  | { | ||||||
|  |     base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_DSE_MASK) |  PORT_PCR_DSE(strength); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Reads the whole port status flag. | ||||||
|  |  * | ||||||
|  |  * If a pin is configured to generate the DMA request,  the corresponding flag | ||||||
|  |  * is cleared automatically at the completion of the requested DMA transfer. | ||||||
|  |  * Otherwise, the flag remains set until a logic one is written to that flag. | ||||||
|  |  * If configured for a level sensitive interrupt that remains asserted, the flag | ||||||
|  |  * is set again immediately. | ||||||
|  |  * | ||||||
|  |  * @param base PORT peripheral base pointer. | ||||||
|  |  * @return Current port interrupt status flags, for example, 0x00010001 means the | ||||||
|  |  *         pin 0 and 16 have the interrupt. | ||||||
|  |  */ | ||||||
|  | static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base) | ||||||
|  | { | ||||||
|  |     return base->ISFR; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Clears the multiple pin interrupt status flag. | ||||||
|  |  * | ||||||
|  |  * @param base PORT peripheral base pointer. | ||||||
|  |  * @param mask PORT pin number macro. | ||||||
|  |  */ | ||||||
|  | static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask) | ||||||
|  | { | ||||||
|  |     base->ISFR = mask; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*@}*/ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*! @}*/ | ||||||
|  | 
 | ||||||
|  | #endif /* _FSL_PORT_H_ */ | ||||||
|  | @ -0,0 +1,70 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2017 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  *  | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*************************************************
 | ||||||
|  | File name: pin_mux | ||||||
|  | Description:  | ||||||
|  | Others: take for references | ||||||
|  |                 https://github.com/open-isa-org/open-isa.org
 | ||||||
|  | History:  | ||||||
|  | 1. Date: 2022-02-16 | ||||||
|  | Author: AIIT XUOS Lab | ||||||
|  | Modification:   | ||||||
|  | *************************************************/ | ||||||
|  | 
 | ||||||
|  | #ifndef _PIN_MUX_H_ | ||||||
|  | #define _PIN_MUX_H_ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @brief Direction type  */ | ||||||
|  | typedef enum _pin_mux_direction | ||||||
|  | { | ||||||
|  |   kPIN_MUX_DirectionInput = 0U,         /* Input direction */ | ||||||
|  |   kPIN_MUX_DirectionOutput = 1U,        /* Output direction */ | ||||||
|  |   kPIN_MUX_DirectionInputOrOutput = 2U  /* Input or output direction */ | ||||||
|  | } pin_mux_direction_t; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @addtogroup pin_mux | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * API | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Calls initialization functions. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void BOARD_InitBootPins(void); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Configures pin routing and optionally pin electrical features. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void BOARD_InitPins(void); | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @} | ||||||
|  |  */ | ||||||
|  | #endif /* _PIN_MUX_H_ */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * EOF | ||||||
|  |  ******************************************************************************/ | ||||||
|  | @ -24,7 +24,7 @@ | ||||||
| #define LCD_HEIGHT  BSP_LCD_X_MAX | #define LCD_HEIGHT  BSP_LCD_X_MAX | ||||||
| #define LCD_WIDTH   BSP_LCD_Y_MAX | #define LCD_WIDTH   BSP_LCD_Y_MAX | ||||||
| 
 | 
 | ||||||
| 
 | // static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH];
 | ||||||
| static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable.init"); | static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable.init"); | ||||||
| static void InitLcdifPixelClock(void) | static void InitLcdifPixelClock(void) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -72,17 +72,18 @@ static int32_t GtpI2cWrite(uint8_t client_addr,uint8_t *buf,int32_t len) | ||||||
|     while(retries < 5) |     while(retries < 5) | ||||||
|     { |     { | ||||||
|         ret = I2C_Transfer(&msg, 1); |         ret = I2C_Transfer(&msg, 1); | ||||||
|         if (ret == 1)break; |         if (ret == 1) { break; } | ||||||
|         retries++; |         retries++; | ||||||
|     } |     } | ||||||
|     if((retries >= 5)) |     if (retries >= 5) | ||||||
|     { |     { | ||||||
|         KPrintf("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((uint16_t)(buf[0] << 8)) | buf[1]), len-2, ret); |         KPrintf("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((uint16_t)(buf[0] << 8)) | buf[1]), len-2, ret); | ||||||
|         ret = -1; |         ret = -1; | ||||||
|     } |     } | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| static int32_t GtpI2cRead(uint8_t client_addr, uint8_t *buf, int32_t len) | 
 | ||||||
|  | static int32_t GtpI2cRead(uint8_t client_addr, uint8_t* buf, int32_t len) | ||||||
| { | { | ||||||
|     struct i2c_msg msgs[2]; |     struct i2c_msg msgs[2]; | ||||||
|     int32_t ret = -1; |     int32_t ret = -1; | ||||||
|  | @ -100,8 +101,8 @@ static int32_t GtpI2cRead(uint8_t client_addr, uint8_t *buf, int32_t len) | ||||||
|      |      | ||||||
|     while(retries < 5) |     while(retries < 5) | ||||||
|     { |     { | ||||||
|         ret = I2C_Transfer( msgs, 2); |         ret = I2C_Transfer(msgs, 2); | ||||||
|         if(ret == 2)break; |         if (ret == 2)break; | ||||||
|         retries++; |         retries++; | ||||||
|     } |     } | ||||||
|     if((retries >= 5)) |     if((retries >= 5)) | ||||||
|  | @ -111,6 +112,7 @@ static int32_t GtpI2cRead(uint8_t client_addr, uint8_t *buf, int32_t len) | ||||||
|     } |     } | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  | 
 | ||||||
| static int32_t gt91xx_Config_Write_Proc() | static int32_t gt91xx_Config_Write_Proc() | ||||||
| { | { | ||||||
|     int32_t ret = -1; |     int32_t ret = -1; | ||||||
|  | @ -154,8 +156,12 @@ static int32_t gt91xx_Config_Write_Proc() | ||||||
|   */ |   */ | ||||||
| bool GetTouchEvent(POINT *touch_point,touch_event_t *touch_event) | bool GetTouchEvent(POINT *touch_point,touch_event_t *touch_event) | ||||||
| { | { | ||||||
|  |     if (touch_point == NULL || touch_event == NULL) { | ||||||
|  |         KPrintf("error: touch event error params.\n"); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|      |      | ||||||
|     uint8_t  end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; |     uint8_t  end_cmd[3] = { GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0 }; | ||||||
|     uint8_t  point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; |     uint8_t  point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; | ||||||
|     uint8_t  touch_num = 0; |     uint8_t  touch_num = 0; | ||||||
|     uint8_t  finger = 0; |     uint8_t  finger = 0; | ||||||
|  |  | ||||||
|  | @ -32,42 +32,43 @@ lpi2c_master_handle_t g_m_handle; | ||||||
| volatile bool g_MasterCompletionFlag = false; | volatile bool g_MasterCompletionFlag = false; | ||||||
| volatile bool g_TouchPadInputSignal = false; | volatile bool g_TouchPadInputSignal = false; | ||||||
| volatile bool SemReleaseFlag = false; | volatile bool SemReleaseFlag = false; | ||||||
|  | uint32_t i2c_lockup_cnt = 0; | ||||||
| /*******************************************************************************
 | /*******************************************************************************
 | ||||||
|  * Code |  * Code | ||||||
|  ******************************************************************************/ |  ******************************************************************************/ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   * @brief  对GT91xx芯片进行复位 |   * @brief  <EFBFBD><EFBFBD>GT91xxоƬ<EFBFBD><EFBFBD><EFBFBD>и<EFBFBD>λ | ||||||
|   * @param  无 |   * @param  <EFBFBD><EFBFBD> | ||||||
|   * @retval 无 |   * @retval <EFBFBD><EFBFBD> | ||||||
|   */ |   */ | ||||||
| void GTP_ResetChip(void) | void GTP_ResetChip(void) | ||||||
| { | { | ||||||
| 	/* 先把RST INT配置为输出模式 */ | 	/* <EFBFBD>Ȱ<EFBFBD>RST INT<4E><54><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ģʽ */ | ||||||
| 	gpio_pin_config_t rst_int_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; | 	gpio_pin_config_t rst_int_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; | ||||||
| 
 | 
 | ||||||
| 	GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); | 	GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); | ||||||
| 
 | 
 | ||||||
| 	/*初始化GT9157,INT为低电平,则gt9157的设备地址被配置为0xBA*/ | 	/*<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>GT9157,INTΪ<54>͵<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>gt9157<35><37><EFBFBD>豸<EFBFBD><E8B1B8>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0xBA*/ | ||||||
| 
 | 
 | ||||||
| 	/*复位为低电平,为初始化做准备*/ | 	/*<EFBFBD><EFBFBD>λΪ<EFBFBD>͵<EFBFBD>ƽ<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/ | ||||||
| 	GPIO_PinWrite(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, 0U); | 	GPIO_PinWrite(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, 0U); | ||||||
| 
 | 
 | ||||||
| 	//INT配置成中断输入
 | 	//INT<EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | ||||||
| 	rst_int_config.direction = kGPIO_DigitalInput; | 	rst_int_config.direction = kGPIO_DigitalInput; | ||||||
| 	rst_int_config.outputLogic = 0; | 	rst_int_config.outputLogic = 0; | ||||||
| 	rst_int_config.interruptMode = kGPIO_IntFallingEdge; | 	rst_int_config.interruptMode = kGPIO_IntFallingEdge; | ||||||
| 
 | 
 | ||||||
| 	GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); | 	GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); | ||||||
| 
 | 
 | ||||||
| 	/* 使能引脚中断 */   | 	/* ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> */   | ||||||
| 	GPIO_PortEnableInterrupts(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); | 	GPIO_PortEnableInterrupts(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| * @brief  禁止触摸芯片的中断 | * @brief  <EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> | ||||||
| * @param  无 | * @param  <EFBFBD><EFBFBD> | ||||||
| * @retval 无 | * @retval <EFBFBD><EFBFBD> | ||||||
| */ | */ | ||||||
| void GTP_IRQDisable(void) | void GTP_IRQDisable(void) | ||||||
| { | { | ||||||
|  | @ -75,9 +76,9 @@ void GTP_IRQDisable(void) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| * @brief  使能触摸芯片的中断 | * @brief  ʹ<EFBFBD>ܴ<EFBFBD><EFBFBD><EFBFBD>оƬ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> | ||||||
| * @param  无 | * @param  <EFBFBD><EFBFBD> | ||||||
| * @retval 无 | * @retval <EFBFBD><EFBFBD> | ||||||
| */ | */ | ||||||
| void GTP_IRQEnable(void) | void GTP_IRQEnable(void) | ||||||
| { | { | ||||||
|  | @ -93,25 +94,25 @@ void GTP_IRQEnable(void) | ||||||
| 
 | 
 | ||||||
|   gpio_pin_config_t rst_int_config; |   gpio_pin_config_t rst_int_config; | ||||||
|     |     | ||||||
|   //INT配置成中断输入
 |   //INT<EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | ||||||
| 	rst_int_config.direction = kGPIO_DigitalInput; | 	rst_int_config.direction = kGPIO_DigitalInput; | ||||||
| 	rst_int_config.outputLogic = 0; | 	rst_int_config.outputLogic = 0; | ||||||
| 	rst_int_config.interruptMode = kGPIO_IntFallingEdge; | 	rst_int_config.interruptMode = kGPIO_IntFallingEdge; | ||||||
| 
 | 
 | ||||||
| 	GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); | 	GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); | ||||||
| 
 | 
 | ||||||
| 	/* 使能引脚中断 */   | 	/* ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> */   | ||||||
| 	GPIO_PortEnableInterrupts(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); | 	GPIO_PortEnableInterrupts(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); | ||||||
| 
 | 
 | ||||||
|   /* 使能中断IRQ */   |   /* ʹ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>IRQ */   | ||||||
| 	EnableIRQ(GT9xx_PEN_IRQ); | 	EnableIRQ(GT9xx_PEN_IRQ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| * @brief  初始化触摸芯片使用的I2C外设 | * @brief  <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬʹ<EFBFBD>õ<EFBFBD>I2C<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||||
| * @param  无 | * @param  <EFBFBD><EFBFBD> | ||||||
| * @retval 无 | * @retval <EFBFBD><EFBFBD> | ||||||
| */	 | */	 | ||||||
| void GTP_I2C_ModeInit(void) | void GTP_I2C_ModeInit(void) | ||||||
| { | { | ||||||
|  | @ -142,25 +143,56 @@ void GtpI2cDeinit(void) | ||||||
| 	LPI2C_MasterDeinit(GTP_I2C_MASTER); | 	LPI2C_MasterDeinit(GTP_I2C_MASTER); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void I2CLockupRecover(void) { | ||||||
|  | 	IOMUXC_SetPinMux(TOUCH_PAD_RECOVER_SCL_IOMUXC, 0U); | ||||||
|  | 	IOMUXC_SetPinMux(TOUCH_PAD_RECOVER_SDA_IOMUXC, 0U); | ||||||
|  | 
 | ||||||
|  | 	const gpio_pin_config_t rec_pin_config = { | ||||||
|  | 		.direction = kGPIO_DigitalOutput, | ||||||
|  | 		.outputLogic = 1U, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	GPIO_PinInit(TOUCH_PAD_RECOVER_SCL_GPIO, TOUCH_PAD_RECOVER_SCL_GPIO_PIN, &rec_pin_config); | ||||||
|  | 	GPIO_PinInit(TOUCH_PAD_RECOVER_SDA_GPIO, TOUCH_PAD_RECOVER_SDA_GPIO_PIN, &rec_pin_config); | ||||||
|  | 
 | ||||||
|  | 	uint32_t primask = DisableGlobalIRQ(); | ||||||
|  | 	// recover scl
 | ||||||
|  | 	for (uint32_t i = 0; i < 0xfffff; ++i) {} | ||||||
|  | 	for (uint32_t i = 0U; i < I2C_RECOVER_NUM_CLOCKS; ++i) { | ||||||
|  | 		for (uint32_t i = 0; i < 0xfffff; ++i) {} | ||||||
|  | 		GPIO_PinWrite(TOUCH_PAD_RECOVER_SCL_GPIO, TOUCH_PAD_RECOVER_SCL_GPIO_PIN, 0U); | ||||||
|  | 		for (uint32_t i = 0; i < 0xfffff; ++i) {} | ||||||
|  | 		GPIO_PinWrite(TOUCH_PAD_RECOVER_SCL_GPIO, TOUCH_PAD_RECOVER_SCL_GPIO_PIN, 1U); | ||||||
|  | 	} | ||||||
|  | 	GPIO_PinWrite(TOUCH_PAD_RECOVER_SDA_GPIO, TOUCH_PAD_RECOVER_SDA_GPIO_PIN, 1U); | ||||||
|  | 	EnableGlobalIRQ(primask); | ||||||
|  | 
 | ||||||
|  | 	// reset pin to scl
 | ||||||
|  | 	IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 1U); | ||||||
|  | 	IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0u); | ||||||
|  | 	IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 1U); | ||||||
|  | 	IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0u); | ||||||
|  | 
 | ||||||
|  | 	i2c_lockup_cnt = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|   * @brief   使用IIC读取数据 |   * @brief   ʹ<EFBFBD><EFBFBD>IIC<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||||
|   * @param    |   * @param    | ||||||
|   * 	@arg ClientAddr:从设备地址 |   * 	@arg ClientAddr:<EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD>ַ | ||||||
|   *		@arg pBuffer:存放由从机读取的数据的缓冲区指针 |   *		@arg pBuffer:<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɴӻ<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD> | ||||||
|   *		@arg NumByteToRead:读取的数据长度 |   *		@arg NumByteToRead:<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><EFBFBD> | ||||||
|   * @retval  无 |   * @retval  <EFBFBD><EFBFBD> | ||||||
|   */ |   */ | ||||||
| uint32_t I2C_ReadBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint16_t NumByteToRead) | uint32_t I2C_ReadBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint16_t NumByteToRead) | ||||||
| { | { | ||||||
| 	lpi2c_master_transfer_t masterXfer = {0}; | 	lpi2c_master_transfer_t masterXfer = { 0 }; | ||||||
| 	status_t reVal = kStatus_Fail; | 	status_t reVal = kStatus_Fail; | ||||||
|     uint32_t i2c_timeout = I2CT_LONG_TIMEOUT; |     uint32_t i2c_timeout = I2CT_LONG_TIMEOUT; | ||||||
| 
 | 	/* subAddress = 0x00, data = pBuffer <20>Դӻ<D4B4><D3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | ||||||
| 
 | 		<EFBFBD><EFBFBD>ʼ<EFBFBD>ź<EFBFBD>start + <EFBFBD>豸<EFBFBD><EFBFBD>ַslaveaddress(w д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>) + <EFBFBD>ӵ<EFBFBD>ַsubAddress +  | ||||||
| 	/* subAddress = 0x00, data = pBuffer 自从机处接收
 |     <EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>ź<EFBFBD>repeated start + <EFBFBD>豸<EFBFBD><EFBFBD>ַslaveaddress(r <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) +  | ||||||
| 		起始信号start + 设备地址slaveaddress(w 写方向) + 子地址subAddress +  |     <EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rx data buffer + ֹͣ<EFBFBD>ź<EFBFBD>stop */ | ||||||
|     重复起始信号repeated start + 设备地址slaveaddress(r 读方向) +  |  | ||||||
|     接收缓冲数据rx data buffer + 停止信号stop */ |  | ||||||
| 	masterXfer.slaveAddress = (ClientAddr>>1); | 	masterXfer.slaveAddress = (ClientAddr>>1); | ||||||
| 	masterXfer.direction = kLPI2C_Read; | 	masterXfer.direction = kLPI2C_Read; | ||||||
| 	masterXfer.subaddress = (uint32_t)0; | 	masterXfer.subaddress = (uint32_t)0; | ||||||
|  | @ -169,47 +201,44 @@ uint32_t I2C_ReadBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint16_t NumByteToRe | ||||||
| 	masterXfer.dataSize = NumByteToRead; | 	masterXfer.dataSize = NumByteToRead; | ||||||
| 	masterXfer.flags = kLPI2C_TransferDefaultFlag; | 	masterXfer.flags = kLPI2C_TransferDefaultFlag; | ||||||
| 
 | 
 | ||||||
| 	/* 复位传输完成标志 */ | 	/* <EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־ */ | ||||||
| 	g_MasterCompletionFlag = false; | 	g_MasterCompletionFlag = false; | ||||||
| 
 |  | ||||||
| 	reVal = LPI2C_MasterTransferNonBlocking(GTP_I2C_MASTER, &g_m_handle, &masterXfer); | 	reVal = LPI2C_MasterTransferNonBlocking(GTP_I2C_MASTER, &g_m_handle, &masterXfer); | ||||||
| 	if (reVal != kStatus_Success) | 	if (reVal != kStatus_Success) | ||||||
| 	{ | 	{ | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 	 | 	/* <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */ | ||||||
| 	/* 等待传输完成 */ |  | ||||||
| 	while (!g_MasterCompletionFlag) | 	while (!g_MasterCompletionFlag) | ||||||
| 	{ | 	{ | ||||||
| 		if((i2c_timeout--) == 0)  | 		if ((i2c_timeout--) == 0) | ||||||
| 			return I2C_Timeout_Callback(0); | 			return I2C_Timeout_Callback(0); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	g_MasterCompletionFlag = false; | 	g_MasterCompletionFlag = false; | ||||||
| 	 |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   * @brief   使用IIC写入数据 |   * @brief   ʹ<EFBFBD><EFBFBD>IICд<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||||
|   * @param    |   * @param    | ||||||
|   * 	@arg ClientAddr:从设备地址 |   * 	@arg ClientAddr:<EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD>ַ | ||||||
|   *		@arg pBuffer:缓冲区指针 |   *		@arg pBuffer:<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD> | ||||||
|   *     @arg NumByteToWrite:写的字节数 |   *     @arg NumByteToWrite:д<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD> | ||||||
|   * @retval  无 |   * @retval  <EFBFBD><EFBFBD> | ||||||
|   */ |   */ | ||||||
| uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer,  uint8_t NumByteToWrite) | uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer,  uint8_t NumByteToWrite) | ||||||
| { | { | ||||||
| 	lpi2c_master_transfer_t masterXfer = {0}; | 	lpi2c_master_transfer_t masterXfer = { 0 }; | ||||||
| 	status_t reVal = kStatus_Fail; | 	status_t reVal = kStatus_Fail; | ||||||
|     uint32_t i2c_timeout = I2CT_LONG_TIMEOUT; |     uint32_t i2c_timeout = I2CT_LONG_TIMEOUT; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	/* subAddress = 0x00, data = pBuffer 发送至从机
 | 	/* subAddress = 0x00, data = pBuffer <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӻ<EFBFBD>
 | ||||||
| 		起始信号start + 设备地址slaveaddress(w 写方向) +  | 		<EFBFBD><EFBFBD>ʼ<EFBFBD>ź<EFBFBD>start + <EFBFBD>豸<EFBFBD><EFBFBD>ַslaveaddress(w д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>) +  | ||||||
|     发送缓冲数据tx data buffer + 停止信号stop */ |     <EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tx data buffer + ֹͣ<EFBFBD>ź<EFBFBD>stop */ | ||||||
| 
 | 
 | ||||||
| 	masterXfer.slaveAddress = (ClientAddr>>1); | 	masterXfer.slaveAddress = (ClientAddr >> 1); | ||||||
| 	masterXfer.direction = kLPI2C_Write; | 	masterXfer.direction = kLPI2C_Write; | ||||||
| 	masterXfer.subaddress = (uint32_t)0; | 	masterXfer.subaddress = (uint32_t)0; | ||||||
| 	masterXfer.subaddressSize = 0; | 	masterXfer.subaddressSize = 0; | ||||||
|  | @ -217,16 +246,19 @@ uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer,  uint8_t NumByteToW | ||||||
| 	masterXfer.dataSize = NumByteToWrite; | 	masterXfer.dataSize = NumByteToWrite; | ||||||
| 	masterXfer.flags = kLPI2C_TransferDefaultFlag; | 	masterXfer.flags = kLPI2C_TransferDefaultFlag; | ||||||
| 
 | 
 | ||||||
| 	/* 复位传输完成标志 */ | 	/* <EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־ */ | ||||||
| 	g_MasterCompletionFlag = false; | 	g_MasterCompletionFlag = false; | ||||||
| 
 |  | ||||||
| 	reVal = LPI2C_MasterTransferNonBlocking(GTP_I2C_MASTER, &g_m_handle, &masterXfer); | 	reVal = LPI2C_MasterTransferNonBlocking(GTP_I2C_MASTER, &g_m_handle, &masterXfer); | ||||||
| 	if (reVal != kStatus_Success) | 	if (reVal != kStatus_Success) | ||||||
| 	{ | 	{ | ||||||
|  | 		// handle hangs
 | ||||||
|  | 		i2c_lockup_cnt++; | ||||||
|  | 		if (i2c_lockup_cnt >= I2C_BUSY_LIMIT) { | ||||||
|  | 			I2CLockupRecover(); | ||||||
|  | 		} | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
| 
 | 	/* <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */ | ||||||
| 	/* 等待传输完成 */ |  | ||||||
| 	while (!g_MasterCompletionFlag) | 	while (!g_MasterCompletionFlag) | ||||||
| 	{ | 	{ | ||||||
|     	if((i2c_timeout--) == 0) |     	if((i2c_timeout--) == 0) | ||||||
|  | @ -239,68 +271,72 @@ uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer,  uint8_t NumByteToW | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   * @brief  IIC等待超时调用本函数输出调试信息 |   * @brief  IIC<EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ | ||||||
|   * @param  None. |   * @param  None. | ||||||
|   * @retval 返回0xff,表示IIC读取数据失败 |   * @retval <EFBFBD><EFBFBD><EFBFBD><EFBFBD>0xff<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾIIC<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD> | ||||||
|   */ |   */ | ||||||
| static  uint32_t I2C_Timeout_Callback(uint8_t errorCode) | static  uint32_t I2C_Timeout_Callback(uint8_t errorCode) | ||||||
| { | { | ||||||
| 	/* Block communication and all processes */ | 	/* Block communication and all processes */ | ||||||
| 	KPrintf("I2C timeout!errorCode = %d\n",errorCode); | 	// KPrintf("I2C timeout!errorCode = %d\n",errorCode);
 | ||||||
| 
 | 
 | ||||||
| 	return 0xFF; | 	return 0xFF; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| * @brief  I2C外设传输完成的回调函数 | * @brief  I2C<EFBFBD><EFBFBD><EFBFBD>贫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵĻص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||||
| * @param  无 | * @param  <EFBFBD><EFBFBD> | ||||||
| * @retval 无 | * @retval <EFBFBD><EFBFBD> | ||||||
| */ | */ | ||||||
| static void I2C_Master_Callback(LPI2C_Type *base, lpi2c_master_handle_t *handle, status_t status, void *userData) | static void I2C_Master_Callback(LPI2C_Type *base, lpi2c_master_handle_t *handle, status_t status, void *userData) | ||||||
| {		 | {		 | ||||||
|     /* 接收到kStatus_Success标志后,
 |     /* <20><><EFBFBD>յ<EFBFBD>kStatus_Success<73><73>־<EFBFBD><D6BE>
 | ||||||
|        设置g_MasterCompletionFlag标志表明传输成功 */ |        <EFBFBD><EFBFBD><EFBFBD><EFBFBD>g_MasterCompletionFlag<EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD> */ | ||||||
|     if (status == kStatus_Success) |     if (status != kStatus_LPI2C_Nak) { | ||||||
|     { |  | ||||||
|         g_MasterCompletionFlag = true; |         g_MasterCompletionFlag = true; | ||||||
|  |         /* Display failure information when status is not success. */ | ||||||
|  |         if (status != kStatus_Success) | ||||||
|  |         { | ||||||
|  |             // KPrintf("Error occured during transfer!.\n");
 | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| * @brief  触摸引脚及芯片初始化 | * @brief  <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ż<EFBFBD>оƬ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD> | ||||||
| * @param  无 | * @param  <EFBFBD><EFBFBD> | ||||||
| * @retval 无 | * @retval <EFBFBD><EFBFBD> | ||||||
| */ | */ | ||||||
| void I2C_Touch_Init(void) | void I2C_Touch_Init(void) | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| //  /* 初始化I2C外设工作模式 */
 | //  /* <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>I2C<EFBFBD><EFBFBD><EFBFBD>蹤<EFBFBD><EFBFBD>ģʽ */
 | ||||||
|   GTP_I2C_ModeInit();  |   GTP_I2C_ModeInit();  | ||||||
|    |    | ||||||
|   /* 复位触摸芯片,配置地址 */ |   /* <EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ַ */ | ||||||
|   GTP_ResetChip(); |   GTP_ResetChip(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /***************************中断相关******************************/ | /***************************<EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD>******************************/ | ||||||
| /**
 | /**
 | ||||||
| * @brief  触摸芯片TOUCH_PAD_INT_GPIO_PIN引脚的中断服务函数 | * @brief  <EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬTOUCH_PAD_INT_GPIO_PIN<EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD>жϷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||||
| * @param  无 | * @param  <EFBFBD><EFBFBD> | ||||||
| * @retval 无 | * @retval <EFBFBD><EFBFBD> | ||||||
| */ | */ | ||||||
| //void TOUCH_PAD_IRQHANDLER(void)
 | //void TOUCH_PAD_IRQHANDLER(void)
 | ||||||
| extern int touch_sem; | extern int touch_sem; | ||||||
| void GT9xx_PEN_IRQHandler(int irqn, void *arg) | void GT9xx_PEN_IRQHandler(int irqn, void *arg) | ||||||
| { | { | ||||||
| 	DisableIRQ(GT9xx_PEN_IRQ); | 	DisableIRQ(GT9xx_PEN_IRQ); | ||||||
|     /* 确认是触摸芯片的中断 */ |     /* ȷ<EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><EFBFBD><EFBFBD>оƬ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> */ | ||||||
|     if(GPIO_GetPinsInterruptFlags(TOUCH_PAD_INT_GPIO) & 1U << TOUCH_PAD_INT_GPIO_PIN) |     if(GPIO_GetPinsInterruptFlags(TOUCH_PAD_INT_GPIO) & 1U << TOUCH_PAD_INT_GPIO_PIN) | ||||||
|     { |     { | ||||||
|        /* 清除中断标志 */ |        /* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϱ<EFBFBD>־ */ | ||||||
|       GPIO_PortClearInterruptFlags(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); |       GPIO_PortClearInterruptFlags(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); | ||||||
|       /* 切换触摸输入状态标志 */ |       /* <EFBFBD>л<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD>־ */ | ||||||
|       g_TouchPadInputSignal = true; |       g_TouchPadInputSignal = true; | ||||||
| 	  if(!SemReleaseFlag)  | 	  if(!SemReleaseFlag)  | ||||||
| 	  { | 	  { | ||||||
|  | @ -322,7 +358,7 @@ DECLARE_HW_IRQ(GT9xx_PEN_IRQ, GT9xx_PEN_IRQHandler, NONE); | ||||||
|  *	terminate the operation; each message begins with a START. |  *	terminate the operation; each message begins with a START. | ||||||
|  * @num: Number of messages to be executed. |  * @num: Number of messages to be executed. | ||||||
|  */ |  */ | ||||||
| int I2C_Transfer( struct i2c_msg *msgs,int num) | int I2C_Transfer(struct i2c_msg* msgs, int num) | ||||||
| { | { | ||||||
| 	int im = 0; | 	int im = 0; | ||||||
| 	int ret = 0; | 	int ret = 0; | ||||||
|  | @ -331,19 +367,19 @@ int I2C_Transfer( struct i2c_msg *msgs,int num) | ||||||
| 
 | 
 | ||||||
| 	for (im = 0; ret == 0 && im != num; im++) | 	for (im = 0; ret == 0 && im != num; im++) | ||||||
| 	{ | 	{ | ||||||
| 		if ((msgs[im].flags&I2C_M_RD))																//根据flag判断是读数据还是写数据
 | 		if (msgs[im].flags & I2C_M_RD)																//<2F><><EFBFBD><EFBFBD>flag<61>ж<EFBFBD><D0B6>Ƕ<EFBFBD><C7B6><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
 | ||||||
| 		{ | 		{ | ||||||
| 			ret = I2C_ReadBytes(msgs[im].addr, msgs[im].buf, msgs[im].len);		//IIC读取数据
 | 			ret = I2C_ReadBytes(msgs[im].addr, msgs[im].buf, msgs[im].len);		//IIC<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | ||||||
| 		} else | 		} else | ||||||
| 		{ | 		{ | ||||||
| 			ret = I2C_WriteBytes(msgs[im].addr,  msgs[im].buf, msgs[im].len);	//IIC写入数据
 | 			ret = I2C_WriteBytes(msgs[im].addr, msgs[im].buf, msgs[im].len);	//IICд<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if(ret) | 	if(ret) | ||||||
| 		return ret; | 		return ret; | ||||||
| 
 | 
 | ||||||
| 	return im;   													//正常完成的传输结构个数
 | 	return im;   													//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵĴ<EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -26,12 +26,13 @@ extern volatile bool SemReleaseFlag; | ||||||
| 
 | 
 | ||||||
| #define GTP_I2C_BAUDRATE 400000U | #define GTP_I2C_BAUDRATE 400000U | ||||||
| 
 | 
 | ||||||
| /* 等待超时时间 */ | /* <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>ʱʱ<EFBFBD><EFBFBD> */ | ||||||
| #define I2CT_FLAG_TIMEOUT         ((uint32_t)0x10000) | #define I2CT_FLAG_TIMEOUT         ((uint32_t)0x10000) | ||||||
| #define I2CT_LONG_TIMEOUT         ((uint32_t)(10 * I2CT_FLAG_TIMEOUT)) | #define I2CT_LONG_TIMEOUT         ((uint32_t)(10 * I2CT_FLAG_TIMEOUT)) | ||||||
| 
 | 
 | ||||||
|  | #define I2C_BUSY_LIMIT            5 | ||||||
| 
 | 
 | ||||||
| /*! @brief 触摸芯片引脚定义 */ | /*! @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ<EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD><EFBFBD><EFBFBD> */ | ||||||
| 
 | 
 | ||||||
| #define TOUCH_PAD_SCL_IOMUXC			  IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL | #define TOUCH_PAD_SCL_IOMUXC			  IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL | ||||||
| #define TOUCH_PAD_SDA_IOMUXC			  IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA | #define TOUCH_PAD_SDA_IOMUXC			  IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA | ||||||
|  | @ -48,9 +49,18 @@ extern volatile bool SemReleaseFlag; | ||||||
| #define GT9xx_PEN_IRQ           GPIO2_Combined_16_31_IRQn | #define GT9xx_PEN_IRQ           GPIO2_Combined_16_31_IRQn | ||||||
| #define GT9xx_PEN_IRQHandler    GPIO2_Combined_16_31_IRQHandler | #define GT9xx_PEN_IRQHandler    GPIO2_Combined_16_31_IRQHandler | ||||||
| 
 | 
 | ||||||
|  | #define TOUCH_PAD_RECOVER_SCL_GPIO          GPIO1 | ||||||
|  | #define TOUCH_PAD_RECOVER_SCL_GPIO_PIN      (16U) | ||||||
|  | #define TOUCH_PAD_RECOVER_SDA_GPIO          GPIO1 | ||||||
|  | #define TOUCH_PAD_RECOVER_SDA_GPIO_PIN      (17U) | ||||||
|  | #define TOUCH_PAD_RECOVER_SCL_IOMUXC    IOMUXC_GPIO_AD_B1_00_GPIO1_IO16 | ||||||
|  | #define TOUCH_PAD_RECOVER_SDA_IOMUXC    IOMUXC_GPIO_AD_B1_01_GPIO1_IO17 | ||||||
|  | 
 | ||||||
|  | #define I2C_RECOVER_NUM_CLOCKS      10U     /* # clock cycles for recovery  */ | ||||||
|  | #define I2C_RECOVER_CLOCK_FREQ      50000U  /* clock frequency for recovery */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| //函数接口
 | //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
 | ||||||
| int32_t GTP_I2C_ReadBytes(uint8_t client_addr, uint8_t *buf, int32_t len); | int32_t GTP_I2C_ReadBytes(uint8_t client_addr, uint8_t *buf, int32_t len); | ||||||
| 
 | 
 | ||||||
| void I2C_Touch_Init(void); | void I2C_Touch_Init(void); | ||||||
|  |  | ||||||
|  | @ -7,8 +7,8 @@ | ||||||
| * @date 2022-04-25 | * @date 2022-04-25 | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #ifndef CONNECT_TOUCH_H | #ifndef __CONNECT_TOUCH_H__ | ||||||
| #define CONNECT_TOUCH_H | #define __CONNECT_TOUCH_H__ | ||||||
| 
 | 
 | ||||||
| #include <device.h>	  | #include <device.h>	  | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -393,7 +393,7 @@ static void* BigMemMalloc(struct DynamicBuddyMemory *dynamic_buddy, x_size_t siz | ||||||
| 	/* failure allocation */ | 	/* failure allocation */ | ||||||
| 	if(result == NONE) { | 	if(result == NONE) { | ||||||
| #ifndef MEM_EXTERN_SRAM | #ifndef MEM_EXTERN_SRAM | ||||||
| 	    KPrintf("%s: allocation failed, size %d.\n", __func__,allocsize); | 	    KPrintf("%s: allocation failed, size %d.\n", __func__, size); | ||||||
| #endif | #endif | ||||||
|         return result; |         return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -101,7 +101,6 @@ SWITCH: | ||||||
|         _KTaskOsAssignStackCheck(new_task); |         _KTaskOsAssignStackCheck(new_task); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         SwitchKtaskContext((x_ubase)&from_task->stack_point, |         SwitchKtaskContext((x_ubase)&from_task->stack_point, | ||||||
|                     (x_ubase)&new_task->stack_point, new_task); |                     (x_ubase)&new_task->stack_point, new_task); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1653,11 +1653,11 @@ void shellTask(void *param) | ||||||
| 
 | 
 | ||||||
|             data_len = shell->read(data); |             data_len = shell->read(data); | ||||||
|             if(data_len > 0) { |             if(data_len > 0) { | ||||||
|                 int lock = CriticalAreaLock(); |                 // int lock = CriticalAreaLock();
 | ||||||
|                 for (i = 0; i < data_len; i++) { |                 for (i = 0; i < data_len; i++) { | ||||||
|                     shellHandler(shell, data[i]); |                     shellHandler(shell, data[i]); | ||||||
|                 } |                 } | ||||||
|                 CriticalAreaUnLock(lock); |                 // CriticalAreaUnLock(lock);
 | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue