mcu_ab568x/app/platform/bsp/bsp_charge.c
2025-05-30 18:03:10 +08:00

278 lines
8.1 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.

#include "include.h"
#include "app_variable.h"
#if CHARGE_EN
#define TRACE_EN 0
#if TRACE_EN
#define TRACE(...) printf(__VA_ARGS__)
#else
#define TRACE(...)
#endif
#define DC_IN() ((RTCCON >> 20) & 0x01) //VUSB Online state: 0->not online, 1->online
static charge_cfg_t charge_cfg;
#if TRACE_EN
AT(.com_rodata.tkey)
const char charge_on_str[] = "Charge on: %d\n";
AT(.com_rodata.tkey)
const char charge_off_str[] = "Charge off: %d %d\n";
#endif
static void charge_timer_callback (co_timer_t *timer, void *param);
AT(.text.charge_com.sta)
void bsp_charge_sta(u8 sta)
{
TRACE(charge_on_str,sta);
if (sta == 1) {
//充电开启
sys_cb.charge_sta = 1;
sys_cb.charge_bled_flag = 0;
SysVariable.flagField.poweronCharge = true;
func_switch_to_assign_screen(FUNC_CHARGE, false);
if (sys_cb.gui_sleep_sta) {
sys_cb.wkp_flag = true;
}
} else if (sta == 2)
{
}
else {
//充电关闭
TRACE(charge_off_str, sta ,sys_cb.charge_sta);
if (sys_cb.vbat <= (LPWR_OFF_VBAT - 50)) { // 电压小于3.5v不开机, 给自动关机留出空间
if (func_cb.sta != FUN_POWER_OFF_LOGO) {
/* 电压过低强制进入关机流程 */
if (sys_cb.gui_sleep_sta) {
sys_cb.wkp_flag = true;
}
func_switch_to_assign_screen(FUN_POWER_OFF_LOGO, true);
}
// power_on_check();
}
else
{
if (sys_cb.charge_sta == 1 || sys_cb.charge_sta == 2)
{
sys_cb.charge_sta = 0;
if (sys_cb.gui_sleep_sta) {
sys_cb.wkp_flag = true;
}
//返回充电界面的上一级界面
if (func_cb.sta == FUNC_CHARGE) {
func_directly_back_to();
}
// func_cb.sta = FUNC_CLOCK;
}
else
{
sys_cb.charge_sta = 0;
}
sys_cb.charge_bled_flag = 0;
}
}
}
void bsp_charge_off(void)
{
if (charge_cfg.chag_sta > CHAG_STA_OFF) {
charge_stop(0);
}
}
AT(.text.charge_com.det)
u8 charge_dc_detect(void)
{
if (!xcfg_cb.charge_en) {
return 0;
}
return (RTCCON >> 20) & 0x01;
}
void bsp_charge_set_stop_time(u16 stop_time)
{
charge_cfg.stop_time = stop_time;
}
/**
* 充电初始化
*/
void bsp_charge_init(void)
{
charge_cfg_t *p = &charge_cfg;
static co_timer_t charge_timeer;
memset(p, 0, sizeof(charge_cfg_t));
if (xcfg_cb.charge_en) {
p->trick_curr_en = CHARGE_TRICK_EN;
p->dcin_reset = CHARGE_DC_RESET;
p->buck_mode_en = BUCK_MODE_EN*xcfg_cb.buck_mode_en;
p->trick_stop_volt = CHARGE_TRICK_STOP_VOLT;
p->stop_volt = CHARGE_STOP_VOLT;
p->follow_volt = CHARGE_VOLT_FOLLOW;
p->const_curr = CHARGE_CONSTANT_CURR;
p->trick_curr = CHARGE_TRICKLE_CURR;
p->stop_curr = CHARGE_STOP_CURR;
p->stop_curr_thd = 80;
p->bled_on_pr = 0;
p->detect_cnt = 5;
p->stop_time = 36000; //默认30分钟
RTCCON3 &= ~BIT(12); //RTCCON3[12], INBOX Wakeup disable
RTCCON7 &= ~BIT(6); //PWRUPICH = 20mA
RTCCON8 |= BIT(4); //inbox voltage selection. 1'b1, 1.7v; 1'b0, 1.1v
RTCCON7 = (RTCCON7 & (~(0x03<<15))) | (0x01<<15);
RTCCON11 |= BIT(5);
RTCCON5 |= BIT(7);
RTCCON11 &= ~BIT(6);
sys_cb.chg_on = 1;
charge_init(p);
}
co_timer_set(&charge_timeer, 5000, TIMER_REPEAT, LEVEL_LOW_PRI, charge_timer_callback, NULL);
co_timer_set_sleep(&charge_timeer, true);
}
/**
* 充电开关,原子操作
*/
AT(.com_text.detect)
void charge_ctrl(bool onoff)
{
GLOBAL_INT_DISABLE();
RTCCON8 = onoff ? (RTCCON8 & ~BIT(1)) : (RTCCON8 | BIT(1));
sys_cb.chg_on = onoff;
GLOBAL_INT_RESTORE();
}
/**
* 充电保护管理续充NTC保护 5s执行一次
*/
static void charge_timer_callback (co_timer_t *timer, void *param)
{
static charge_sta_m charge_full_flag = CHARGE_NO_FULL;
static uint16_t refill_count = 0;
static uint16_t refill_curr_cnt = 0;
#if CHARGE_USER_NTC_EN && TS_MODE_EN
static uint16_t charge_ntc_stop_flag = 0;
#endif
static u8 recon_cout = 0;
if(sys_cb.reconnect_flag){
recon_cout++;
if(recon_cout >= 2){
sys_cb.reconnect_flag = false;
}
}else{
recon_cout = 0;
}
#if TS_MODE_EN
adc_cb.ntc_temp = ts_adc2ntc(adc_cb.vts);
TRACE("[0x%x] DC_IN:%d charge_sta:%d VBAT:%d VBAT2:%d VTS:%d NTC:%d\n",RTCCON8, CHARGE_DC_IN(), sys_cb.charge_sta, adc_cb.vbat_val, adc_cb.vbat2, adc_cb.vts, adc_cb.ntc_temp);
#endif // TS_MODE_EN
switch(sys_cb.charge_sta){
case 0: //移开5v
charge_full_flag = CHARGE_NO_FULL;
#if CHARGE_USER_NTC_EN && TS_MODE_EN
charge_ntc_stop_flag = 0;
#endif
charge_ctrl(1);
break;
case 1: //充电中
//NTC
#if CHARGE_USER_NTC_EN && TS_MODE_EN
if((charge_ntc_stop_flag== 0) && ((adc_cb.ntc_temp > CHARGE_NTC_ADC_MAX_TEMP) || (adc_cb.ntc_temp < CHARGE_NTC_ADC_MIN_TEMP))){
//温度异常 停止充
TRACE("NTC STOP CHARGE:%d\n", adc_cb.ntc_temp);
charge_ntc_stop_flag = 1;
charge_ctrl(0);
}
if((charge_ntc_stop_flag== 1) && (adc_cb.ntc_temp < CHARGE_NTC_ADC_MAX_RE_TEMP) && (adc_cb.ntc_temp > CHARGE_NTC_ADC_MIN_RE_TEMP)){
//温度恢复 继续充
TRACE("NTC Continue CHARGE:%d\n", adc_cb.ntc_temp);
charge_ntc_stop_flag = 0;
charge_ctrl(1);
}
#endif
if((sys_cb.vbat >= CHARGE_VBAT_REFILL) && (bsp_vbat_percent_get() >= 100)){
TRACE("full:%d\n", sys_cb.vbat);
if (sys_cb.gui_sleep_sta) {
sys_cb.wkp_flag = true;
}
sys_cb.charge_sta = 2;
}
break;
case 2: //充电满
// #if CHARGE_USER_NTC_EN && TS_MODE_EN
// charge_ntc_stop_flag = 0;
// #endif
// if(charge_full_flag == CHARGE_NO_FULL){
// charge_full_flag = CHARGE_FULL;
// //停止充
// charge_ctrl(0);
// }else if(charge_full_flag == CHARGE_FULL){ //充满状态,检测电池是否放电到续充
// if(sys_cb.vbat < CHARGE_VBAT_REFILL){
// TRACE("start refill:%d\n", sys_cb.vbat);
// charge_full_flag = CHARGE_REFILL;
// refill_count = 0;
// refill_curr_cnt = 0;
// charge_ctrl(1);
// }
// }else if(charge_full_flag == CHARGE_REFILL){ //续充判断是否充满
// refill_count++;
// if (PWRCON1 & BIT(30)) { //I
// refill_curr_cnt++;
// }else{
// if (refill_count % 20 == 0) {//每100s一个计数周期
// refill_curr_cnt = 0;
// }
// }
// if((refill_count > 240) || (refill_curr_cnt > 10)){// 限制最多充20分钟 电流满足10s
// TRACE("stop refill:%d %d\n", refill_count, refill_curr_cnt);
// charge_full_flag = CHARGE_FULL;
// //停止充
// charge_ctrl(0);
// }
// }
break;
}
}
void charge_set_detect_cnt(u8 value)
{
charge_cfg.detect_cnt = value;
}
/**
* 充电状态函数
* 返回充电状态
* 0 : 5V没接上
1 : 充电中
2 :充满
*/
u8 bsp_charge_sta_get(void)
{
return sys_cb.charge_sta;
}
#endif // CHARGE_EN