
#include "head.h"
#ifdef __IEC61850_GOOSE_FUNC__
#include "app_61850.h"
#endif
#include "goose.h"

int g_bgseEnable;

const struct gse_tbl g_goose_send_tbl[GOOSE_SEND_TBL_NUMBER]=
{
	{"节点故障",				"GSE_KO_FAULT"},
	{"故障隔离成功",		"GSE_KO_GLOK"},
	{"开关拒跳",				"GSE_KO_JT"},
	{"过流闭锁",				"GSE_KO_GLBS"},
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 //中山要求通信异常，全系统均异常
	{"状态闭锁值",			"GSE_KO_BS_STATUS"},
	{"状态复归值",				"GSE_KO_BS_FG"},
#endif
};
const struct gse_tbl g_goose_recv_tbl[GOOSE_RECV_TBL_NUMBER]=
{
	{"M侧节点故障01",			"GSE_KI_M01"},
	{"M侧节点故障02",			"GSE_KI_M02"},
	{"M侧节点故障03",			"GSE_KI_M03"},
	{"M侧节点故障04",			"GSE_KI_M04"},
	{"M侧节点故障05",			"GSE_KI_M05"},
	{"M侧节点故障06",			"GSE_KI_M06"},
	{"M侧节点故障07",			"GSE_KI_M07"},
	{"M侧节点故障08",			"GSE_KI_M08"},
	
	{"N侧节点故障01",			"GSE_KI_N01"},
	{"N侧节点故障02",			"GSE_KI_N02"},
	{"N侧节点故障03",			"GSE_KI_N03"},
	{"N侧节点故障04",			"GSE_KI_N04"},

	{"M侧障隔离成功01",		"GSE_KI_GLCG01"},
	{"M侧障隔离成功02",		"GSE_KI_GLCG02"},
	{"M侧障隔离成功03",		"GSE_KI_GLCG03"},
	{"M侧障隔离成功04",		"GSE_KI_GLCG04"},
	{"M侧障隔离成功05",		"GSE_KI_GLCG05"},
	{"M侧障隔离成功06",		"GSE_KI_GLCG06"},
	{"M侧障隔离成功07",		"GSE_KI_GLCG07"},
	{"M侧障隔离成功08",		"GSE_KI_GLCG08"},
	{"N侧障隔离成功01",		"GSE_KI_GLCG09"},
	{"N侧障隔离成功02",		"GSE_KI_GLCG10"},
	{"N侧障隔离成功03",		"GSE_KI_GLCG11"},
	{"N侧障隔离成功04",		"GSE_KI_GLCG12"},	
	
	{"M侧开关拒跳01",			"GSE_KI_JT01"},
	{"M侧开关拒跳02",			"GSE_KI_JT02"},
	{"M侧开关拒跳03",			"GSE_KI_JT03"},
	{"M侧开关拒跳04",			"GSE_KI_JT04"},
	{"M侧开关拒跳05",			"GSE_KI_JT05"},
	{"馈线开关拒跳01",			"GSE_KI_JT06"},
	{"馈线开关拒跳02",			"GSE_KI_JT07"},
	{"馈线开关拒跳03",			"GSE_KI_JT08"},
	{"N侧开关拒跳01",			"GSE_KI_JT09"},
	{"N侧开关拒跳02",			"GSE_KI_JT10"},
	{"N侧开关拒跳03",			"GSE_KI_JT11"},
	{"馈线开关拒跳04",			"GSE_KI_JT12"},

	{"馈线过流闭锁01",			"GSE_KI_GLBS01"},
	{"馈线过流闭锁02",			"GSE_KI_GLBS02"},
	{"馈线过流闭锁03",			"GSE_KI_GLBS03"},
	{"馈线过流闭锁04",			"GSE_KI_GLBS04"},
	{"馈线过流闭锁05",			"GSE_KI_GLBS05"},
	{"馈线过流闭锁06",			"GSE_KI_GLBS06"},	
	{"馈线过流闭锁07",			"GSE_KI_GLBS07"},
	{"馈线过流闭锁08",			"GSE_KI_GLBS08"},
	{"馈线过流闭锁09",			"GSE_KI_GLBS09"},
	{"馈线过流闭锁10",			"GSE_KI_GLBS10"},
	{"馈线过流闭锁11",			"GSE_KI_GLBS11"},
	{"馈线过流闭锁12",			"GSE_KI_GLBS12"},

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020  //中山要求通信异常，全系统均异常
	{"状态闭锁值01",				"GSE_KI_BS_STATUS01"},
	{"状态闭锁值02",				"GSE_KI_BS_STATUS02"},
	{"状态闭锁值03",				"GSE_KI_BS_STATUS03"},
	{"状态闭锁值04",				"GSE_KI_BS_STATUS04"},
	{"状态闭锁值05",				"GSE_KI_BS_STATUS05"},
	{"状态闭锁值06",				"GSE_KI_BS_STATUS06"},
	{"状态闭锁值07",				"GSE_KI_BS_STATUS07"},
	{"状态闭锁值08",				"GSE_KI_BS_STATUS08"},
	{"状态闭锁值09",				"GSE_KI_BS_STATUS09"},
	{"状态闭锁值10",				"GSE_KI_BS_STATUS10"},
	{"状态闭锁值11",				"GSE_KI_BS_STATUS11"},
	{"状态闭锁值12",				"GSE_KI_BS_STATUS12"},	
	{"状态复归值01",				"GSE_KI_FG_STATUS01"},
	{"状态复归值02",				"GSE_KI_FG_STATUS02"},
	{"状态复归值03",				"GSE_KI_FG_STATUS03"},
	{"状态复归值04",				"GSE_KI_FG_STATUS04"},
	{"状态复归值05",				"GSE_KI_FG_STATUS05"},
	{"状态复归值06",				"GSE_KI_FG_STATUS06"},
	{"状态复归值07",				"GSE_KI_FG_STATUS07"},
	{"状态复归值08",				"GSE_KI_FG_STATUS08"},
	{"状态复归值09",				"GSE_KI_FG_STATUS09"},
	{"状态复归值10",				"GSE_KI_FG_STATUS10"},
	{"状态复归值11",				"GSE_KI_FG_STATUS11"},
	{"状态复归值12",				"GSE_KI_FG_STATUS12"},	
#endif
};

FA_GOOSE tFAg;
bool bFAgInit=false;

void fa_g_init(void)
{
	int i;
	if(!bFAgInit)  // 61850 初始化会调用 fa_g_extinit ,将初始化部分tFAg的变量，两处调用可能先后顺序不确定，保证只初始化一次
	{
		bFAgInit=true;
		memset(&tFAg,0,sizeof(tFAg));
	}
	for(i=0;i<GOOSE_RECV_TBL_NUMBER;i++)
	{
		tFAg.inval[i]=-1;  // 默认为-1 ，有正确接收时置位
	}
	InitTR(&tFAg.tRstTime,pRunSet->dT_sendext*100, 0);  
	InitTR(&tFAg.tGooseStillTime,T_20ms,T_20ms);  	
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
	InitTR(&tFAg.tErrfgtime,tRunPara.gse_T1,0);  		
#endif
	fa_g_packet(true);	//发送数据初始化
}

// buf 为32个遥信的起始位置
void fa_g_unpack(void)
{
	int i;
	bool bgzglok=0;
	int sw=0;
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	TRELAY_T *pR=&g_tRelay[sw];
	if(BH_GOOSE_EN_YB(sw))   //智能FA 不投入时，不处理订阅信息
	{
		for(i=0;i<=GOOSE_RECV_LOGIC_NUM;i++)
		{
			int soeno=EV_GOOSE_BGN+i;
			if(tFAg.inval[i]>0)
			{
				if(soe_check(soeno)==false)
				{
					soe_record_ev(soeno, 1, 0,0,0 );
					ResetTR(&tFAg.tRstTime);
				}
			}
			else
			{
				if(soe_check(soeno)==true)
				{
					soe_record_ev(soeno, 0, 0,0,0 );
				}
			}
		}
		for(i=0;i<GOOSE_EQU_SIDE+GOOSE_EQU_SIDE_N;i++)
		{
			tFAg.ugside[i].bFlag.bgl=(tFAg.inval[GOOSE_RECV_TBL_M01+i]>0)?1:0;
			tFAg.ugside[i].bFlag.bgzglok=(tFAg.inval[GOOSE_RECV_TBL_GL01+i]>0)?1:0;
			tFAg.ugside[i].bFlag.bglbs=(tFAg.inval[GOOSE_RECV_TBL_GLBS01+i]>0)?1:0;
			bgzglok|=tFAg.ugside[i].bFlag.bgzglok;
		}
		for(i=0;i<GOOSE_EQU_MAX;i++)
		{
			tFAg.ugside[i].bFlag.btzsb=(tFAg.inval[GOOSE_RECV_TBL_JT01+i]>0)?1:0;
		}
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020  //中山要求通信异常，全系统均异常
		{
			u32 st,fg;
			uint32_t  flags;
			st=0;
			fg=0;
			for(i=0;i<GOOSE_EQU_MAX;i++)
			{
				st|=tFAg.inval[GOOSE_RECV_TBL_STATUS01+i];
				fg|=tFAg.inval[GOOSE_RECV_TBL_FG01+i];		
			}
			rt_irq_save(flags);
			tFAg.commerrst|=(st&~(1<<tRunPara.gse_id));
			if(tFAg.commerrst)
			{
				tFAg.commerrfg|=(fg&~(1<<tRunPara.gse_id));
			}
			if((st&(1<<tRunPara.gse_id))&&tFAg.commerr==0)  // 本机收到其他装置本机闭锁，但本机已恢复数据，重新发送复归值
			{
				tFAg.commerrfg|=(1<<tRunPara.gse_id);
			}			
			for(i=0;i<GOOSE_EQU_MAX;i++)
			{
				if(tFAg.inval[GOOSE_RECV_TBL_STATUS01+i])  // 现阶段，本段代码起不了作用，原因是61850接收时，把本身保存的接收控制块的数据重新拷贝了过来，这儿清掉，重新接收后又被赋值
				{
					tFAg.inval[GOOSE_RECV_TBL_STATUS01+i]&=(~tFAg.commerrfg); // 清保存的本机闭锁值，防止通信异常，闭锁值无法更新
				}
			}				
			tFAg.commerrst&=(~tFAg.commerrfg);	
			rt_irq_restore(flags);	
			
		}
#endif
		
		if(bgzglok)  //收到故障隔离成功信息，需转发
		{
			if(pR->tSWST.uSWST.bFlag.bTZWZ) //开关在跳位不转发
			{
				return;
			}	
			if(pRunSet->tSwSet[sw].tGocSet.bsw_fz) //分支开关不转发
			{
				return;
			}	 
			if(g_tRelay[sw].tgoc.bTzout) // 本装置处于跳闸状态，不转发故障隔离信号
			{
				RunTR(&poc->tgzglokForbitTime, true, 1);		//故障隔离发送闭锁
				return;
			}
			if(!poc->tgzglokForbitTime.boolTrip) //故障隔离发送未闭锁
			{
				RunTR(&poc->tgzglokextTime, true, 1);		
				poc->psta.bFlag.bgzglok=poc->tgzglokextTime.boolTrip;
				RunTR(&poc->tgzglokForbitTime, poc->psta.bFlag.bgzglok, 1);		//故障隔离发送闭锁
			}
		}
		if(soe_check(EV_GOOSE_DECODE)==true)
		{				
			soe_record_ev(EV_GOOSE_DECODE,0, 0,0,0 ); 
		}
	}
}		


