/*******************************************************************************************************/
//micro_inverter protect file
//date: 2023.11.02
//owner: xie wei
/*******************************************************************************************************/
//head file
#include "control.h"
#include "protect.h"
//variable definition
union MICROINV_Pro MicroInv_Fault_Flag;
uint16_t Grid_VolRMS_max_cnt=0,Grid_VolRMS_min_cnt=0,Grid_VolRMS_Recover_cnt=0;
uint8_t System_Fault_CLR_cmd=0;
uint16_t Grid_VolInstant_max_cnt=0,Grid_VolInstant_Recover_cnt=0;
uint16_t Grid_CurInstant_max_cnt=0,Grid_CurInstant_Recover_cnt=0;
uint16_t PVVol_max_cnt = 0,PVVol_min_cnt = 0,PVVol_OVP_Recover_cnt=0,PVVol_UVP_Recover_cnt=0;
uint16_t PVCur_OCP_Recover_cnt = 0,PVCur_OCP_cnt = 0;
///////////////////////////////////////////
void MicroInv_Protect(void)
{
	#ifdef DRIVER_DEBUG
		MicroInv_Fault_Flag.all = 0;
	#else
	/////////////////////GRID VOLTAGE RMS////////////////
	#if defined OFF_GRID_CLOSELOOP_DEBUG || defined OFF_GRID_OPENLOOP_DEBUG
		MicroInv_Fault_Flag.bit.Grid_RMS_OVP_SW = 0;
		MicroInv_Fault_Flag.bit.Grid_RMS_UVP_SW = 0;
	#else
	if( Ugridrms > GRID_VOLRMS_MAX_THRESHOLD && MicroInv_Fault_Flag.bit.Grid_RMS_OVP_SW == 0 )
	{
		Grid_VolRMS_min_cnt = 0;
		Grid_VolRMS_Recover_cnt = 0;
		if( Grid_VolRMS_max_cnt > FAULT_FILTER_TIMES )
		{
			MicroInv_Fault_Flag.bit.Grid_RMS_OVP_SW = 1;
	  //  DDL_Printf("Grid Voltage RMS SW OVP Fault Happened!\r\n");
			Grid_VolRMS_max_cnt = 0;
		}
		else
		{
			Grid_VolRMS_max_cnt++;
		}
	}
	else if( Ugridrms < GRID_VOLRMS_MIN_THRESHOLD && MicroInv_Fault_Flag.bit.Grid_RMS_UVP_SW == 0 
				&&((MicroInv_State==SSTART)||(MicroInv_State==RUN))	)
	{
		Grid_VolRMS_max_cnt = 0;
		Grid_VolRMS_Recover_cnt = 0;
		if( Grid_VolRMS_min_cnt > FAULT_FILTER_TIMES )
		{
			MicroInv_Fault_Flag.bit.Grid_RMS_UVP_SW = 1;
	//		DDL_Printf("Grid Voltage RMS SW UVP Fault Happened!\r\n");
			Grid_VolRMS_min_cnt = 0;
		}
		else
		{
			Grid_VolRMS_min_cnt++;
		}
	}
	else
	{
		Grid_VolRMS_max_cnt = 0;
		Grid_VolRMS_min_cnt = 0;
		if( System_Fault_CLR_cmd == 1 && 
			(MicroInv_Fault_Flag.bit.Grid_RMS_OVP_SW==1||MicroInv_Fault_Flag.bit.Grid_RMS_UVP_SW==1) )
		{
			if( Grid_VolRMS_Recover_cnt > FAULT_FILTER_TIMES )
			{
				MicroInv_Fault_Flag.bit.Grid_RMS_OVP_SW = 0;
				MicroInv_Fault_Flag.bit.Grid_RMS_UVP_SW = 0;
	//			DDL_Printf("Grid Voltage RMS SW Fault Cleared!\r\n");
				Grid_VolRMS_Recover_cnt = 0;
			}
			else
			{
				Grid_VolRMS_Recover_cnt++;
			}
		}
	}
	#endif
	/////////////////////PV VOLTAGE ////////////////
	if( Vpv_LPF.output > PVVOL_MAX_THRESHOLD && MicroInv_Fault_Flag.bit.PVVOL_OVP_SW == 0 )
	{
		PVVol_OVP_Recover_cnt = 0;
		if( PVVol_max_cnt > FAULT_FILTER_TIMES )
		{
			MicroInv_Fault_Flag.bit.PVVOL_OVP_SW = 1;
	//		DDL_Printf("PV Voltage OVP SW Fault Happened!\r\n");
			PVVol_max_cnt = 0;
		}
		else
		{
			PVVol_max_cnt++;
		}
	}
	else
	{
		PVVol_max_cnt = 0;
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.PVVOL_OVP_SW==1 )
		{
			if( PVVol_OVP_Recover_cnt > FAULT_FILTER_TIMES )
			{
				MicroInv_Fault_Flag.bit.PVVOL_OVP_SW = 0;
	//			DDL_Printf("PV Voltage SW OVP Fault Cleared!\r\n");
				PVVol_OVP_Recover_cnt = 0;
			}
			else
			{
				PVVol_OVP_Recover_cnt++;
			}
		}
	}
	
  if( Vpv_LPF.output < PVVOL_MIN_THRESHOLD && MicroInv_Fault_Flag.bit.PVVOL_UVP_SW == 0
      && ((MicroInv_State==SSTART)||(MicroInv_State==RUN)) )
	{
		PVVol_UVP_Recover_cnt = 0;
		if( PVVol_min_cnt > FAULT_FILTER_TIMES )
		{
			MicroInv_Fault_Flag.bit.PVVOL_UVP_SW = 1;
	//		DDL_Printf("PV Voltage SW UVP Fault Happened!\r\n");
			PVVol_min_cnt = 0;
		}
		else
		{
			PVVol_min_cnt++;
		}
	}
	else
	{
		PVVol_min_cnt = 0;
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.PVVOL_UVP_SW==1 )
		{
			if( PVVol_UVP_Recover_cnt > FAULT_FILTER_TIMES )
			{
				MicroInv_Fault_Flag.bit.PVVOL_UVP_SW = 0;
	//			DDL_Printf("PV Voltage SW UVP Fault Cleared!\r\n");
				PVVol_UVP_Recover_cnt = 0;
			}
			else
			{
				PVVol_UVP_Recover_cnt++;
			}
		}
	}
	/////////////////////GRID VOLTAGE ////////////////
	if( Vgrid > GRID_VOLINSTANT_MAX_THRESHOLD && MicroInv_Fault_Flag.bit.Grid_OVP_SW == 0 )
	{
		Grid_VolInstant_Recover_cnt = 0;
		if( Grid_VolInstant_max_cnt > FAULT_FILTER_TIMES )
		{
			MicroInv_Fault_Flag.bit.Grid_OVP_SW = 1;
	//		DDL_Printf("Grid Instant Voltage SW OVP Fault Happened!\r\n");
			Grid_VolInstant_max_cnt = 0;
		}
		else
		{
			Grid_VolInstant_max_cnt++;
		}
	}
	else
	{
		Grid_VolInstant_max_cnt = 0;
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.Grid_OVP_SW==1 )
		{
			if( Grid_VolInstant_Recover_cnt > FAULT_FILTER_TIMES )
			{
				MicroInv_Fault_Flag.bit.Grid_OVP_SW = 0;
		//		DDL_Printf("Grid Instant Voltage SW OVP Fault Cleared!\r\n");
				Grid_VolInstant_Recover_cnt = 0;
			}
			else
			{
				Grid_VolInstant_Recover_cnt++;
			}
		}
	}
	
	//	////////////////////GRID CURRENT/////////////////////////
	if( Iac > GRID_CURINSTANT_MAX_THRESHOLD&& MicroInv_Fault_Flag.bit.Grid_OCP_SW  == 0 )
	{
		Grid_CurInstant_Recover_cnt = 0;
		if( Grid_CurInstant_max_cnt > FAULT_FILTER_TIMES )
		{
			MicroInv_Fault_Flag.bit.Grid_OCP_SW = 1;
  //    DDL_Printf("Grid Current SW OCP Fault Happened!\r\n");
			Grid_CurInstant_max_cnt = 0;
		}
		else
		{
			Grid_CurInstant_max_cnt++;
		}
	}
	else
	{
		Grid_CurInstant_max_cnt = 0;
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.Grid_OCP_SW==1 )
		{
			if( Grid_CurInstant_Recover_cnt > FAULT_FILTER_TIMES )
			{
				MicroInv_Fault_Flag.bit.Grid_OCP_SW = 0;
 //       DDL_Printf("Grid Current SW OCP Fault Cleared!\r\n");
				Grid_CurInstant_Recover_cnt = 0;
			}
			else
			{
				Grid_CurInstant_Recover_cnt++;
			}
		}
	}
  
	
		////////////////////PV CURRENT/////////////////////////
	if( Ipv > PVCUR_MAX_THRESHOLD && MicroInv_Fault_Flag.bit.PVCur_OCP_SW  == 0 )
	{
		PVCur_OCP_Recover_cnt = 0;
		if( PVCur_OCP_cnt > FAULT_FILTER_TIMES )
		{
			MicroInv_Fault_Flag.bit.PVCur_OCP_SW = 1;
//      DDL_Printf("PV Input Current SW OCP Fault Happened!\r\n");
			PVCur_OCP_cnt = 0;
		}
		else
		{
			PVCur_OCP_cnt++;
		}
	}
	else
	{
		PVCur_OCP_cnt = 0;
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.PVCur_OCP_SW==1 )
		{
			if( PVCur_OCP_Recover_cnt > FAULT_FILTER_TIMES )
			{
				MicroInv_Fault_Flag.bit.PVCur_OCP_SW = 0;
 //       DDL_Printf("PV Input Current SW OCP Fault Cleared!\r\n");
				PVCur_OCP_Recover_cnt = 0;
			}
			else
			{
				PVCur_OCP_Recover_cnt++;
			}
		}
	}
	#endif

