//********************************************************************************
//								     Include
//********************************************************************************
#include "MDSFxx_SFR.h"
#include "XSFR_GLOBAL.h"
#include "Allhex.h"
//********************************************************************************
//								       RAM
//********************************************************************************
//The variables defined by data are placed in the first 128 bytes (0x00~0x7F) address space
//The variables defined by idata are placed in the (0x00~0xFF) address space
//The variable defined by xdata are placed in the external extended RAM  (generally refers to the external 0xF000~0xF1FF space, the specific space size varies with the MCU , and some MCU do not have external RAM)

//The variable defined by data is the fastest, followed by idata, and xdata is slower than the first two
//Variables that are often used are declared with data/idata; variables that are not commonly used are declared with xdata.

#if (Vbus_Protect == 1)
   uint8 MotorErrorState = 0;
	//uint8 MotorErrorState = OverVbus | UnderVbus;
	xdata uint16 OverVbusProtectCount = BUS_VOLT_DURATION;
	xdata uint16 UnderVbusProtectCount = BUS_VOLT_DURATION;
#else
	uint8 MotorErrorState = 0;
#endif

#if (Temperature_Protect == 1)
	xdata uint16 OverTemperatureProtectCount = TEMPERATURE_DURATION;
#endif

#if (FaultLock_Protect == 1)
	xdata uint16 	MotorFaultDelayCount 	= 0;
#endif

#if (POCP_Protect == 1)
	xdata uint16 POCP_ProtectCount = PHASE_OCP_DURATION;
#endif
//********************************************************************************
//								    OVP/UVP
//********************************************************************************
#if (Vbus_Protect == 1)
void Vbus_Protect_Fun (uint16 Adc_Vbus){
	if(Adc_Vbus > OVER_BUS_VOLT_VALUE){
		if(OverVbusProtectCount >= BUS_VOLT_DURATION){
			OverVbusProtectCount = BUS_VOLT_DURATION; 
			MotorErrorState |= OverVbus;
		}
		else
			OverVbusProtectCount += 10;
	}
	else{
		if(Adc_Vbus < CLEAR_OVER_BUS_VOLT_VALUE){
			if(OverVbusProtectCount < 1){
				OverVbusProtectCount = 0;
				MotorErrorState &= ~(OverVbus);
			}
			else
				OverVbusProtectCount -= 10;
		}
	}

	if(Adc_Vbus < UNDER_BUS_VOLT_VALUE){
		if(UnderVbusProtectCount >= BUS_VOLT_DURATION){
			UnderVbusProtectCount = BUS_VOLT_DURATION; 
			MotorErrorState |= UnderVbus;
		}
		else
			UnderVbusProtectCount += 10;
	}
	else{
		if(Adc_Vbus > CLEAR_UNDER_BUS_VOLT_VALUE){
			if(UnderVbusProtectCount < 1){
				UnderVbusProtectCount = 0;
				MotorErrorState &= ~(UnderVbus);
			}
			else
				UnderVbusProtectCount -= 10;
		}
	}
}
#endif
//********************************************************************************
//								     OTP
//********************************************************************************
#if (Temperature_Protect == 1)
void Temperature_Protect_Fun (uint16 Adc_Temperature){
	if(Adc_Temperature > OVER_TEMPERATURE_VALUE){
		if(OverTemperatureProtectCount >= TEMPERATURE_DURATION){
			OverTemperatureProtectCount = TEMPERATURE_DURATION; 
			MotorErrorState |= OverTemperature;
		}
		else
			OverTemperatureProtectCount += 10;
	}
	else{
		if(Adc_Temperature < CLEAR_OVER_TEMPERATURE_VALUE){
			if(OverTemperatureProtectCount < 1){
				OverTemperatureProtectCount = 0;
				MotorErrorState &= ~(OverTemperature);
			}
			else
				OverTemperatureProtectCount -= 10;
		}
	}
}
#endif
//********************************************************************************
//								 Lock Protect
//********************************************************************************
#if (FaultLock_Protect == 1)
xdata	uint16	mot_lock_cnt; 
void FaultLock_Fun (void)    // 10ms
{
	if(MotorState == M_RUN)
	{
		if(MotorFaultDelayCount > FAULTLOCK_DELAY_DURATION)    // 200ms
		{
			if(EstimatedSpeed > OverSpeed)
			{
				mot_lock_cnt += 1;
			}
			else if(EstimatedSpeed <= UnderSpeed)
			{
				mot_lock_cnt += 1;
			}
			else
			{
				if(mot_lock_cnt > 0)
				{
					mot_lock_cnt -= 1;
				}			
			}

			if(mot_lock_cnt > 50)
			{
				mot_lock_cnt = 0;
				MotorErrorState = FaultLock;
			}
		}
		else
		{
			MotorFaultDelayCount += 10;
		}
	}
	else
	{
		mot_lock_cnt = 0;
		MotorFaultDelayCount = 0;
		if(MotorState != M_ERROR)
		{
			MotorFaultState = 0;
		}
	}
}
#endif
//********************************************************************************
//								      OCP
//********************************************************************************
void AOCP_Protect_Fun (void){
	if(MotorState == M_IPD){
		MotorErrorState &= ~(AOCP);
	}
	else{
		MotorErrorState |= AOCP;
	}
}
//********************************************************************************
//								    Ibus OCP
//********************************************************************************
// void IBUS_OCP_Protect_Fun (void){
	
// }
//********************************************************************************
//								   Phase  OCP
//********************************************************************************
#if (POCP_Protect == 1)
void Phase_OCP_Protect_Fun (void){
	int IcFb;
	IaFb = dFB_Ia_DRH << 8;
	IaFb |= dFB_Ia_DRL;
	IbFb = dFB_Ib_DRH << 8;
	IbFb |= dFB_Ib_DRL;
	IcFb = -IaFb - IbFb;
	if((abs(IaFb) > PHASE_OCP_VALUE) || (abs(IbFb) > PHASE_OCP_VALUE) || (abs(IcFb) > PHASE_OCP_VALUE)){
		if(POCP_ProtectCount >= PHASE_OCP_DURATION){
			POCP_ProtectCount = PHASE_OCP_DURATION; 
			MotorErrorState |= POCP;
		}
		else
			POCP_ProtectCount += 10;
	}
	else{
		if(POCP_ProtectCount < 1){
			POCP_ProtectCount = 0;
			MotorErrorState &= ~(POCP);
		}
		else
			POCP_ProtectCount -= 10;
	}
}
#endif