void fa_g_decode(int commstate)
{
	int sw=0;
//	TGOC_T *poc=&g_tRelay[ sw].tgoc;		
	if((commstate==-1)&&BH_GOOSE_EN_YB(sw))
	{
		if(soe_check(EV_GOOSE_DECODE)==false)
		{				
			soe_record_ev(EV_GOOSE_DECODE,1, 0,0,0 ); 
		}
		return;
	}
#if 0
	if((commstate>0)&&BH_GOOSE_EN_YB(sw))
	{
		if(soe_check(EV_GOOSE_ERR)==false)
		{				
			soe_record_ev(EV_GOOSE_ERR,1, 0,0,0 ); 
			poc->psta.bFlag.bcomerr=1;
		}
		if(soe_check(EV_SYS_GOOSE_ERR)==false)	//置系统通信异常soe
		{
			soe_record_ev(EV_SYS_GOOSE_ERR, 1, 0,0,0 );
			tFAg.syscomerr=1;  //goose系统通信异常
		}		
		tFAg.commerr=1;
	}
	else
	{
		if(soe_check(EV_GOOSE_ERR)==true)
		{				
			soe_record_ev(EV_GOOSE_ERR,0, 0,0,0 ); 
		}
		tFAg.commerr=0;
	}
	#endif
}

void fa_g_extinit(int num,int firstaddr) // app_goose.c中调用fa_g.c中的变量初始化
{
	int i;
	if(num>=GOOSE_RECV_GOLBNUM)num=GOOSE_RECV_GOLBNUM;
	if(!bFAgInit)
	{
		bFAgInit=true;
		memset(&tFAg,0,sizeof(tFAg));
	}	
	tFAg.recvgolbnum=num;
	for(i=0;i<num;i++)
	{
		tFAg.dTrecv[i]=dTCounter;
	}
	tFAg.bNside=false;
	if(num==1&&firstaddr>=GOOSE_RECV_TBL_N01)tFAg.bNside=true; // 若输入控制块只有一个，判断是M侧还是N侧
}
void fa_g_gocbrecvdT(int index) // app_goose.c中接收后调用，用于通信超时处理
{
	if(index<GOOSE_RECV_GOLBNUM)
	{
		tFAg.dTrecv[index]=dTCounter;		
	}
}

void fa_g_bs_fa(int sw)
{
	TRELAY_T *pR=&g_tRelay[sw];
	TSETSW *pSet = &pRunSet->tSwSet[sw];				
	TGOC_T *poc=&g_tRelay[ sw].tgoc;		
	 if( pR->tSWST.uSWST.bFlag.bTZWZ&&(!pSet->tGocSet.bsw_ll&&!pSet->tGocSet.bsw_fz))
	 {
		if(poc->bgooseGz)
		{
			if(soe_check(EV_GOOSE_GZBS_FA)==false)	// goose故障闭锁
			{
				soe_record_ev(EV_GOOSE_GZBS_FA, 1, 0,0,0 );
			}
		}
		else
		{
			if(soe_check(EV_GOOSE_TZBS_FA)==false)	// goose故障闭锁
			{
				soe_record_ev(EV_GOOSE_TZBS_FA, 1, 0,0,0 );
			}
		}
		poc->bgooseBsHz=true;
	 }
	 else
	 {
		poc->bgooseGz=false;
		poc->bgooseBsHz=false;
	 }
}

#ifdef GOOSE_NETTYPE_SET
extern unsigned char fec_get_hsr_prp_flag(void);//返回订阅点组网类型
#endif 
void fa_g_app_time(int sw) // 1s  执行一次函数
{	
	sw=0;
#ifdef GD_AREA_ZHUHAI_V2 //珠海局，单一网口网线掉了，需弹soe	
	if( rt_get_net_linkstatus(0) && BH_GOOSE_EN_YB(sw)&&g_goose_net_type)  //普通模式，不报单网卡掉线
	{
		if(soe_check(EV_NET1_DOWN)==false)
		{				
			soe_record_ev(EV_NET1_DOWN,1, 0,0,0 ); 
		}
	}
	else
	{
		if(soe_check(EV_NET1_DOWN)==true)
		{				
			soe_record_ev(EV_NET1_DOWN,0, 0,0,0 ); 
		}
	}
	if( rt_get_net_linkstatus(1) && BH_GOOSE_EN_YB(sw)&&g_goose_net_type)
	{
		if(soe_check(EV_NET2_DOWN)==false)
		{				
			soe_record_ev(EV_NET2_DOWN,1, 0,0,0 ); 
		}
	}
	else
	{
		if(soe_check(EV_NET2_DOWN)==true)
		{				
			soe_record_ev(EV_NET2_DOWN,0, 0,0,0 ); 
		}
	}
#endif

#ifdef GOOSE_NETTYPE_SET
	u8 temp;
	static u8 nettype;
	static u32 count;

	//unsigned char fec_get_hsr_prp_flag()
	//return 1--hsr;return 2--prp;return 3--hsr&prp
	if(BH_GOOSE_EN(sw)&&g_goose_net_type)//
	{
		//nettype		
		temp=fec_get_hsr_prp_flag();
		if(temp)
		{
			nettype |= temp;
		}
		//10s判一次
		count++;	
		if(count%10==0) 
		{
			if(nettype)
			{
				if(nettype&g_goose_net_type)
				{
					if(soe_check(EV_GOOSE_NETTYPE_ERR)==true)
					{				
						soe_record_ev(EV_GOOSE_NETTYPE_ERR,0, 0,0,0 ); 
					}
				}						
				else
				{
					if(soe_check(EV_GOOSE_NETTYPE_ERR)==false)
					{				
						soe_record_ev(EV_GOOSE_NETTYPE_ERR,1, 0,0,0 ); 
					}
				}
			}
			nettype=0;
		}			
	}
	else
	{
		if(soe_check(EV_GOOSE_NETTYPE_ERR)==true)
		{				
			soe_record_ev(EV_GOOSE_NETTYPE_ERR,0, 0,0,0 ); 
		}
	}	
#endif

#ifdef GD_AREA_ZHONGSHAN_2020// 中山局
	{
		bool bCfgerr;
		bCfgerr=pRunSet->tSwSet[sw].tGocSet.bKg_mainloop  // 主环开关
				&&(tFAg.recvgolbnum==0)                              //接收控制块未配置
				&&(gi_platelib_state ==IEC61850_LIB_INIT_SUCCESS); // 61850初始化完毕
		if(bCfgerr)
		{
			if(soe_check(EV_GOOSE_CONFIG_ERR)==false)
			{				
				soe_record_ev(EV_GOOSE_CONFIG_ERR,1, 0,0,0 ); 
			}

		}
		else
		{
			if(soe_check(EV_GOOSE_CONFIG_ERR)==true)
			{				
				soe_record_ev(EV_GOOSE_CONFIG_ERR,0, 0,0,0 ); 
			}
		}
	}
#endif
}
void fa_g_commcheck(DWORD dStep) // 防止goose信息丢失，相关置位信息延时复归
{
	int i;
	bool bret=false;
	bool boverdT=false;
	int sw=0;
	for(i=0;i<=GOOSE_RECV_LOGIC_NUM;i++)
	{
		bret|=(tFAg.inval[i]>0)?true:false;
	}
  	RunTR(&tFAg.tRstTime, bret, dStep);		//  信息延迟复归
  	if(tFAg.tRstTime.boolTrip)
	{
		for(i=0;i<=GOOSE_RECV_LOGIC_NUM;i++)
		{
			if(tFAg.tRstTime.boolTrip&&(tFAg.inval[i]>0))tFAg.inval[i]=0;
		}
		ResetTR(&tFAg.tRstTime);
		fa_g_unpack();
	}

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
	if(tFAg.commerr)
	{
		tFAg.commerrst|=(1<<tRunPara.gse_id);
		tFAg.commerrfg&=~(1<<tRunPara.gse_id); // 本机通信异常，清除复归位
	}
	else
	{
		tFAg.commerrst&=~(1<<tRunPara.gse_id);
	}
	if(tFAg.commerrst>0) // 
	{
		if(soe_check(EV_SYS_GOOSE_ERR)==false)	//置系统通信异常soe
		{
			soe_record_ev(EV_SYS_GOOSE_ERR, 1, 0,0,0 );
			tFAg.syscomerr=1;  //goose系统通信异常
			fa_g_bs_fa(sw);	
			if(tFAg.commerr)
			{
				InitTR(&tFAg.tErrfgtime,tRunPara.gse_T1,0); 	 // 若是本机通信异常，发送时间为T1
			}
			else
			{
				InitTR(&tFAg.tErrfgtime,tRunPara.gse_T2,0); 	 // 若不是本机通信异常，发送时间为T2
			}			
		}	
	}
	else
	{
		if(soe_check(EV_SYS_GOOSE_ERR)==true)	//置系统通信异常soe
		{
			soe_record_ev(EV_SYS_GOOSE_ERR, 0, 0,0,0 );
			tFAg.syscomerr=0;  //goose系统通信异常
		}
	}
	RunTR(&tFAg.tErrfgtime, tFAg.commerrfg, dStep);	//	分布式功能投入
	if(tFAg.tErrfgtime.boolTrip) //复归发送时间到，清复归标志:条件 无通信异常
	{
		tFAg.commerrfg&=tFAg.commerrst;			
		ResetTR(&tFAg.tErrfgtime);			
	}
#endif
	
	for(i=0;i<tFAg.recvgolbnum;i++)
	{
		boverdT|=((dTCounter-tFAg.dTrecv[i])>T_1s*20)?true:false;
		if(!BH_GOOSE_EN_YB(sw))
		{
			tFAg.dTrecv[i]=dTCounter;
			}
#ifdef GD_AREA_ZHUHAI_V2 //珠海局，要求报M和N侧故障
		{
			bool berr=((dTCounter-tFAg.dTrecv[i])>T_1s*20)?true:false;
			if(berr&&BH_GOOSE_EN_YB(sw))
			{
				if(((i==tFAg.recvgolbnum-1)&&(tFAg.recvgolbnum>1))||tFAg.bNside)
				{
					if(soe_check(EV_GOOSE_ERR_N)==false)
					{				
						soe_record_ev(EV_GOOSE_ERR_N,1, 0,0,0 ); 
					}
				}
				else
				{
					if(soe_check(EV_GOOSE_ERR_M)==false)
					{				
						soe_record_ev(EV_GOOSE_ERR_M,1, 0,0,0 ); 
					}
				}
			}
			else
			{
				if(((i==tFAg.recvgolbnum-1)&&(tFAg.recvgolbnum>1))||tFAg.bNside)
				{
					if(soe_check(EV_GOOSE_ERR_N)==true)
					{				
						soe_record_ev(EV_GOOSE_ERR_N,0, 0,0,0 ); 
					}
				}
				else if(soe_check(EV_GOOSE_ERR_M)==true)
				{
					int j;
					bool berr1=false;
					for(j=0;j<tFAg.recvgolbnum-1;j++)
					{
						berr1|=((dTCounter-tFAg.dTrecv[j])>T_1s*20)?true:false;
					}
					if(berr1==false)
					{
						soe_record_ev(EV_GOOSE_ERR_M,0, 0,0,0 ); 
					}
				}
			}
		}
#endif
	}
	if(boverdT&&BH_GOOSE_EN_YB(sw))
	{
//#ifndef GD_AREA_ZHUHAI_V2 //珠海局，要求报M和N侧故障
		if(soe_check(EV_GOOSE_ERR)==false)
		{				
			soe_record_ev(EV_GOOSE_ERR,1, 0,0,0 ); 			
		}
//#endif		
		tFAg.commerr=1;
	}
	else
	{
//#ifndef GD_AREA_ZHUHAI_V2 //珠海局，要求报M和N侧故障
		if(soe_check(EV_GOOSE_ERR)==true)
		{				
			soe_record_ev(EV_GOOSE_ERR,0, 0,0,0 );   //本机通信恢复 
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
			tFAg.commerrfg|=(1<<tRunPara.gse_id);	 // 本机通信恢复,置复归位
#endif
		}
//#endif
		tFAg.commerr=0;		
	}
	
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 

	//分布式FA由投入转为退出时，需处理闭锁FA 的相关信息，同通信异常类似
	RunTR(&tFAg.tGooseStillTime, BH_GOOSE_EN_YB(sw), dStep);	//	分布式功能投入
	bret=tFAg.tGooseStillTime.boolTrip&&(!BH_GOOSE_EN_YB(sw)); // 分布式功能由投入转为退出
	if(bret)
	{
		fa_g_bs_fa(sw); 	
		ResetTR(&tFAg.tGooseStillTime);
	}	
#endif	
}

