KT24-1110_65E-HA-651B/apps/soundbox/task_manager/idle/idle.c
2024-11-10 18:44:17 +08:00

514 lines
12 KiB
C
Raw Permalink 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.

/*************************************************************
此文件函数主要是idle模式按键处理和事件处理
void app_idle_task()
idle模式主函数
static int idle_sys_event_handler(struct sys_event *event)
idle模式系统事件所有处理入口
static void idle_task_close(void)
idle模式退出
该模式只是作为系统空跑的,可以做家关机,把没有用的模块关闭
**************************************************************/
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "app_task.h"
#include "tone_player.h"
#include "asm/charge.h"
#include "app_charge.h"
#include "app_main.h"
#include "ui_manage.h"
#include "vm.h"
#include "app_chargestore.h"
#include "user_cfg.h"
#include "ui/ui_api.h"
#include "key_event_deal.h"
#define LOG_TAG_CONST APP_IDLE
#define LOG_TAG "[APP_IDLE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
static int timer_printf_1sec = 0;
static u8 is_idle_flag = 0;
static u8 goto_poweron_cnt = 0;
static u8 goto_poweron_flag = 0;
extern u8 get_power_on_status(void);
static void idle_key_poweron_deal(u8 step);
static void idle_app_open_module();
#define POWER_ON_CNT 10
/// idle 是否关闭不用的模块,减少功耗
#define LOW_POWER_IN_IDLE 0
#if LOW_POWER_IN_IDLE
///*----------------------------------------------------------------------------*/
/**@brief 下面处理是为了关闭不需要用的模块,减少系统功耗
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
#include "usb/otg.h"
#include "usb/host/usb_host.h"
#include "asm/power/p33.h"
struct timer_hdl {
u32 ticks;
int index;
int prd;
u32 fine_cnt;
void *power_ctrl;
struct list_head head;
};
static struct timer_hdl hdl;
static u8 suspend_flag = 0;
#define __this (&hdl)
static const u32 timer_div[] = {
/*0000*/ 1,
/*0001*/ 4,
/*0010*/ 16,
/*0011*/ 64,
/*0100*/ 2,
/*0101*/ 8,
/*0110*/ 32,
/*0111*/ 128,
/*1000*/ 256,
/*1001*/ 4 * 256,
/*1010*/ 16 * 256,
/*1011*/ 64 * 256,
/*1100*/ 2 * 256,
/*1101*/ 8 * 256,
/*1110*/ 32 * 256,
/*1111*/ 128 * 256,
};
#define APP_TIMER_CLK clk_get("timer")
#define MAX_TIME_CNT 0x7fff
#define MIN_TIME_CNT 0x100
#define TIMER_UNIT_MS 2
#define MAX_TIMER_PERIOD_MS (1000/TIMER_UNIT_MS)
extern void adc_scan(void *priv);
___interrupt
static void idle_timer2_isr()
{
static u32 cnt = 0;
JL_TIMER2->CON |= BIT(14);
++cnt;
if ((cnt % 5) == 0) {
}
if (cnt == 500) {
cnt = 0;
}
/* adc_scan(NULL); */
}
static int idle_timer2_init()
{
u32 prd_cnt;
u8 index;
for (index = 0; index < (sizeof(timer_div) / sizeof(timer_div[0])); index++) {
prd_cnt = TIMER_UNIT_MS * (APP_TIMER_CLK / 1000) / timer_div[index];
if (prd_cnt > MIN_TIME_CNT && prd_cnt < MAX_TIME_CNT) {
break;
}
}
__this->index = index;
__this->prd = prd_cnt;
JL_TIMER2->CNT = 0;
JL_TIMER2->PRD = prd_cnt; //2ms
request_irq(IRQ_TIME2_IDX, 3, idle_timer2_isr, 0);
JL_TIMER2->CON = (index << 4) | BIT(0) | BIT(3);
log_info("PRD : 0x%x / %d", JL_TIMER2->PRD, clk_get("timer"));
return 0;
}
static void idle_timer2_uninit()
{
JL_TIMER2->CON &= ~(BIT(1) | BIT(0));
}
static void idle_timer1_open()
{
JL_TIMER1->CON |= BIT(0);
}
static void idle_timer1_close()
{
JL_TIMER1->CON &= ~(BIT(1) | BIT(0));
}
u32 regs_buf[11] = {0};
void resume_some_peripheral()
{
u32 *regs_ptr = regs_buf;
if (!suspend_flag) {
return;
}
clk_set("sys", 24 * 1000000L);
JL_ANA->DAA_CON0 = *regs_ptr++ ;
JL_ANA->DAA_CON1 = *regs_ptr++ ;
JL_ANA->DAA_CON2 = *regs_ptr++ ;
JL_ANA->DAA_CON3 = *regs_ptr++ ;
JL_ANA->DAA_CON7 = *regs_ptr++ ;
JL_ANA->ADA_CON0 = *regs_ptr++ ;
JL_ANA->ADA_CON1 = *regs_ptr++ ;
JL_ANA->ADA_CON2 = *regs_ptr++ ;
JL_ANA->ADA_CON3 = *regs_ptr++ ;
JL_ANA->ADA_CON4 = *regs_ptr++ ;
suspend_flag = 0;
}
void suspend_some_peripheral()
{
u32 *regs_ptr = regs_buf;
if (suspend_flag) {
return;
}
clk_set("sys", 6 * 1000000L);
SYSVDD_VOL_SEL(SYSVDD_VOL_SEL_102V);
VDC13_VOL_SEL(VDC13_VOL_SEL_105V);
*regs_ptr++ = JL_ANA->DAA_CON0;
*regs_ptr++ = JL_ANA->DAA_CON1;
*regs_ptr++ = JL_ANA->DAA_CON2;
*regs_ptr++ = JL_ANA->DAA_CON3;
*regs_ptr++ = JL_ANA->DAA_CON7;
*regs_ptr++ = JL_ANA->ADA_CON0;
*regs_ptr++ = JL_ANA->ADA_CON1;
*regs_ptr++ = JL_ANA->ADA_CON2;
*regs_ptr++ = JL_ANA->ADA_CON3;
*regs_ptr++ = JL_ANA->ADA_CON4;
JL_ANA->DAA_CON0 = 0;
JL_ANA->DAA_CON1 = 0;
JL_ANA->DAA_CON2 = 0;
JL_ANA->DAA_CON3 = 0;
JL_ANA->DAA_CON7 = 0;
JL_ANA->ADA_CON0 = 0;
JL_ANA->ADA_CON1 = 0;
JL_ANA->ADA_CON2 = 0;
JL_ANA->ADA_CON3 = 0;
JL_ANA->ADA_CON4 = 0;
suspend_flag = 1;
}
static u8 is_idle_query(void)
{
return is_idle_flag;
}
#if 0
REGISTER_LP_TARGET(idle_lp_target) = {
.name = "not_idle",
.is_idle = is_idle_query,
};
#endif
#endif
static void idle_key_poweron_deal(u8 step)
{
switch (step) {
case 0:
goto_poweron_cnt = 0;
goto_poweron_flag = 1;
break;
case 1:
log_info("poweron flag:%d cnt:%d\n", goto_poweron_flag, goto_poweron_cnt);
if (goto_poweron_flag) {
goto_poweron_cnt++;
if (goto_poweron_cnt >= POWER_ON_CNT) {
goto_poweron_cnt = 0;
goto_poweron_flag = 0;
app_var.goto_poweroff_flag = 0;
#if LOW_POWER_IN_IDLE
idle_app_open_module();
#endif
#if TWFG_APP_POWERON_IGNORE_DEV
app_task_switch_to(APP_POWERON_TASK);
#endif
}
}
break;
}
}
#if (TWFG_APP_POWERON_IGNORE_DEV == 0)
static u16 ignore_dev_timeout = 0;
static void poweron_task_switch_to_bt(void *priv) //超时还没有设备挂载,则切到蓝牙模式
{
app_task_switch_to(APP_BT_TASK);
}
#endif
//*----------------------------------------------------------------------------*/
/**@brief idle 按键消息入口
@param 无
@return 1、消息已经处理不需要发送到common 0、消息发送到common处理
@note
*/
/*----------------------------------------------------------------------------*/
static int idle_key_event_opr(struct sys_event *event)
{
int ret = false;
int key_event = event->u.key.event;
int key_value = event->u.key.value;
log_info("key_event:%d \n", key_event);
switch (key_event) {
case KEY_POWER_ON:
case KEY_POWER_ON_HOLD:
idle_key_poweron_deal(key_event - KEY_POWER_ON);
ret = true;
break;
}
return ret;
}
//*----------------------------------------------------------------------------*/
/**@brief idle 模式活跃状态 所有消息入口
@param 无
@return 1、当前消息已经处理不需要发送comomon 0、当前消息不是idle处理的发送到common统一处理
@note
*/
/*----------------------------------------------------------------------------*/
extern int app_common_otg_devcie_event(struct sys_event *event);
static int idle_sys_event_handler(struct sys_event *event)
{
switch (event->type) {
case SYS_KEY_EVENT:
return idle_key_event_opr(event);
case SYS_BT_EVENT:
/* return 0; */
return true;
case SYS_DEVICE_EVENT:
#if TCFG_CHARGESTORE_ENABLE || TCFG_TEST_BOX_ENABLE
if ((u32)event->arg == DEVICE_EVENT_CHARGE_STORE) {
app_chargestore_event_handler(&event->u.chargestore);
}
#endif
return 0;
default:
return true;
}
}
//*----------------------------------------------------------------------------*/
/**@brief idle 退出
@param 无
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void idle_task_close()
{
UI_HIDE_CURR_WINDOW();
}
//*----------------------------------------------------------------------------*/
/**@brief idle 重新打开需要的模块
@param 无
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void idle_app_open_module()
{
#if LOW_POWER_IN_IDLE
is_idle_flag = 0;
#if (TCFG_LOWPOWER_LOWPOWER_SEL == 0)
resume_some_peripheral();
#endif
#if (TCFG_SD0_ENABLE || TCFG_SD1_ENABLE)
extern void sdx_dev_detect_timer_add();
sdx_dev_detect_timer_add();
#endif
#if (TCFG_PC_ENABLE || TCFG_UDISK_ENABLE)
extern void usb_detect_timer_add();
usb_detect_timer_add();
#endif
#if TCFG_LINEIN_ENABLE
extern void linein_detect_timer_add();
linein_detect_timer_add();
#endif
if (timer_printf_1sec) {
sys_timer_del(timer_printf_1sec);
}
#endif //LOW_POWER_IN_IDLE
}
//*----------------------------------------------------------------------------*/
/**@brief idle 关闭不需要的模块
@param 无
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void idle_app_close_module()
{
#if LOW_POWER_IN_IDLE
int ret = false;
is_idle_flag = 1;
#if (TCFG_SD0_ENABLE || TCFG_SD1_ENABLE)
extern void sdx_dev_detect_timer_del();
sdx_dev_detect_timer_del();
#endif
#if (((TCFG_PC_ENABLE) && (!TCFG_USB_PORT_CHARGE)) || ((TCFG_UDISK_ENABLE) && (!TCFG_PC_ENABLE)))
extern void usb_detect_timer_del();
extern u32 usb_otg_online(const usb_dev usb_id);
/* extern int usb_mount_offline(usb_dev usb_id); */
extern void usb_pause();
extern int dev_manager_del(char *logo);
usb_detect_timer_del();
os_time_dly((TCFG_OTG_DET_INTERVAL + 9) / 10);
if (usb_otg_online(0) == HOST_MODE) {
#if TCFG_UDISK_ENABLE
dev_manager_del("udisk0");
usb_host_unmount(0);
usb_h_sie_close(0);
/*
经过测试发现有相当一部分在DP/DM设成高阻状态下U盘的电流仍维持在
20 ~ 30mA需要把DP设成上拉DM设成下拉这些U盘的电流才能降到2mA
以下。即有部分U盘需要主机维持在空闲时J状态才能进入suspend。
*/
usb_iomode(1);
gpio_set_die(IO_PORT_DP, 1);
gpio_set_pull_up(IO_PORT_DP, 1);
gpio_set_pull_down(IO_PORT_DP, 0);
gpio_set_direction(IO_PORT_DP, 1);
gpio_set_die(IO_PORT_DM, 1);
gpio_set_pull_up(IO_PORT_DM, 0);
gpio_set_pull_down(IO_PORT_DM, 1);
gpio_set_direction(IO_PORT_DM, 1);
/* usb_mount_offline(0); */
#endif
} else if (usb_otg_online(0) == SLAVE_MODE) {
#if TCFG_PC_ENABLE
usb_pause();
usb_iomode(1);
gpio_set_die(IO_PORT_DP, 0);
gpio_set_pull_up(IO_PORT_DP, 0);
gpio_set_pull_down(IO_PORT_DP, 0);
gpio_set_direction(IO_PORT_DP, 1);
gpio_set_die(IO_PORT_DM, 0);
gpio_set_pull_up(IO_PORT_DM, 0);
gpio_set_pull_down(IO_PORT_DM, 0);
gpio_set_direction(IO_PORT_DM, 1);
#endif
}
#endif
#if TCFG_LINEIN_ENABLE
extern void linein_detect_timer_del();
linein_detect_timer_del();
#endif
#if (TCFG_LOWPOWER_LOWPOWER_SEL == 0)
suspend_some_peripheral();
#endif
#endif
}
//*----------------------------------------------------------------------------*/
/**@brief idle 启动
@param 无
@return
@note 关闭SD卡 、 usb 、假关机还是软关机
*/
/*----------------------------------------------------------------------------*/
static void idle_app_start()
{
#if LOW_POWER_IN_IDLE
idle_app_close_module();
#endif
UI_SHOW_WINDOW(ID_WINDOW_IDLE);
#if (TCFG_CHARGE_ENABLE && !TCFG_CHARGE_POWERON_ENABLE)
#else
sys_key_event_enable();
#endif
}
//*----------------------------------------------------------------------------*/
/**@brief idle 主任务
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void app_idle_task()
{
int res;
int msg[32];
idle_app_start();
while (1) {
app_task_get_msg(msg, ARRAY_SIZE(msg), 1);
switch (msg[0]) {
case APP_MSG_SYS_EVENT:
if (idle_sys_event_handler((struct sys_event *)(&msg[1])) == false) {
app_default_event_deal((struct sys_event *)(&msg[1])); //由common统一处理
}
break;
default:
break;
}
if (app_task_exitting()) {
idle_task_close();
return;
}
}
}