/*
 * @Author       : ChenJie
 * @Date         : 2021-12-15 10:40:06
 * @Version      : V3.0
 * @LastEditors  : ChenJie
 * @LastEditTime : 2022-05-17 19:27:00
 * @Description  : AppFunc
 * @FilePath     : \undefinedd:\1_WorkFiles\2_Software\10_ReplaceBatteryControl\ECTEK_ToolChain\VehicleControl\VehicleControl\src\System\Vehicle\AppFunc.c
 */
#include "string.h"
#include "stdlib.h"
#include "HardwareLib.h"
#include "CanVar.h"
#include "math.h"
#include "AppFunc.h"
#include "Std_Types.h"

void GetDIOState(void)
{
	//配置高有效，底层悬空为0，触发为1,应用层输出悬空为0，触发为1
//	DINDrv_SetChanThres(_DIN_INDEX_X10, 1, 40950U);
//	DINDrv_SetChanThres(_DIN_INDEX_X17, 1, 40950U);
//	DINDrv_SetChanThres(_DIN_INDEX_X18, 1, 40950U);
//	DINDrv_SetChanThres(_DIN_INDEX_X13, 1, 40950U);
//	DINDrv_SetChanThres(_DIN_INDEX_X9, 1, 40950U);
//	DINDrv_SetChanThres(_DIN_INDEX_X5, 1, 40950U);
//	DINDrv_SetChanThres(_DIN_INDEX_X11, 1, 40950U);
//	DINDrv_SetChanThres(_DIN_INDEX_X14, 1, 40950U);

	DINDrv_SetChanThres(_DIN_INDEX_X10, 1, (4095*3));
	DINDrv_SetChanThres(_DIN_INDEX_X17, 1, (4095*3));
	DINDrv_SetChanThres(_DIN_INDEX_X18, 1, (4095*3));
	DINDrv_SetChanThres(_DIN_INDEX_X13, 1, (4095*3));
	DINDrv_SetChanThres(_DIN_INDEX_X9, 1, (4095*3));
	DINDrv_SetChanThres(_DIN_INDEX_X5, 1, (4095*3));
	DINDrv_SetChanThres(_DIN_INDEX_X11, 1, (4095*3));
	DINDrv_SetChanThres(_DIN_INDEX_X14, 1, (4095*3));
	chrgModuelPwrCtlFB 		=DINDrv_GetChanState(_DIN_INDEX_X10);
	paraChrgCtlFB 			=DINDrv_GetChanState(_DIN_INDEX_X17);
	outToBaseCtlFB_A 		=DINDrv_GetChanState(_DIN_INDEX_X18);
	outToChrgCtlFB_A		=DINDrv_GetChanState(_DIN_INDEX_X13);
	outToChrgCtlFB_B		=DINDrv_GetChanState(_DIN_INDEX_X9);
	outToBaseCtlFB_B		=DINDrv_GetChanState(_DIN_INDEX_X14);
	fuseActionFB_A			=DINDrv_GetChanState(_DIN_INDEX_X5);
	fuseActionFB_B			=DINDrv_GetChanState(_DIN_INDEX_X11);

	A_volDetect 			=DINDrv_GetChanState(_DIN_INDEX_X7);
	B_volDetect				=DINDrv_GetChanState(_DIN_INDEX_X6);
	connectorHvlock1 		=DINDrv_GetChanState(_DIN_INDEX_X22);
	connectorHvlock2		=DINDrv_GetChanState(_DIN_INDEX_X23);
}
void GetAIOValue(void)
{
	uint16 PluginTemp1_Vol = 0;
	uint32 PluginTemp1_R = 0;
	uint16 PluginTemp2_Vol = 0;
	uint32 PluginTemp2_R = 0;
	uint16 PluginTemp3_Vol = 0;
	uint32 PluginTemp3_R = 0;
	uint16 PluginTemp4_Vol = 0;
	uint32 PluginTemp4_R = 0;
	//温度采集获取
	PluginTemp1_Vol = ATDDrv_GetChanResult(_ATD_INDEX_PLUGINTEMP1);
	PluginTemp2_Vol = ATDDrv_GetChanResult(_ATD_INDEX_PLUGINTEMP2);
	PluginTemp3_Vol = ATDDrv_GetChanResult(_ATD_INDEX_PLUGINTEMP3);
	PluginTemp4_Vol = ATDDrv_GetChanResult(_ATD_INDEX_PLUGINTEMP4);
	PluginTemp1_R = (uint32)((PluginTemp1_Vol / (5.0 * 4095 - PluginTemp1_Vol)) * 1000.0);
	PluginTemp2_R = (uint32)((PluginTemp2_Vol / (5.0 * 4095 - PluginTemp2_Vol)) * 1000.0);
	PluginTemp3_R = (uint32)((PluginTemp3_Vol / (5.0 * 4095 - PluginTemp3_Vol)) * 1000.0);
	PluginTemp4_R = (uint32)((PluginTemp4_Vol / (5.0 * 4095 - PluginTemp4_Vol)) * 1000.0);
	chrgGunTemp1_A = (uint8)Look1_u32u8(PluginTemp1_R, R_table, T_table, 240);
	chrgGunTemp2_A = (uint8)Look1_u32u8(PluginTemp2_R, R_table, T_table, 240);
	chrgGunTemp1_B = (uint8)Look1_u32u8(PluginTemp3_R, R_table, T_table, 240);
	chrgGunTemp2_B = (uint8)Look1_u32u8(PluginTemp4_R, R_table, T_table, 240);
}
void ctrlFunc(void)
{
	static uint8 A_volDetectTmp = 0;
	static uint32 xk24_outputTime = 0;
	if(A_volDetect==1)
	{
		A_volDetectTmp = A_volDetect;
	}
	if(A_volDetectTmp==1 && A_volDetect==0 && xk24_outputTime<3000)
	{
		PSwtDrv_Interface(_PSWT_INDEX_X24, 1);
		xk24_outputTime = xk24_outputTime + 10;
	}
	if(xk24_outputTime>=3000)
	{
		xk24_outputTime = 0;
		PSwtDrv_Interface(_PSWT_INDEX_X24, 0);
		A_volDetectTmp = 0;
	}
	if(chrgModulePwrCtrl==1)
	{
		PSwtDrv_Interface(_PSWT_INDEX_X36, 1);
	}
	else
	{
		PSwtDrv_Interface(_PSWT_INDEX_X36, 0);
	}
	if(chrgStartState==0&&chrgStopState==1)
	{
		if(baseSwitchCtrl==1)
		{
			PSwtDrv_Interface(_PSWT_INDEX_X32, 1);
			PSwtDrv_Interface(_PSWT_INDEX_X20, 1);
			PSwtDrv_Interface(_PSWT_INDEX_X16, 1);
			PSwtDrv_Interface(_PSWT_INDEX_X12, 1);
			PSwtDrv_Interface(_PSWT_INDEX_X8, 1);
		}
		else
		{
			PSwtDrv_Interface(_PSWT_INDEX_X32, 0);
			PSwtDrv_Interface(_PSWT_INDEX_X20, 0);
			PSwtDrv_Interface(_PSWT_INDEX_X16, 0);
			PSwtDrv_Interface(_PSWT_INDEX_X12, 0);
			PSwtDrv_Interface(_PSWT_INDEX_X8, 0);
		}
	}

	 chrgBoxTemp1 = temp_gf1;
	 chrgBoxTemp2 = temp_gf2;
	 chrgBoxGasOver1 = gashighLevel_gf1;
	 chrgBoxGasOver2 = gashighLevel_gf2;
	 chrgBoxFumesOver1 = fumesHigh_gf1;
	 chrgBoxFumesOver2 = fumesHigh_gf2;

	 ctrlFXFB1 = getbit(workMode_gf1,5);
	 ctrlFXFB2 = getbit(workMode_gf2,5);
	 chrgBox1Warning = warningLevel_gf1;
	 chrgBox2Warning = warningLevel_gf2;

}
/*
void LockAndUnlockCtrl()
{
	static uint16 LockDelay = 0;
	static uint16 UnlockDelay = 0;
	static uint16 BleConCounter = 0;
	static uint16 battSwpeModeCounter = 0;
	if (ebcd_flg_ebcManCtrlEn) //手动控制使能
	{
		if (ebcd_flg_ebcManCtrlMode == 1) //循环控制模式
		{
			if (ebcd_st_lockSensor == 1) //处于锁紧状态，传感器判定一个
			{
				LockDelay = LockDelay + 10;
				if (LockDelay > LockDelayTime) //锁紧状态超时就解锁
				{
					ManuControlTimes++;
					LockDelay = 0;
					ebcd_st_SwitchCtrlFlg = Unlock;
				}
			}
			else if (ebcd_st_unlockSensor == 1) //处于解锁状态，传感器判定一个
			{
				UnlockDelay = UnlockDelay + 10;
				if (UnlockDelay > UnlockDelayTime)
				{
					UnlockDelay = 0;
					ebcd_st_SwitchCtrlFlg = Lock;
				}
			}
		}
		else if (ebcd_flg_ebcManCtrlMode == 2) //控制锁紧
		{
			ebcd_st_SwitchCtrlFlg = Lock;
		}
		else if (ebcd_flg_ebcManCtrlMode == 3) //控制解锁
		{
			ebcd_st_SwitchCtrlFlg = Unlock;
		}
	}
	else //正常工作模式
	{
		switch (ebcd_st_ebcWork)
		{
		case DriveMode: //行车状态，自动进入，默认状态
		{
			ebcd_st_SwitchCtrlFlg = Lock;
			PSwtDrv_Interface(_PSWT_INDEX_EBCLEDCONTROL, 0); //行车状态换电指示灯关闭
			if (bled_flg_handShake == 1)
			{
				ebcd_st_ebcWork = CommuMode; //进入通讯状态
				bled_flg_handShake = 0;
				break;
			}
			break;
		}
		case CommuMode: //通讯状态，握手才能进入
		{
			BleConCounter = BleConCounter + 10;
			if ((BleConCounter % 1000) < 500) //换电指示灯闪烁
			{
				PSwtDrv_Interface(_PSWT_INDEX_EBCLEDCONTROL, 1);
			}
			else
			{
				PSwtDrv_Interface(_PSWT_INDEX_EBCLEDCONTROL, 0);
			}

			if (BleConCounter >= 60 * 1000 || bled_flg_backToDrv == 1)
			{
				ebcd_st_ebcWork = DriveMode; //切换到行车状态
				BleConCounter = 0;
				bled_flg_backToDrv = 0;
				break;
			}
			else if (BattCD_stWakeupU.B.bLogic == 0 && BattCD_stWakeupU.B.bWkpSig1 == 1)
			{
				ebcd_st_ebcWork = SwapMode; //切换到换电状态
				BleConCounter = 0;
				break;
			}
			if (bled_st_dataTrans == 1)
			{
				BleConCounter = 0;
				bled_st_dataTrans = 0;
			}
			break;
		}
		case SwapMode: //换电状态
		{
			PSwtDrv_Interface(_PSWT_INDEX_EBCLEDCONTROL, 1); //换电状态换电指示灯常亮
			battSwpeModeCounter = battSwpeModeCounter + 10;
			if (bled_flg_swapBattDone == 1)
			{
				ebcd_Nr_swapBatt++;
				ebcd_Nr_swapSucBatt++;
				bled_flg_swapBattDone = 0;
				ebcd_st_ebcWork = CommuMode; //切换到通讯状态
				break;
			}
			else if (battSwpeModeCounter >= 60 * 1000)
			{
				ebcd_Nr_swapBatt++;
				battSwpeModeCounter = DriveMode; //切换到行车状态
				ebcd_st_ebcWork = 0;
				break;
			}
			if (bled_st_dataTrans == 1)
			{
				battSwpeModeCounter = 0;
				bled_st_dataTrans = 0;
			}
			if (bled_flg_unlockCmdForce)
			{
				ebcd_st_SwitchCtrlFlg = Unlock;
				bled_flg_unlockCmdForce = 0;
			}
			if (bled_flg_lockCmdForce)
			{
				ebcd_st_SwitchCtrlFlg = Lock;
				bled_flg_lockCmdForce = 0;
			}
			break;
		}
		}
	}

	//锁紧解锁执行
	if (ebcd_st_SwitchCtrlFlg == Unlock)
	{
		UnlockCtrl();
	}
	else
	{
		LockCtrl();
	}
}
*/