void fa_g_packet(bool bfirst)
{
	int sw=0;
	UGOOSE_STU *pug=&tFAg.ug;	
	TRELAY_T *pR=&g_tRelay[sw];
	TGOC_T *poc=&pR->tgoc;		
	bool bcommerrsend=false;

	pug->bFlag.bzx=poc->psta.bFlag.bZX;    						// 本线路正向故障 
	pug->bFlag.bfx=poc->psta.bFlag.bFX;   						// 本线路反向故障 
	pug->bFlag.blx=poc->psta.bFlag.bLX;						//本线路无方向故障
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 || defined GD_AREA_MAIN_2020	
	pug->bFlag.bgl=poc->psta.bFlag.bWX||poc->psta2.bFlag.bWX;						// 本线路跳闸失败
#else
	pug->bFlag.bgl=poc->psta.bFlag.bWX;						// 本线路跳闸失败
#endif
	
	pug->bFlag.bgzglok=poc->psta.bFlag.bgzglok;						// 本线路跳闸失败
	pug->bFlag.btzsb=poc->psta.bFlag.btzsb||(pR->uBHDZ.bFlag.bTZSB&&pRunSet->bTT_fhkg_pub);						// 本线路跳闸失败
	pug->bFlag.bglbs=poc->psta.bFlag.bGLBS;		 //负荷开关

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020  //中山要求通信异常，全系统均异常
	if(tFAg.commerrst!=tFAg.commerrstsave||tFAg.commerrfg!=tFAg.commerrfgsave)
	{
		bcommerrsend=true;		
		tFAg.commerrstsave=tFAg.commerrst;
		tFAg.commerrfgsave=tFAg.commerrfg;
	}	
#endif
	g_bgseEnable=BH_GOOSE_EN_YB(sw)||pRunSet->bTT_fhkg_pub;	
	if((pug->wfFlag!=tFAg.ug_save)||bfirst||bcommerrsend)  //启动goose 发送
	{
		int *dat=tFAg.outval;
		tFAg.ug_save=pug->wfFlag;
		dat[GOOSE_SEND_TBL_GZ]=(pug->bFlag.bgl||pug->bFlag.blx||pug->bFlag.bTstgz);
		dat[GOOSE_SEND_TBL_GL]=(pug->bFlag.bgzglok||pug->bFlag.bTstglok);
		dat[GOOSE_SEND_TBL_JT]=(pug->bFlag.btzsb)||pug->bFlag.bTstjt;  //开关拒跳:智能FA逻辑或负荷开关常规动作拒跳
		dat[GOOSE_SEND_TBL_GLBS]=pug->bFlag.bglbs||pug->bFlag.bTstglbs;		 //负荷开关
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020  //中山要求通信异常，全系统均异常
		dat[GOOSE_SEND_TBL_STATUS]=tFAg.commerrstsave; 	 // 通信状态
		dat[GOOSE_SEND_TBL_FG]=tFAg.commerrfgsave;	 //复归值
#endif
		if(!bfirst)
		{
			tFAg.bSend=true;
		#ifdef __IEC61850_GOOSE_FUNC__	
			goose_send_wakeup();
		#endif
		}
	}
	
}


// A相电流方向判断
void GOc_dir_phA(int sw)
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	int indexI;
	bool bzx,bfx;	
	u32 dIgl,dIgl_fh;
	dIgl=pSet->dIgl;
	dIgl_fh=pSet->dIgl_fh;
	indexI=UI_SW_INDEX(sw,SW_AC_IA);	

	poc->psta.bFlag.bQDA = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta.bFlag.bQDA);  // A相过流启动
	bzx=CalDir_A(sw,poc->psta.bFlag.bQDA&&pSet->bTT_DIR,false);
	bfx=(!bzx)&&poc->psta.bFlag.bQDA&&pSet->bTT_DIR;

	poc->psta.bFlag.bZXA=poc->psta.bFlag.bQDA		// A相电流启动
						&&bzx					// 正方向
						&&pSet->bTT_DIR		//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);

	poc->psta.bFlag.bFXA=poc->psta.bFlag.bQDA		// A相电流启动
						&&(bfx)					//反方向
						&&pSet->bTT_DIR		//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);


	poc->psta.bFlag.bWXA=poc->psta.bFlag.bQDA		// A相电流启动
						&&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC);	// 功率方向退出或功率方向投入，PT异常退方向)

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
	dIgl=pSet->dIgl2;
	dIgl_fh=pSet->dIgl2_fh;
	poc->psta2.bFlag.bQDA = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta2.bFlag.bQDA);  // A相过流启动
	bzx=CalDir_A(sw,poc->psta2.bFlag.bQDA&&pSet->bTT_DIR,false);
	bfx=(!bzx)&&poc->psta2.bFlag.bQDA&&pSet->bTT_DIR;

	poc->psta2.bFlag.bZXA=poc->psta2.bFlag.bQDA		// A相电流启动
						&&bzx					// 正方向
						&&pSet->bTT_DIR		//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);

	poc->psta2.bFlag.bFXA=poc->psta2.bFlag.bQDA		// A相电流启动
						&&(bfx)					//反方向
						&&pSet->bTT_DIR		//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);


	poc->psta2.bFlag.bWXA=poc->psta2.bFlag.bQDA		// A相电流启动
						&&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC);	// 功率方向退出或功率方向投入，PT异常退方向)

#endif	
}

// B相电流方向判断
void GOc_dir_phB(int sw)
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	int indexI;
	bool bzx,bfx;	
	u32 dIgl,dIgl_fh;
	dIgl=pSet->dIgl;
	dIgl_fh=pSet->dIgl_fh;
	indexI=UI_SW_INDEX(sw,SW_AC_IB);		
	poc->psta.bFlag.bQDB = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta.bFlag.bQDB);  // A相过流启动
	bzx=CalDir_B(sw,poc->psta.bFlag.bQDB&&pSet->bTT_DIR,false);
	bfx=(!bzx)&&poc->psta.bFlag.bQDB&&pSet->bTT_DIR;
	
	poc->psta.bFlag.bZXB=poc->psta.bFlag.bQDB		// A相电流启动
						&&bzx					// 正方向
						&&pSet->bTT_DIR					//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta.bFlag.bFXB=poc->psta.bFlag.bQDB		// A相电流启动
						&&(bfx)					//反方向
						&&pSet->bTT_DIR					//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta.bFlag.bWXB=poc->psta.bFlag.bQDB		// A相电流启动
						&&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC);	// 功率方向退出或功率方向投入，PT异常退方向)

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
	dIgl=pSet->dIgl2;
	dIgl_fh=pSet->dIgl2_fh;
	poc->psta2.bFlag.bQDB = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta2.bFlag.bQDB);  // A相过流启动
	bzx=CalDir_B(sw,poc->psta2.bFlag.bQDB&&pSet->bTT_DIR,false);
	bfx=(!bzx)&&poc->psta2.bFlag.bQDB&&pSet->bTT_DIR;
	
	poc->psta2.bFlag.bZXB=poc->psta2.bFlag.bQDB		// A相电流启动
						&&bzx					// 正方向
						&&pSet->bTT_DIR					//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta2.bFlag.bFXB=poc->psta2.bFlag.bQDB		// A相电流启动
						&&(bfx)					//反方向
						&&pSet->bTT_DIR					//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta2.bFlag.bWXB=poc->psta2.bFlag.bQDB		// A相电流启动
						&&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC);	// 功率方向退出或功率方向投入，PT异常退方向)

#endif	
}

// C相电流方向判断
void GOc_dir_phC(int sw)
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	int indexI;
	bool bzx,bfx;	
	u32 dIgl,dIgl_fh;
	dIgl=pSet->dIgl;
	dIgl_fh=pSet->dIgl_fh;
	indexI=UI_SW_INDEX(sw,SW_AC_IC);		
	poc->psta.bFlag.bQDC = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta.bFlag.bQDC);  // A相过流启动
	bzx=CalDir_C(sw,poc->psta.bFlag.bQDC&&pSet->bTT_DIR,false);
	bfx=(!bzx)&&poc->psta.bFlag.bQDC&&pSet->bTT_DIR;
	
	poc->psta.bFlag.bZXC=poc->psta.bFlag.bQDC		// A相电流启动
						&&bzx					// 正方向
						&&pSet->bTT_DIR					//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta.bFlag.bFXC=poc->psta.bFlag.bQDC		// A相电流启动
						&&(bfx)					//反方向
						&&pSet->bTT_DIR					//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta.bFlag.bWXC=poc->psta.bFlag.bQDC		// A相电流启动
						&&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC);	// 功率方向未投入，或PT异常
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
	dIgl=pSet->dIgl2;
	dIgl_fh=pSet->dIgl2_fh;
	poc->psta2.bFlag.bQDC = OverRelay(g_ui[indexI ].m2[0], dIgl, dIgl_fh, poc->psta2.bFlag.bQDC);  // A相过流启动
	bzx=CalDir_C(sw,poc->psta2.bFlag.bQDC&&pSet->bTT_DIR,false);
	bfx=(!bzx)&&poc->psta2.bFlag.bQDC&&pSet->bTT_DIR;

	poc->psta2.bFlag.bZXC=poc->psta2.bFlag.bQDC		// A相电流启动
						&&bzx					// 正方向
						&&pSet->bTT_DIR 				//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta2.bFlag.bFXC=poc->psta2.bFlag.bQDC		// A相电流启动
						&&(bfx) 				//反方向
						&&pSet->bTT_DIR 				//功率方向投入
						&&(!tPT.uPT1DX.bFlag.bPTYC);  //  无TV异常

	poc->psta2.bFlag.bWXC=poc->psta2.bFlag.bQDC		// A相电流启动
						&&(!pSet->bTT_DIR||tPT.uPT1DX.bFlag.bPTYC); // 功率方向未投入，或PT异常
	
#endif		

}

void GOc_lx_check(int sw)
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	int indexI;
	
	indexI=UI_SW_INDEX(sw,SW_AC_I0);	
	poc->psta.bFlag.bQDLX = OverRelay(g_ui[indexI ].m2[0], pSet->dIlx, pSet->dIlx_fh, poc->psta.bFlag.bQDLX);  //零序启动

}
bool GOC_bh_all(int sw)
{
	int i;
	for(i=BH_GL1;i<=FA_LX2;i++)
	{
		if(g_tRelay[sw].tOC[i].sta.bFlag.bQD)return true;
	}	
	return false;
}

