/********************************************************************************
Copyright (C), Sinowealth Electronic. Ltd.
Author: 	Sino
Version: 	V0.0
Date: 		2020/04/26
History:
	V2.0	2020/04/26		 Preliminary
********************************************************************************/
#include "Main.h"


//保护相关的参数
BOOL bUVLock;                       //负载锁定，当欠压恢复后，置位该标志，而不是直接清零bUV，当负载释放后，再清零bUV
BOOL bOVLock;                       //充电器锁定，当过压恢复后，置位该标志，而不是直接清零bOV，当充电器释放后，再清零bOV
U16	xdata uiOVDelayCnt;
U16	xdata uiOVRDelayCnt;
U16	xdata uiUVDelayCnt;
U16	xdata uiUVRDelayCnt;
U16	xdata uiOTCDelayCnt;
U16	xdata uiOTCRDelayCnt;
U16	xdata uiUTCDelayCnt;
U16	xdata uiUTCRDelayCnt;
U16	xdata uiOTDDelayCnt;
U16	xdata uiOTDRDelayCnt;
U16	xdata uiUTDDelayCnt;
U16	xdata uiUTDRDelayCnt;
U16	xdata uiOCCDelayCnt;
U16	xdata uiOCD1DelayCnt;
U16	xdata uiOCD2DelayCnt;
U16	xdata uiOCCRcnt;
U16 xdata uiOCDRcnt;

/*************************************************************************************************
* 函数名: ProtectOV
* 参  数: 无
* 返回值: 无
* 描  述: 单节电池过压保护检测，过压后置位bOV为1
*************************************************************************************************/
void ProtectOV(void)
{
	if(!(bOV||bAFE_OV))
	{
		if(uiCellVmax > E2uiOVvol)
		{
			if(++uiOVDelayCnt >= OV_DELAY_CNT)
			{
				bOV = 1;
				bOVLock = 0;
				uiOVDelayCnt = 0;
				uiOVRDelayCnt = 0;
			}
		}
		else if(uiCellVmax < E2uiOVRvol)
		{
			uiOVDelayCnt = 0;
		}
	}
	else if(!bOVLock)
	{
		if(uiCellVmax < E2uiOVRvol)
		{			
			if(++uiOVRDelayCnt >= OVR_DELAY_CNT)
			{
				if(bChgerLock)
				{
					bOVLock = 1;				//过压阈值恢复，但是还需检测负载释放释放
					bChgerStartCheckFlg = 1;	//开启充电器
				}
				else
				{
					bOV = 0;
                    bAFE_OV = 0;
                    AFEClrFlg();
				}
				uiOVDelayCnt = 0;
				uiOVRDelayCnt = 0;
			}
		}
		else if(uiCellVmax > E2uiOVvol)
		{
			uiOVRDelayCnt = 0;
		}
	}
}

/*************************************************************************************************
* 函数名: ProtectUV
* 参  数: 无
* 返回值: 无
* 描  述: 单节电芯欠压保护检测，保护后置位bUV为1
*************************************************************************************************/
void ProtectUV(void)
{
	if(!bUV)
	{
		if(uiCellVmin < E2uiUVvol)
		{
			if(++uiUVDelayCnt >= UV_DELAY_CNT)
			{
				bUV = 1;
				bUVLock = 0;
				uiUVDelayCnt = 0;
				uiUVRDelayCnt = 0;
			}
		}
		else if(uiCellVmin > E2uiUVRvol)
		{
			uiUVDelayCnt = 0;
		}
	}
	else if(!bUVLock)
	{
		if(uiCellVmin > E2uiUVRvol)
		{			
			if(++uiUVRDelayCnt >= UVR_DELAY_CNT)
			{
				if(bLoadLock)					//如果支持负载锁定，则不立刻清UV标志，需要负载释放后再清零
				{
					bUVLock = 1;				//欠压阈值恢复，但是还需检测负载释放释放
					bLoadStartCheckFlg = 1;		//开启负载检测
				}
				else
				{
					bUV = 0;
				}
				uiUVDelayCnt = 0;
				uiUVRDelayCnt = 0;
			}
		}
		else if(uiCellVmin < E2uiUVvol)
		{
			uiUVRDelayCnt = 0;
		}
	}
}