/**
 * @brief : lookUp Table Fun
 * @param {uint32} u0 x
 * @param {uint32} bp0 x_table
 * @param {uint16} table y_table
 * @param {uint16} maxIndex
 * @return {*}
 */
uint16 Look1_u32u8(uint32 u0, uint32 *bp0, uint8 *table, uint16 MaxLen)
{
	uint32 bpIdx = 0;
	uint32 iLeft = 0;
	uint32 iRght = 0;
	uint16 y = 0;
	uint32 yL_0d0 = 0;
	uint32 yR_0d0 = 0;
	uint32 maxIndex = MaxLen - 1;
	if (u0 <= bp0[0U])
	{
		iLeft = 0U;
		iRght = 0U;
	}
	else if (u0 < bp0[maxIndex])
	{
		//对折法寻找u0的位置
		bpIdx = maxIndex >> 1U;
		iLeft = 0U;
		iRght = maxIndex;
		while ((iRght - iLeft) > 1)
		{
			if (u0 < bp0[bpIdx])
			{
				iRght = bpIdx;
			}
			else
			{
				iLeft = bpIdx;
			}
			bpIdx = (iRght + iLeft) >> 1U;
		}
	}
	else
	{
		iLeft = maxIndex;
		iRght = maxIndex;
	}
	//找到位置以后计算插值
	if (iLeft != iRght)
	{
		//线性插值
		yR_0d0 = table[iLeft + 1U];
		yL_0d0 = table[iLeft];
		if (yR_0d0 >= yL_0d0)
		{
			y = (uint16)(((uint32)(u0 - bp0[iLeft]) * (yR_0d0 - yL_0d0)) / (bp0[iLeft + 1] - bp0[iLeft]) + yL_0d0);
		}
		else
		{
			y = (uint16)(yL_0d0 - ((uint32)(u0 - bp0[iLeft]) * (yL_0d0 - yR_0d0)) / (bp0[iLeft + 1] - bp0[iLeft]));
		}
	}
	else
	{
		y = (uint16)table[iLeft];
	}
	return y;
}

