SY8837_Demo_For_OurSelf/UsrSrc/charger/charger_module.c

622 lines
13 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.

/*
******************************************************************************
*
* @file charger_module.c
* @brief charger module
* @ic sy8835
*
* @version 1.0
* @date 2024/11/01 17:35:40
* @author Alex Xu
*
* Copyright (c) 2013-2099,Tkplusemi Technology Co.,Ltd.
* All Rights Reserved
*
* History:
* Revision Date Author Desc
* 1.0.0 2024/11/01 Alex build this file
******************************************************************************
*/
/*_____ I N C L U D E S ____________________________________________________*/
#include "charger_module.h"
#include "adc.h"
#include "sys_tim.h"
#include "discharge_module.h"
#include "system.h"
#include "vox_module.h"
#include "led.h"
#include "userapp.h"
#include "bat.h"
bit Charger_Done = 0;
#ifdef NTC_ENABLE
bit NTC_Pro_Flag = 0;
#endif
idata TE_CHG_STA ChgStatus; // CHG状态定义
#if CHARGER_ENABLE
/******************************************************************************\
Macro definitions
\******************************************************************************/
#define NTC_PRO_DEBOUNCE_TIM 10
/******************************************************************************\
Variables definitions
\******************************************************************************/
idata uint8_t gConstant_Cur_Max_Setting = CHG_ICC_2_00MA; //Charge最大充电电流。
idata s_gCharger_Cfg gCharge_Cfg;
/******************************************************************************\
Functions definitions
\******************************************************************************/
/*
*******************************************************************************
* void Charger_init(void)
*
* Description : Charger Initialization
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void Charger_Init(void)
{
#ifdef SY8838Q //合封OVP芯片SY8838Q
SFRADDR = PMU_CTL7; //合封芯片关闭VBUS OV检测使能
SFRDATA &= ~0x20;
SFRADDR = REG_CHG0;
SFRDATA |= 0x04; //合封关VDPM环
#endif
gCharge_Cfg.nTrickle_Cur = CHG_ITC_20MA;
gCharge_Cfg.nIterm_Cur = CHG_ITERM_20MA;
gCharge_Cfg.nConstant_Cur = gConstant_Cur_Max_Setting;
gCharge_Cfg.nVFloat = CHG_VFLOAT_4_200V;
REG_CHG1 = gCharge_Cfg.nTrickle_Cur | gCharge_Cfg.nIterm_Cur | gCharge_Cfg.nConstant_Cur ; //设置Charger的涓流充电电流、截止充电电流、恒流CC。
REG_CHG2 = gCharge_Cfg.nVFloat;
}
#ifdef NTC_ENABLE
/*
*******************************************************************************
* uint8_t Charger_NTC_Control(uint8_t Charge_sta)
*
* Description : Charger NTC Control
* NTC 支持 103 和 104 电阻NTC 温度检测由软件通过 ADC 采集 NTC 引脚电压。
* 如果支持电量计温度检测线性化,支持电量计方案 103 的 NTC 需要并一个 8.2k
* 电阻20uA 电流103 NTC 需要串联 10k 电阻104 的 NTC 并联 82k 电阻。
* 在使能充电前软件先检测NTC 温度,如果 NTC 浮空,屏蔽 NTC 功能,
* 并锁定;如果 NTC 下拉到 0V关闭充电和放电。NTC 保护后,软件关闭充电,
* 温度恢复正常并持续 250ms再继续充电。
*
* Arguments : NTC_Protect_Type_e NTC_Type:Shield 、JEITA or IEC;Charge_sta:Charge or not
* Returns :NTC_Flag (0:Shield; 1:JEITA; 2:IEC)
* Notes : NONE
*
*******************************************************************************
*/
uint8_t PMU_NTC_Handle(uint8_t Charge_sta)
{
uint16_t NTC_Adc = 0;
uint8_t NTC_Flag = FALSE;
bit NTC_Change_CV_Chg_Flag;
static bit DisChg_NTC_Low_Pro_Flag;
static bit DisChg_NTC_High_Pro_Flag;
static bit CHG_NTC_Low_Pro_Flag;
static bit CHG_NTC_High_Pro_Flag;
static bit NTC_250mA_Chg_Flag;
static bit NTC_500mA_Chg_Flag;
#if ADC_ENABLE
NTC_Adc = g_Vntc_Adc;
#endif
if( NTC_Adc >= NONE_NTC ) ////屏蔽NTC功能NTC浮空屏蔽 NTC 功能,并锁定。
{
return FALSE;
}
#if NTC_JEITA
if( Charge_sta ) //VBUS plugin status 充电模式
{
if( ( NTC_Adc <= T_0C ) && ( NTC_Adc > T_60C ) )
{
if( NTC_Adc > T_10C ) //0.5*ICC充电
{
NTC_250mA_Chg_Flag = 1;
gCharge_Cfg.nConstant_Cur = gConstant_Cur_Max_Setting / 2;
if( NTC_500mA_Chg_Flag )
{
if( NTC_Adc > T_8C )
{
NTC_500mA_Chg_Flag = 0;
//gCharge_Cur.nConstant_Cur = gConstant_Cur_Max_Setting / 2;
}
else
{
gCharge_Cfg.nConstant_Cur = gConstant_Cur_Max_Setting;
}
}
NTC_Flag = FALSE;
}
else
if( NTC_Adc <= T_10C && NTC_Adc > T_45C ) //1*ICC充电
{
NTC_500mA_Chg_Flag = 1;
gCharge_Cfg.nConstant_Cur = gConstant_Cur_Max_Setting;
if( NTC_250mA_Chg_Flag )
{
if( NTC_Adc <= T_12C )
{
NTC_250mA_Chg_Flag = 0;
// gCharge_Cur.nConstant_Cur = gConstant_Cur_Max_Setting;
}
else
{
gCharge_Cfg.nConstant_Cur = gConstant_Cur_Max_Setting / 2;
}
}
gCharge_Cfg.nVFloat = CHG_VFLOAT_4_200V;
if( NTC_Change_CV_Chg_Flag )
{
if( NTC_Adc <= T_42C )
{
NTC_Change_CV_Chg_Flag = 0;
// gCharge_Cur.nVFloat = CHG_VFLOAT_4_200V;
}
else
{
gCharge_Cfg.nVFloat = CHG_VFLOAT_4_000V;
}
}
NTC_Flag = FALSE;
}
else
if( NTC_Adc <= T_45C ) //浮充电压4.05V
{
NTC_Change_CV_Chg_Flag = 1;
gCharge_Cfg.nVFloat = CHG_VFLOAT_4_000V;
if( NTC_500mA_Chg_Flag )
{
if(NTC_Adc <= T_47C)
{
NTC_500mA_Chg_Flag = 0;
// gCharge_Cur.nVFloat = CHG_VFLOAT_4_050V;
}
else
{
gCharge_Cfg.nVFloat = CHG_VFLOAT_4_200V;
}
}
NTC_Flag = FALSE;
}
if( CHG_NTC_Low_Pro_Flag )
{
if( NTC_Adc < T_3C)
{
CHG_NTC_Low_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
if( CHG_NTC_High_Pro_Flag )
{
if( NTC_Adc > T_57C )
{
CHG_NTC_High_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
}
else
{
if( NTC_Adc > T_0C ) //不充电
{
CHG_NTC_Low_Pro_Flag = 1;
#ifdef _DEBUG_CHARGER
printf("NTC Low Pro!NTC_Adc:%d,(line:%d)\r\n",(uint16)NTC_Adc,(uint16)__LINE__);
#endif
NTC_Flag = TRUE;
}
else
if( NTC_Adc <= T_60C ) //不充电
{
CHG_NTC_High_Pro_Flag = 1;
NTC_Flag = TRUE;
#ifdef _DEBUG_CHARGER
printf("NTC High Pro!NTC_Adc:%d,(line:%d)\r\n",(uint16)NTC_Adc,(uint16)__LINE__);
#endif
}
}
DisChg_NTC_Low_Pro_Flag = 0;
DisChg_NTC_High_Pro_Flag = 0;
}
else //放电模式
{
CHG_NTC_Low_Pro_Flag = 0;
CHG_NTC_High_Pro_Flag = 0;
if( NTC_Adc <= T_N20C && NTC_Adc > T_80C ) //正常放电
{
if( DisChg_NTC_Low_Pro_Flag )
{
if( NTC_Adc < T_N15C )
{
DisChg_NTC_Low_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
if( DisChg_NTC_High_Pro_Flag )
{
if( NTC_Adc > T_75C )
{
DisChg_NTC_High_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
}
else //异常不放电
{
if( NTC_Adc > T_N20C )
{
DisChg_NTC_Low_Pro_Flag = 1;
}
else
if( NTC_Adc < T_80C )
{
DisChg_NTC_High_Pro_Flag = 1;
}
NTC_Flag = TRUE;
}
}
#elif NTC_IEC
if(Charge_sta) //VBUS plugin status 充电模式
{
if(NTC_Adc <= T_0C && NTC_Adc > T_45C) //正常充电
{
if(CHG_NTC_Low_Pro_Flag)
{
if( NTC_Adc < T_3C )
{
CHG_NTC_Low_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
if(CHG_NTC_High_Pro_Flag)
{
if( NTC_Adc > T_42C )
{
CHG_NTC_High_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
}
else //异常不充电
{
if(NTC_Adc > T_0C)
{
CHG_NTC_Low_Pro_Flag = 1;
}
else
if(NTC_Adc <= T_45C)
{
CHG_NTC_High_Pro_Flag = 1;
}
#ifdef _DEBUG_CHARGER
printf("NTC Pro!NTC_Adc:%d,CHG_CTL:0x%x,(line:%d)\r\n",(uint16)NTC_Adc,(uint16)CHG_CTL,(uint16)__LINE__);
#endif
NTC_Flag = TRUE;
}
DisChg_NTC_Low_Pro_Flag = 0;
DisChg_NTC_High_Pro_Flag = 0;
}
else //放电模式
{
CHG_NTC_Low_Pro_Flag = 0;
CHG_NTC_High_Pro_Flag = 0;
if( (NTC_Adc <= T_N20C) && (NTC_Adc > T_80C) ) //正常放电
{
if( DisChg_NTC_Low_Pro_Flag )
{
if( NTC_Adc < T_N15C )
{
DisChg_NTC_Low_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
if(DisChg_NTC_High_Pro_Flag)
{
if( NTC_Adc > T_75C )
{
DisChg_NTC_High_Pro_Flag = 0;
NTC_Flag = FALSE;
}
else
{
NTC_Flag = TRUE;
}
}
}
else //异常不放电
{
if(NTC_Adc > T_N20C)
{
DisChg_NTC_Low_Pro_Flag = 1;
}
else
if(NTC_Adc <= T_80C)
{
DisChg_NTC_High_Pro_Flag = 1;
}
NTC_Flag = TRUE;
}
}
#endif
return NTC_Flag;
}
#endif
/*
*******************************************************************************
* void Charger_Handler(void)
*
* Description : Charger Handle. ---- 充电过程除了根据 NTC 动态调节充电电流和截止电压外,其他由硬件控制。充电过程
发生异常,硬件进行相应处理,并发送标志位,软件可以进行相应处理。
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
/*
1、充电超时充电超时后软件关闭充电使能等待VIN拔出。
2、输入UVLO保护软件无需处理充电启动条件看PG。
3、VIN DPM软件无需处理
4、输入过压保护软件无需处理
5、电池过压保护软件无需处理
6、电池短路保护软件无需处理
7、NTC保护按JEITA或IEC标准调整充电参数
8、过温保护软件无需处理
软件只需处理VIN是否PG、NTC保护、充电完成和复充其它保护均由硬件自动关闭Charger保护恢复后软件会重新启动Charger
各个保护软件可以读取对应的标志位或状态位软件只需处理充电超时充电超时后软件关闭充电使能等待VIN拔出。
*/
void Charger_Handler(void)
{
if( !(CHIP_STA4 & 0x80) ) //未检测到Power good,则关闭Charger使能后返回。
{
CHG_CTL &= ~CHG_EN; //Disable Charger
ChgStatus = CHG_NONE;
Charger_Done = 0;
#ifdef _DEBUG_CHARGER
printf("No Chg\r\n");
#endif
return;
}
/*Charger Vbus Over Voltage.*/
if ( IRQ_FLAG0 & VBUS_OverVol )
{
IRQ_FLAG0 = VBUS_OverVol;
CHG_CTL &= ~CHG_EN; //Disable Charger
ChgStatus = CHG_PROTECT;
return;
}
/* 过温保护 --- 硬件实现 */
if( CHIP_STA3 & 0x02 )
{
CHG_CTL &= ~CHG_EN; //Disable Charger
ChgStatus = CHG_PROTECT;
return;
}
/* 电池过压保护。 */
if( IRQ_FLAG9 & BAT_OverVol ) //电池过压保护
{
IRQ_FLAG9 = BAT_OverVol;
CHG_CTL &= ~CHG_EN; //Disable Charger
return;
}
/*各项保护都无需软件处理只处理充电超时超时后需要等VBUS重新插拔后才重新开始Charger流程。*/
if ( IRQ_FLAG9 & ( CHG_FastChgTmr | CHG_TricleChgTmr ) ) //充电超时,Tricle charg and Fast charge timeout
{
CHG_CTL &= ~CHG_EN; //Disable Charger
if ( IRQ_FLAG10 & ( VBUS_PLUG_OUT | VBUS_PLUG_IN ) ) //Plugin\Plugout interrupt
{
IRQ_FLAG9 = CHG_FastChgTmr | CHG_TricleChgTmr;
IRQ_FLAG10 = VBUS_PLUG_OUT | VBUS_PLUG_IN; //Clear Plugin\Plugout interrupt
}
return;
}
else /*充电未超时存在Plug则清Plugin\Plugout int*/
{
IRQ_FLAG10 = VBUS_PLUG_OUT | VBUS_PLUG_IN; //Clear Plugin\Plugout interrupt
}
#ifdef NTC_ENABLE
/*NTC Handle*/ //使能Charger前先检测NTC温度异常就不开充电。(CHIP_STA4 & 0x80):PG
if( PMU_NTC_Handle( CHG_ON ) ) //NTC保护不充电。
{
CHG_CTL &= ~CHG_EN; //Disable Charger.
NTC_Pro_Flag = 1;
ChgStatus = CHG_PROTECT;
return;
}
NTC_Pro_Flag = 0;
#endif
if( IRQ_FLAG9 & CHG_Complete ) //Charg complete interrupt
{
#if ADC_ENABLE
if( g_Vbat_Adc < BAT_RECHARG )
{
IRQ_FLAG9 = CHG_Complete;
}
else
{
CHG_CTL &= ~CHG_EN; //Disable Charger
}
if( !Charger_Done )
{
Charger_Done = 1;
ChgStatus = CHG_STA_COMPLETED;
#ifdef LED_DISPLAY
LED_On_Flag = 1;
#endif
}
#endif
}
else
{
REG_CHG1 = gCharge_Cfg.nTrickle_Cur | gCharge_Cfg.nIterm_Cur | gCharge_Cfg.nConstant_Cur ; //设置Charger的涓流充电电流、截止充电电流、恒流CC。
REG_CHG2 = gCharge_Cfg.nVFloat; //设置CV电压阈值。
CHG_CTL |= CHG_SafyTmr_EN | CHG_EN; //Enable Charger And Charger Timeout
#if BAT_VALUE
if( bat_level > ( C_bat_level_protect + 1 ) )
{
F_batlevel_protect = 0;
}
if( bat_level > (C_bat_level_lowpower + 2) )
{
F_batlevel_low = 0;
}
#endif
ChgStatus = CHG_STA_ING;
#ifdef _DEBUG_CHARGER
printf("Chg ing\r\n");
#endif
Charger_Done = 0;
}
}
#endif