void GOC_dir_check(int sw,u32  dStep)
{
	bool bY1;
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOc_dir_phA(sw);
	GOc_dir_phB(sw);
	GOc_dir_phC(sw);
	GOc_lx_check(sw);

	//正方向判断，保持2秒
	bY1=(poc->psta.bFlag.bZXA||poc->psta.bFlag.bZXB||poc->psta.bFlag.bZXC)&&(!poc->sta.bFlag.bXBbs)&&BH_GOOSE_EN_YB(sw);
	RunTR(&poc->tTZX_300ms, bY1, dStep);
	poc->psta.bFlag.bZX=poc->tTZX_300ms.boolTrip;
	//反方向判断，保持2秒
	bY1=(poc->psta.bFlag.bFXA||poc->psta.bFlag.bFXB||poc->psta.bFlag.bFXC)&&(!poc->sta.bFlag.bXBbs)&&BH_GOOSE_EN_YB(sw);
	RunTR(&poc->tTFX_300ms, bY1, dStep);
	poc->psta.bFlag.bFX=poc->tTFX_300ms.boolTrip;

	//无方向判断，保持2秒
	bY1=(poc->psta.bFlag.bWXA||poc->psta.bFlag.bWXB||poc->psta.bFlag.bWXC)&&(!poc->sta.bFlag.bXBbs)&&BH_GOOSE_EN_YB(sw);
	RunTR(&poc->tTWX_300ms, bY1, dStep);
	poc->psta.bFlag.bWX=poc->tTWX_300ms.boolTrip;	

	//零序判断，保持2秒
	bY1=poc->psta.bFlag.bQDLX&&BH_GOOSE_EN_YB(sw);
	RunTR(&poc->tTLX_300ms, bY1, dStep);
	poc->psta.bFlag.bLX=poc->tTLX_300ms.boolTrip;	

	//过流闭锁
	bY1=(GOC_bh_all(sw)&&pRunSet->bTT_fhkg_pub);		 //负荷开关
	RunTR(&poc->tTGLBS_300ms, bY1, dStep);
	poc->psta.bFlag.bGLBS=poc->tTGLBS_300ms.boolTrip;	
	
	poc->psta.bFlag.bGZ=poc->psta.bFlag.bZX|poc->psta.bFlag.bFX|poc->psta.bFlag.bWX|poc->psta.bFlag.bLX;  //线路有故障

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
	//正方向判断，保持2秒
	bY1=(poc->psta2.bFlag.bZXA||poc->psta2.bFlag.bZXB||poc->psta2.bFlag.bZXC)&&(!poc->sta.bFlag.bXBbs2)&&BH_GOOSE_EN_YB(sw);
	RunTR(&poc->tTZX2_300ms, bY1, dStep);
	poc->psta2.bFlag.bZX=poc->tTZX2_300ms.boolTrip;
	//反方向判断，保持2秒
	bY1=(poc->psta2.bFlag.bFXA||poc->psta2.bFlag.bFXB||poc->psta2.bFlag.bFXC)&&(!poc->sta.bFlag.bXBbs2)&&BH_GOOSE_EN_YB(sw);
	RunTR(&poc->tTFX2_300ms, bY1, dStep);
	poc->psta2.bFlag.bFX=poc->tTFX2_300ms.boolTrip;
	//无方向判断，保持2秒
	bY1=(poc->psta2.bFlag.bWXA||poc->psta2.bFlag.bWXB||poc->psta2.bFlag.bWXC)&&(!poc->sta.bFlag.bXBbs2)&&BH_GOOSE_EN_YB(sw);
	RunTR(&poc->tTWX2_300ms, bY1, dStep);
	poc->psta2.bFlag.bWX=poc->tTWX2_300ms.boolTrip;	
	
	poc->psta2.bFlag.bGZ=poc->psta2.bFlag.bZX|poc->psta2.bFlag.bFX|poc->psta2.bFlag.bWX|poc->psta2.bFlag.bLX;  //线路有故障
	poc->psta.bFlag.bGZ|=poc->psta2.bFlag.bGZ;

#endif
	
}


bool fag_goosecheck_gzqc(int sw)  //故障切除邻域故障信息判断
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	TSETSW *pSet = &pRunSet->tSwSet[sw];
	UGOOSE_STU *pg;
	int i;
	if(pSet->tGocSet.bTT_DIR&&(!tPT.uPT1DX.bFlag.bPTYC))// 带方向判断
	{
		if(poc->psta.bFlag.bZX)  //本线路有正向故障,L邻域
		{	
			bool bY1=false;
			for(i=GOOSE_EQU_SIDE;i<GOOSE_EQU_MAX;i++)
			{
				pg=&tFAg.ugside[i];
				bY1|=pg->bFlag.bfx;  // L邻域 有反向故障
			}
			return (!bY1);
		}

		if(poc->psta.bFlag.bFX)  //本线路有反向故障， B邻域 无正向向故障
		{	
			bool bY1=false;
			for(i=0;i<GOOSE_EQU_SIDE;i++)
			{
				pg=&tFAg.ugside[i];
				bY1|=pg->bFlag.bzx;  // B邻域 正向向故障
			}
			return (!bY1);
		}
		return false;
	}
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020 || defined GD_AREA_MAIN_2020
 	if(poc->psta.bFlag.bWX||poc->psta2.bFlag.bWX||poc->psta.bFlag.bLX)  //本线路有无方向故障 ，或零序故障
 #else
	if(poc->psta.bFlag.bWX||poc->psta.bFlag.bLX)  //本线路有无方向故障 ，或零序故障
 #endif
	{
		bool bY1=false;
		bool bY2=false;
		bool ret=false;
		for(i=0;i<GOOSE_EQU_SIDE;i++) 
		{
			pg=&tFAg.ugside[i];
			bY1|=(pg->bFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); 
		}
		for(i=GOOSE_EQU_SIDE;i<GOOSE_EQU_MAX;i++)
		{
			pg=&tFAg.ugside[i];
			bY2|=(pg->bFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); 
		}	
		if(pRunSet->tSwSet[sw].tGocSet.bsw_fz) //末端开关
		{
			ret=(bY1||bY2) ; // 末端开关，邻域有故障
		}
		else if(pRunSet->tSwSet[sw].tGocSet.bsw_sd)  //首端开关
		{
			ret=(!(bY1||bY2)); //任一侧有故障(首开关)
		}
		else
		{
			ret=(bY1^bY2); //非首末端，邻域有一侧无故障
		}
		return ret;
	}

	return false;

}


bool fag_goosecheck_gzgl(int sw)  //故障隔离邻域故障信息判断
{
	TSETSW *pSet = &pRunSet->tSwSet[sw];
	UGOOSE_STU *pg;
	int i;
	if(pSet->tGocSet.bTT_DIR&&(!tPT.uPT1DX.bFlag.bPTYC))
	{
		return false; //合环方式下，无故障隔离故障产生
	}
	else
	{
		bool bY1=false;
		int num=0;
		for(i=0;i<GOOSE_EQU_MAX;i++) 
		{
			pg=&tFAg.ugside[i];
			bY1=(pg->bFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); 
			if(bY1)
			{
				num++;
			}
		}
		return (num==1); 
	}
	return false;
}



bool fag_goosecheck_ll(int sw)  // 联络开关动作，邻域条件判断
{
	int i;
	UGOOSE_STU *pg;
	bool bgzglok=false;
	TSETSW *pSet = &pRunSet->tSwSet[sw];

	if(pSet->tGocSet.bTT_DIR&&(!tPT.uPT1DX.bFlag.bPTYC))// 带方向判断,无故障隔离发送，条件自动满足
	{
		bgzglok=true;
	}
	else
	{
		for(i=0;i<GOOSE_EQU_MAX;i++) 
		{
			pg=&tFAg.ugside[i];
			bgzglok|=pg->bFlag.bgzglok;  //收到故障隔离成功信息
		}
	}
	return bgzglok;
}

void fag_get_side_dz(int sw)  //获取相邻侧故障信息
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;
	UGOOSE_STU *pg;
	bool bdz=false;
	bool btzsb=false;
	int i;
	for(i=0;i<GOOSE_EQU_MAX;i++) 
	{
		pg=&tFAg.ugside[i];
		bdz|=(pg->bFlag.bgl||pg->bFlag.blx||pg->bFlag.bzx||pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs);
		btzsb|=pg->bFlag.btzsb;
	}
	poc->b_side_gz=bdz;
	poc->b_side_tzsb=btzsb;
}
void fag_cd(int sw,DWORD dStep)  // 
{
	TRELAY_T *pR=&g_tRelay[sw];
	TGOC_T *poc=&g_tRelay[ sw].tgoc;
	TSETSW *pSet = &pRunSet->tSwSet[sw];
	FA_CD *pcd;
	bool bQD;	
	bool bY1;
	fag_get_side_dz(sw);  //  获取开关临域信息
	poc->psta.bFlag.bYY1 = OverRelay(g_sw_pub.m2_max[2], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY1); // 有压
	poc->psta.bFlag.bYY2 = OverRelay(g_sw_pub.m2_max[3], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY2); 
	poc->psta.bFlag.bWY1 = LowRelay(g_sw_pub.m2_max[2], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bWY1); //无压
	poc->psta.bFlag.bWY2 = LowRelay(g_sw_pub.m2_max[3], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bWY2); 

	// 故障切除充电判断
	pcd=&pR->tgoc.tqccd;
	RunTR(&pcd->tWYTime, (poc->psta.bFlag.bWY1&&poc->psta.bFlag.bWY2), dStep); //  放电两侧无压60秒

	pcd->sta.bFlag.bFD=(!BH_GOOSE_EN(sw))	 // 分布式退出
		|| pR->tSWST.uSWST.bFlag.bTZWZ   //开关跳位
		||pcd->tWYTime.boolTrip;			// 两侧无压超过60秒


	bQD=(BH_GOOSE_EN(sw))	
		//&&!poc->b_side_gz  //邻域无故障
		//&&!poc->psta.bFlag.bGZ    //本开关无故障
		&&(poc->psta.bFlag.bYY1||poc->psta.bFlag.bYY2||(pRunSet->dT_cd==0))  //一侧有电压
		&& pR->tSWST.uSWST.bFlag.bHZWZ
		&&!pcd->sta.bFlag.bFD;

	RunTR(&pcd->tCDTime, bQD, dStep);
	pcd->sta.bFlag.bCD=(pcd->tCDTime.boolTrip||pcd->sta.bFlag.bCD)&&(!pcd->sta.bFlag.bFD);  //充电完成
	pR->run_stu.goose_qccd=pcd->sta.bFlag.bCD;

	// 隔离充电判断
	pcd=&pR->tgoc.tglcd;
	RunTR(&pcd->tWYTime, (poc->psta.bFlag.bWY1&&poc->psta.bFlag.bWY2), dStep); //  放电两侧无压60秒

	pcd->sta.bFlag.bFD=(!BH_GOOSE_EN(sw))	 // 分布式退出
		|| pR->tSWST.uSWST.bFlag.bTZWZ   //开关跳位
		||poc->psta.bFlag.bGZ                      //本开关有故障，故障隔离立即放电
		||pcd->tWYTime.boolTrip;			// 两侧无压超过60秒


	bQD=(BH_GOOSE_EN(sw))	
		&&!poc->b_side_gz  //邻域无故障
		&&!poc->psta.bFlag.bGZ    //本开关无故障
		&&(poc->psta.bFlag.bYY1||poc->psta.bFlag.bYY2||(pRunSet->dT_cd==0))  //一侧有电压
		&& pR->tSWST.uSWST.bFlag.bHZWZ
		&&!pcd->sta.bFlag.bFD;

	RunTR(&pcd->tCDTime, bQD, dStep);
	pcd->sta.bFlag.bCD=(pcd->tCDTime.boolTrip||pcd->sta.bFlag.bCD)&&(!pcd->sta.bFlag.bFD);  //充电完成
	pR->run_stu.goose_glcd=pcd->sta.bFlag.bCD;

	//联络充电判断
	pcd=&pR->tgoc.tllcd;
	RunTR(&pcd->tWYTime, (poc->psta.bFlag.bWY1&&poc->psta.bFlag.bWY2), dStep);  //无压判断
	pcd->sta.bFlag.bFD=(!BH_GOOSE_EN(sw))	 // 分布式退出
			||!pSet->tGocSet.bTT_ll		//联络功能退出
//#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020   //中山要求联络开关固定
#if defined GD_AREA_ZHONGSHAN   //中山要求联络开关固定
			||!pSet->tGocSet.bsw_ll
#endif
			||pcd->tWYTime.boolTrip			// 两侧无压超过15秒
			||poc->b_side_gz   //领域故障
			||pR->tgoc.b_side_tzsb//领域拒动
			//||!g_run_stu.yf          //KK把手非远方
			||poc->sta.bFlag.bllhz;	//本开关联络动作

	bQD=(BH_GOOSE_EN(sw))	 //充电条件:保护投入
		&&(poc->psta.bFlag.bYY1&&poc->psta.bFlag.bYY2)  //两侧有压
		&& pR->tSWST.uSWST.bFlag.bTZWZ  // 开关跳位
		&&!pcd->sta.bFlag.bFD; 					//无放电
	RunTR(&pcd->tCDTime, bQD, dStep);
	pcd->sta.bFlag.bCD=(pcd->tCDTime.boolTrip||pcd->sta.bFlag.bCD)  //充电完成，并自保持
			&&(!pcd->sta.bFlag.bFD);  //无放电标志

	pR->run_stu.goose_ll_cd=pcd->sta.bFlag.bCD;  //充电标志

	 //缓动型无压无流判断
	poc->bslowEn=(!pSet->tGocSet.bFA_slow)
				||(pSet->tGocSet.bFA_slow	//缓动型
				&&poc->psta.bFlag.bWY1		//无压
				&&poc->psta.bFlag.bWY2
				&&pR->tSWST.uSWST.bFlag.bSXWL); //无流

	bY1=soe_check(EV_GOOSE_GZBS_FA)||soe_check(EV_GOOSE_TZBS_FA);	
	RunTR(&poc->tTHz1s,pR->tSWST.uSWST.bFlag.bHZWZ&&bY1, dStep);  //合闸后1秒，清动作标志
	if(poc->tTHz1s.boolTrip&&BH_GOOSE_EN(sw))
	{
		pR->tgoc.bgooseGz=false;
		pR->tgoc.bgooseBsHz=false;
		if(soe_check(EV_GOOSE_GZBS_FA)==true)	// goose故障闭锁
		{
			soe_record_ev(EV_GOOSE_GZBS_FA, 0, 0,0,0 );
		}
		if(soe_check(EV_GOOSE_TZBS_FA)==true)	// goose故障闭锁
		{
			soe_record_ev(EV_GOOSE_TZBS_FA, 0, 0,0,0 );
		}	
	}

}


