332 lines
11 KiB
C
332 lines
11 KiB
C
|
|
#include "app_config.h"
|
|||
|
|
#include "includes.h"
|
|||
|
|
#include "ui/ui_api.h"
|
|||
|
|
#include "clock_cfg.h"
|
|||
|
|
#include "led_lyric.h"
|
|||
|
|
|
|||
|
|
#if (TCFG_UI_ENABLE && (CONFIG_UI_STYLE == STYLE_JL_LED_LYRICS))
|
|||
|
|
|
|||
|
|
#define UI_TASK_NAME "ui"
|
|||
|
|
|
|||
|
|
struct lyric_ui_display_env {
|
|||
|
|
u16 tmp_menu_ret_cnt;//子页面显示计数
|
|||
|
|
u16 auto_reflash_time;//自动刷新计数
|
|||
|
|
u16 time_count;//计数器
|
|||
|
|
void (*timeout_cb)(int);//回调函数
|
|||
|
|
int main_menu;//当前主页
|
|||
|
|
int this_menu;//当前子页面
|
|||
|
|
const struct lyric_ui_dis *lyric_ui;//指向具体模式的处理函数
|
|||
|
|
void *private;//页面open时候传入的函数
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
enum {
|
|||
|
|
UI_MSG_STRICK,//定时器事件
|
|||
|
|
UI_MSG_REFLASH,//刷新主页
|
|||
|
|
UI_MSG_OTHER,//显示子页面
|
|||
|
|
UI_MSG_MENU_SW,////页面切换
|
|||
|
|
UI_MSG_MENU_CLOSE,//页面关闭
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
static struct lyric_ui_display_env __lyric_ui_display_env = {0};
|
|||
|
|
#define __lyric_ui_display (&__lyric_ui_display_env)
|
|||
|
|
|
|||
|
|
static const struct lyric_ui_dis *lyric_ui_dis_main[] = {
|
|||
|
|
#if TCFG_APP_BT_EN
|
|||
|
|
&lyric_bt_main,
|
|||
|
|
#endif
|
|||
|
|
#if TCFG_APP_MUSIC_EN
|
|||
|
|
&lyric_music_main,
|
|||
|
|
#endif
|
|||
|
|
#if TCFG_APP_FM_EN
|
|||
|
|
&lyric_fm_main,
|
|||
|
|
#endif
|
|||
|
|
#if TCFG_APP_RECORD_EN
|
|||
|
|
&lyric_record_main,
|
|||
|
|
#endif
|
|||
|
|
#if TCFG_APP_LINEIN_EN
|
|||
|
|
&lyric_linein_main,
|
|||
|
|
#endif
|
|||
|
|
#if TCFG_APP_RTC_EN
|
|||
|
|
&lyric_rtc_main,
|
|||
|
|
#endif
|
|||
|
|
#if TCFG_APP_PC_EN
|
|||
|
|
&lyric_pc_main,
|
|||
|
|
#endif
|
|||
|
|
#if TCFG_APP_SPDIF_EN
|
|||
|
|
/* &idle_main, */
|
|||
|
|
#endif
|
|||
|
|
&lyric_idle_main,
|
|||
|
|
&lyric_power_off_main,
|
|||
|
|
&lyric_power_on_main,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
#define list_for_each_lyric_ui_main(c) \
|
|||
|
|
int ui_list = 0;\
|
|||
|
|
for (c = lyric_ui_dis_main[ui_list]; ui_list <sizeof(lyric_ui_dis_main)/sizeof(lyric_ui_dis_main[0]); ui_list++,c = lyric_ui_dis_main[ui_list])
|
|||
|
|
|
|||
|
|
|
|||
|
|
static int post_ui_msg(int *msg, u8 len)
|
|||
|
|
{
|
|||
|
|
int count = 0;
|
|||
|
|
int err = 0;
|
|||
|
|
|
|||
|
|
__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 > 10) {
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
count++;
|
|||
|
|
os_time_dly(1);
|
|||
|
|
goto __retry;
|
|||
|
|
}
|
|||
|
|
return err;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//=================================================================================//
|
|||
|
|
// API 函数
|
|||
|
|
//=================================================================================//
|
|||
|
|
|
|||
|
|
//=================================================================================//
|
|||
|
|
// @brief: 非主界面显示
|
|||
|
|
// @input:
|
|||
|
|
// 1)app_menu: 要显示的非主界面
|
|||
|
|
// 2)ret_time: 持续时间ms, 返回主界面
|
|||
|
|
// 3)arg: 显示参数
|
|||
|
|
// 4)子菜单被打断或者时间到了
|
|||
|
|
//=================================================================================//
|
|||
|
|
void lyric_ui_set_tmp_menu(u8 app_menu, u16 ret_time, s32 arg, void (*timeout_cb)(u8 menu))
|
|||
|
|
{
|
|||
|
|
int msg[6];
|
|||
|
|
msg[0] = UI_MSG_OTHER;
|
|||
|
|
msg[1] = app_menu;
|
|||
|
|
msg[2] = arg;
|
|||
|
|
msg[3] = (int)((ret_time + 99) / 100);
|
|||
|
|
msg[4] = (int)timeout_cb;
|
|||
|
|
post_ui_msg(msg, 5);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//进入app时设置一次, 设置主界面
|
|||
|
|
void lyric_ui_set_main_menu(enum ui_menu_main menu)
|
|||
|
|
{
|
|||
|
|
int msg[2];
|
|||
|
|
msg[0] = UI_MSG_MENU_SW;
|
|||
|
|
msg[1] = menu;
|
|||
|
|
post_ui_msg(msg, 2);
|
|||
|
|
}
|
|||
|
|
//进入app时设置一次, 关闭主界面
|
|||
|
|
void lyric_ui_close_main_menu()
|
|||
|
|
{
|
|||
|
|
int msg[1];
|
|||
|
|
msg[0] = UI_MSG_MENU_CLOSE;
|
|||
|
|
post_ui_msg(msg, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//=================================================================================//
|
|||
|
|
// @brief: 主界面显示刷新
|
|||
|
|
// @input:
|
|||
|
|
// 1)break_in : 1:打断显示 0:不打断显示
|
|||
|
|
// 打断显示可以理解为当前正在显示临时页面并非主页,例如设置页面,打断显示可以打断当前显示,恢复主页刷新
|
|||
|
|
// 实例化函数:lyric_ui_menu_reflash
|
|||
|
|
//=================================================================================//
|
|||
|
|
void lyric_ui_menu_reflash(u8 break_in)//break_in 是否打断显示,例如显示设置过程中需要刷新新界面。是是否打断设置界面显示
|
|||
|
|
{
|
|||
|
|
int msg[2];
|
|||
|
|
msg[0] = UI_MSG_REFLASH;
|
|||
|
|
msg[1] = !!break_in;
|
|||
|
|
post_ui_msg(msg, 2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//=================================================================================//
|
|||
|
|
// @brief: 自动刷新时间
|
|||
|
|
// @input: 自动刷新主页
|
|||
|
|
//=================================================================================//
|
|||
|
|
void lyric_ui_set_auto_reflash(u32 msec)//自动刷新主页
|
|||
|
|
{
|
|||
|
|
__lyric_ui_display->auto_reflash_time = (msec + 99) / 100;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
u8 lyric_ui_get_app_menu(u8 type)
|
|||
|
|
{
|
|||
|
|
if (type) {
|
|||
|
|
return __lyric_ui_display->main_menu;
|
|||
|
|
} else {
|
|||
|
|
return __lyric_ui_display->this_menu;
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void lyric_ui_strick_loop()
|
|||
|
|
{
|
|||
|
|
int msg[1];
|
|||
|
|
if (__lyric_ui_display->auto_reflash_time && ((++__lyric_ui_display->time_count) >= __lyric_ui_display->auto_reflash_time)) {
|
|||
|
|
lyric_ui_menu_reflash(0);//自动刷新主页
|
|||
|
|
__lyric_ui_display->time_count = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (__lyric_ui_display->tmp_menu_ret_cnt && ((--__lyric_ui_display->tmp_menu_ret_cnt) == 0)) {
|
|||
|
|
msg[0] = UI_MSG_STRICK;
|
|||
|
|
post_ui_msg(msg, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//=================================================================================//
|
|||
|
|
// 实例化函数
|
|||
|
|
//=================================================================================//
|
|||
|
|
//=================================================================================//
|
|||
|
|
// @brief: 子界面显示实例化函数
|
|||
|
|
// api 对应 lyric_ui_menu_reflash
|
|||
|
|
//=================================================================================//
|
|||
|
|
static void __lyric_ui_menu_reflash_action(u8 break_in)
|
|||
|
|
{
|
|||
|
|
if (break_in && (__lyric_ui_display->this_menu != MENU_MAIN)) {//如果需要打断显示,先判断当前是否主页,不是主页
|
|||
|
|
if (__lyric_ui_display->timeout_cb) {//判断是否有打断显示回调函数,有则告诉应用,当前页面已经被打断
|
|||
|
|
__lyric_ui_display->timeout_cb(__lyric_ui_display->this_menu);
|
|||
|
|
__lyric_ui_display->timeout_cb = NULL;
|
|||
|
|
}
|
|||
|
|
} else if (__lyric_ui_display->this_menu != MENU_MAIN) {//不支持打断显示
|
|||
|
|
return ;
|
|||
|
|
}
|
|||
|
|
if (__lyric_ui_display->lyric_ui && __lyric_ui_display->lyric_ui->lyric_ui_main) {
|
|||
|
|
__lyric_ui_display->lyric_ui->lyric_ui_main(); //刷新主页
|
|||
|
|
}
|
|||
|
|
__lyric_ui_display->this_menu = MENU_MAIN;
|
|||
|
|
}
|
|||
|
|
//=================================================================================//
|
|||
|
|
// @brief: 子界面显示实例化函数
|
|||
|
|
// api 对应 lyric_ui_set_tmp_menu
|
|||
|
|
//=================================================================================//
|
|||
|
|
static void __lyric_ui_user_action(int menu, u16 ret_time, u32 arg, void (*timeout_cb)(u8 menu))
|
|||
|
|
{
|
|||
|
|
int ret = false;
|
|||
|
|
if (menu != __lyric_ui_display->this_menu) {//如果显示的子页面和当前不一样,则回调注册的回调函数
|
|||
|
|
if (__lyric_ui_display->timeout_cb) {
|
|||
|
|
__lyric_ui_display->timeout_cb(__lyric_ui_display->this_menu);
|
|||
|
|
__lyric_ui_display->timeout_cb = NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
__lyric_ui_display->tmp_menu_ret_cnt = ret_time;
|
|||
|
|
__lyric_ui_display->timeout_cb = timeout_cb;
|
|||
|
|
__lyric_ui_display->this_menu = menu;
|
|||
|
|
if (__lyric_ui_display->lyric_ui && __lyric_ui_display->lyric_ui->lyric_ui_user) {//判断使用有指向的主页,有的则优先主页处理
|
|||
|
|
ret = __lyric_ui_display->lyric_ui->lyric_ui_user(menu, arg);
|
|||
|
|
}
|
|||
|
|
if (ret != true) {
|
|||
|
|
lyric_ui_common(menu, arg); //公共显示
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//=================================================================================//
|
|||
|
|
// @brief: 主界面显示实例化函数
|
|||
|
|
// api 对应 lyric_ui_close_main_menu
|
|||
|
|
//=================================================================================//
|
|||
|
|
static void __lyric_ui_main_close_main_action()
|
|||
|
|
{
|
|||
|
|
__lyric_ui_display->auto_reflash_time = 0;//停止自动计数
|
|||
|
|
__lyric_ui_display->tmp_menu_ret_cnt = 0;
|
|||
|
|
__lyric_ui_display->time_count = 0;
|
|||
|
|
|
|||
|
|
if (__lyric_ui_display->timeout_cb) {//检测回调
|
|||
|
|
__lyric_ui_display->timeout_cb(__lyric_ui_display->this_menu);
|
|||
|
|
__lyric_ui_display->timeout_cb = NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (__lyric_ui_display->lyric_ui && __lyric_ui_display->lyric_ui->lyric_close) {//掉用关闭
|
|||
|
|
__lyric_ui_display->lyric_ui->lyric_close();
|
|||
|
|
__lyric_ui_display->lyric_ui == NULL;
|
|||
|
|
}
|
|||
|
|
__lyric_ui_display->main_menu = 0;
|
|||
|
|
__lyric_ui_display->this_menu = MENU_MAIN;
|
|||
|
|
}
|
|||
|
|
//=================================================================================//
|
|||
|
|
// @brief: 主界面显示实例化函数
|
|||
|
|
// api 对应 __lyric_ui_main_open_main_action
|
|||
|
|
//=================================================================================//
|
|||
|
|
static void __lyric_ui_main_open_main_action(int cur_main)
|
|||
|
|
{
|
|||
|
|
const struct lyric_ui_dis *lyric_ui;
|
|||
|
|
__lyric_ui_main_close_main_action();
|
|||
|
|
list_for_each_lyric_ui_main(lyric_ui) {
|
|||
|
|
if (lyric_ui->lyric_ui == cur_main) {
|
|||
|
|
__lyric_ui_display->lyric_ui = lyric_ui;
|
|||
|
|
if (lyric_ui->lyric_open) {
|
|||
|
|
lyric_ui->lyric_open();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (lyric_ui->lyric_ui_main) {
|
|||
|
|
lyric_ui->lyric_ui_main();
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
__lyric_ui_display->main_menu = cur_main;
|
|||
|
|
__lyric_ui_display->this_menu = MENU_MAIN;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void __lyric_ui_strick_action()
|
|||
|
|
{
|
|||
|
|
if (!__lyric_ui_display->tmp_menu_ret_cnt && __lyric_ui_display->main_menu) {
|
|||
|
|
if (__lyric_ui_display->timeout_cb) {
|
|||
|
|
__lyric_ui_display->timeout_cb(__lyric_ui_display->this_menu);
|
|||
|
|
__lyric_ui_display->timeout_cb = NULL;
|
|||
|
|
}
|
|||
|
|
if (__lyric_ui_display->lyric_ui && __lyric_ui_display->lyric_ui->lyric_ui_main) {
|
|||
|
|
__lyric_ui_display->lyric_ui->lyric_ui_main();
|
|||
|
|
}
|
|||
|
|
__lyric_ui_display->this_menu = MENU_MAIN;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void lyric_ui_task(void *p)
|
|||
|
|
{
|
|||
|
|
int msg[32];
|
|||
|
|
int ret;
|
|||
|
|
sys_timer_add(NULL, lyric_ui_strick_loop, 100); //500ms
|
|||
|
|
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_STRICK:
|
|||
|
|
__lyric_ui_strick_action();
|
|||
|
|
break;
|
|||
|
|
case UI_MSG_REFLASH:
|
|||
|
|
__lyric_ui_menu_reflash_action(!!msg[1]);
|
|||
|
|
break;
|
|||
|
|
case UI_MSG_OTHER:
|
|||
|
|
__lyric_ui_user_action(msg[1], msg[3], msg[2], (void (*)(u8))msg[4]);
|
|||
|
|
break;
|
|||
|
|
case UI_MSG_MENU_SW:
|
|||
|
|
__lyric_ui_main_open_main_action(msg[1]);
|
|||
|
|
break;
|
|||
|
|
case UI_MSG_MENU_CLOSE:
|
|||
|
|
__lyric_ui_main_close_main_action();
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int lyric_ui_init(const struct ui_devices_cfg *ui_cfg)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
int err = 0;
|
|||
|
|
clock_add(DEC_UI_CLK);
|
|||
|
|
err = task_create(lyric_ui_task, NULL, UI_TASK_NAME);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif /* #if TCFG_UI_ENABLE */
|