/*************************************************************************************************
* 函数名: ProtectOTC
* 参  数: 无
* 返回值: 无
* 描  述: 充电高温保护检测，保护后置位bOTC为1
*************************************************************************************************/
void ProtectOTC(void)
{
	if(!bOTC)
	{
		if(uiTempeMax > E2uiTempOTC)
		{
			if(++uiOTCDelayCnt >= TEMPE_DELAY_CNT)
			{
				bOTC = 1;
				uiOTCDelayCnt = 0;
				uiOTCRDelayCnt = 0;
			}
		}
		else if(uiTempeMax < E2uiTempOTCR)
		{
			uiOTCDelayCnt = 0;
		}
	}
	else
	{
		if(uiTempeMax < E2uiTempOTCR)
		{
			if(++uiOTCRDelayCnt >= TEMPER_DELAY_CNT)
			{
				bOTC = 0;
				uiOTCDelayCnt = 0;
				uiOTCRDelayCnt = 0;
			}
		}
		else if(uiTempeMax > E2uiTempOTC)
		{
			uiOTCRDelayCnt = 0;
		}
	}
}


/*************************************************************************************************
* 函数名: ProtectUTC
* 参  数: 无
* 返回值: 无
* 描  述: 充电低温保护检测，保护后置位bUTC为1
*************************************************************************************************/
void ProtectUTC(void)
{
	if(!bUTC)
	{
		if(uiTempeMin < E2uiTempUTC)
		{
			if(++uiUTCDelayCnt >= TEMPE_DELAY_CNT)
			{
				bUTC = 1;
				uiUTCDelayCnt = 0;
				uiUTCRDelayCnt = 0;
			}
		}
		else if(uiTempeMin > E2uiTempUTCR)
		{
			uiUTCDelayCnt = 0;
		}
	}
	else
	{
		if(uiTempeMin > E2uiTempUTCR)
		{
			if(++uiUTCRDelayCnt >= TEMPER_DELAY_CNT)
			{
				bUTC = 0;
				uiUTCDelayCnt = 0;
				uiUTCRDelayCnt = 0;
			}
		}
		else if(uiTempeMin < E2uiTempUTC)
		{
			uiUTCRDelayCnt = 0;
		}
	}
}


/*************************************************************************************************
* 函数名: ProtectOTD
* 参  数: 无
* 返回值: 无
* 描  述: 放电高温保护检测，保护后置位bOTD为1
*************************************************************************************************/
void ProtectOTD(void)
{
	if(!bOTD)
	{
		if(uiTempeMax > E2uiTempOTD)
		{
			if(++uiOTDDelayCnt >= TEMPE_DELAY_CNT)
			{
				bOTD = 1;
				uiOTDDelayCnt = 0;
				uiOTDRDelayCnt = 0;
			}
		}
		else if(uiTempeMax < E2uiTempOTDR)
		{
			uiOTDDelayCnt = 0;
		}
	}
	else
	{
		if(uiTempeMax < E2uiTempOTDR)
		{
			if(++uiOTDRDelayCnt >= TEMPER_DELAY_CNT)
			{
				bOTD = 0;
				uiOTDDelayCnt = 0;
				uiOTDRDelayCnt = 0;
			}
		}
		else if(uiTempeMax > E2uiTempOTD)
		{
			uiOTDRDelayCnt = 0;
		}
	}
}


/*************************************************************************************************
* 函数名: ProtectUTD
* 参  数: 无
* 返回值: 无
* 描  述: 放电低温保护检测，保护后置位bUTD为1
*************************************************************************************************/
void ProtectUTD(void)
{
	if(!bUTD)
	{
		if(uiTempeMin < E2uiTempUTD)
		{
			if(++uiUTDDelayCnt >= TEMPE_DELAY_CNT)
			{
				bUTD = 1;
				uiUTDDelayCnt = 0;
				uiUTDRDelayCnt = 0;
			}
		}
		else if(uiTempeMin > E2uiTempUTDR)
		{
			uiUTDDelayCnt = 0;
		}
	}
	else
	{
		if(uiTempeMin > E2uiTempUTDR)
		{
			if(++uiUTDRDelayCnt >= TEMPER_DELAY_CNT)
			{
				bUTD = 0;
				uiUTDDelayCnt = 0;
				uiUTDRDelayCnt = 0;
			}
		}
		else if(uiTempeMin < E2uiTempUTD)
		{
			uiUTDRDelayCnt = 0;
		}
	}
}