//	///////////////HW fault/////////////

	uint8_t ExtFault_Flag = ((CM_EMB0->STAT&EMB_FLAG_PORT1)==EMB_FLAG_PORT1);
	if( ExtFault_Flag == 1 && MicroInv_Fault_Flag.bit.FB_OCP1_HW == 0 )
	{
		MicroInv_Fault_Flag.bit.FB_OCP1_HW = 1;
//		DDL_Printf("Flyback1 Current HW OCP Fault Happened!\r\n");
	}
	else
	{
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.FB_OCP1_HW == 1 )
		{
			MicroInv_Fault_Flag.bit.FB_OCP1_HW = 0;
//			DDL_Printf("Flyback1 Current HW OCP Fault Cleared!\r\n");
			CM_EMB0->STATCLR |= EMB_STATCLR_PORTINFCLR1;
		}
	}
	ExtFault_Flag = ((CM_EMB0->STAT&EMB_FLAG_PORT3)==EMB_FLAG_PORT3);
	if( ExtFault_Flag == 1 && MicroInv_Fault_Flag.bit.FB_OCP2_HW == 0 )
	{
		MicroInv_Fault_Flag.bit.FB_OCP2_HW = 1;
//		DDL_Printf("Flyback2 Current HW OCP Fault Happened!\r\n");
	}
	else
	{
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.FB_OCP2_HW == 1 )
		{
			MicroInv_Fault_Flag.bit.FB_OCP2_HW = 0;
	//		DDL_Printf("Flyback2 Current HW OCP Fault Cleared!\r\n");
			CM_EMB0->STATCLR |= EMB_STATCLR_PORTINFCLR3;
		}
	}	
	
	ExtFault_Flag = ((CM_EMB0->STAT&EMB_FLAG_PORT5)==EMB_FLAG_PORT5);
	if( ExtFault_Flag == 1 && MicroInv_Fault_Flag.bit.IACL_OCP_HW == 0 )
	{
		MicroInv_Fault_Flag.bit.IACL_OCP_HW = 1;
//		DDL_Printf("Grid Left Current HW OCP Fault Happened!\r\n");
	}
	else
	{
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.IACL_OCP_HW == 1 )
		{
			MicroInv_Fault_Flag.bit.IACL_OCP_HW = 0;
//			DDL_Printf("Grid Left Current HW OCP Fault Cleared!\r\n");
			CM_EMB0->STATCLR |= EMB_STATCLR_PORTINFCLR5;
		}
	}
	
	ExtFault_Flag = ((CM_EMB0->STAT&EMB_FLAG_PORT2)==EMB_FLAG_PORT2);
	if( ExtFault_Flag == 1 && MicroInv_Fault_Flag.bit.IACR_OCP_HW == 0 )
	{
		MicroInv_Fault_Flag.bit.IACR_OCP_HW = 1;
	//	DDL_Printf("Grid Right Current HW OCP Fault Happened!\r\n");
	}
	else
	{
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.IACR_OCP_HW == 1 )
		{
			MicroInv_Fault_Flag.bit.IACR_OCP_HW = 0;
//			DDL_Printf("Grid Right Current HW OCP Fault Cleared!\r\n");
			CM_EMB0->STATCLR |= EMB_STATCLR_PORTINFCLR2;
		}
	}
	
	ExtFault_Flag = ((CM_EMB0->STAT&EMB_FLAG_PORT4)==EMB_FLAG_PORT4);
	if( ExtFault_Flag == 1 && MicroInv_Fault_Flag.bit.VBUS_OVP_HW == 0 )
	{
		MicroInv_Fault_Flag.bit.VBUS_OVP_HW = 1;
//		DDL_Printf("Flyback Output Voltage HW OVP Fault Happened!\r\n");
	}
	else
	{
		if( System_Fault_CLR_cmd == 1 && MicroInv_Fault_Flag.bit.VBUS_OVP_HW == 1 )
		{
			MicroInv_Fault_Flag.bit.VBUS_OVP_HW = 0;
	//		DDL_Printf("Flyback Output Voltage HW OVP Fault Cleared!\r\n");
			CM_EMB0->STATCLR |= EMB_STATCLR_PORTINFCLR4;
		}
	}

	if( MicroInv_Fault_Flag.all != 0 )
	{
		AllPWM_Disable();
	}
}