/**
 * @brief : 故障判断函数
 * @param {BOOL} Enable 使能状态
 * @param {BOOL} Input 判断输入
 * @param {UINT16} *N 判断次数累计
 * @param {UINT16} Thr 判断次数阈值
 * @return {*}
 */
BOOL JudgeTimeSystem(BOOL Enable, BOOL Input, UINT16 *N, UINT16 Thr)
{
	BOOL Flg = FALSE;
	if (Input && Enable)
	{
		*N = (*N + 1) > 2000 ? 2000 : (*N + 1);
	}
	else
	{
		*N = 0;
	}
	if (*N > Thr && Enable)
	{
		Flg = TRUE;
	}
	else
	{
		Flg = FALSE;
	}
	return Flg;
}
BOOL DiagThrSystem1(BOOL Enable, BOOL precondition, UINT16 Input, UINT16 fltThr, UINT16 recThr, UINT16 fltNumThr, UINT16 recNumThr, UINT16 *fltNum, UINT16 *recNum, UINT8 *fitFlg)
{
	if (Enable && precondition && Input > fltThr)
	{
		*fltNum = (*fltNum + 1) > 20000 ? 20000 : (*fltNum + 1);
	}
	else
	{
		*fltNum = 0;
	}
	if (Enable && precondition && Input < recThr)
	{
		*recNum = (*recNum + 1) > 20000 ? 20000 : (*recNum + 1);
	}
	else
	{
		*recNum = 0;
	}
	if ((*fltNum > fltNumThr || (*fitFlg && *recNum < recNumThr)) && precondition)
	{
		*fitFlg = TRUE;
	}
	else
	{
		*fitFlg = FALSE;
	}
	return *fitFlg;
}
/**
 * @brief : 获取故障码函数，从故障数组中获取故障码，并将之前的故障码向前移动
 * @param {UINT16} *ErrorArray
 * @param {UINT8} Errorlen
 * @return {*}
 */
UINT16 GetErrorNum(UINT16 *ErrorArray, UINT8 Errorlen)
{
	UINT16 OutNum;
	OutNum = *(ErrorArray);
	for (UINT8 i = 0; i < Errorlen - 1; i++)
	{
		*(ErrorArray + i) = *(ErrorArray + i + 1);
		if (*(ErrorArray + i + 1) == 0)
			break;
	}
	return OutNum;
}
/**
 * @brief : 故障码注入函数，将故障码写入到故障数组中，如果存在则不写入，如果存在则不写入
 * @param {UINT16} *ErrorArray
 * @param {UINT8} Errorlen
 * @param {UINT16} ErrorNum
 * @return {*}
 */
UINT8 PutErrorNum(UINT16 *ErrorArray, UINT8 Errorlen, UINT16 ErrorNum)
{
	for (UINT8 i = 0; i < Errorlen; i++)
	{
		if (*(ErrorArray + i) == 0)
		{
			*(ErrorArray + i) = ErrorNum;
			return 0;
		}
		else
		{
			if (*(ErrorArray + i) == ErrorNum)
			{
				return 1;
			}
			else
			{
				continue;
			}
		}
	}
	return 2;
}