/*************************************************************************************************
* 函数名: ProtectOCC
* 参  数: 无
* 返回值: 无
* 描  述: 充电过流保护检测，保护后置位bOCC为1
*************************************************************************************************/
void ProtectOCC(void)
{
	if(!bOCC)
    {
		if(slCadcCurrent > E2slOCCCurrent)
		{
            if(++uiOCCDelayCnt >= OCC_DELAY_CNT)
            {
                bOCC = 1;
				bChgerStartCheckFlg = 1;		//设置充电器开始检测标志
                uiOCCDelayCnt = 0;
			}
		}
		else if(!bChgerChkingFlg)
		{
            if(uiOCCDelayCnt > 0)
            {
    			uiOCCDelayCnt--;	
            }
		}
    }
}


/*************************************************************************************************
* 函数名: ProtectOCD1
* 参  数: 无
* 返回值: 无
* 描  述: 放电过流1保护检测，保护后置位bOCD1为1
*************************************************************************************************/
void ProtectOCD1(void)
{
	if(!bOCD1)
    {
		if(slCadcCurrent < E2slOCD1Current)
		{
            if(++uiOCD1DelayCnt >= OCD1_DELAY_CNT)
            {
                uiOCD1DelayCnt = 0;
                bOCD1 = 1;
				bLoadStartCheckFlg = 1;		//开启负载检测
            }
		}
		else if(!bLoadChkingFlg)
		{
            if(uiOCD1DelayCnt > 0)
            {
    			uiOCD1DelayCnt--;
            }
		}
    }
}


/*************************************************************************************************
* 函数名: ProtectOCD2
* 参  数: 无
* 返回值: 无
* 描  述: 放电过流2保护检测，保护后置位bOCD2为1
*************************************************************************************************/
void ProtectOCD2(void)
{
	if(!bOCD2)
    {
		if(slCadcCurrent < E2slOCD2Current)
		{
            if(++uiOCD2DelayCnt > OCD2_DELAY_CNT)
            {
                uiOCD2DelayCnt = 0;
                bOCD2 = 1;
 				bLoadStartCheckFlg = 1;		//开启负载检测
           }
		}
		else if(!bLoadChkingFlg)
		{
            if(uiOCD2DelayCnt > 0)
            {
    			uiOCD2DelayCnt--;
            }
		}
    }
}


/*************************************************************************************************
* 函数名: ProtectProcess
* 参  数: 无
* 返回值: 无
* 描  述: 各种保护检测
*************************************************************************************************/
void ProtectProcess(void)
{
	if(!bPorSelfTestFlg)		//如果是上电1s自检过程中，则不检测正常保护
	{
		ProtectOV();			//检测过压保护及其释放
		ProtectUV();			//检测欠压保护及其释放
		
		ProtectOTC();			//检测充电高温保护及其释放
		ProtectUTC();			//检测充电低温保护及其释放
		ProtectOTD();			//检测放电高温保护及其释放
		ProtectUTD();			//检测放电低温保护及其释放
		
		ProtectOCC();			//充电过流保护
		ProtectOCD1();			//放电过流1保护
		ProtectOCD2();			//放电过流2保护
	}
}


/*************************************************************************************************
* 函数名: ProtectOCRecover
* 参  数: 无
* 返回值: 无
* 描  述: 电流保护自恢复
*************************************************************************************************/
void ProtectOCRecover(void)
{
	if(bOCRC_EN)
	{
		if(bOCD1 || bOCD2 || bAFE_SC)
		{
			if(++uiOCDRcnt >= OCDR_DELAY_CNT)
			{
				ucLoadRCnt = 0;    
				uiOCDRcnt = 0;
				bOCD1 = 0;
				bOCD2 = 0;
                bLoadStartCheckFlg = 0;
                bLoadChkingFlg = 0;
               if(bAFE_SC)
                {
					bAFE_SC = 0;
					AFEClrFlg();
                }
			}
		}
		
		if(bOCC)
		{			
			if(++uiOCCRcnt > OCCR_DELAY_CNT)
			{
				uiOCCRcnt = 0;
				bOCC = 0;
				ucChgerRCnt = 0;
                bChgerChkingFlg = 0;
			}
		}
	}
}

