KT24-1110_65E-HA-651B/apps/common/ui/lcd/lcd_ui_api.c
2024-11-10 18:44:17 +08:00

737 lines
17 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "app_config.h"
#include "includes.h"
#include "ui/ui_api.h"
#include "ui/ui.h"
#include "typedef.h"
#include "clock_cfg.h"
#if (TCFG_UI_ENABLE &&TCFG_SPI_LCD_ENABLE && (!TCFG_SIMPLE_LCD_ENABLE))
#include "ui/ui_sys_param.h"
#include "ui/res_config.h"
#define CURR_WINDOW_MAIN (0)
#define UI_NO_ARG (-1)
#define UI_TASK_NAME "ui"
enum {
UI_MSG_OTHER,
UI_MSG_KEY,
UI_MSG_TOUCH,
UI_MSG_SHOW,
UI_MSG_HIDE,
UI_TIME_TOUCH_RESUME,
UI_TIME_TOUCH_SUPEND,
UI_MSG_EXIT,
};
struct ui_server_env {
u8 init: 1;
u8 key_lock : 1;
OS_SEM start_sem;
int (*touch_event_call)(void);
int touch_event_interval;
u16 timer;
u8 shut_down_time;
};
int lcd_backlight_status();
int lcd_backlight_ctrl(u8 on);
void ui_backlight_open(void);
void ui_backlight_close(void);
int lcd_sleep_ctrl(u8 enter);
static struct ui_server_env __ui_display = {0};
static u8 lcd_bl_idle_flag = 0;
int key_is_ui_takeover()
{
return __ui_display.key_lock;
}
void key_ui_takeover(u8 on)
{
__ui_display.key_lock = !!on;
}
static int post_ui_msg(int *msg, u8 len)
{
int err = 0;
int count = 0;
if (!__ui_display.init) {
return -1;
}
__retry:
err = os_taskq_post_type(UI_TASK_NAME, msg[0], len - 1, &msg[1]);
if (cpu_in_irq() || cpu_irq_disabled()) {
return err;
}
if (err) {
if (!strcmp(os_current_task(), UI_TASK_NAME)) {
return err;
}
if (count > 20) {
return -1;
}
count++;
os_time_dly(1);
goto __retry;
}
return err;
}
//=================================================================================//
// @brief: 显示主页 应用于非ui线程显示主页使用
//有针对ui线程进行处理允许用于ui线程等同ui_show使用
//=================================================================================//
int ui_show_main(int id)
{
u32 rets;//, reti;
__asm__ volatile("%0 = rets":"=r"(rets));
printf("__func__ %s %x\n", __func__, rets);
static u32 mem_id[8] = {0};
static OS_SEM sem;// = zalloc(sizeof(OS_SEM));
int msg[8];
int i;
if (id <= 0) {
if (mem_id[7 + id]) {
id = mem_id[7 + id];
} else {
printf("[ui_show_main] id %d is invalid.\n", id);
return 0;
}
}
//else {
if (mem_id[7] != id) {
for (i = 1; i <= 7; i++) {
mem_id[i - 1] = mem_id[i];
}
mem_id[7] = id;
}
//}
printf("[ui_show_main] id = 0x%x\n", id);
/* if (!strcmp(os_current_task(), UI_TASK_NAME)) { */
/* ui_show(id); */
/* return 0; */
/* } */
u8 need_pend = 0;
if (!(cpu_in_irq() || cpu_irq_disabled())) {
if (strcmp(os_current_task(), UI_TASK_NAME)) {
need_pend = 1;
}
}
msg[0] = UI_MSG_SHOW;
msg[1] = id;
msg[2] = 0;
if (need_pend) {
os_sem_create(&sem, 0);
msg[2] = (int)&sem;
}
if (!post_ui_msg(msg, 3)) {
if (need_pend) {
os_sem_pend(&sem, 0);
}
}
if (!lcd_backlight_status()) {
printf("backlight is close ... ui_show_main_now\n");
lcd_bl_idle_flag = 0;
ui_auto_shut_down_enable();
ui_touch_timer_start();
}
return 0;
}
//=================================================================================//
// @brief: 关闭主页 应用于非ui线程关闭使用
//有针对ui线程进行处理允许用于ui线程等同ui_hide使用
//=================================================================================//
int ui_hide_main(int id)
{
u32 rets;//, reti;
__asm__ volatile("%0 = rets":"=r"(rets));
printf("__func__ %s %x\n", __func__, rets);
static OS_SEM sem;// = zalloc(sizeof(OS_SEM));
int msg[8];
u8 need_pend = 0;;
if (!(cpu_in_irq() || cpu_irq_disabled())) {
if (strcmp(os_current_task(), UI_TASK_NAME)) {
need_pend = 1;
}
}
/* if (!strcmp(os_current_task(), UI_TASK_NAME)) { */
/* if (CURR_WINDOW_MAIN == id) { */
/* id = ui_get_current_window_id(); */
/* } */
/* ui_hide(id); */
/* return 0; */
/* } */
msg[0] = UI_MSG_HIDE;
msg[1] = id;
msg[2] = 0;
if (need_pend) {
os_sem_create(&sem, 0);
msg[2] = (int)&sem;
}
if (!post_ui_msg(msg, 3)) {
if (need_pend) {
os_sem_pend(&sem, 0);
}
}
return 0;
}
//=================================================================================//
// @brief: 关闭当前主页 灵活使用自动判断当前主页进行关闭
//用户可以不用关心当前打开的主页,特别适用于一个任务使用了多个主页的场景
//=================================================================================//
int ui_hide_curr_main()
{
return ui_hide_main(CURR_WINDOW_MAIN);
}
//=================================================================================//
// @brief: 应用往ui发送消息ui主页需要注册回调函数关闭当前主页
// //消息发送方法demo UI_MSG_POST("test1:a=%4,test2:bcd=%4,test3:efgh=%4,test4:hijkl=%4", 1,2,3,4);
// 往test1、test2、test3、test4发送了字符为a、bcd、efgh、hijkl附带变量为1、2、3、4
// 每次可以只发一个消息,也可以不带数据例如:UI_MSG_POST("test1")
//=================================================================================//
int ui_server_msg_post(const char *msg, ...)
{
int ret = 0;
int argv[9];
argv[0] = UI_MSG_OTHER;
argv[1] = (int)msg;
va_list argptr;
va_start(argptr, msg);
for (int i = 2; i < 7; i++) {
argv[i] = va_arg(argptr, int);
}
va_end(argptr);
return post_ui_msg(argv, 9);
}
//=================================================================================//
// @brief: 应用往ui发送key消息由ui控件分配
//=================================================================================//
int ui_key_msg_post(int key)
{
u8 count = 0;
int msg[8];
if (key >= 0x80) {
return -1;
}
msg[0] = UI_MSG_KEY;
msg[1] = key;
return post_ui_msg(msg, 2);
}
//=================================================================================//
// @brief: 应用往ui发送触摸消息由ui控件分配
//=================================================================================//
int ui_touch_msg_post(struct touch_event *event)
{
int msg[8];
int i = 0;
ui_auto_shut_down_modify();
if (!lcd_backlight_status()) {
ui_backlight_open();
return 0;
}
msg[0] = UI_MSG_TOUCH;
msg[1] = (int)NULL;
memcpy(&msg[2], event, sizeof(struct touch_event));
return post_ui_msg(msg, sizeof(struct touch_event) / 4 + 2);
}
//=================================================================================//
// @brief: 应用往ui发送触摸消息由ui控件分配
//=================================================================================//
int ui_touch_msg_post_withcallback(struct touch_event *event, void (*cb)(u8 finish))
{
int msg[8];
int i = 0;
msg[0] = UI_MSG_TOUCH;
msg[1] = (int)cb;
memcpy(&msg[2], event, sizeof(struct touch_event));
return post_ui_msg(msg, sizeof(struct touch_event) / 4 + 2);
}
const char *str_substr_iter(const char *str, char delim, int *iter)
{
const char *substr;
ASSERT(str != NULL);
substr = str + *iter;
if (*substr == '\0') {
return NULL;
}
for (str = substr; *str != '\0'; str++) {
(*iter)++;
if (*str == delim) {
break;
}
}
return substr;
}
static int do_msg_handler(const char *msg, va_list *pargptr, int (*handler)(const char *, u32))
{
int ret = 0;
int width;
int step = 0;
u32 arg = 0x5678;
int m[16];
char *t = (char *)&m[3];
va_list argptr = *pargptr;
if (*msg == '\0') {
handler((const char *)' ', 0);
return 0;
}
while (*msg && *msg != ',') {
switch (step) {
case 0:
if (*msg == ':') {
step = 1;
}
break;
case 1:
switch (*msg) {
case '%':
msg++;
if (*msg >= '0' && *msg <= '9') {
if (*msg == '1') {
arg = va_arg(argptr, int) & 0xff;
} else if (*msg == '2') {
arg = va_arg(argptr, int) & 0xffff;
} else if (*msg == '4') {
arg = va_arg(argptr, int);
}
} else if (*msg == 'p') {
arg = va_arg(argptr, int);
}
m[2] = arg;
handler((char *)&m[3], m[2]);
t = (char *)&m[3];
step = 0;
break;
case '=':
*t = '\0';
break;
case ' ':
break;
default:
*t++ = *msg;
break;
}
break;
}
msg++;
}
*pargptr = argptr;
return ret;
}
int ui_message_handler(int id, const char *msg, va_list argptr)
{
int iter = 0;
const char *str;
const struct uimsg_handl *handler;
struct window *window = (struct window *)ui_core_get_element_by_id(id);
if (!window || !window->private_data) {
return -EINVAL;
}
handler = (const struct uimsg_handl *)window->private_data;
while ((str = str_substr_iter(msg, ',', &iter)) != NULL) {
for (; handler->msg != NULL; handler++) {
if (!memcmp(str, handler->msg, strlen(handler->msg))) {
do_msg_handler(str + strlen(handler->msg), &argptr, handler->handler);
break;
}
}
}
return 0;
}
extern void sys_param_init(void);
void ui_touch_timer_delete()
{
if (!__ui_display.init) {
return;
}
#if UI_WATCH_RES_ENABLE
local_irq_disable();
if (!__ui_display.timer) {
local_irq_enable();
return;
}
local_irq_enable();
#endif
int msg[8];
msg[0] = UI_TIME_TOUCH_SUPEND;
post_ui_msg(msg, 1);
}
void ui_touch_timer_start()
{
if (!__ui_display.init) {
return;
}
local_irq_disable();
if (__ui_display.timer) {
local_irq_enable();
return;
}
local_irq_enable();
int msg[8];
msg[0] = UI_TIME_TOUCH_RESUME;
post_ui_msg(msg, 1);
}
void ui_set_touch_event(int (*touch_event)(void), int interval)
{
__ui_display.touch_event_call = touch_event;
__ui_display.touch_event_interval = interval;
}
void ui_auto_shut_down_enable(void);
void ui_auto_shut_down_disable(void);
static int ui_auto_shut_down_timer = 0;
static u8 open_flag = 0;
void ui_backlight_open(void)
{
u32 rets;//, reti;
__asm__ volatile("%0 = rets":"=r"(rets));
lcd_bl_idle_flag = 0;
if (!__ui_display.init) {
return;
}
if (open_flag) {
return;
}
printf("__func__ %s %x\n", __func__, rets);
if (!lcd_backlight_status()) {
open_flag = 1;
/* UI_MSG_POST("ui_lp_cb:exit=%4", 1); */
/* sys_key_event_enable();//关闭按键 */
ui_auto_shut_down_enable();
//lcd_sleep_ctrl(0);//屏幕退出低功耗
#if UI_WATCH_RES_ENABLE
ui_show_main(0);//恢复当前ui
#endif
ui_touch_timer_start();
}
}
void ui_backlight_close(void)
{
if (!__ui_display.init) {
return;
}
open_flag = 0;
if (lcd_backlight_status()) {
/* UI_MSG_POST("ui_lp_cb:enter=%4", 0); */
/* sys_key_event_disable();//关闭按键 */
#if UI_WATCH_RES_ENABLE
ui_hide_curr_main();//关闭当前页面
#endif
ui_auto_shut_down_disable();
ui_touch_timer_delete();
}
lcd_bl_idle_flag = 1;
}
#if TCFG_UI_SHUT_DOWN_TIME
void ui_set_shut_down_time(u8 time)
{
__ui_display.shut_down_time = time;
}
int ui_get_shut_down_time()
{
return __ui_display.shut_down_time;
}
#endif
void ui_auto_shut_down_enable(void)
{
#if TCFG_UI_SHUT_DOWN_TIME
if (!__ui_display.init) {
return;
}
if (ui_auto_shut_down_timer == 0) {
if (__ui_display.shut_down_time == 0) {
__ui_display.shut_down_time = 10;
}
if (__ui_display.shut_down_time > 20) {
__ui_display.shut_down_time = 20;
}
g_printf("ui shut down time:%d", __ui_display.shut_down_time);
ui_auto_shut_down_timer = sys_timeout_add(NULL, ui_backlight_close, __ui_display.shut_down_time * 1000);
}
#endif
}
void ui_auto_shut_down_disable(void)
{
#if TCFG_UI_SHUT_DOWN_TIME
if (ui_auto_shut_down_timer) {
sys_timeout_del(ui_auto_shut_down_timer);
ui_auto_shut_down_timer = 0;
}
#endif
}
void ui_auto_shut_down_modify(void)
{
#if TCFG_UI_SHUT_DOWN_TIME
if (ui_auto_shut_down_timer) {
sys_timer_modify(ui_auto_shut_down_timer, __ui_display.shut_down_time * 1000);
}
#endif
}
static u8 lcd_bl_idle_query(void)
{
return lcd_bl_idle_flag;
}
REGISTER_LP_TARGET(lcd_backlight_lp_target) = {
.name = "lcd_backlight",
.is_idle = lcd_bl_idle_query,
};
__attribute__((weak)) void ui_sysinfo_init()
{
}
static void ui_task(void *p)
{
int msg[32];
int ret;
struct element_key_event e = {0};
sys_param_init();
/* struct ui_style style; */
/* style.file = NULL; */
extern void ui_sysinfo_init();
ui_sysinfo_init();
ui_framework_init(p);
/* ret = ui_set_style_file(&style); */
/* if (ret) { */
/* printf("ui task fail!\n"); */
/* return; */
/* } */
__ui_display.init = 1;
os_sem_post(&(__ui_display.start_sem));
struct touch_event *touch;
struct element_touch_event t;
if (__ui_display.touch_event_call && __ui_display.touch_event_interval) {
__ui_display.timer = sys_timer_add((void *)NULL, __ui_display.touch_event_call, __ui_display.touch_event_interval); //注册按键扫描定时器
}
while (1) {
ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg)); //500ms_reflash
if (ret != OS_TASKQ) {
continue;
}
switch (msg[0]) { //action
case UI_MSG_EXIT:
os_sem_post((OS_SEM *)msg[1]);
os_time_dly(10000);
break;
case UI_MSG_OTHER:
ui_message_handler(ui_get_current_window_id(), (const char *)msg[1], (void *)&msg[2]);
break;
case UI_MSG_KEY:
e.value = msg[1];
ui_event_onkey(&e);
break;
case UI_MSG_TOUCH:
touch = (struct touch_event *)&msg[2];
t.event = touch->event;
t.pos.x = touch->x;
t.pos.y = touch->y;
/* printf("event = %d %d %d \n", t.event, t.pos.x, t.pos.y); */
if (msg[1]) {
((void(*)(u8))msg[1])(0);
}
ui_event_ontouch(&t);
if (msg[1]) {
((void(*)(u8))msg[1])(1);
}
break;
case UI_MSG_SHOW:
if (!lcd_backlight_status()) {
lcd_sleep_ctrl(0);//退出低功耗
}
if (ui_id2type((msg[1])) == CTRL_TYPE_WINDOW && ui_get_current_window_id() > 0) {
printf("ui = %x show repeat.....\n", ui_get_current_window_id());
ui_hide(ui_get_current_window_id());
}
ui_show(msg[1]);
if (msg[2]) {
os_sem_post((OS_SEM *)msg[2]);
}
break;
case UI_MSG_HIDE:
if (CURR_WINDOW_MAIN == msg[1]) {
ui_hide(ui_get_current_window_id());
} else {
ui_hide(msg[1]);
}
if (msg[2]) {
os_sem_post((OS_SEM *)msg[2]);
}
break;
case UI_TIME_TOUCH_RESUME:
lcd_backlight_ctrl(true);
if (__ui_display.timer) {
break;
}
if (__ui_display.touch_event_call && __ui_display.touch_event_interval) {
__ui_display.timer = sys_timer_add((void *)NULL, __ui_display.touch_event_call, __ui_display.touch_event_interval); //注册按键扫描定时器
}
break;
case UI_TIME_TOUCH_SUPEND:
if (__ui_display.timer) {
sys_timer_del(__ui_display.timer);
__ui_display.timer = 0;
}
lcd_backlight_ctrl(false);
break;
default:
break;
}
}
}
extern int ui_file_check_valid();
extern int ui_upgrade_file_check_valid();
int lcd_ui_init(void *arg)
{
int err = 0;
clock_add_set(DEC_UI_CLK);
printf("open_resouece_start...\n");
if (ui_file_check_valid()) {
printf("ui_file_check_valid fail!!!\n");
if (ui_upgrade_file_check_valid()) {
printf("ui_upgrade_file_check_valid fail!!!\n");
return -1;
}
}
os_sem_create(&(__ui_display.start_sem), 0);
err = task_create(ui_task, arg, UI_TASK_NAME);
os_sem_pend(&(__ui_display.start_sem), 0);
return err;
}
#else
int key_is_ui_takeover()
{
return 0;
}
void key_ui_takeover(u8 on)
{
}
int ui_key_msg_post(int key)
{
return 0;
}
int ui_touch_msg_post(struct touch_event *event)
{
return 0;
}
int ui_touch_msg_post_withcallback(struct touch_event *event, void (*cb)(u8 finish))
{
return 0;
}
void ui_touch_timer_delete()
{
}
void ui_touch_timer_start()
{
}
void ui_backlight_ctrl(u8 lcd_open_flag)
{
}
#endif