void fag_oc_gl(int sw,u32  dStep)
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	bool bgl,bGoose,bTz; 
	// 电流启动
	bgl = OverRelay(g_sw[sw].m2_max, pSet->dIgl, pSet->dIgl_fh, poc->sta.bFlag.bglQD); 

	bGoose=(fag_goosecheck_gzqc(sw))||(tFAg.commerr>0); //goose判断满足要求，中山通信异常后，BH_GOOSE_EN 不满足要求，不会启动 
	poc->sta.bFlag.bglQD=  (BH_GOOSE_EN(sw)	
			&&poc->tqccd.sta.bFlag.bCD		//故障隔离充电完成
			&& (bgl)
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020   //中山要求联络开关固定			
			&&(!pSet->bsw_fz)  // 中山局要求分支走常规保护逻辑
#endif
			&&!poc->sta.bFlag.bXBbs);  //谐波闭锁

	if(poc->sta.bFlag.bglQD)  //幅值启动
	{
		if(!poc->sta.bFlag.bglQDWave)
		{
			rcd_start(sw,RECORD_TYPE_GLGZ, RECORD_LEN_TZQD); 	//录波类型：跳闸类
			poc->sta.bFlag.bglQDWave=true;
		}
	}
	RunTR(&poc->tglQDTime, poc->sta.bFlag.bglQD, dStep);	
	RunTR(&poc->tglQD25ms, poc->sta.bFlag.bglQD, dStep);
	// 如果速断时间到，启动时间未到，调用幅值启动加速模块
	
	if(poc->sta.bFlag.bglQD&& poc->tglQDTime.boolTrip && !poc->tglQD25ms.boolTrip)
	{
		if(protect_amp_qd_js(sw))
		{
			// 预置25ms，让下个循环再出口
			PreSetTime(&poc->tglQD25ms, T_25ms);	
		}
	}
	bTz = poc->tglQDTime.boolTrip&&bGoose			// 电流启动					
		&& poc->tglQD25ms.boolTrip; //启动后25ms

	RunTR(&poc->tglslowTime,(bTz&&pSet->bFA_slow), dStep);  // 缓动型，跳闸信息自动延长	 		

	poc->sta.bFlag.bglTz=(bTz&&(!pSet->bFA_slow))// 非缓动型，直接出口
						||(poc->bslowEn&&poc->tglslowTime.boolTrip);			

	if(poc->sta.bFlag.bglTz)  //启动信息
	{
		int ui_begin;	
		DWORD Ia,Ib,Ic;
		ui_begin = UI_SW_INDEX_BEGIN(sw);
		Ia = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IA].m2[0]), 256, g_ui[ui_begin + SW_AC_IA].m2_factor_k);
		Ib = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IB].m2[0]), 256, g_ui[ui_begin + SW_AC_IB].m2_factor_k);
		Ic = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IC].m2[0]), 256, g_ui[ui_begin + SW_AC_IC].m2_factor_k);
	
		if(soe_check(EV_GOOSE_GL_TZ+sw*EV_SW_NUM)==false)  //过流跳闸
		{				
			soe_record_ev( EV_GOOSE_GL_TZ+sw*EV_SW_NUM,1, Ia,Ib,Ic ); 
			poc->bglTzLed=true;
			poc->sta.bFlag.bglTzH=true;
			poc->bgooseGz=true;
		}
		if(soe_check(EV_GOOSE_QC_QD+sw*EV_SW_NUM)==false)  // 故障隔离启动
		{				
			soe_record_ev( EV_GOOSE_QC_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
	}
	else
	{
		if(soe_check(EV_GOOSE_GL_TZ+sw*EV_SW_NUM)==true)  // 过流跳闸
		{				
			soe_record_ev( EV_GOOSE_GL_TZ+sw*EV_SW_NUM,0, 0,0,0 ); 
		}		
	}

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
	// 电流启动
	bgl = OverRelay(g_sw[sw].m2_max, pSet->dIgl2, pSet->dIgl2_fh, poc->sta.bFlag.bgl2QD); 
	bGoose=(fag_goosecheck_gzqc(sw))||(tFAg.commerr>0); //goose判断满足要求，或通信异常
	poc->sta.bFlag.bgl2QD=  (BH_GOOSE_EN(sw)	
			&&poc->tqccd.sta.bFlag.bCD		//故障隔离充电完成
			&& (bgl)
			&&(!pSet->bsw_fz)  // 中山局要求分支走常规保护逻辑
			&&!poc->sta.bFlag.bXBbs2);  //谐波闭锁


	if(poc->sta.bFlag.bgl2QD)  //幅值启动
	{
		if(!poc->sta.bFlag.bgl2QDWave)
		{
			rcd_start(sw,RECORD_TYPE_GLGZ, RECORD_LEN_TZQD);	//录波类型：跳闸类
			poc->sta.bFlag.bgl2QDWave=true;
		}
	}
	RunTR(&poc->tgl2QDTime, poc->sta.bFlag.bgl2QD, dStep);	
	RunTR(&poc->tgl2QD25ms, poc->sta.bFlag.bgl2QD, dStep);
	// 如果速断时间到，启动时间未到，调用幅值启动加速模块

	if(poc->sta.bFlag.bgl2QD && poc->tgl2QDTime.boolTrip && !poc->tgl2QD25ms.boolTrip)
	{
		if(protect_amp_qd_js(sw))
		{
			// 预置25ms，让下个循环再出口
			PreSetTime(&poc->tgl2QD25ms, T_25ms);	
		}
	}	

	bTz = poc->tgl2QDTime.boolTrip&&bGoose			// 电流启动					
		&& poc->tgl2QD25ms.boolTrip; //启动后25ms

	RunTR(&poc->tgl2slowTime,(bTz&&pSet->bFA_slow), dStep);  // 缓动型，跳闸信息自动延长					
	poc->sta.bFlag.bgl2Tz=(bTz&&(!pSet->bFA_slow))// 非缓动型，直接出口
						||(poc->bslowEn&&poc->tgl2slowTime.boolTrip);

	if(poc->sta.bFlag.bgl2Tz)  //启动信息
	{
		int ui_begin;	
		DWORD Ia,Ib,Ic;
		ui_begin = UI_SW_INDEX_BEGIN(sw);
		Ia = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IA].m2[0]), 256, g_ui[ui_begin + SW_AC_IA].m2_factor_k);
		Ib = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IB].m2[0]), 256, g_ui[ui_begin + SW_AC_IB].m2_factor_k);
		Ic = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IC].m2[0]), 256, g_ui[ui_begin + SW_AC_IC].m2_factor_k);

		if(soe_check(EV_GOOSE_GL2_TZ+sw*EV_SW_NUM)==false)  //过流跳闸
		{				
			soe_record_ev( EV_GOOSE_GL2_TZ+sw*EV_SW_NUM,1, Ia,Ib,Ic ); 
			poc->bglTzLed=true;
			poc->sta.bFlag.bglTzH=true;
			poc->bgooseGz=true;
		}
		if(soe_check(EV_GOOSE_QC_QD+sw*EV_SW_NUM)==false)  // 故障隔离启动
		{				
			soe_record_ev( EV_GOOSE_QC_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
	}
	else
	{
		if(soe_check(EV_GOOSE_GL2_TZ+sw*EV_SW_NUM)==true)  // 过流跳闸
		{				
			soe_record_ev( EV_GOOSE_GL2_TZ+sw*EV_SW_NUM,0, 0,0,0 ); 
		}		
	}

#endif
	
}

