463 lines
12 KiB
C
463 lines
12 KiB
C
#ifdef SUPPORT_MS_EXTENSIONS
|
|
#pragma bss_seg(".charge.data.bss")
|
|
#pragma data_seg(".charge.data")
|
|
#pragma const_seg(".charge.text.const")
|
|
#pragma code_seg(".charge.text")
|
|
#endif
|
|
#include "app_config.h"
|
|
#include "asm/charge.h"
|
|
#include "asm/power_interface.h"
|
|
#include "system/event.h"
|
|
#include "system/includes.h"
|
|
#include "app_action.h"
|
|
#include "asm/wdt.h"
|
|
#include "app_power_manage.h"
|
|
#include "app_chargestore.h"
|
|
#include "btstack/avctp_user.h"
|
|
#include "app_main.h"
|
|
#include "bt_tws.h"
|
|
#include "usb/otg.h"
|
|
#include "bt_common.h"
|
|
#include "battery_manager.h"
|
|
#include "app_charge.h"
|
|
#include "dual_bank_updata_api.h"
|
|
#include "gpadc.h"
|
|
#include "ui/ui_api.h"
|
|
#include "jlui_app/ui_sys_param.h"
|
|
|
|
#define LOG_TAG_CONST APP_CHARGE
|
|
#define LOG_TAG "[APP_CHARGE]"
|
|
#define LOG_ERROR_ENABLE
|
|
#define LOG_DEBUG_ENABLE
|
|
#define LOG_INFO_ENABLE
|
|
/* #define LOG_DUMP_ENABLE */
|
|
#define LOG_CLI_ENABLE
|
|
#include "debug.h"
|
|
|
|
#if TCFG_CHARGE_ENABLE
|
|
|
|
static u8 charge_full_flag = 0;
|
|
|
|
#if TCFG_RECHARGE_ENABLE
|
|
static int recharge_timer = 0;
|
|
|
|
static void recharge_check(void *priv)
|
|
{
|
|
if ((adc_get_voltage(AD_CH_PMU_VBAT) * AD_CH_PMU_VBAT_DIV) < TCFG_RECHARGE_VOLTAGE) {
|
|
sys_timer_del(recharge_timer);
|
|
recharge_timer = 0;
|
|
charge_start();
|
|
}
|
|
}
|
|
|
|
static void recharge_detect_start(void)
|
|
{
|
|
if (recharge_timer == 0) {
|
|
recharge_timer = sys_timer_add(NULL, recharge_check, 10000);
|
|
}
|
|
}
|
|
|
|
static void recharge_detect_close(void)
|
|
{
|
|
if (recharge_timer) {
|
|
sys_timer_del(recharge_timer);
|
|
recharge_timer = 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
u8 get_charge_full_flag(void)
|
|
{
|
|
return charge_full_flag;
|
|
}
|
|
|
|
static void charge_start_deal(void)
|
|
{
|
|
log_info("%s\n", __FUNCTION__);
|
|
|
|
power_set_mode(PWR_LDO15);
|
|
|
|
batmgr_send_msg(BAT_MSG_CHARGE_START, 0);
|
|
}
|
|
|
|
static void charge_full_deal(void)
|
|
{
|
|
const struct app_charge_handler *handler;
|
|
|
|
log_info("%s\n", __func__);
|
|
|
|
charge_full_flag = 1;
|
|
charge_close();
|
|
|
|
#if TCFG_RECHARGE_ENABLE
|
|
recharge_detect_start();
|
|
#endif
|
|
for_each_app_charge_handler(handler) {
|
|
handler->handler(CHARGE_EVENT_CHARGE_FULL, 0);
|
|
}
|
|
|
|
if (get_charge_poweron_en() == 0) {
|
|
/* power_set_soft_poweroff(); */
|
|
#if (!TCFG_CHARGESTORE_ENABLE)
|
|
vbat_timer_delete();
|
|
#endif
|
|
} else {
|
|
batmgr_send_msg(BAT_MSG_CHARGE_FULL, 0);
|
|
}
|
|
}
|
|
|
|
static void charge_close_deal(void)
|
|
{
|
|
log_info("%s\n", __FUNCTION__);
|
|
|
|
/* power_set_mode(TCFG_LOWPOWER_POWER_SEL); */
|
|
|
|
batmgr_send_msg(BAT_MSG_CHARGE_CLOSE, 0);
|
|
}
|
|
|
|
|
|
void app_charge_power_off_keep_mode()
|
|
{
|
|
//兼容一些充电仓5v输出慢的时候会导致无法充电的问题
|
|
if (get_lvcmp_det()) {
|
|
log_info("...charge ing...\n");
|
|
cpu_reset();
|
|
}
|
|
|
|
log_info("get_charge_online_flag:%d %d\n", get_charge_online_flag(), get_ldo5v_online_hw());
|
|
if (get_ldo5v_online_hw() && get_charge_online_flag()) {
|
|
power_set_soft_poweroff();
|
|
} else {
|
|
charge_check_and_set_pinr(1);
|
|
#if TCFG_CHARGE_OFF_POWERON_EN
|
|
cpu_reset();
|
|
#else
|
|
power_set_soft_poweroff();
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static void ldo5v_keep_softoff(void)
|
|
{
|
|
log_info("%s\n", __func__);
|
|
|
|
if (!app_in_mode(APP_MODE_IDLE)) {
|
|
sys_enter_soft_poweroff(POWEROFF_POWER_KEEP);
|
|
} else {
|
|
app_charge_power_off_keep_mode();
|
|
}
|
|
}
|
|
|
|
/*ldoin电压大于拔出电压(0.6V左右)且小于VBat电压时调用该函数进行一些错误提示或其他处理*/
|
|
void ldo5v_keep_deal(void)
|
|
{
|
|
int abandon = 0;
|
|
const struct app_charge_handler *handler;
|
|
|
|
log_info("%s\n", __func__);
|
|
#if TCFG_RECHARGE_ENABLE
|
|
recharge_detect_close();
|
|
#endif
|
|
|
|
|
|
//插入交换
|
|
batmgr_send_msg(POWER_EVENT_POWER_CHANGE, 0);
|
|
|
|
charge_check_and_set_pinr(0);
|
|
|
|
for_each_app_charge_handler(handler) {
|
|
abandon += handler->handler(CHARGE_EVENT_LDO5V_KEEP, 0);
|
|
}
|
|
|
|
#if defined(TCFG_CHARGE_KEEP_UPDATA) && TCFG_CHARGE_KEEP_UPDATA
|
|
//升级过程中,不执行关机操作
|
|
if (dual_bank_update_exist_flag_get() || classic_update_task_exist_flag_get()) {
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if (get_charge_poweron_en() == 0) {
|
|
if (abandon == 0) {
|
|
ldo5v_keep_softoff();
|
|
}
|
|
} else {
|
|
batmgr_send_msg(BAT_MSG_CHARGE_ERR, 0);
|
|
}
|
|
}
|
|
|
|
void charge_ldo5v_in_deal(void)
|
|
{
|
|
int abandon = 0;
|
|
const struct app_charge_handler *handler;
|
|
|
|
log_info("%s\n", __FUNCTION__);
|
|
#if TCFG_RECHARGE_ENABLE
|
|
recharge_detect_close();
|
|
#endif
|
|
|
|
//插入交换
|
|
batmgr_send_msg(POWER_EVENT_POWER_CHANGE, 0);
|
|
|
|
charge_full_flag = 0;
|
|
|
|
charge_check_and_set_pinr(0);
|
|
|
|
for_each_app_charge_handler(handler) {
|
|
abandon += handler->handler(CHARGE_EVENT_LDO5V_IN, 0);
|
|
}
|
|
|
|
#if defined(TCFG_CHARGE_KEEP_UPDATA) && TCFG_CHARGE_KEEP_UPDATA
|
|
//升级过程中,不执行充电插入关机流程
|
|
if (dual_bank_update_exist_flag_get() || classic_update_task_exist_flag_get()) {
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if (get_charge_poweron_en() == 0) {
|
|
if (!app_in_mode(APP_MODE_IDLE)) {
|
|
if (abandon == 0) {
|
|
sys_enter_soft_poweroff(POWEROFF_RESET);
|
|
}
|
|
} else {
|
|
charge_start();
|
|
wdt_init(WDT_32S);
|
|
log_info("set wdt to 32s!\n");
|
|
goto _check_reset;
|
|
}
|
|
} else {
|
|
charge_start();
|
|
goto _check_reset;
|
|
}
|
|
return;
|
|
|
|
_check_reset:
|
|
//防止耳机低电时,插拔充电有几率出现关机不充电问题
|
|
if (app_var.goto_poweroff_flag) {
|
|
cpu_reset();
|
|
}
|
|
}
|
|
|
|
void charge_ldo5v_off_deal(void)
|
|
{
|
|
int abandon = 0;
|
|
int off_type = LDO5V_OFF_TYPE_NORMAL_ON;
|
|
bool lowpower_flag = FALSE, is_bt_mode, is_idle_mode;
|
|
const struct app_charge_handler *handler;
|
|
|
|
log_info("%s\n", __FUNCTION__);
|
|
|
|
//拨出交换
|
|
batmgr_send_msg(POWER_EVENT_POWER_CHANGE, 0);
|
|
|
|
charge_full_flag = 0;
|
|
|
|
charge_close();
|
|
power_set_mode(TCFG_LOWPOWER_POWER_SEL);
|
|
|
|
#if TCFG_RECHARGE_ENABLE
|
|
recharge_detect_close();
|
|
#endif
|
|
batmgr_send_msg(BAT_MSG_CHARGE_LDO5V_OFF, 0);
|
|
|
|
charge_check_and_set_pinr(1);
|
|
|
|
#if TCFG_SYS_LVD_EN
|
|
lowpower_flag = get_vbat_need_shutdown();
|
|
#endif
|
|
is_bt_mode = app_in_mode(APP_MODE_BT);
|
|
is_idle_mode = app_in_mode(APP_MODE_IDLE);
|
|
|
|
if ((get_charge_poweron_en() == 0)) {
|
|
wdt_init(WDT_4S);
|
|
log_info("set wdt to 4s!\n");
|
|
#if TCFG_CHARGE_OFF_POWERON_EN
|
|
log_info("ldo5v off,task switch to BT\n");
|
|
if (app_var.goto_poweroff_flag == 0) {
|
|
if (!is_bt_mode) {
|
|
if (lowpower_flag == FALSE) {
|
|
off_type = LDO5V_OFF_TYPE_NORMAL_ON;//正常拔出开机
|
|
} else {
|
|
log_info("ldo5v off,lowpower,need enter softpoweroff\n");
|
|
off_type = LDO5V_OFF_TYPE_LOWPOWER_OFF;//拔出低电关机
|
|
}
|
|
}
|
|
}
|
|
#else //TCFG_CHARGE_OFF_POWERON_EN
|
|
log_info("ldo5v off,enter softpoweroff\n");
|
|
off_type = LDO5V_OFF_TYPE_NORMAL_OFF;//正常拔出关机
|
|
#endif
|
|
} else {
|
|
if (is_idle_mode && (app_var.goto_poweroff_flag == 0)) {
|
|
#if TCFG_CHARGE_OFF_POWERON_EN
|
|
log_info("ldo5v off,task switch to BT\n");
|
|
if (lowpower_flag == FALSE) {
|
|
off_type = LDO5V_OFF_TYPE_NORMAL_ON;//正常拔出开机
|
|
} else {
|
|
log_info("ldo5v off,lowpower,need enter softpoweroff\n");
|
|
off_type = LDO5V_OFF_TYPE_LOWPOWER_OFF;//拔出低电关机
|
|
}
|
|
#else
|
|
off_type = LDO5V_OFF_TYPE_NORMAL_OFF;//正常拔出关机
|
|
#endif
|
|
}
|
|
}
|
|
|
|
for_each_app_charge_handler(handler) {
|
|
abandon += handler->handler(CHARGE_EVENT_LDO5V_OFF, off_type);
|
|
}
|
|
|
|
if (abandon) {
|
|
return;
|
|
}
|
|
|
|
switch (off_type) {
|
|
case LDO5V_OFF_TYPE_NORMAL_OFF:
|
|
case LDO5V_OFF_TYPE_LOWPOWER_OFF:
|
|
power_set_soft_poweroff();
|
|
break;
|
|
case LDO5V_OFF_TYPE_CHARGESTORE_OFF:
|
|
if (is_bt_mode) {
|
|
sys_enter_soft_poweroff(POWEROFF_NORMAL);
|
|
} else {
|
|
power_set_soft_poweroff();
|
|
}
|
|
break;
|
|
case LDO5V_OFF_TYPE_NORMAL_ON:
|
|
#if 1//idle充电,需要拔出开机先power_on
|
|
if (app_in_mode(APP_MODE_IDLE)) {
|
|
app_var.play_poweron_tone = 1;
|
|
app_send_message(APP_MSG_GOTO_MODE, APP_MODE_POWERON);
|
|
}
|
|
#else
|
|
app_var.play_poweron_tone = 0;
|
|
app_send_message(APP_MSG_GOTO_MODE, APP_MODE_BT);
|
|
#endif//直接开机
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int app_charge_event_handler(int *msg)
|
|
{
|
|
int ret = false;
|
|
u8 otg_status = 0;
|
|
|
|
switch (msg[0]) {
|
|
case CHARGE_EVENT_CHARGE_START:
|
|
#if TCFG_UI_ENABLE
|
|
if (get_ui_sys_param(bed_light)) {//床头时钟
|
|
/* UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BEDSIDE_WATCH); */
|
|
/* UI_WINDOW_PREEMPTION_POSH(ID_WINDOW_BEDSIDE_WATCH, NULL, NULL, UI_WINDOW_PREEMPTION_TYPE_CHARGE); */
|
|
UI_HIDE_CURR_WINDOW();
|
|
UI_SHOW_WINDOW(ID_WINDOW_BEDSIDE_WATCH);
|
|
} else {
|
|
#if 0
|
|
UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BATCHARGE);
|
|
UI_WINDOW_PREEMPTION_POSH(ID_WINDOW_BATCHARGE, NULL, NULL, UI_WINDOW_PREEMPTION_TYPE_CHARGE);
|
|
#else
|
|
UI_HIDE_CURR_WINDOW();
|
|
UI_SHOW_WINDOW(ID_WINDOW_BATCHARGE);
|
|
#endif
|
|
}
|
|
#endif
|
|
charge_start_deal();
|
|
break;
|
|
case CHARGE_EVENT_CHARGE_CLOSE:
|
|
charge_close_deal();
|
|
|
|
#if TCFG_UI_ENABLE
|
|
if (get_ui_sys_param(bed_light)) {
|
|
/* UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BEDSIDE_WATCH); */
|
|
} else {
|
|
/*充满后退出充电页面*/
|
|
#if 0
|
|
UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BATCHARGE);
|
|
//退出页面后,如果没有记录页面,则回表盘
|
|
if (!ui_return_page_id()) {
|
|
UI_SHOW_WINDOW(ID_WINDOW_DIAL);
|
|
}
|
|
#else
|
|
//拔出的时候再显示一次电量页面
|
|
UI_HIDE_CURR_WINDOW();
|
|
UI_SHOW_WINDOW(ID_WINDOW_BATCHARGE);
|
|
#endif
|
|
}
|
|
#endif
|
|
break;
|
|
case CHARGE_EVENT_CHARGE_FULL:
|
|
charge_full_deal();
|
|
break;
|
|
case CHARGE_EVENT_LDO5V_KEEP:
|
|
ldo5v_keep_deal();
|
|
break;
|
|
case CHARGE_EVENT_LDO5V_IN:
|
|
#if ((TCFG_OTG_MODE & OTG_SLAVE_MODE) && (TCFG_OTG_MODE & OTG_CHARGE_MODE))
|
|
while (1) {
|
|
otg_status = usb_otg_online(0);
|
|
if (otg_status != IDLE_MODE) {
|
|
break;
|
|
}
|
|
os_time_dly(2);
|
|
}
|
|
if (otg_status == SLAVE_MODE) {
|
|
set_charge_poweron_en(1);
|
|
}
|
|
#endif
|
|
|
|
if (get_charge_poweron_en() || (otg_status != SLAVE_MODE)) {
|
|
charge_ldo5v_in_deal();
|
|
}
|
|
break;
|
|
case CHARGE_EVENT_LDO5V_OFF:
|
|
#if TCFG_UI_ENABLE
|
|
if (get_ui_sys_param(bed_light)) {
|
|
/*拔出时退出床头时钟*/
|
|
#if 0
|
|
UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BEDSIDE_WATCH);
|
|
#else
|
|
if (ui_get_current_window_id() == ID_WINDOW_BEDSIDE_WATCH) {
|
|
int page_ret = UI_WINDOW_BACK_SHOW(0);
|
|
if (page_ret == 2) {
|
|
UI_SHOW_WINDOW(ID_WINDOW_DIAL);
|
|
}
|
|
}
|
|
#endif
|
|
} else {
|
|
/* UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BATCHARGE); */
|
|
}
|
|
#endif
|
|
#if ((TCFG_OTG_MODE & OTG_SLAVE_MODE) && (TCFG_OTG_MODE & OTG_CHARGE_MODE))
|
|
while (1) {
|
|
otg_status = usb_otg_online(0);
|
|
if (otg_status != IDLE_MODE) {
|
|
break;
|
|
}
|
|
os_time_dly(2);
|
|
}
|
|
#endif
|
|
if (get_charge_poweron_en() || (otg_status != SLAVE_MODE)) {
|
|
charge_ldo5v_off_deal();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
APP_MSG_HANDLER(bat_charge_msg_entry) = {
|
|
.owner = 0xff,
|
|
.from = MSG_FROM_BATTERY,
|
|
.handler = app_charge_event_handler,
|
|
};
|
|
|
|
#else
|
|
|
|
u8 get_charge_full_flag(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|