/* ****************************************************************************** * * @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" #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) { 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; //I2cSfr_Write( IRQ_EN0, VDPM_IRQ ); } #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_050V; } } NTC_Flag = FALSE; } else if( NTC_Adc <= T_45C ) //浮充电压4.05V { NTC_Change_CV_Chg_Flag = 1; gCharge_Cfg.nVFloat = CHG_VFLOAT_4_050V; 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拔出。 */ void Charger_Handler(void) { if( pmu_Info.pmu_Fault_STA2 & ( Fault_Sta2_VinUV | Fault_Sta2_VinOVP | Fault_Sta2_CHIP_OTP | Fault_Sta2_PMID_OCP_SHP ) ) //检测到VIN异常、芯片过热、PMID异常,则关闭Charger使能后返回。 { Set_PMU_CHG(OFF); //Disable Charger ChgStatus = CHG_NONE; #ifdef _DEBUG_CHARGER printf("No Chg\r\n"); #endif return; } /*各项保护都无需软件处理,只处理充电超时,超时后需要等VBUS重新插拔后才重新开始Charger流程。*/ ChgStatus = CHG_PROTECT; #ifdef NTC_ENABLE /*NTC Handle*/ //使能Charger前先检测NTC温度,异常就不开充电。(CHIP_STA4 & 0x80):PG if( PMU_NTC_Handle(CHG_ON) ) //NTC保护,不充电。 { Set_PMU_CHG(OFF); //Disable Charger. NTC_Pro_Flag = 1; return; } NTC_Pro_Flag = 0; #endif if( (pmu_Info.pmu_Chip_STA & ChipSTA_DISCHG) == ChipSTA_CHG_DONE ) //Charg complete interrupt { #ifdef _DEBUG_CHARGER printf("Chg Done\r\n"); #endif ChgStatus = CHG_STA_COMPLETED; } else { I2cSfr_Write( CHG_ICC_SET, gCharge_Cfg.nConstant_Cur ); I2cSfr_Write( CHG_VFLOAT_SET, gCharge_Cfg.nVFloat ); I2cSfr_Write( CHG_ITC_ITERM_SET, ( gCharge_Cfg.nTrickle_Cur << 4 ) | gCharge_Cfg.nIterm_Cur ); Set_PMU_CHG(ON); //Enable Charger ChgStatus = CHG_STA_ING; #ifdef _DEBUG_CHARGER printf("Chg ing\r\n"); #endif } } #endif