void fag_oc_lx(int sw,u32  dStep)
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	bool blx,bGoose,bTz; 

	// 电流启动
	blx = OverRelay(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2[0], pSet->dIlx, pSet->dIlx_fh, poc->sta.bFlag.blxQD); 
	bGoose=(fag_goosecheck_gzqc(sw))||(tFAg.commerr>0); //goose判断满足要求，或通信异常
	poc->sta.bFlag.blxQD  = (BH_GOOSE_EN(sw)
			&&poc->tqccd.sta.bFlag.bCD		//故障隔离充电完成
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020   //中山要求联络开关固定			
			&&(!pSet->bsw_fz)  // 中山局要求分支走常规保护逻辑
#endif
			&& (blx));

	if(poc->sta.bFlag.blxQD)  //幅值启动
	{
		if(!poc->sta.bFlag.blxQDWave)
		{
			rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); 	//录波类型：跳闸类
			poc->sta.bFlag.blxQDWave=true;
		}
	}
	RunTR(&poc->tlxQDTime, poc->sta.bFlag.blxQD, dStep);	
	RunTR(&poc->tlxQD25ms, poc->sta.bFlag.blxQD, dStep);

	// 如果速断时间到，启动时间未到，调用幅值启动加速模块
	
	if(poc->sta.bFlag.blxQD && poc->tlxQDTime.boolTrip && !poc->tlxQD25ms.boolTrip)
	{
		if(protect_amp_lx_js(sw))
		{
			// 预置25ms，让下个循环再出口
			PreSetTime(&poc->tlxQD25ms, T_25ms);	
		}
	}

	bTz = poc->tlxQDTime.boolTrip&&bGoose			// 电流启动					
		&& poc->tlxQD25ms.boolTrip; //启动后25ms

	RunTR(&poc->tlxslowTime,(bTz&&pSet->bFA_slow), dStep);  // 缓动型，跳闸信息自动延长					
	poc->sta.bFlag.blxTz=(bTz&&(!pSet->bFA_slow))// 非缓动型，直接出口
						||(poc->bslowEn&&poc->tlxslowTime.boolTrip);
	
	if(poc->sta.bFlag.blxTz)  //启动信息
	{
		int ui_begin;	
		DWORD I0;
		ui_begin = UI_SW_INDEX_BEGIN(sw);
		I0= _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_I0].m2[0]), 256, g_ui[ui_begin + SW_AC_I0].m2_factor_k);
		if(soe_check(EV_GOOSE_LX_TZ+sw*EV_SW_NUM)==false)  //零序跳闸
		{				
			soe_record_ev( EV_GOOSE_LX_TZ+sw*EV_SW_NUM,1, I0,0,0 ); 
			poc->blxTzLed=true;
			poc->sta.bFlag.blxTzH=true;
			poc->bgooseGz=true;
		}
		if(soe_check(EV_GOOSE_QC_QD+sw*EV_SW_NUM)==false)  // 故障切除启动
		{				
			soe_record_ev( EV_GOOSE_QC_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
	}
	else
	{
		if(soe_check(EV_GOOSE_LX_TZ+sw*EV_SW_NUM)==true)  // 零序跳闸
		{				
			soe_record_ev( EV_GOOSE_LX_TZ+sw*EV_SW_NUM,0, 0,0,0 ); 
		}		
	}
}
// 缓动型故障扩展发送时间，需大于变电站出口时间，保证无压无流后，领域故障还存在
void fag_gzgl(int sw,DWORD dStep)  // 故障隔离
{
	TRELAY_T *pR=&g_tRelay[sw];
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	TGOC_T *poc=&pR->tgoc;
	UGOOSE_STU *pg;
	bool bY1,bY2,bGoose,bfztz; 
	int i;
	bool  bWY1, bWY2;   // 无压判断
	bWY1 = LowRelay(g_sw_pub.m2_max[2], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh,  false); //无压
	bWY2 = LowRelay(g_sw_pub.m2_max[3], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh,  false); 
	bY1=false;
	for(i=0;i<GOOSE_EQU_MAX;i++)  //邻域有故障产生
	{
		pg=&tFAg.ugside[i];
		bY1|=(pg->bFlag.bgl|pg->bFlag.blx|pg->bFlag.bzx|pg->bFlag.bfx|pg->bFlag.bglbs|pg->bFlag.blxbs); 
	}

	bfztz=(!pSet->bsw_fz)||pSet->bTT_mxTfz;  //非分支或分支线且母线故障跳分支未投入

	bY2=(BH_GOOSE_EN(sw))	
		&&bfztz
		&&bY1 // 邻域有故障产生
		&&poc->bslowEn				//缓动型，需无压无流，速动自动满足
		&& pR->tSWST.uSWST.bFlag.bHZWZ		//在合闸位置
		&&pR->tgoc.tglcd.sta.bFlag.bCD;  //充电完成,无放电条件
		
	RunTR(&poc->tgoose15ms_gzgl, bY2, dStep);  // 电流启动 15ms后，goose 判断有效
	bGoose=fag_goosecheck_gzgl(sw)
			&&poc->tgoose15ms_gzgl.boolTrip
			&&(tFAg.commerr==0);  // 故障隔离，通信正常时处理，异常，靠失压跳闸

	if(poc->tgoose15ms_gzgl.boolTrip&&!poc->sta.bFlag.bgzglQD)  //goose 判断时间到，若条件不满足，放电，防止邻域开关故障撤销后，由于发送间隔问题，goose条件又满足导致误动
	{
		if(!bGoose)  //外部条件不满足
		{
			pR->tgoc.tglcd.sta.bFlag.bCD=false;
			ResetTR(&poc->tglcd.tCDTime);
		}
	}
#ifdef GD_AREA_ZHONGSHAN_2020 // 中山要求，动作后，通信异常不起作用，继续动作
	poc->sta.bFlag.bgzglQD=((bGoose&&bY2)||poc->sta.bFlag.bgzglQD)&&bWY1&&bWY2;  //故障隔离启动, 增加无压条件 
#else
	poc->sta.bFlag.bgzglQD=((bGoose&&bY2)||poc->sta.bFlag.bgzglQD)&&pR->tgoc.tglcd.sta.bFlag.bCD&&bWY1&&bWY2;  //故障隔离启动, 增加无压条件 
#endif
	RunTR(&poc->tgzglTime,poc->sta.bFlag.bgzglQD, dStep);  // 故障隔离时间到，出口
	poc->sta.bFlag.bgzglTz=poc->tgzglTime.boolTrip;  //故障隔离启动
	
	if(poc->sta.bFlag.bgzglTz)
	{
		if(soe_check(EV_GOOSE_GL_QD+sw*EV_SW_NUM)==false)  // 故障隔离启动
		{				
			soe_record_ev( EV_GOOSE_GL_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
		poc->bgzglTzLed=true;
		poc->sta.bFlag.bgzglTzH=true;
		poc->sta.bFlag.bgzglQD=false;
		poc->bgooseGz=true;
	}
}

void fag_lostvol_sd(int sw,DWORD dStep)  // 首端开关失压跳闸
{
	TRELAY_T *pR=&g_tRelay[sw];
	TGOC_T*poc = &pR->tgoc;
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	bool  bWY1, bWY2,bEnble;  
	
	/***********启动	**********************************/		

	bWY1 = LowRelay(g_sw_pub.m2_max[2], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh,  poc->sta.bFlag.bsdQD); //无压
	bWY2 = LowRelay(g_sw_pub.m2_max[3], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh,  poc->sta.bFlag.bsdQD); 

#ifdef GD_AREA_ZHONGSHAN_2020 // 中山要求，动作后，通信异常不起作用，继续动作
	bEnble=(pSet->bTT_sdlost&&pSet->bsw_sd) ; //首端开关，失压投退投入，无通信异常
	poc->sta.bFlag.bsdQD = bEnble
							&& (BH_GOOSE_EN_YB(sw))	
							&&(tFAg.bComErr==0||poc->sta.bFlag.bsdQD)
							&& pR->tgoc.psta.bFlag.bCYY        // 曾有压
							&& pR->tSWST.uSWST.bFlag.bHZWZ		//在合闸位置
							&& pR->tSWST.uSWST.bFlag.bSXWL		//三相无流;	
							&&(poc->tqccd.sta.bFlag.bCD||poc->sta.bFlag.bsdQD)	
							&& bWY1
							&& bWY2;
#else
	bEnble=(pSet->bTT_sdlost&&pSet->bsw_sd&&(tFAg.commerr==0)) ; //首端开关，失压投退投入，无通信异常
	poc->sta.bFlag.bsdQD = bEnble
							&& (BH_GOOSE_EN(sw))	
							&& pR->tgoc.psta.bFlag.bCYY        // 曾有压
							&& pR->tSWST.uSWST.bFlag.bHZWZ		//在合闸位置
							&& pR->tSWST.uSWST.bFlag.bSXWL		//三相无流;	
							&&poc->tqccd.sta.bFlag.bCD
							&& bWY1
							&& bWY2;
#endif
	/***********失压分闸*********************************/
	RunTR(&poc->tsdlostTime, poc->sta.bFlag.bsdQD, dStep);
	poc->sta.bFlag.bsdTz = poc->tsdlostTime.boolTrip;

	if(poc->sta.bFlag.bsdTz)  //启动信息
	{
		if(soe_check(EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM)==false)  // 故障隔离启动
		{				
			soe_record_ev( EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
		if(soe_check(EV_GOOSE_GL_QD+sw*EV_SW_NUM)==false)  // 故障隔离启动
		{				
			soe_record_ev( EV_GOOSE_GL_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
		poc->bsdTzLed=true;
		poc->sta.bFlag.bsdTzH=true;
		pR->tgoc.psta.bFlag.bCYY =false;
		poc->bgooseGz=true;
		ResetTR(&pR->tgoc.tCYY3sdelayms);

	}
	else
	{
		if(soe_check(EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM)==true)  // 故障隔离启动
		{				
			soe_record_ev( EV_GOOSE_SDLOST_TZ+sw*EV_SW_NUM,0, 0,0,0 );
		}		
	}
}    

void fag_lostvol_commer(int sw,DWORD dStep)  // 通信异常失压跳闸
{
	TRELAY_T *pR=&g_tRelay[sw];
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	TGOC_T*poc = &pR->tgoc;
	bool  bWY1, bWY2,bEnble;  
	bool bfztz;
	
	/***********启动	**********************************/		

	bWY1 = LowRelay(g_sw_pub.m2_max[2], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh,  poc->sta.bFlag.berrQD); //无压
	bWY2 = LowRelay(g_sw_pub.m2_max[3], pRunSet->tSwSet[sw].dU_fa_WY,pRunSet->tSwSet[sw].dU_fa_WY_fh,  poc->sta.bFlag.berrQD); 

	bEnble=(tFAg.commerr>0) ; //通信异常，失压跳闸

	bfztz=(!pSet->bsw_fz)||pSet->bTT_mxTfz;  //非分支或分支线且母线故障跳分支未投入

	poc->sta.bFlag.berrQD = bEnble
							&&bfztz
							&& (BH_GOOSE_EN(sw))	
							&& pR->tgoc.psta.bFlag.bCYY        // 曾有压
							&& pR->tSWST.uSWST.bFlag.bHZWZ		//在合闸位置
							&& pR->tSWST.uSWST.bFlag.bSXWL		//三相无流;	
							&& bWY1
							&& bWY2;

	/***********失压分闸*********************************/
	RunTR(&poc->terrlostTime, poc->sta.bFlag.berrQD, dStep);
	poc->sta.bFlag.berrTz = poc->terrlostTime.boolTrip;

	if(poc->sta.bFlag.berrTz)  //启动信息
	{
		if(soe_check(EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM)==false)  //失压跳闸
		{				
			soe_record_ev( EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
		if(soe_check(EV_GOOSE_GL_QD+sw*EV_SW_NUM)==false)  // 故障隔离启动
		{				
			soe_record_ev( EV_GOOSE_GL_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
		}

		poc->berrTzLed=true;
		poc->sta.bFlag.berrTzH=true;
		pR->tgoc.psta.bFlag.bCYY =false;
		poc->bgooseGz=true;
		ResetTR(&pR->tgoc.tCYY3sdelayms);
	}
	else
	{
		if(soe_check(EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM)==true)  //失压跳闸
		{				
			soe_record_ev( EV_GOOSE_ERRLOST_TZ+sw*EV_SW_NUM,0, 0,0,0 ); 
		}
	}
}    


void fag_exttz(int sw,DWORD  dStep)  // 下级开关跳闸失败，本级开关跳闸
{
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	GOC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet;
	UGOOSE_STU *pg;
	bool btzsb=false;
	bool bfztz;
	int i;
	bool bgzgl;
	for(i=0;i<GOOSE_EQU_MAX;i++)
	{
		pg=&tFAg.ugside[i];
		btzsb|=(pg->bFlag.btzsb);  // 相邻开关有跳闸失败
	}	
	bgzgl=fag_goosecheck_gzgl(sw)&&(!pSet->bsw_sd)&&(!pSet->bsw_fz);
	bfztz=(!pSet->bsw_fz)||pSet->bTT_mxTfz;  //非分支或分支线且母线故障跳分支未投入
	RunTR(&poc->textbsTime,btzsb&&bgzgl, dStep);  // 缓动型，跳闸信息自动延长					
	poc->sta.bFlag.bextQD=btzsb				//相邻线路有开关跳闸失败
						&&!poc->textbsTime.boolTrip
						&&(tFAg.commerr==0) //通信正常
						&&bfztz
						&&(BH_GOOSE_EN(sw))	
						&&g_tRelay[ sw].tSWST.uSWST.bFlag.bHZWZ
						&&poc->bslowEn  //缓动 无压无流 速动，自动满足
						&&!poc->psta.bFlag.btzsb;
	poc->sta.bFlag.bextTz=poc->sta.bFlag.bextQD;
	if(poc->sta.bFlag.bextTz)
	{
		if(soe_check(EV_GOOSE_EXT_TZ+sw*EV_SW_NUM)==false)  //保护总
		{				
			soe_record_ev( EV_GOOSE_EXT_TZ+sw*EV_SW_NUM,1, 0,0,0 ); 
		#ifdef GD_AREA_ZHONGSHAN_2020
			g_tRelay[i].run_stu.fgbs=1;//该SOE返回太快，需直接赋值
		#endif
		}
		poc->sta.bFlag.bextTzH=true;
		poc->bgooseGz=true;

	}		
	else
	{
		if(soe_check(EV_GOOSE_EXT_TZ+sw*EV_SW_NUM)==true)  //保护总
		{				
			soe_record_ev( EV_GOOSE_EXT_TZ+sw*EV_SW_NUM,0, 0,0,0 ); 
		}
	} 		
}

// 两侧有压，开关在分位，确认联络开关有效，
//单侧失压后，判合闸条件，条件满足，合联络开关，恢复供电，重新确认联络开关位置

void fag_ll(int sw,DWORD dStep)  //  联络开关逻辑处理
{

	TRELAY_T *pR=&g_tRelay[sw];
	TSETSW *pSet = &pRunSet->tSwSet[sw];	
	TGOC_T*poc = &pR->tgoc;
	bool bY1,bQD; 
	bool bWY1,bWY2;
	bool bYY1,bYY2,bllYY;
	bool bLstQD=false;
	//有压检测
	bWY1 = LowRelay(g_sw_pub.m2_max[2], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bllWY1); //无压
	bWY2 = LowRelay(g_sw_pub.m2_max[3], pSet->dU_fa_WY,pSet->dU_fa_WY_fh, poc->psta.bFlag.bllWY2); 

	bYY1 = OverRelay(g_sw_pub.m2_max[2], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY1); // 有压
	bYY2 = OverRelay(g_sw_pub.m2_max[3], pSet->dU_fa_YY,pSet->dU_fa_YY_fh, poc->psta.bFlag.bYY2); 


	RunTR(&poc->tllWY1Time,bWY1, dStep);  
	RunTR(&poc->tllWY2Time,bWY2, dStep);  

	RunTR(&poc->tllYY1Time,bYY1, dStep);  
	RunTR(&poc->tllYY2Time,bYY2, dStep);  

	poc->psta.bFlag.bllWY1 = poc->tllWY1Time.boolTrip;
	poc->psta.bFlag.bllWY2 = poc->tllWY2Time.boolTrip;

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020   //中山要求联络开关固定，并且单侧失压后报联络合闸失败
	bLstQD =pSet->tGocSet.bTT_ll//联络开关投入
		&&(BH_GOOSE_EN(sw))				//智能分布式已投入
	#ifdef GD_AREA_ZHONGSHAN
		&&pSet->tGocSet.bsw_ll
	#endif
		&&(poc->psta.bFlag.bllWY1^poc->psta.bFlag.bllWY2)  //单侧失压
		&&pR->tSWST.uSWST.bFlag.bTZWZ;	//	开关跳位
#endif		

	bllYY=poc->tllYY1Time.boolTrip&&poc->tllYY2Time.boolTrip;
	poc->sta.bFlag.bllWY_1=((bLstQD&&bllYY)||poc->sta.bFlag.bllWY_1)&&bLstQD;	
	RunTR(&poc->tllQdTime,poc->sta.bFlag.bllWY_1, dStep);  // 双侧有压后，又单侧失压，超过联络合闸时间，报联络合闸不满足


	bQD =pSet->tGocSet.bTT_ll//联络开关投入
#ifdef GD_AREA_ZHONGSHAN_2020   //中山要求联络开关固定
		&&(poc->tllcd.sta.bFlag.bCD||poc->sta.bFlag.bllQD)  //联络开关充电完成
		//&&pSet->tGocSet.bsw_ll
		&&(BH_GOOSE_EN_YB(sw))				//智能分布式已投入
		&&(tFAg.bComErr==0||poc->sta.bFlag.bllQD) // 联络启动后，自保持，通信异常不退出动作逻辑
#else
		&&poc->tllcd.sta.bFlag.bCD  //联络开关充电完成
		&&(BH_GOOSE_EN(sw))				//智能分布式已投入
#endif
		&&(poc->psta.bFlag.bllWY1^poc->psta.bFlag.bllWY2)  //单侧失压
		&&pR->tSWST.uSWST.bFlag.bTZWZ;	//	开关跳位

	RunTR(&poc->tgoosedelayms_ll, bQD, dStep);  // 联络失压后启动

	bY1=	bQD // 单侧失压，联络启动条件满足
			&&(!poc->tgoosedelayms_ll.boolTrip)  //在失压后300ms内
			&&!poc->b_side_gz                         //领域无故障
			&&fag_goosecheck_ll(sw) ; //收到故障隔离信号

	poc->sta.bFlag.bllQD=(bY1||poc->sta.bFlag.bllQD)&&bQD && !poc->b_side_tzsb ;  // 联络启动后，自保持
	RunTR(&poc->tllhzTime,poc->sta.bFlag.bllQD, dStep);  // Y确认时间后，失压可合闸 
	poc->sta.bFlag.bllhz=poc->tllhzTime.boolTrip;

	if(poc->sta.bFlag.bllhz)  //启动信息
	{
		if(soe_check(EV_GOOSE_HZ_QD+sw*EV_SW_NUM)==false)  // 联络合闸启动
		{				
			soe_record_ev( EV_GOOSE_HZ_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
		sw_do(sw,SW_DO_HZ,SW_DO_TYPE_ON);		
		sw_do(sw,SW_DO_BHH,SW_DO_TYPE_ON);		
		poc->sta.bFlag.bllhzH=true;
		ResetTR(&poc->tllQdTime);
		poc->sta.bFlag.bllWY_1=false;
	}
	else
	{
		if(soe_check(EV_GOOSE_HZ_QD+sw*EV_SW_NUM)==true)   // 联络合闸启动返回
		{				
			soe_record_ev( EV_GOOSE_HZ_QD+sw*EV_SW_NUM,0, 0,0,0 ); 
		}
	}

	if(poc->tllQdTime.boolTrip)  //联络失压后合闸不满足
	{
		if(soe_check(EV_GOOSE_LL_UNOK+sw*EV_SW_NUM)==false)  //  
		{				
			soe_record_ev( EV_GOOSE_LL_UNOK+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
		ResetTR(&poc->tllQdTime);
		ResetTR(&poc->tllcd.tCDTime);
		poc->sta.bFlag.bllWY_1=false;
		poc->tllcd.sta.bFlag.bCD=false;
	}	
	if(poc->tllcd.sta.bFlag.bCD||pR->tSWST.uSWST.bFlag.bHZWZ)
	{
		if(soe_check(EV_GOOSE_LL_UNOK+sw*EV_SW_NUM)==true)  //  
		{				
			soe_record_ev( EV_GOOSE_LL_UNOK+sw*EV_SW_NUM,0, 0,0,0 ); 
		}
	}

	RunTR(&poc->tHzcheckTime, poc->sta.bFlag.bllhzH, dStep);		//

	if(poc->tHzcheckTime.boolTrip) //跳闸失败时间到，清标志，报soe
	{
		if(pR->tSWST.uSWST.bFlag.bTZWZ)  //合闸闸失败
		{

			if(soe_check(EV_GOOSE_HZ_FAIL+sw*EV_SW_NUM)==false)  //
			{				
				soe_record_ev( EV_GOOSE_HZ_FAIL+sw*EV_SW_NUM,1, 0,0,0 );   // 联络合闸失败
			}
		}
		else  //跳闸成功
		{
			if(soe_check(EV_GOOSE_HZ_OK+sw*EV_SW_NUM)==false)  //联络合闸成功
			{				
				soe_record_ev( EV_GOOSE_HZ_OK+sw*EV_SW_NUM,1, 0,0,0 ); 
			}
		}
		poc->sta.bFlag.bllhzH=false;
	}
}
#ifdef GD_AREA_ZHONGSHAN_2020
void fag_oc_acc(int sw,u32  dStep)  // 分布式合闸加速跳闸
{
	bool bQDD;	
	bool bJS3,bJS4,bJS5;
	bool bY1,bY2; 
	int ui_begin;
	int oc;	
	ui_begin = UI_SW_INDEX_BEGIN(sw);
	for(oc=FAG_GL1;oc<FAG_BHNUMBER;oc++)
	{	
		TOC_T *poc = &g_tRelay[sw].tgoc.tOc[oc];
		OC_SET *pSet = &pRunSet->tSwSet[sw].tGocSet.tOc[oc];
		u16 soeno=EV_GOOSE_HZ_GL1+oc+sw*EV_SW_NUM;
		bool bgloc=(oc==FAG_LX)?false:true;
		bool bxbbs=false;
		// 电流启动
		if(bgloc)
		{
			bool bxb;
			DWORD  xbcoe;			// 谐波系数
			bxb=pRunSet->tSwSet[sw].bTT_goose_xbbs;
			xbcoe=pRunSet->tSwSet[sw].d_goose_xbcoe;
			poc->sta.bFlag.bIaQD = OverRelay(g_ui[ui_begin+SW_AC_IA].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bIaQD); 
			poc->sta.bFlag.bIbQD = OverRelay(g_ui[ui_begin+SW_AC_IB].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bIbQD); 
			poc->sta.bFlag.bIcQD = OverRelay(g_ui[ui_begin+SW_AC_IC].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bIcQD); 

			poc->sta.bFlag.bIaxb =bxb&&XBCalc(sw,SW_AC_IA,xbcoe,poc->sta.bFlag.bIaQD);
			poc->sta.bFlag.bIbxb=bxb&&XBCalc(sw,SW_AC_IB,xbcoe,poc->sta.bFlag.bIbQD);
			poc->sta.bFlag.bIcxb=bxb&&XBCalc(sw,SW_AC_IC,xbcoe,poc->sta.bFlag.bIcQD);
			bQDD=poc->sta.bFlag.bIaQD||poc->sta.bFlag.bIbQD||poc->sta.bFlag.bIcQD;
			bxbbs=poc->sta.bFlag.bIaxb||poc->sta.bFlag.bIbxb||poc->sta.bFlag.bIcxb; //谐波闭锁
		}
		else  //零序加速
		{
			// 零序电流过量继电器
			bY1 = OverRelay(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2[0], pSet->dI, pSet->dI_fh, poc->sta.bFlag.bQD); 
			bY2=true;
			bQDD=bY1&& ((bY2&&pRunSet->bTT_U0BS)||(!pRunSet->bTT_U0BS));
			bxbbs=false;

		}
		// 检查合闸加速标	 
		bJS3 =  g_tRelay[sw].tSWST.uSWST.bFlag.bSHJS;	// 手合加速标

		poc->sta.bFlag.bQD	= (BH_GOOSE_EN_YB(sw))	
							&&(!pRunSet->tSwSet[sw].tGocSet.bsw_fz)
							&& bQDD 
							&& (!bxbbs);//谐波闭锁
		// 加速标保持
		bJS4 = bJS3 || poc->sta.bFlag.bJSBC; 							 
		// 后加速启动条件满足
		bJS5 = poc->sta.bFlag.bQD&& bJS4;
		// 合闸加速标保持
		poc->sta.bFlag.bJSBC = bJS5 && bJS4;	

		if(bJS5)  //幅值启动
		{
			if(!poc->sta.bFlag.bQDWave)
			{
				if(bgloc)
				{
					rcd_start(sw,RECORD_TYPE_GLGZ, RECORD_LEN_TZQD);	//录波类型：跳闸类
				}
				else
				{
					rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD);	//录波类型：跳闸类
				}
				poc->sta.bFlag.bQDWave=true;
			}
		}	
		else
		{
			poc->sta.bFlag.bQDWave=true;
		}
		RunTR(&poc->tQDTime, bJS5, dStep);
		RunTR(&poc->tQD25ms, bJS5, dStep);

		// 如果加速时间到，启动时间未到，调用幅值启动加速模块
		if(poc->sta.bFlag.bQD && poc->tQDTime.boolTrip && !poc->tQD25ms.boolTrip)
		{
			if(bgloc)
			{
				if(protect_amp_qd_js(sw))
				{
					// 预置25ms，让下个循环再出口
					PreSetTime(&poc->tQD25ms, T_25ms);	
				}
			}
			else
			{
				if(protect_amp_lx_js(sw))
				{
					// 预置25ms，让下个循环再出口
					PreSetTime(&poc->tQD25ms, T_25ms);	
				}
			}		
		}	
		poc->sta.bFlag.bTz=poc->tQDTime.boolTrip && poc->tQD25ms.boolTrip; 
		// 出口记录及出口
		if(poc->sta.bFlag.bTz) 
		{
			if(bgloc)
			{
					int ui_begin;	
					DWORD Ia,Ib,Ic;
					ui_begin = UI_SW_INDEX_BEGIN(sw);
					Ia = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IA].m2[0]), 256, g_ui[ui_begin + SW_AC_IA].m2_factor_k);
					Ib = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IB].m2[0]), 256, g_ui[ui_begin + SW_AC_IB].m2_factor_k);
					Ic = _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_IC].m2[0]), 256, g_ui[ui_begin + SW_AC_IC].m2_factor_k);
				
					if(soe_check(soeno)==false)  //过流跳闸
					{				
						soe_record_ev( soeno,1, Ia,Ib,Ic ); 
						poc->sta.bFlag.bDzLed = true;	
						g_tRelay[sw].tgoc.bgooseGz=true;					
					}
			}
			else  // 零序加速
			{
				// 出口记录及出口
				if(poc->sta.bFlag.bTz) 
				{
					int ui_begin;	
					DWORD I0;
					ui_begin = UI_SW_INDEX_BEGIN(sw);
					I0= _Mul_Div_U(sqrt_32fix(g_ui[ui_begin + SW_AC_I0].m2[0]), 256, g_ui[ui_begin + SW_AC_I0].m2_factor_k);
					if(soe_check(soeno)==false)  //零序跳闸
					{				
						soe_record_ev( soeno,1, I0,0,0 ); 
						poc->sta.bFlag.bDzLed = true;	
						g_tRelay[sw].tgoc.bgooseGz=true;
					}
					if(soe_check(soeno)==false)  // 故障切除启动
					{				
						soe_record_ev( soeno,1, 0,0,0 ); 
					}
				}
			}
		}
		else
		{
			if(soe_check(soeno)==true)  // 过流跳闸
			{				
				soe_record_ev( soeno,0, 0,0,0 ); 
			}			
		}	
	}	
}
#endif


void fag_kc(int sw,DWORD dStep)  //goose开出
{
	TRELAY_T *pR=&g_tRelay[sw];
	TGOC_T *poc=&g_tRelay[ sw].tgoc;	
	bool bTz;
	bool bCur;
	bool bgzglok=false;
	bool btzsb=false;
	bTz=poc->sta.bFlag.bglTzH
		||poc->sta.bFlag.blxTzH
		||poc->sta.bFlag.bgzglTzH
		||poc->sta.bFlag.bsdTzH
		||poc->sta.bFlag.bextTzH
		||poc->sta.bFlag.berrTzH;
	// 有跳闸信号时，可由大电流闭锁不动作，
	// 无闭锁时，需保证一次动作信号仅一次出口
	if(bTz&&!pR->bBSTZ&&!poc->bTzout)	
	{
		sw_do(sw,SW_DO_HZ,SW_DO_TYPE_OFF);
		sw_do(sw,SW_DO_BHH,SW_DO_TYPE_OFF);		
		sw_do(sw,SW_DO_BHDZ,SW_DO_TYPE_ON);
		sw_do(sw,SW_DO_FZ,SW_DO_TYPE_ON);
		sw_do(sw,SW_DO_BHT,SW_DO_TYPE_ON);
		poc->bTzout=true;
	}
	// 跳闸失败检查: 跳闸后持续有流或合位
	bCur = ((!pR->tSWST.uSWST.bFlag.bSXWL) || pR->tSWST.uSWST.bFlag.bHZWZ);
	RunTR(&poc->tTzcheckTime, bTz, dStep);		//

	if(poc->tTzcheckTime.boolTrip) //跳闸失败时间到，清标志，报soe
	{
		if(bCur)  //跳闸失败
		{
			bTz=poc->sta.bFlag.bglTzH
				||poc->sta.bFlag.blxTzH
				||poc->sta.bFlag.bgzglTzH
				||poc->sta.bFlag.bsdTzH
				||poc->sta.bFlag.berrTzH;		
			if(poc->sta.bFlag.bglTzH||poc->sta.bFlag.blxTzH||poc->psta.bFlag.bGZ)  //故障切除
			{
				if(soe_check(EV_GOOSE_QC_FAIL+sw*EV_SW_NUM)==false) 
				{				
					soe_record_ev( EV_GOOSE_QC_FAIL+sw*EV_SW_NUM,1, 0,0,0 );   // 故障切除失败
				}
			}
			else
			{
				if(soe_check(EV_GOOSE_GL_FAIL+sw*EV_SW_NUM)==false)  //
				{				
					soe_record_ev( EV_GOOSE_GL_FAIL+sw*EV_SW_NUM,1, 0,0,0 );  //故障隔离失败
				}
			}
			if(bTz)	btzsb=true;  //开关失灵引起的跳闸失败，不再发送
		}
		else  //跳闸成功
		{
			if(poc->sta.bFlag.bglTzH||poc->sta.bFlag.blxTzH||poc->psta.bFlag.bGZ) 
			{
				if(soe_check(EV_GOOSE_QC_OK+sw*EV_SW_NUM)==false)  // 故障切除
				{				
					soe_record_ev( EV_GOOSE_QC_OK+sw*EV_SW_NUM,1, 0,0,0 ); 
				}
			}
			else
			{
				if(soe_check(EV_GOOSE_GL_OK+sw*EV_SW_NUM)==false)  // 故障隔离成功
				{				
					soe_record_ev( EV_GOOSE_GL_OK+sw*EV_SW_NUM,1, 0,0,0 ); 
				}
				bgzglok=true&&(!pRunSet->tSwSet[sw].tGocSet.bsw_fz);  //分支开关不发送故障隔离成功信号
			}
		}	
		poc->bTzout=false;
		poc->sta.bFlag.bglTzH=false;
		poc->sta.bFlag.blxTzH=false;
		poc->sta.bFlag.bgzglTzH=false;
		poc->sta.bFlag.bsdTzH=false;
		poc->sta.bFlag.bextTzH=false;
		poc->sta.bFlag.berrTzH=false;
		ResetTR(&poc->tTzcheckTime);
	}

#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020   //中山要求联络开关固定			
	btzsb|=(pR->uBHDZ.bFlag.bTZSB&&pRunSet->tSwSet[sw].tGocSet.bsw_fz);  //分支开关动作逻辑在常规保护中处理
#endif
	RunTR(&poc->tgzglokextTime, bgzglok, dStep);		//故障隔离成功发送
	poc->psta.bFlag.bgzglok=poc->tgzglokextTime.boolTrip;
	RunTR(&poc->ttzsbextTime, btzsb, dStep);		//跳闸失败发送展宽时间
	poc->psta.bFlag.btzsb=poc->ttzsbextTime.boolTrip;
	RunTR(&poc->tgzglokForbitTime, poc->psta.bFlag.bgzglok, dStep);		//故障隔离发送闭锁
		
}

void fag_bh(int sw,DWORD dStep)
{

	tFAg.bComErr=(tFAg.commerr>0||tFAg.syscomerr>0)?true:false; // goose 通信异常 本机和系统通信异常
	GOC_dir_check(sw,dStep);
	fag_cd(sw,dStep);  // 
	fag_gzgl(sw,dStep);  // 
	fag_lostvol_sd(sw,dStep);  // 
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020  //中山地区，不需要通信失压分闸
#else
	fag_lostvol_commer(sw,dStep);  // 
#endif
	fag_exttz(sw,dStep);  // 
	fag_ll(sw,dStep);  // 
	fag_kc(sw,dStep);  // 
	fa_g_commcheck(dStep);  // goose信息延时复归
}



bool _XB2_Logic_Relay(int sw, DWORD I, DWORD Ixb2, DWORD XBcoe,DWORD Iset)
{
	if(( I > Iset) && ( Ixb2 > pRunSet->dIWL_SQR[sw] ))           // I 与 Ixb2 均应大于无流定值
	{
		if( Ixb2 > _MulFac_U(I, XBcoe ))                         
		{
			return(true);
		}
		else
		{
			return(false);
		}
	}
	else
	{
		return(false);
	}

	return 0;
}

/******************************************************************************
函数名称：	XBCalc
函数版本：	01.01
创建作者：	xxxxxx
创建日期：	2014-12-16
函数说明：	谐波计算
参数说明：	
返回值：  	无
修改记录：	
*/
void XBCalc_goc(int sw)
{
	bool bH1,bH2,bH3;
	bool bxbbs=false;
	bool bxbbs2=false;

	if(!BH_GOOSE_EN(sw))return;
	if(pRunSet->tSwSet[sw].bTT_goose_xbbs)
	{
		bH1 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl);//A相谐波闭锁
		bH2 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl);//B相谐波闭锁
		bH3 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl);//C相谐波闭锁
		bxbbs=(bH1 || bH2 || bH3);
#if defined GD_AREA_ZHONGSHAN || defined GD_AREA_ZHONGSHAN_2020
		bH1 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IA)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl2);//A相谐波闭锁
		bH2 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IB)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl2);//B相谐波闭锁
		bH3 = _XB2_Logic_Relay(sw, g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[0], g_ui[UI_SW_INDEX(sw,SW_AC_IC)].m2[1], pRunSet->tSwSet[sw].d_goose_xbcoe,pRunSet->tSwSet[sw].tGocSet.dIgl2);//C相谐波闭锁
		bxbbs2=(bH1 || bH2 || bH3);
#endif
	}
	
	g_tRelay[sw].tgoc.sta.bFlag.bXBbs =bxbbs;		
	g_tRelay[sw].tgoc.sta.bFlag.bXBbs2 =bxbbs2;		
	if(bxbbs||bxbbs2)
	{	
		if(soe_check(EV_XBBS+sw*EV_SW_NUM)==false) 
		{
			soe_record_ev(EV_XBBS+sw*EV_SW_NUM,1, 0,0,0 ); 
		}
	}
	else
	{
		if(soe_check(EV_XBBS+sw*EV_SW_NUM)==true) 
		{
			soe_record_ev( EV_XBBS+sw*EV_SW_NUM,0, 0,0,0 ); 
		}
	}
	
}

/***************************************endfile**********************************************************/

