
#include "head.h"

enum
{
	JD_STEP_QD=0,    // 启动判断
	JD_STEP_CHECK,  //启动确认
	JD_STEP_COLLECT, //数据收集	
	JD_STEP_CTFAULT,   //暂态故障判定
	JD_STEP_SSFAULT,   //稳态故障处理
	JD_STEP_RST,      //复归
	JD_STEP_NET_RST,  //等待网络复归
};
enum
{
	JD_FAULT_DIR_ZERO=0,
	JD_FAULT_DIR_POS_QD,  //大于启动值正方向
	JD_FAULT_DIR_NEG_QD,   //大于启动值反方向
	JD_FAULT_DIR_POS,           //大于零漂正方向
	JD_FAULT_DIR_NEG,           //大于零漂反方向
};

#ifdef FUN_JDXX

//#define XDL_PRINT
#define UI_JDXX_I0_INDEX UI_SW_INDEX(sw,SW_AC_I0)
#define UI_JDXX_I0S_INDEX UI_SW_INDEX(sw,SW_AC_I0s)

///////////////////////////////////////////////
JDXX_SET tJDXX_val[SWITCH_NUM_MAX];


bool TT_U0yx;   //U0越限判据投退
bool TT_Ulyy;   //Ul线电压有压判据
bool TT_Ipwl;	//相电流无流判据投退	
bool TT_Ipph;   //相电流相位判据
bool TT_U0jd;   //UO就接地

extern unsigned int g_count_156us;
////////////////////////////////////////////////////////////////////////////////////////////////
void jdxx_init(void)
{
	//memset(&tJD,0,sizeof(tJD));
	_getjdxxdz_inf();
	rt_printf("Jdxx_Ver:%02d.%03d \r\n",(FUN_JDXX_VERSION/1000),(FUN_JDXX_VERSION%1000));
}

void jdxx_relayinit(void)
{
	int i;
	
	for(i=0;i<SWITCH_NUM_MAX;i++)
	{		
		JDXX_SET *pJdxx=&tJDXX_val[i];		
		TRELAY_T *pR=&g_tRelay[i];

		//U0判出时间	
		#ifdef FUN_JDXX_JXJD
		InitTR_Time(&pR->tJD.tJDXXU01Time,T_20ms, 0);     	//U01 20ms	
		InitTR_Time(&pR->tJD.tJDXXU02Time,T_20ms, 0);     	//U02 20ms			
		#elif defined FUN_JDXX_TBLQD
		InitTR_Time(&pR->tJD.tJDXXU01Time,T_25ms, T_10ms);     	//U01 40ms
		InitTR_Time(&pR->tJD.tJDXXU02Time,T_25ms, T_10ms);     	//U02 40ms
		#else
		InitTR_Time(&pR->tJD.tJDXXU01Time,T_20ms, T_20ms);     	//U01 20ms，保持100ms(弧光接地)		
		InitTR_Time(&pR->tJD.tJDXXU02Time,T_20ms, T_20ms);     	//U02 20ms，保持100ms(弧光接地)		
		#endif
		InitTR_Time(&pR->tJD.tJDXXU1yyTime,T_20ms*3,0);       //有压60ms		
		InitTR_Time(&pR->tJD.tJDXXU2yyTime,T_20ms*3,0);       //有压60ms
		InitTR_Time(&pR->tJD.tJDXXIylTime,T_20ms*3,0);       //有流60ms

		InitTR_Time(&pR->tJD.tJDXXTripTime, pJdxx->jd_trip_time, T_20ms);
		InitTR_Time(&pR->tJD.tJDXXAlarmTime, pJdxx->jd_alarm_time, T_20ms);

     #ifdef JDXX_YXEV_RST
		InitTR_Time(&pR->tJD.tJDGjEvRstTime, tRunPara.dTEventRst, 0);
		InitTR_Time(&pR->tJD.tJDTzEvRstTime, tRunPara.dTEventRst, 0);
	 #endif
	 
	#ifdef HJS_XDLJD
		InitTR(&pR->tJD.jdxx_jskf_time,pJdxx->jd_js_time, 0); 	// 开放时间 
	#endif
	}
}

void jdxx_u0_rst(int sw)
{
	TRELAY_T *pR=&g_tRelay[sw];

	ResetTR(&pR->tJD.tJDXXU01Time);		//U02 20ms
	ResetTR(&pR->tJD.tJDXXU02Time);		//U02 20ms
	ResetTR(&pR->tJD.tJDXXU1yyTime);	    //	
	ResetTR(&pR->tJD.tJDXXU2yyTime);	    //
	ResetTR(&pR->tJD.tJDXXIylTime);	    //
}

void  jdxx_qd_rst(int sw)  //启动返回
{
	int i;
	TRELAY_T *pR=&g_tRelay[sw];
	
	pR->tJD.jd_step = JD_STEP_QD;
	pR->tJD.sta.bFlag.bTz = false;
	pR->tJD.sta.bFlag.bGj = false;
	pR->tJD.qdPoints=0;
	pR->tJD.adPoints=0;		
	pR->tJD.con_angle=0;
	#ifdef FUN_JDXX_SS_ANGLE
	pR->tJD.dir_cnt=0;
	#endif
	#ifdef HJS_XDLJD
	pR->tJD.sta.bFlag.bJd_qn = 0;		//区外故障		
	#endif
	for(i=0;i<NUM_ANGLE;i++)
	{
		pR->tJD.ui_angle[i]=0;	
	}

	ResetTR(&pR->tJD.tJDXXTripTime);
	ResetTR(&pR->tJD.tJDXXAlarmTime);
	//soe
	pro_rst_event(sw,EV_JDXX_QD);			 
	pro_rst_event(sw,EV_JDXX_JWGZ);
  #ifdef FUN_JDXX_JXJD
	pro_rst_event(sw,EV_JDXX_SWIN_GJ);	
	pro_rst_event(sw,EV_JDXX_LWIN_GJ);	
  #endif
}


void  jdxx_fg(int sw)  //接地选线复归
{
	#ifdef XDL_PRINT
	rt_printf("\r\njdxx_fg:sw=%d JD_STEP_FG",sw);
	#endif
	jdxx_qd_rst(sw);	
}

//soe fugui
void jdxx_soe_fg(int sw,DWORD   dStep)
{
#ifdef JDXX_YXEV_RST
	{
		TRELAY_T *pR=&g_tRelay[sw];		
		
		RunTR( &pR->tJD.tJDGjEvRstTime, true, dStep);
		RunTR( &pR->tJD.tJDTzEvRstTime, true, dStep);
		if(pR->tJD.tJDGjEvRstTime.boolTrip)
		{			
			pro_rst_event(sw,EV_JDXX_GJ);	
			//事故总	主程序复归				
			//if(pJdxx->bTT_jdxx_fault_all)
			//{
			//	pro_rst_event(sw,EV_ALL_FAULT);	
			//}
		}	
		if(pR->tJD.tJDTzEvRstTime.boolTrip)
		{			
			pro_rst_event(sw,EV_JDXX_TZ);
			//事故总	主程序复归					
			//if(pJdxx->bTT_jdxx_fault_all)
			//{
			//	pro_rst_event(sw,EV_ALL_FAULT);	
			//}
		#ifdef FUN_JDXX_JXJD
			pro_rst_event(sw,EV_JDXX_SWIN_TZ);  
			pro_rst_event(sw,EV_JDXX_LWIN_TZ);	
		    pro_rst_event(sw,EV_JDXX_YJ_TZ);
		#endif
		}
	}
#else
	{
		pro_rst_event(sw,EV_JDXX_GJ);	 
		pro_rst_event(sw,EV_JDXX_TZ);
		//事故总	主程序复归					
		//if(pJdxx->bTT_jdxx_fault_all)
		//{
		//	pro_rst_event(sw,EV_ALL_FAULT);	
		//}
	  #ifdef FUN_JDXX_JXJD
		pro_rst_event(sw,EV_JDXX_SWIN_TZ);  
		pro_rst_event(sw,EV_JDXX_LWIN_TZ);	
	    pro_rst_event(sw,EV_JDXX_YJ_TZ);
      #endif
	}
#endif
}

void jdxx_yxev_rst(int sw)
{
#ifdef JDXX_YXEV_RST
	TRELAY_T *pR=&g_tRelay[sw];

	ResetTR(&pR->tJD.tJDGjEvRstTime);
	ResetTR(&pR->tJD.tJDTzEvRstTime);
#endif
	pro_rst_event(sw,EV_JDXX_GJ);	 
	pro_rst_event(sw,EV_JDXX_TZ);
  #ifdef FUN_JDXX_JXJD
	pro_rst_event(sw,EV_JDXX_SWIN_TZ);  
	pro_rst_event(sw,EV_JDXX_LWIN_TZ);	
    pro_rst_event(sw,EV_JDXX_YJ_TZ);
  #endif	
}
/**********************************
//启动前零序通道零漂模值
**********************************/
void jdxx_getzeroval(int sw)
{
	JDXX_SET *pJdxx=&tJDXX_val[sw];	
	TRELAY_T *pR=&g_tRelay[sw];
	
	if(pR->tJD.jd_step==JD_STEP_QD)	//复归判断	
	{
		pR->tJD.zeroval=g_ui[pJdxx->i0_chan].m2[0]+pJdxx->jd_qdval2;
	}
}
/**********************************
//突变量
//index:电流通道
//cur:通道采样索要
**********************************/
s32 jdxx_get_qdval(u32 cur,int index)//突变量
{
	s32 v,v1,v2,val;
	v = g_adc_dots_rec[cur][index];	
	v1 = g_adc_dots_rec[(cur - ADC_REC_SAMPLE) & ADC_REC_DOTS_MASK][index];	
	v2 = g_adc_dots_rec[(cur - ADC_REC_SAMPLE*2) & ADC_REC_DOTS_MASK][index];	
	val = (v -2*v1 + v2);
	return  val;
}

s32 jdxx_getI0_qdval(u32 cur,int index1,int index2,int index3)//突变量
{
	s32 val=0;

	val = jdxx_get_qdval(cur,index1)
	     +jdxx_get_qdval(cur,index2)
	     +jdxx_get_qdval(cur,index3);
	
	return  val;
}
////////////////////////////////////////////////
//复归信号保持
bool jdxx_soe_check(int sw)
{
	if(soe_check(EV_JDXX_GJ+sw*EV_SW_NUM)) return true;
    if(soe_check(EV_JDXX_TZ+sw*EV_SW_NUM)) return true;
	//if(soe_check(EV_JDXX_JWGZ+sw*EV_SW_NUM)) return true; 
  #ifdef FUN_JDXX_JXJD
	if(soe_check(EV_JDXX_SWIN_TZ+sw*EV_SW_NUM)) return true;
	if(soe_check(EV_JDXX_LWIN_TZ+sw*EV_SW_NUM)) return true;	
    if(soe_check(EV_JDXX_YJ_TZ+sw*EV_SW_NUM)) return true;
  #endif
  
    return false;
}
#ifdef FUN_JDXX_JXJD
//瞬时故障延时跳闸逻辑
bool jdxx_ssjd_pro(int sw)
{
	int i,num;
	bool  bQDD; 
	JDXX_SET *pJdxx=&tJDXX_val[sw];
	TRELAY_T *pR=&g_tRelay[sw];	
	
	//短延时接地故障
	if(pJdxx->bTT_jxjd_stz) 
	{		
		//I瞬时接地计次
	    pR->tJD.cnt_sdelay++;
		if(pR->tJD.cnt_sdelay>pJdxx->jd_sdelay_cnt)
		{
			pR->tJD.cnt_sdelay=pJdxx->jd_sdelay_cnt;
		}
		#ifdef XDL_PRINT
		rt_printf("\r\nSW%d:间歇性接地保护I段计次！sdn=%d!",sw,pR->tJD.cnt_sdelay);
		#endif
		
		//jxjd_logic
		bQDD = (pR->tJD.cnt_sdelay>=pJdxx->jd_sdelay_cnt) && (ustimer_get_duration(pR->tJD.jdxx_sdelay_us0[pR->tJD.cnt_sdelay-2]) < (pJdxx->jd_sdelay_time*(USTIMER_SEC/SAM_FREQUENCY)));//短延时故障
		if(bQDD)
		{
			//led			
			pR->tJD.sta.bFlag.bTz = true;
			pR->tJD.sta.bFlag.bTZLed = true;
			//soe
			if(soe_check(EV_JDXX_SWIN_TZ+sw*EV_SW_NUM)==false)	
			{
				soe_record_ev(EV_JDXX_SWIN_TZ+sw*EV_SW_NUM,1, 0,0,0 );

				if(soe_check(EV_JDXX_TZ+sw*EV_SW_NUM)==false)	//区内故障
				{
					soe_record_ev(EV_JDXX_TZ+sw*EV_SW_NUM,1, 0,0,0 );
				}

				//事故总					
				if(pJdxx->bTT_jdxx_fault_all)
				{
					if(!soe_check(EV_ALL_FAULT+sw*EV_SW_NUM))  //保护总
					{				
						soe_record_ev( EV_ALL_FAULT+sw*EV_SW_NUM,1, 0,0,0 ); 
					}
				}

			#ifdef XDL_PRINT
				rt_printf("\r\n间歇性接地保护I段动作");
			#endif	

				//故障处理完毕，进入复归处理流程 
				pR->tJD.jd_step=JD_STEP_RST;
				pR->tJD.cnt_sdelay=0;
				pR->tJD.cnt_ldelay=0;//???
		
	        #ifdef XDL_PRINT
				rt_printf("\r\njdxx_s_fault:T[0]=%d!",pR->tJD.time_qd/USTIMER_SEC);
				rt_printf("\r\njdxx_s_fault:sw=%d step_rst",sw);
	        #endif
			}
	
			return true;
		}
		else//存储故障时刻
		{			
			//SOE
			if(soe_check(EV_JDXX_SWIN_GJ+sw*EV_SW_NUM)==false)
			{
				soe_record_ev(EV_JDXX_SWIN_GJ+sw*EV_SW_NUM,1, 0,0,0 );
			}
			//us0 fifo
			num = pJdxx->jd_sdelay_cnt-1;
			for(i=0;i<num;i++)
			{
				pR->tJD.jdxx_sdelay_us0[num-i]=pR->tJD.jdxx_sdelay_us0[num-1-i];
			}
			pR->tJD.jdxx_sdelay_us0[0] = pR->tJD.time_qd;//ustimer_get_origin();
		#ifdef XDL_PRINT
			rt_printf("\r\njdxx_s_fault:T[0]=%d!",pR->tJD.jdxx_sdelay_us0[0]/USTIMER_SEC);
        #endif	
		}		
	}
	//长延时接地故障
	if(pJdxx->bTT_jxjd_ltz) 
	{		
		//II瞬时接地计次
		pR->tJD.cnt_ldelay++;
		if(pR->tJD.cnt_ldelay>pJdxx->jd_ldelay_cnt)
		{
			pR->tJD.cnt_ldelay=pJdxx->jd_ldelay_cnt;
		}
		#ifdef XDL_PRINT
		rt_printf("\r\nSW%d间歇性接地保护II段计次！ldn=%d!",sw,pR->tJD.cnt_ldelay);
		#endif
		
		//jxjd_logic
		bQDD = (pR->tJD.cnt_ldelay>=pJdxx->jd_ldelay_cnt) && (ustimer_get_duration(pR->tJD.jdxx_ldelay_us0[pR->tJD.cnt_ldelay-2]) < (pJdxx->jd_ldelay_time*(USTIMER_SEC/SAM_FREQUENCY)));//长延时故障
		if(bQDD)
		{
			//led
			pR->tJD.sta.bFlag.bTz = true;
			pR->tJD.sta.bFlag.bTZLed = true;
			//soe
			if(soe_check(EV_JDXX_LWIN_TZ+sw*EV_SW_NUM)==false)	
			{
				soe_record_ev(EV_JDXX_LWIN_TZ+sw*EV_SW_NUM,1, 0,0,0 );
				
				if(soe_check(EV_JDXX_TZ+sw*EV_SW_NUM)==false)	//区内故障
				{
					soe_record_ev(EV_JDXX_TZ+sw*EV_SW_NUM,1, 0,0,0 );
				}

				//事故总					
				if(pJdxx->bTT_jdxx_fault_all)
				{
					if(!soe_check(EV_ALL_FAULT+sw*EV_SW_NUM))  //保护总
					{				
						soe_record_ev( EV_ALL_FAULT+sw*EV_SW_NUM,1, 0,0,0 ); 
					}
				}	

				#ifdef XDL_PRINT
					rt_printf("\r\n间歇性接地保护II段动作");
				#endif				
											
				//故障处理完毕，进入复归处理流程 
				pR->tJD.jd_step=JD_STEP_RST;
				pR->tJD.cnt_sdelay=0;//???
				pR->tJD.cnt_ldelay=0;
		
	        #ifdef XDL_PRINT
				rt_printf("\r\njdxx_l_fault:T[0]=%d!",pR->tJD.time_qd/USTIMER_SEC);
				rt_printf("\r\njdxx_l_fault:sw=%d step_rst",sw);
	        #endif
			}
			return true;
		}
		else//存储故障时刻
		{			
			//SOE
			if(soe_check(EV_JDXX_LWIN_GJ+sw*EV_SW_NUM)==false)
			{
				soe_record_ev(EV_JDXX_LWIN_GJ+sw*EV_SW_NUM,1, 0,0,0 );
			}
			//us0 fifo
			num = pJdxx->jd_ldelay_cnt-1;
			for(i=0;i<num;i++)
			{
				pR->tJD.jdxx_ldelay_us0[num-i]=pR->tJD.jdxx_ldelay_us0[num-1-i];
			}
			pR->tJD.jdxx_ldelay_us0[0] = pR->tJD.time_qd;//ustimer_get_origin();
		#ifdef XDL_PRINT
			rt_printf("\r\njdxx_l_fault:T[0]=%d!",pR->tJD.jdxx_ldelay_us0[0]/USTIMER_SEC);
        #endif
		}
	}	

	return false;
}
#endif
//复归
void jdxx_rst(int sw, DWORD  dStep)
{
	TRELAY_T *pR=&g_tRelay[sw];	

	//状态
	if(pR->tJD.jd_step==JD_STEP_QD) 
	{
		jdxx_soe_fg(sw,dStep);
		return;
	}
    //复归
	if(pR->tJD.jd_step==JD_STEP_RST)
	{
		jdxx_fg(sw);			
	}
	else//pR->tJD.jd_step==JD_STEP_RST
	{
	#ifdef FUN_JDXX_JXJD	    
		bool ret;
	
		ret=jdxx_ssjd_pro(sw); //多次瞬时故障跳闸
	    if(!ret)    	
	#endif
		{
			jdxx_fg(sw);
		}
	}	
}

s16 jdxx_get_adval(u32 dots,int index)
{
	u32 cur=dots&ADC_REC_DOTS_MASK;
	s16 v;
	v = g_adc_dots_rec[cur][index];  
	return v;
}

s16 jdxx_getI0_adval(u32 dots,int index1,int index2,int index3)
{
	u32 cur=dots&ADC_REC_DOTS_MASK;
	s16 v;
	v =  g_adc_dots_rec[cur][index1]
		+g_adc_dots_rec[cur][index2]
		+g_adc_dots_rec[cur][index3];  
	return v;
}

/*bool jdxx_I0_ov(int sw)  //判断零序是否失真
{
	int i;
	JDXX_SET *pJdxx=&pRunSet->tSwSet[sw].tJDXX;
	
	for(i=0;i<pJdxx->jd_faultPoints;i++) // 统计接地时刻的波形，是否满偏失真 ，大于8A，即使用大量程零序波形判断
	{
		s16 v;
		v=jdxx_get_adval(tJD[sw].dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index);//jdxx_get_adval(tJD.dot_qd+i,g_ui[UI_JDXX_I0G_INDEX].chn_index);
		if(_AbsL(v)>=pJdxx->jd_ov_val)
		{
			return true;
		}
	}
	return false;
}*/

#define U0_FULL_DOTNUM 10
bool jdxx_U0_ov(int sw)  //判断一周波零序电压是否失真
{
	int i,j,mod,index;
	u32 dotcur;
	TRELAY_T *pR=&g_tRelay[sw];

	if(pR->tJD.jd_u0_12==1) index=PUB_AC_U01;
	else index=PUB_AC_U02;
	
	mod = (int)(g_count_156us &0x03);
	dotcur=(g_adc_dots_count)*ADC_REC_SAMPLE_RATE+mod-ADC_REC_SAMPLE;
	for(i=0,j=0;i<ADC_REC_SAMPLE;i++) //ADC_REC_SAMPLE 统计接地时刻的波形，是否满偏失真 ，大于8A，即使用大量程零序波形判断
	{
		s16 v;
		
		v=jdxx_get_adval(dotcur+i,g_ui[index].chn_index);
		pR->tJD.jd_U0ov_val=(short)(7.2*g_ui[index].m2_factor_k/256.0+0.5);   //EVT零序 7.8125V满偏，7.2V作为满偏定值
		if(_AbsL(v)>=pR->tJD.jd_U0ov_val)
		{			
			if(++j>U0_FULL_DOTNUM)
			{
				return true;
			}
		}
	}
	return false;
}

bool jdxx_I0_ov(int sw)  //判断零序是否失真
{
	int i;	
	JDXX_SET *pJdxx=&tJDXX_val[sw];
	TRELAY_T *pR=&g_tRelay[sw];

	if(g_ui[UI_JDXX_I0S_INDEX].chn_index==CFG_ADC_CHANNEL_ZERO) 
	{
		return false;
	}
	
	for(i=0;i<pJdxx->jd_faultPoints;i++) // 统计接地时刻的波形，是否满偏失真 ，大于0.5A，即使用大量程零序波形判断
	{
		s16 v;
		v=jdxx_get_adval(pR->tJD.dot_qd+i,g_ui[UI_JDXX_I0_INDEX].chn_index);
		if(_AbsL(v)>=pJdxx->jd_ov_val)
		{
			rt_printf("jdxx:sw=%d 零序小通道电流满偏失真！\r\n",sw);
			return true;
		}
	}
	
	return false;
}

int jdxx_I0Range(int sw)  // 
{
	int i;
	int bv0=0,bv1=0;
	int dots=0;
	JDXX_SET *pJdxx=&tJDXX_val[sw];
	TRELAY_T *pR=&g_tRelay[sw];

	for(i=0;i<pJdxx->jd_faultPoints-1;i++) // 取方向
	{
		if(pJdxx->bTT_jdxx_cph)//(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index==CFG_ADC_CHANNEL_ZERO)
		{
			if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) > 0)//pJdxx->jd_zero)
			{
				bv0=1;
				break;
			}
			else if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) < 0)//-pJdxx->jd_zero)
			{
				bv0=-1;
				break;
			}
		}
		else
		{
		    if(g_ui[pJdxx->i0_chan].chn_index==CFG_ADC_CHANNEL_ZERO)
			{
				if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) > 0)//pJdxx->jd_zero)
				{
					bv0=1;
					break;
				}
				else if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) < 0)//-pJdxx->jd_zero)
				{
					bv0=-1;
					break;
				}
	    	}
			else
			{
				if(jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[pJdxx->i0_chan].chn_index) > 0)//pJdxx->jd_zero)
				{
					bv0=1;
					break;
				}
				else if(jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[pJdxx->i0_chan].chn_index) < 0)//-pJdxx->jd_zero)
				{
					bv0=-1;
					break;
				}
			}
		}	
	}
	for(i++;i<pJdxx->jd_faultPoints;i++) // 取方向
	{
		if(pJdxx->bTT_jdxx_cph)//(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index==CFG_ADC_CHANNEL_ZERO)
		{
			if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) > 0)//pJdxx->jd_zero)
			{
				bv1=1;
			}
			else if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) < 0)//-pJdxx->jd_zero)
			{
				bv1=-1;
			}
		}
		else
		{
			if(g_ui[pJdxx->i0_chan].chn_index==CFG_ADC_CHANNEL_ZERO)
			{
				if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) > 0)//pJdxx->jd_zero)
				{
					bv1=1;
				}
				else if(jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index) < 0)//-pJdxx->jd_zero)
				{
					bv1=-1;
				}
			}
			else
			{
				if(jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[pJdxx->i0_chan].chn_index) > 0)//pJdxx->jd_zero)
				{
					bv1=1;
				}
				else if(jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[pJdxx->i0_chan].chn_index) < 0)//-pJdxx->jd_zero)
				{
					bv1=-1;
				}
			}
		}
		dots=i+1;
		if(bv0!=bv1)break;	
	}

	#ifdef XDL_PRINT
	rt_printf("\r\n sw=%d 启动后同方向点数%d",sw,dots);
	#endif
	return dots;
}

int jdxx_Iabc_check_dir(int sw) // Ia Ib Ic 接地相判断，以零序启动时刻为主，查找零序启动后32点内的最大值，做积分，看三相的方向
{
	int dots;
	long va,vb,vc,v1,v2,v3;
	int i;
	TRELAY_T *pR=&g_tRelay[sw];
	
	dots=jdxx_I0Range(sw);
	va=0;
	vb=0;
	vc=0;
	for(i=0;i<dots;i++) //
	{
		va+=jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index);
		vb+=jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index);
		vc+=jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index);
	}
	#ifdef XDL_PRINT
	rt_printf("\r\n三相积分值Ia=%d Ib=%d Ic=%d",va,vb,vc);
	#endif
	//一相和另外两相反相
	if((va>0&&vb<=0&&vc<=0)||(va<0&&vb>=0&&vc>=0)) //不同相 
	{
		return SW_AC_IA;  // A相接地
	}
	else if((vb>0&&va<=0&&vc<=0)||(vb<0&&va>=0&&vc>=0))
	{
		return SW_AC_IB; // B相接地
	}
	else if((vc>0&&va<=0&&vb<=0)||(vc<0&&va>=0&&vb>=0))
	{
		return SW_AC_IC;  // C相接地
	}
	//突变:4倍
	v1=_AbsL(va);
	v2=_AbsL(vb);
	v3=_AbsL(vc);
	if((v1>>2)>v2 && (v1>>2)>v3)
	{
		return SW_AC_IA;  // A相接地
	}
	else if((v2>>2)>v1 && (v2>>2)>v3)
	{
		return SW_AC_IB;  // A相接地
	}
	else if((v3>>2)>v1 && (v3>>2)>v2)
	{
		return SW_AC_IC;  // A相接地
	}
	//无法判相
	return -1;

}

// 电压波形起始点
int jdxx_get_dotsoff(int sw,int pha)
{
	int vdots=0,dotsoff=0;	
	JDXX_SET *pJdxx=&tJDXX_val[sw];
	TRELAY_T *pR=&g_tRelay[sw];

	if((pJdxx->jd_voltype==PUB_AC_U01)||(pJdxx->jd_voltype==PUB_AC_U02))
	{
		vdots=pR->tJD.dot_qd;
	}
	else if(pJdxx->jd_voltype==PUB_AC_UA1)
	{
		if(pha==SW_AC_IA)   // A相接地，与UA1比较，波形不需偏移
		{
			dotsoff=0;
		}
		else if(pha==SW_AC_IB) // B相接地，与UA1比较，参考电压波形需后移120度，即128/3=42.66
		{
			dotsoff=-43;
		}
		else 
		{
			dotsoff=43; // C相接地，参考电压UA1波形需前移120度
		}		
		vdots=pR->tJD.dot_qd+dotsoff-ADC_REC_SAMPLE*2;  // 电压波形起始点
	}
	else if(pJdxx->jd_voltype==PUB_AC_UAB1)  
	{
		if(pha==SW_AC_IA)   // A相接地，与UAB1比较，UAB1波形超前Ia30度，30/360*128=10.666(11点)
		{
			dotsoff=11;
		}
		else if(pha==SW_AC_IB) // B相接地，与UAB1比较，参考电压波形需后移120度，即128/3=42.66+10.66
		{
			dotsoff=-53;
		}
		else 
		{
			dotsoff=53; // C相接地，参考电压UA1波形需前移120度
		}		
		vdots=pR->tJD.dot_qd+dotsoff-ADC_REC_SAMPLE*2;	// 电压波形起始点
	}
	
	return vdots;
}

int jdxx_VI0_dir(int sw,int pha)
{
	int i,dotsnum,vdots;
	s32 v0,I0;
	JDXX_SET *pJdxx=&tJDXX_val[sw];
    TRELAY_T *pR=&g_tRelay[sw];
	
	if(pha<0)return 0;
			
	vdots=jdxx_get_dotsoff(sw,pha);
	dotsnum=jdxx_I0Range(sw);  // 零序电流统计点数
	if(dotsnum==0) return 0;
	
	//积分	
	v0=0;
	I0=0;
	for(i=0;i<dotsnum;i++) //
	{
		if(pRunSet->bTT_U0ZC)	//U0
		{
		    if(pR->tJD.jd_u0_12==1)
	    	{
				v0+=jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[PUB_AC_UA1].chn_index,g_ui[PUB_AC_UB1].chn_index,g_ui[PUB_AC_UC1].chn_index);
	    	}
			else
			{
				v0+=jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[PUB_AC_UA2].chn_index,g_ui[PUB_AC_UB2].chn_index,g_ui[PUB_AC_UC2].chn_index);
	    	}
		}
		else	
		{
			if(pR->tJD.jd_u0_12==1)
	    	{
		    	v0+=jdxx_get_qdval(vdots+i,g_ui[PUB_AC_U01].chn_index); 
			}
	    	else
			{
				v0+=jdxx_get_qdval(vdots+i,g_ui[PUB_AC_U02].chn_index); 
    		}
		}
	
		if(g_ui[pJdxx->i0_chan].chn_index==CFG_ADC_CHANNEL_ZERO) //I0
		{
			I0+=jdxx_getI0_qdval(pR->tJD.dot_qd+i,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index);
		}
		else
		{
			I0+=jdxx_get_qdval(pR->tJD.dot_qd+i,g_ui[pJdxx->i0_chan].chn_index);
		}
	}

	#ifdef XDL_PRINT
	rt_printf("\r\nV_I0积分:V=%d I0=%d",v0,I0);
	#endif
	
//V0是否突变
	//if(_AbsL(v0)<=(DWORD)pJdxx->jd_volzero*dotsnum) return 0; //电压突变太小
//区内区外判断
	if((v0>0&&I0>0)||(v0<0&&I0<0)) return 1;
	else return -1;	 
}

// 判界内界外，零序电流和参考电压比波形的相似度 chnl 为相别
//返回：ret=-1 无法判出相、区内区外
//      ret=0  正确判出
int jdxx_checkjd(int sw)  
{
	int pha0,ret0;
	JDXX_SET *pJdxx=&tJDXX_val[sw];
	TRELAY_T *pR=&g_tRelay[sw];

	if(pJdxx->bTT_jdxx_cph)
	{
		pha0=jdxx_Iabc_check_dir(sw);	 // 通过三相电流方向判断接地相
		ret0=jdxx_VI0_dir(sw,pha0); 	 // U 和I0的积分:同向为1,已向为 1		
		if(ret0==0)
		{
			#ifdef XDL_PRINT
			if(pha0<0)
			{
				rt_printf("\r\n判相失败！pha=%d",pha0);
			}
			else
			{
				rt_printf("\r\n区内区外判别失败！电压零流方向=%d(1:界内,-1:界外)",ret0);
			}
			#endif
			return -1;			
		}
		#ifdef XDL_PRINT
		rt_printf("\r\n暂态接地判据:sw=%d 电压零流方向=%d(1:界内,-1:界外)  pha=%d",sw,ret0,pha0); 
		#endif
		//rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); 	//录波类型：跳闸类
		//判断界内	
		if(((pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))  && ret0<0)|| 
		   (!(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0>0)) 
		{			
			pR->tJD.tc_result=1;				
		}
	     else
	   	{			
			pR->tJD.tc_result=0;				
		}
	}
	else//U0参与逻辑
	{
		pha0=4;//不判相
		ret0=jdxx_VI0_dir(sw,pha0);      // U 和I0的积分，同向为1 ，反向为-1
		if(ret0==0)
		{
			#ifdef XDL_PRINT
			rt_printf("\r\n区内区外判别失败！电压零流方向=%d(1:界内,-1:界外)",ret0);			
			#endif
			return -1;			
		}
		#ifdef XDL_PRINT
		rt_printf("\r\n暂态接地判据:sw=%d 电压零流方向=%d(1:界内,-1:界外)",sw,-ret0);//U0/I0反相为界内,同向为界外
		#endif
		//rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); 	//录波类型：跳闸类
		//判断界内
	#if	defined FUN_JDXX_JXJD || defined DTU_HUNAN
		if(((pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0>0)||	//极性
		   (!(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0<0))	 
	#else
		if((((pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0>0)||  //极性
		   (!(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw)) && ret0<0))    
		   &&(g_ui[pJdxx->i0_chan].m2[0] >= pJdxx->jd_qdval2)) //I0幅值
	#endif
		{			
			pR->tJD.tc_result=1;			
		}
		else
	   	{			
			pR->tJD.tc_result=0;				
		}
		#ifdef XDL_PRINT
		rt_printf("\r\n首端算法结论:sw=%d result=%d(1:界内,-1:界外)",sw,pR->tJD.tc_result);
		#endif
	}	
	return 0;
}
/**********************************
//接地选线启动逻辑
**********************************/
//有功分量判据
void jdxx_yg_qd(int sw)
{
	int ret0;
	float pea,th_pea;
	TRELAY_T *pR=&g_tRelay[sw];
	JDXX_SET *pJdxx=&tJDXX_val[sw];

	//判区内区外
	if(pR->tJD.jd_step==JD_STEP_QD)
	{		
		//有功分量选择
		if(g_ui[UI_JDXX_I0S_INDEX].chn_index!=CFG_ADC_CHANNEL_ZERO)  pea = g_ui_p0[sw].Peas;
		else pea = g_ui_p0[sw].Pea;
		//有功门槛值，约15K
		if(g_equ_config_ac[g_sw_pub.ac_cfg_index[pJdxx->i0_chan]].scale==EQU_SCALE_EVT_6V50_100V)  th_pea=0.02;//_sw_ui_e_k(int ui_index)  		
		else th_pea=0.30; //100/6.5*0.02=0.30			
		
		//有功分量判区内区外
		if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
		{
			 if((pea-th_pea)>0) ret0=-1;//0.30--100V;0.02--6.5V
			 else ret0=1;
		}
		else
		{
              if((pea+th_pea)<0) ret0=-1;
			 else ret0=1;
		}	
	    #ifdef XDL_PRINT
		rt_printf("\r\n暂态接地判据:sw=%d 电压零流方向=%d(1:界内,-1:界外)",sw,-ret0);//U0/I0反相为界内,同向为界外
		#endif
		//rcd_start(sw,RECORD_TYPE_LXGL, RECORD_LEN_TZQD); 	//录波类型：跳闸类
		//判断界内
		if( ret0<0) 
		{			
			pR->tJD.tc_result=1;			
		}
		else
	   	{			
			pR->tJD.tc_result=0;				
		}
		pR->tJD.jd_step = JD_STEP_SSFAULT;
	}
}

//首半波判据
#define NUM_QDFX  (ADC_REC_SAMPLE<<2) //四个周波
void jdxx_qd(int sw)
{
	s32 qdval;
	int mod,dir;
	u32 dotcnt,dotend,dotcur;//,dotnum;	
	JDXX_SET *pJdxx=&tJDXX_val[sw];
	TRELAY_T *pR=&g_tRelay[sw];
	
	mod = (int)(g_count_156us &0x03);
	dotend=(g_adc_dots_count)*ADC_REC_SAMPLE_RATE+mod;

	if(pR->tJD.jd_step==JD_STEP_RST||pR->tJD.jd_step==JD_STEP_SSFAULT) return;	
	//tbl
	dotcur=dotend -NUM_QDFX;
	dir=0;
	for(dotcnt=0;dotcnt<NUM_QDFX;dotcnt++) //U0已持续四个周波 ADC_REC_SAMPLE*3
	{
		u32 cur;

		cur = dotcur & ADC_REC_DOTS_MASK;	//当前采样点
		dotcur++;		
		//启动判断
		if(pR->tJD.jd_step==JD_STEP_QD)
		{	        		
			if(g_ui[pJdxx->i0_chan].chn_index==CFG_ADC_CHANNEL_ZERO)
			{
				qdval=jdxx_getI0_qdval(cur,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index);
			}
			else
			{
				qdval=jdxx_get_qdval(cur,g_ui[pJdxx->i0_chan].chn_index);
			}
			if(_AbsL(qdval) > pR->tJD.jd_qdval)  //大于启动值
			{
				pR->tJD.jd_step=JD_STEP_CHECK;
				pR->tJD.qdPoints=0;
				pR->tJD.dot_qd=cur;  //保存当前启动点的采样序号				
				if(qdval>0)
				{
					dir=1;
				}
				else if(qdval<0)
				{
					dir=-1;
				}
				#ifdef XDL_PRINT
				rt_printf_time("jdxx:JD_STEP_CHECK sw=%d dot=%d  qdval=%d set=%d\r\n",sw,cur,qdval,pR->tJD.jd_qdval);
				#endif
			}
		}
		else  if(pR->tJD.jd_step==JD_STEP_CHECK)  //收集数据
		{
			if(g_ui[pJdxx->i0_chan].chn_index==CFG_ADC_CHANNEL_ZERO)
			{
				qdval=jdxx_getI0_qdval(cur,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index);
			}
			else
			{
				qdval=jdxx_get_qdval(cur,g_ui[pJdxx->i0_chan].chn_index);
			}
			if((qdval*dir<0)//反相
				||(_AbsL(qdval) < pR->tJD.jd_qdval))  //小于启动值
			{
				#ifdef XDL_PRINT
				if(qdval*dir<0)
				{
					rt_printf("jdxx:sw=%d dot=%d;启动后干扰\r\n",sw,cur);
				}
				else
				{
					rt_printf("jdxx:sw=%d dot=%d;启动后有值小于启动值\r\n",sw,cur);
				}
				#endif
				pR->tJD.jd_step=JD_STEP_QD;
				continue;
			}
			pR->tJD.qdPoints++;
			if(pR->tJD.qdPoints>=pJdxx->jd_qdPoints)  // 大于启动个数，进入数据收集阶段，可启动录波
			{
				pR->tJD.jd_step=JD_STEP_COLLECT;
				pR->tJD.adPoints=0;
				#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d dot=%d;JD_STEP_COLLECT\r\n",sw,cur);	
				#endif
			}
		}
		else  if(pR->tJD.jd_step==JD_STEP_COLLECT)  //收集数据
		{
			pR->tJD.adPoints++;
			if(pR->tJD.adPoints>=pJdxx->jd_faultPoints)
			{
				pR->tJD.jd_step=JD_STEP_CTFAULT;
				#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d JD_STEP_CTFAULT! dcnt=%d\r\n",sw,dotcnt);
				#endif
			}
		}
		else if(pR->tJD.jd_step==JD_STEP_CTFAULT)  //暂态特征判断
		{
			int i,ret;
			bool bFault=false;
			s32 val=0;
			int ovQDpoints=0;
			
			if(!bFault)  //故障未确认
			{				
				for(i=pJdxx->jd_qdPoints;i<pJdxx->jd_faultPoints+pJdxx->jd_qdPoints;i++)
				{
					u32 cur=(pR->tJD.dot_qd+i)&ADC_REC_DOTS_MASK;
					if(g_ui[pJdxx->i0_chan].chn_index==CFG_ADC_CHANNEL_ZERO)
					{
						val=_AbsL(jdxx_getI0_qdval(cur,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index));
					}
					else
					{
						val=_AbsL(jdxx_get_qdval(cur,g_ui[pJdxx->i0_chan].chn_index));
					}
					if(val > pR->tJD.jd_qdval)
					{
						ovQDpoints++;
					}
					if(ovQDpoints>pJdxx->jd_surePoints)
					{
						bFault=true;
						break;
					}
				}
			}		
			//故障确认，判断暂态接地线路逻辑
			if(bFault)	 
			{
			#ifdef  FUN_JDXX_TBLQD
				if(pJdxx->bTT_jdxx_p0dir)
				{
					pR->tJD.tc_result=1;	//启动
					pR->tJD.adPoints=0;
					pR->tJD.jd_step=JD_STEP_SSFAULT;
					if(soe_check(EV_JDXX_QD+sw*EV_SW_NUM)==false)
					{
						soe_record_ev( EV_JDXX_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
					}	

				#ifdef XDL_PRINT
					rt_printf("jdxx:sw=%d JD_STEP_SSFAULT\r\n",sw);
				#endif	
				
				    return;
				}
				else
			#endif
				{
					ret=jdxx_checkjd(sw);
					if(ret<0)
					{
						pR->tJD.jd_step=JD_STEP_RST;
						#ifdef XDL_PRINT
						rt_printf("\r\njdxx_fg:sw=%d JD_STEP_FG",sw);
						#endif
						return;
					}
					else
					{
						pR->tJD.adPoints=0;
						pR->tJD.jd_step=JD_STEP_SSFAULT;
						if(soe_check(EV_JDXX_QD+sw*EV_SW_NUM)==false)
						{
							soe_record_ev( EV_JDXX_QD+sw*EV_SW_NUM,1, 0,0,0 ); 
						}	

					#ifdef XDL_PRINT
						rt_printf("jdxx:sw=%d JD_STEP_SSFAULT\r\n",sw);
					#endif	
					
					    return;
					}
				}
			}
			else//干扰,复归
			{		
			#if 0//def  FUN_JDXX_TBLQD //只需要U0期间出现了I0突变，就ok
				{
				  #ifdef XDL_PRINT
					rt_printf("jdxx:sw=%d 启动后确认干扰\r\n",sw);					
				  #endif
					pR->tJD.jd_step=JD_STEP_QD;
					continue;
				}
			#else
                if(dotcnt<(NUM_QDFX-128))//最后1周波前必须确认(512-128)
            	{
                  #ifdef XDL_PRINT
					rt_printf("jdxx:sw=%d 启动后确认干扰\r\n",sw);					
				  #endif
					pR->tJD.jd_step=JD_STEP_QD;
					continue;

            	}
				else
				{
					pR->tJD.adPoints=0;
					pR->tJD.jd_step=JD_STEP_RST;
					
					#ifdef XDL_PRINT
					rt_printf("\r\njdxx_fg:sw=%d JD_STEP_FG!(not sure)",sw);
					#endif
					return;
				}
			#endif
			}
		}		
	}
}

//稳态判据
#define		ANGF150 	(150*65536)      	//150度
#define 	ANGN150    	((-150)*65536)   	//-150度
#define		ANGF30    	(30*65536)      	//30度
#define 	ANGN30    	((-30)*65536)   	//-30度
#ifdef FUN_JDXX_12FS //针对电科院一二次融合测试
#define		ANGF96	    (110*65536)      	//110度
#define		ANGN96	    ((-110)*65536)     	//-110度
#define		ANGF45	    (30*65536)      	//30度
#define		ANGN45	    ((-30)*65536)      	//-30度
#else
#define		ANGF96	    (96*65536)      	//96度
#define		ANGN96	    ((-96)*65536)     	//-96度
#define		ANGF45	    (45*65536)      	//45度
#define		ANGN45	    ((-45)*65536)      	//-45度
#endif
#define     ANGF360     (360*65536)      	//360度
#define     ANGF90      (90*65536)      	//90度
#define     ANGN90     ((-90)*65536)      	//-90度

#define     ANGF70      (70*65536)      	//70度
#define     ANGN70     ((-70)*65536)      	//-70度




int jdxx_angle_range(int sw)
{
	int i,ret;	
	long deltaA;
	TRELAY_T *pR=&g_tRelay[sw];	
#if 1
	long max,min;
	max=pR->tJD.ui_angle[0];
	min=pR->tJD.ui_angle[0];
	for(i=1;i<NUM_ANGLE;i++)
	{
		if(pR->tJD.ui_angle[i] > max)
		{
			max =  pR->tJD.ui_angle[i];
		}
		else if(pR->tJD.ui_angle[i] < min)
		{
			min =  pR->tJD.ui_angle[i];
		}
	}	
	#ifdef XDL_PRINT
	rt_printf("jdxx:sw=%d AngleMax=%d , AngleMin=%d！\r\n",sw,(max>>16),(min>>16));
    #endif
	if((max > ANGF90) && (min<ANGN90))//在2-3象限
	{
		for(i=0;i<NUM_ANGLE;i++)
		{
			if(pR->tJD.ui_angle[i] < 0) 
			{
				pR->tJD.ui_angle[i] += ANGF360;//归一化到0~360
			}			
			#ifdef XDL_PRINT
			rt_printf("jdxx:sw=%d Angle23=%d！\r\n",sw,(pR->tJD.ui_angle[i]>>16));
            #endif
		}
	}
	//相角
	deltaA=0;
	for(i=0;i<NUM_ANGLE;i++)
	{
		deltaA += pR->tJD.ui_angle[i];
	}
	deltaA /=NUM_ANGLE;
#else
    int j;

	ret=3;
	deltaA=0;
	for(i=0,j=0;i<NUM_ANGLE;i++)
	{
		if(pR->tJD.ui_angle[i] > 0) continue;
		else
		{
			deltaA +=pR->tJD.ui_angle[i];
			j++;
		}
	}

	if(j==0) 
	{
		ret=3;//非界外
	}
	else
	{
		deltaA /=j;		
	}
#endif	
    //判区内区外
    ret=3;
	if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
	{
		if(deltaA>ANGF45 && deltaA<ANGF96) ret=2; //界外
	}
	else
	{
		if(deltaA>ANGN96 && deltaA<ANGN45) ret=2;//界外
	}

#ifdef XDL_PRINT
	if(ret==2)
	{
		rt_printf("jdxx:sw=%d 零序功率方向判区外接地！ret0=%d！Angle=%d！\r\n",sw,ret,(deltaA>>16));
	}
#endif

	return ret;	
}

/**************************************************************************
函数名称：CalcUIzAng
函数版本：1.00    
函数功能说明：接地零序角度必须归一到-180-180。(部分项目角度没有归一化到-180-180)

输入参数：long Real1,
          long Imag1,
          long Imag2,
          long Imag2

输出参数：
返回值：  long 角差; 
**************************************************************************/
long CalcUIzAng(long Real1, long Imag1, long Real2, long Imag2)
{
    long lTmp;

    lTmp = _AngPQ(Real1, Imag1)- _AngPQ(Real2,Imag2); 

    //规格化在0 ~ 360之间
    if(lTmp < 0)
    {
        lTmp += ANGLE_P360;
    }
    if(lTmp>ANGLE_P180)  //转换为-180 ~180
    {
	lTmp-=ANGLE_P360;
    }

    return (lTmp);
}

void jdxx_fault(int sw,DWORD dStep)
{
	int ret0,ret1,bQNGZ,u0_index;
	bool b_tz,b_gj;	
	JDXX_SET *pJdxx=&tJDXX_val[sw];
	TRELAY_T *pR=&g_tRelay[sw];	

#ifdef ITEM_FYF630Z
	b_gj = pJdxx->bTT_jdxx_gj;
	b_tz = pJdxx->bTT_jdxx_tz;
  #ifdef BH_JZ_YB
	if(!g_tRelay[sw].run_stu.bh_ck) 
  #else 
	if(pRunSet->tSwSet[sw].bSW_JZ)
  #endif
	{
		if(b_tz){
			b_tz = false;
			b_gj = true;
		}
	}
#elif defined DFTU_LINUX_ZXJC || defined DTU_HUNAN || defined DTU4_GW_TEST || defined FB_SHANDONG || defined FBS_GX
	b_gj = pJdxx->bTT_jdxx_gj;
	b_tz = pJdxx->bTT_jdxx_tz;
#else
	b_gj = pJdxx->bTT_jdxx_gj;
	b_tz = pJdxx->bTT_jdxx_tz;

	if(JZS_ALL_EN(sw))  // 集中模式或者就地式FA自适应非首开关不跳闸
	{
		if(b_tz){
			b_tz = false;
			b_gj = true;
		}
	}
#endif
	

	if(pR->tJD.jd_step==JD_STEP_SSFAULT)//稳态逻辑判定	
	{
		//判稳态电流
	#if defined FUN_JDXX_JXJD || defined DTU_HUNAN
		ret1=1;
	#else
		if(g_ui[pJdxx->i0_chan].m2[0] >= pJdxx->jd_qdval2)	
		{
			ret1=1;
		}
		else
		{
			ret1=0;			
			if(pR->tJD.tc_result)
			{
				pR->tJD.tc_result=0;
				#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d ret1=%d--暂态误判！\r\n",sw,ret1);				
				#endif
			}
		}
	#endif
		//判相位		
		if(pR->tJD.jd_u0_12==1) u0_index=PUB_AC_U01;
		else u0_index=PUB_AC_U02;
		//判稳态相位
		if(!pJdxx->bTT_jdxx_p0dir)
		{		
			ret0=3; 		
		}
		else
		{
			long deltaA;			
			//计算零序功率角度:-180~180		(固定大通道)	
			if(g_ui[pJdxx->i0_chan].m2[0] >= pJdxx->jd_qdval2)
			{
				deltaA=CalcUIzAng(g_ui[u0_index].ri.r,g_ui[u0_index].ri.i,g_ui[pJdxx->i0_chan].ri.r,g_ui[pJdxx->i0_chan].ri.i);
			    if((g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].chn_index!=CFG_ADC_CHANNEL_ZERO)&&(g_ui[UI_JDXX_I0_INDEX].m2[0] > pJdxx->jd_ov_val2))
			    {
				    deltaA=CalcUIzAng(g_ui[u0_index].ri.r,g_ui[u0_index].ri.i,g_ui[UI_JDXX_I0_INDEX].ri.r,g_ui[UI_JDXX_I0_INDEX].ri.i);
			    }
			}
			else //区外处理
			{
				if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
				{
					deltaA=ANGF90;
				}
				else
				{
					deltaA=ANGN90;
				}
			}
		#ifdef XDL_PRINT
			if(pR->tJD.con_angle < NUM_ANGLE) rt_printf("jdxx:sw=%d Z_angle=%d\r\n",sw,(deltaA>>16));
		#endif

		#ifdef CN_AREA_GW_SHANXI
			if(deltaA>ANGF30 && deltaA<ANGF150) 
			{
				if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
				{
					ret0=2; //界外
				}
				else
				{
					ret0=1;//界内
				}
			}
			else if(deltaA>ANGN150 && deltaA<ANGN30) 
			{
				if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
				{
					ret0=1;//界内
				}
				else
				{
					ret0=2;//界外
				}
			}
			else 
			{
				ret0=0;//干扰 
			#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d 零序功率方向不正确,非接地！\r\n",sw);
			#endif
			}
		#elif defined FUN_JDXX_SS_ANGLE
			if(deltaA>ANGF90 && deltaA<ANGF180) 
			{
				if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
				{
					
					if(pR->tJD.dir_cnt)	
					{
						pR->tJD.dir_cnt--;
						ret0=1;//界内
					}
					if(pR->tJD.dir_cnt==0)	
					{
						ret0=2; //界外	
					#ifdef XDL_PRINT
						rt_printf("jdxx:sw=%d 零序功率方向抖动,非接地！\r\n",sw);
					#endif
					}
				}
				else
				{
					//pR->tJD.dir_cnt=(pR->tJD.dir_cnt+1)%20;
					if(pR->tJD.dir_cnt<20) 
					{
						pR->tJD.dir_cnt++;
					}
						
					if(pR->tJD.dir_cnt)	
					{
						ret0=1;//界内
					}	
				}

		
			}
			else if(deltaA>ANGN180 && deltaA<ANGN90) 
			{
				if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
				{
					//pR->tJD.dir_cnt=(pR->tJD.dir_cnt+1)%20;
					if(pR->tJD.dir_cnt<20) 
					{
						pR->tJD.dir_cnt++;
					}
					
					if(pR->tJD.dir_cnt)
					{
						ret0=1;//界内
					}
					
				}
				else
				{
					if(pR->tJD.dir_cnt)	
					{
						pR->tJD.dir_cnt--;	
						ret0=1;//界内
					}

					if(pR->tJD.dir_cnt==0)	
					{
						ret0=2;//界外
					#ifdef XDL_PRINT
						rt_printf("jdxx:sw=%d 零序功率方向抖动,非接地！\r\n",sw);
					#endif
					}										
				}
			}
			else 
			{
				if(pR->tJD.dir_cnt)	
				{
					pR->tJD.dir_cnt--;	
					ret0=1;//界内
				}
				
				if(pR->tJD.dir_cnt==0)	
				{
					ret0=0;//干扰 
				#ifdef XDL_PRINT
					rt_printf("jdxx:sw=%d 零序功率方向不正确,非接地！\r\n",sw);
				#endif
				}
			}
		#else
			//计算角度,判相位
		    if(pR->tJD.con_angle < NUM_ANGLE) 
			{
				pR->tJD.ui_angle[pR->tJD.con_angle++] = deltaA; 
				return;
	    	}
		    else
	    	{
				ret0=jdxx_angle_range(sw);
	    	}			
		#endif							
		}
		//U0强制启动
		if(TT_U0jd)
		{
			if(pRunSet->tSwSet[sw].bTT_Current_Inv ^ get_power_on_dir(sw))
			{
				ret0=2;
				ret1=0;
			}
			else
			{
				ret0=3;
				ret1=1;
			}				
		}

		//故障处理
		if(pR->tJD.tc_result && (ret0==1||ret0==3)&&(ret1==1)) 
		{
			bQNGZ=1;
		}
		else if((pR->tJD.tc_result==0 && (ret0==2||ret0==3))
			   ||(ret1==0))
		{
			bQNGZ=2;
		}
		else 
		{
			bQNGZ=0;
		}
        		
		//区内
		if(bQNGZ==1)  
		{
			#ifdef HJS_XDLJD
			pR->tJD.sta.bFlag.bJd_qn = 1;		//区内故障		
			#endif
			//告警
			if(b_gj)
			{
				RunTR(&pR->tJD.tJDXXAlarmTime, bQNGZ, dStep);//故障持续时间	
				pR->tJD.sta.bFlag.bGj=pR->tJD.tJDXXAlarmTime.boolTrip;
				if(pR->tJD.sta.bFlag.bGj)
				{
					if(soe_check(EV_JDXX_GJ+sw*EV_SW_NUM)==false)		
					{
						//断面
						DWORD I0,U0;						
						I0 = _Mul_Div_U(sqrt_32fix(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2[0]), 256, g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2_factor_k);						
						U0 = _Mul_Div_U(sqrt_32fix(g_ui[u0_index].m2[0]), 256, g_ui[u0_index].m2_factor_k);		
						
						pR->tJD.sta.bFlag.bGJLed = true; 
						soe_record_ev(EV_JDXX_GJ+sw*EV_SW_NUM,1,I0,U0,0 );
						if(pJdxx->bTT_jdxx_fault_all)
						{
							if(!soe_check(EV_ALL_FAULT+sw*EV_SW_NUM))  //保护总
							{				
								soe_record_ev( EV_ALL_FAULT+sw*EV_SW_NUM,1, 0,0,0 ); 
							}
						}

						//故障处理完毕，进入复归处理流程 
						if(!b_tz)//未投出口
						{
							pR->tJD.tc_result=0;
							pR->tJD.jd_step=JD_STEP_RST;

							#ifdef XDL_PRINT
							rt_printf("\r\njdxx_fault:sw=%d step_rst",sw);
							#endif	
						}
					}
				}
			}
			//出口
			if(b_tz)
			{
				RunTR( &pR->tJD.tJDXXTripTime, bQNGZ , dStep);//故障持续时间	
				pR->tJD.sta.bFlag.bTz=pR->tJD.tJDXXTripTime.boolTrip;
			#ifdef HJS_XDLJD
				if(pR->tJD.sta.bFlag.bHjsTz)
				{
					pR->tJD.sta.bFlag.bTz_prot = pR->tJD.sta.bFlag.bTz;
				}
				else
				{
					pR->tJD.sta.bFlag.bTz_prot = 0;
				}
			#endif
				if(pR->tJD.sta.bFlag.bTz) //出口
				{			
					//断面
					DWORD I0,U0;						
					I0 = _Mul_Div_U(sqrt_32fix(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2[0]), 256, g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2_factor_k); 					
					U0 = _Mul_Div_U(sqrt_32fix(g_ui[u0_index].m2[0]), 256, g_ui[u0_index].m2_factor_k); 

					pR->tJD.sta.bFlag.bTZLed = true; 					
					//soe
					#ifdef FUN_JDXX_JXJD
					if(soe_check(EV_JDXX_YJ_TZ+sw*EV_SW_NUM)==false)	
					{
						soe_record_ev(EV_JDXX_YJ_TZ+sw*EV_SW_NUM,1, I0,U0,0 );

						#ifndef HJS_XDLJD
						if(soe_check(EV_JDXX_TZ+sw*EV_SW_NUM)==false)  //区内跳闸
						{				
							soe_record_ev( EV_JDXX_TZ+sw*EV_SW_NUM,1, I0,U0,0 ); 
						}
						#else
						if((soe_check(EV_JDXX_TZ+sw*EV_SW_NUM)==false)&&(!pR->tJD.sta.bFlag.bHjsTz))  //区内跳闸
						{				
							soe_record_ev( EV_JDXX_TZ+sw*EV_SW_NUM,1, I0,U0,0 ); 
						}
						#endif
						
						if(pJdxx->bTT_jdxx_fault_all)
						{
							if(soe_check(EV_ALL_FAULT+sw*EV_SW_NUM)==false)  //保护总
							{				
								soe_record_ev( EV_ALL_FAULT+sw*EV_SW_NUM,1, 0,0,0 ); 
							}
						}
                        #ifdef XDL_PRINT
						    rt_printf("\r\n区内永久接地动作");
                        #endif						
					}
					#else
					if(soe_check(EV_JDXX_TZ+sw*EV_SW_NUM)==false)	
					{
						soe_record_ev(EV_JDXX_TZ+sw*EV_SW_NUM,1, I0,U0,0 );

						if(!soe_check(EV_ALL_FAULT+sw*EV_SW_NUM))  //保护总
						{				
							soe_record_ev( EV_ALL_FAULT+sw*EV_SW_NUM,1, 0,0,0 ); 
						}
					#ifdef XDL_PRINT
						rt_printf("\r\n区内接地动作");
					#endif						
					}
					#endif
					
					//故障处理完毕，进入复归处理流程 
					pR->tJD.tc_result=0;
					pR->tJD.jd_step=JD_STEP_RST;
					#ifdef FUN_JDXX_JXJD
						pR->tJD.cnt_sdelay=0;
						pR->tJD.cnt_ldelay=0;
					#endif

			        #ifdef XDL_PRINT
					rt_printf("\r\njdxx_fault:T[0]=%d!",pR->tJD.time_qd/USTIMER_SEC);
					rt_printf("\r\njdxx_fault:sw=%d step_rst!",sw);
			        #endif	
				}
			}
		}
		else if(bQNGZ==2)//区外
		{			
			if(soe_check(EV_JDXX_JWGZ+sw*EV_SW_NUM)==false)		// soe返回
			{
				//断面
				DWORD I0,U0;						
				I0 = _Mul_Div_U(sqrt_32fix(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2[0]), 256, g_ui[UI_SW_INDEX(sw,SW_AC_I0)].m2_factor_k);						
				U0 = _Mul_Div_U(sqrt_32fix(g_ui[u0_index].m2[0]), 256, g_ui[u0_index].m2_factor_k);	

				soe_record_ev(EV_JDXX_JWGZ+sw*EV_SW_NUM,1, I0,U0,0 );
				rt_printf("\r\n区外接地");
			}

			//故障处理完毕，进入复归处理流程 
			#ifdef HJS_XDLJD
			pR->tJD.sta.bFlag.bJd_qn = 0;		//区外故障		
			#endif
			pR->tJD.tc_result=0;
			pR->tJD.jd_step=JD_STEP_RST;

        #ifdef XDL_PRINT
			rt_printf("\r\njdxx_fault:sw=%d step_rst",sw);
        #endif	
		}		
		else// if((tJD[sw].tc_result && ret0==2)||(tJD[sw].tc_result==0 && ret0==1))
		{       
		//故障处理完毕，进入复归处理流程 
			#ifdef HJS_XDLJD
			pR->tJD.sta.bFlag.bJd_qn = 0;		//区外故障		
			#endif
			pR->tJD.tc_result=0;
			pR->tJD.jd_step=JD_STEP_RST;

        #ifdef XDL_PRINT
			rt_printf("\r\njdxx:sw=%d 暂态与稳态矛盾,非接地！",sw);
			rt_printf("\r\njdxx_fault:sw=%d step_rst",sw);
        #endif
		}
	}						
}

#define		ANGF145 	(145*65536)    	//145度
#define 	ANGF95    	(95*65536)   	//95度
#define		ANGN145    	((-145)*65536) 	//-145度
#define 	ANGN95    	((-95)*65536)  //-95度

#ifdef PT_DX_LOCK_XDL
static bool check_pt_ok(u32 sw)
{
	TSETSW *pSet = &pRunSet->tSwSet[sw];
	if(((FA_ALL_EN(sw) && (pSet->bTT_fa_ptdx))
		|| (BH_ALL_EN(sw) && (pSet->bTT_bh_ptdx)))
		&& (soe_check(EV_PT1ERR+sw*EV_SW_NUM) || soe_check(EV_PT2ERR+sw*EV_SW_NUM))
		)
	{
		return false;
	}
	
	return true;
}
#endif

void jdxx_pro(int sw,DWORD  dStep)  //接地故障判断 5ms中断中处理
{
	bool bQD1,bQD2,bQD3,bQD4,bQD5;
	int soeno;

	TRELAY_T *pR=&g_tRelay[sw];
	JDXX_SET *pJdxx=&tJDXX_val[sw];

	//if(!pJdxx->bTT_jdxx) return;
	#ifdef DFTU_LINUX_ZXJC
	if(!(pRunSet->tSwSet[sw].bTT_BH && pJdxx->bTT_jdxx)) return; //g_run_stu.bhall && 
	#else
	if(!(FUN_ALL_EN(sw) && pJdxx->bTT_jdxx)) return; //g_run_stu.bhall && 	
	#endif

#ifdef PT_DX_LOCK_XDL
	if(!check_pt_ok(sw))
	{
		return;
	}
#endif
	
	#ifdef FUN_JDXX_JXJD	
	//分位清计次
	if(pR->tSWST.uSWST.bFlag.bTZWZ) //跳位无流
	{
		pR->tJD.cnt_sdelay=0;
		pR->tJD.cnt_ldelay=0;
	}
	#endif

	//定义通道
	if(pRunSet->bTT_U0ZC)
	{
		if(((g_sw_pub.ui_flags & UI_FLAGS_MAKE_U01)==0)&&((g_sw_pub.ui_flags & UI_FLAGS_MAKE_U02)==0))
			return;
	}
	else
	{
		if(g_ui[PUB_AC_U01].chn_index==CFG_ADC_CHANNEL_ZERO && g_ui[PUB_AC_U02].chn_index==CFG_ADC_CHANNEL_ZERO)
			return;
	}
	//选相
	if(pJdxx->bTT_jdxx_cph)
	{
		if((g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index==CFG_ADC_CHANNEL_ZERO)
			||(g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index==CFG_ADC_CHANNEL_ZERO)
			||(g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index==CFG_ADC_CHANNEL_ZERO))
			return;
	}	
	
	//U0启动录波	
	bQD1 = (g_ui[PUB_AC_U01].m2[0] > pJdxx->jd_U0gl);
	bQD2 = (g_ui[PUB_AC_U02].m2[0] > pJdxx->jd_U0gl);
	RunTR( &pR->tJD.tJDXXU01Time, bQD1, dStep);//U0计算时间:20ms			
	RunTR( &pR->tJD.tJDXXU02Time, bQD2, dStep);//U0计算时间:20ms	
	//相有压有流
#ifdef CN_AREA_FUJIAN_TEST//福建电压为小信号
	bQD3 =  (g_sw_pub.m2_max[3] > pRunSet->dVOL70V_SQR_U2);//(g_ui[PUB_AC_UAB1].chn_index!=CFG_ADC_CHANNEL_ZERO || g_ui[PUB_AC_UBC1].chn_index!=CFG_ADC_CHANNEL_ZERO)
#else
	bQD3 =  (g_sw_pub.m2_max[2] > pRunSet->dVOL70V_SQR);//(g_ui[PUB_AC_UAB1].chn_index!=CFG_ADC_CHANNEL_ZERO || g_ui[PUB_AC_UBC1].chn_index!=CFG_ADC_CHANNEL_ZERO)
#endif
	bQD4 =  (g_sw_pub.m2_max[3] > pRunSet->dVOL70V_SQR);//(g_ui[PUB_AC_UAB2].chn_index!=CFG_ADC_CHANNEL_ZERO || g_ui[PUB_AC_UBC2].chn_index!=CFG_ADC_CHANNEL_ZERO)
	bQD5 = (g_sw[sw].m2_min >pRunSet->dIWL_SQR[sw]);
	RunTR( &pR->tJD.tJDXXU1yyTime, bQD3, dStep);//Ul有压时间时间:60ms			
	RunTR( &pR->tJD.tJDXXU2yyTime, bQD4, dStep);//Ul有压时间时间:60ms		
	RunTR( &pR->tJD.tJDXXIylTime, bQD5, dStep);//Iph有流时间时间:60ms		
	//取通道启动前的采样值，作为零漂值，在故障复归时使用
	//if(!bQD1 && !bQD2)
	//{
		//tJD[sw].dot_save=(g_adc_dots_count)*ADC_REC_SAMPLE_RATE+mod;
	//	jdxx_getzeroval(sw); 
	//}
	
	//U01故障处理
	soeno = EV_JDXX_U01GJ+sw*EV_SW_NUM;
	if(pR->tJD.tJDXXU01Time.boolTrip) 
	{
			
		if(soe_check(soeno)==false)			
		{
			DWORD u0;
			pR->tJD.jd_u0_12 = 1;  
			u0 = _Mul_Div_U(sqrt_32fix(g_ui[PUB_AC_U01].m2[0]), 256, g_ui[PUB_AC_U01].m2_factor_k);
			soe_record_ev(soeno, 1, u0,0,0);

			// 置启动标志，记录启动不能放在录波启动成功的条件里，避免启动失败后频繁打印！记录启动时刻.
			if(pRunSet->tSwSet[sw].bTT_Power_v2 == 0)
			{
				jdxx_fg(sw);//零压启动强制复归				
				#ifdef JDXX_YXEV_RST
				jdxx_yxev_rst(sw);
				#endif
				pR->tJD.time_qd = ustimer_get_origin();
				rcd_start(sw,RECORD_TYPE_XDLJD,RECORD_LEN_TZQD); 
			#ifdef XDL_PRINT
				rt_printf("\r\njdxx_u01_time:T[0]=%d!",pR->tJD.time_qd/USTIMER_SEC);
	        #endif	
			}
		}
	}
	else
	{	
		//计算零序功率:扩大10倍,提高计算分辨率
		if(pRunSet->tSwSet[sw].bTT_Power_v2 == 0)
		{
			if(bQD1)
			{
				g_ui_p0[sw].Pea  += g_ui_p0[sw].p*10;
				g_ui_p0[sw].Per  += g_ui_p0[sw].q*10;
				g_ui_p0[sw].Peas += g_ui_p0[sw].ps*10;
				g_ui_p0[sw].Pers += g_ui_p0[sw].qs*10;
			}
			else
			{
				g_ui_p0[sw].Pea  =0;
				g_ui_p0[sw].Per  =0;
				g_ui_p0[sw].Peas =0;
				g_ui_p0[sw].Pers =0;
			}
		}			
		//soe复归
		if(soe_check(soeno)==true)
		{
			pR->tJD.jd_u0_12 = 0; 
			soe_record_ev( soeno, 0, 0,0,0 );			
			jdxx_u0_rst(sw);
		}
	} 
	//U02
	soeno = EV_JDXX_U02GJ+sw*EV_SW_NUM;
	if(pR->tJD.tJDXXU02Time.boolTrip) 
	{
		
		if(soe_check(soeno)==false) 		
		{
			DWORD u0;			
			pR->tJD.jd_u0_12 = 2;  
			u0 = _Mul_Div_U(sqrt_32fix(g_ui[PUB_AC_U02].m2[0]), 256, g_ui[PUB_AC_U02].m2_factor_k);
			soe_record_ev(soeno, 1, u0,0,0);

			// 置启动标志，不能放在录波启动成功的条件里，避免启动失败后频繁打印！记录启动时刻.
			if(pRunSet->tSwSet[sw].bTT_Power_v2)
			{				
				jdxx_fg(sw);//零压启动强制复归		
				#ifdef JDXX_YXEV_RST
				jdxx_yxev_rst(sw);
				#endif
				pR->tJD.time_qd = ustimer_get_origin();
				rcd_start(sw,RECORD_TYPE_XDLJD,RECORD_LEN_TZQD); 
			#ifdef XDL_PRINT
				rt_printf("\r\njdxx_u02_time:T[0]=%d!",pR->tJD.time_qd/USTIMER_SEC);
	        #endif	
			}
		}
	}
	else
	{	
		//计算零序功率:扩大10倍,提高计算分辨率
		if(pRunSet->tSwSet[sw].bTT_Power_v2)
		{
			if(bQD2)
			{
				g_ui_p0[sw].Pea  += g_ui_p0[sw].p*10;
				g_ui_p0[sw].Per  += g_ui_p0[sw].q*10;
				g_ui_p0[sw].Peas += g_ui_p0[sw].ps*10;
				g_ui_p0[sw].Pers += g_ui_p0[sw].qs*10;
			}
			else
			{
				g_ui_p0[sw].Pea  =0;
				g_ui_p0[sw].Per  =0;
				g_ui_p0[sw].Peas =0;
				g_ui_p0[sw].Pers =0;
			}
		}			
		//soe复归
		if(soe_check(soeno)==true)
		{
			pR->tJD.jd_u0_12 = 0; 
			soe_record_ev( soeno, 0, 0,0,0 ); 			
			jdxx_u0_rst(sw);
		}
	} 

	//U0达到定值，启动
	if(pR->tJD.tJDXXU01Time.boolTrip||pR->tJD.tJDXXU02Time.boolTrip)
	{		
		//正常波形
		if(pR->tJD.jd_step!=JD_STEP_RST)
		{            
			//判电压满幅度			
			if(TT_U0yx && jdxx_U0_ov(sw)) 
			{
				pR->tJD.jd_step=JD_STEP_RST;
				#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d 零序电压失真！\r\n",sw);
				#endif
				return;
			}
			//判断线电压无压
			if(TT_Ulyy && 
				((pR->tJD.tJDXXU1yyTime.boolTrip==false && pR->tJD.tJDXXU01Time.boolTrip) ||(pR->tJD.tJDXXU2yyTime.boolTrip==false && pR->tJD.tJDXXU02Time.boolTrip)))			
			{
				pR->tJD.jd_step=JD_STEP_RST;
			#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d 线路无压！\r\n",sw);
			#endif
				return;
			}
			//判断相电流无流
			if(TT_Ipwl && !pR->tJD.tJDXXIylTime.boolTrip)			
			{
				pR->tJD.jd_step=JD_STEP_RST;
			#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d 断线无流！\r\n",sw);
			#endif
				return;
			}
		    //判断相电流相序
			if(TT_Ipph && pR->tJD.tJDXXIylTime.boolTrip)//有流
			{
				long deltaIAB,deltaIAC;
				
				deltaIAB=CalcAngSub(g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_IB)].ri.i);
				deltaIAC=CalcAngSub(g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_IC)].ri.i);
				if(deltaIAB<ANGF95||deltaIAB>ANGF145||deltaIAC>ANGN95||deltaIAC<ANGN145)
				{
					pR->tJD.jd_step=JD_STEP_RST;
	            #ifdef XDL_PRINT
					rt_printf("jdxx:sw=%d : PIab=%d,PIac=%d. 三相乱序！ \r\n",sw,deltaIAB>>16,deltaIAC>>16);
	            #endif
					return;
				}
			}			
			//获得电流启动值
			if(pR->tJD.jd_step!=JD_STEP_SSFAULT)
			{								
				g_ui[pJdxx->i0_chan].fz = _AmXY(g_ui[pJdxx->i0_chan].ri.r,g_ui[pJdxx->i0_chan].ri.i);
				pR->tJD.jd_qdval=(g_ui[pJdxx->i0_chan].fz>>2);//1/4
				if(pR->tJD.jd_qdval < pJdxx->jd_qdval)
				{
					pR->tJD.jd_qdval = pJdxx->jd_qdval;
				}
				#ifdef XDL_PRINT
				rt_printf("jdxx:sw=%d 零流启动值=%d ,定值=%d！\r\n",sw,pR->tJD.jd_qdval,pJdxx->jd_qdval);
				//rt_printf("jdxx:sw=%d 零序有功=%f ,零序无功=%f;零序s有功=%f ,零序s无功=%f！\r\n",sw,g_ui_p0[sw].Pea,g_ui_p0[sw].Per,g_ui_p0[sw].Peas,g_ui_p0[sw].Pers);
				#endif
			}			
			//fault
		#ifdef  CN_AREA_GW_SHANXI 
			if(pJdxx->bTT_jdxx_p0dir)
			{
				if(pR->tJD.jd_step==JD_STEP_QD)
				{
					if(g_ui[UI_JDXX_I0_INDEX].m2[0]>=pJdxx->jd_zero_N)
					{
						pR->tJD.tc_result=1;
						pR->tJD.jd_step = JD_STEP_SSFAULT;
						#ifdef XDL_PRINT
						rt_printf("jdxx:sw=%d 功率方向投，进入稳态判据！\r\n",sw);
						#endif
					}
				}
			}
			else
		#endif
			{
				#if 0
				if(pJdxx->jd_type==1)//有功分量法
				{
					jdxx_yg_qd(sw);
				}
				else//首半波
				#endif
				if(TT_U0jd)
				{
					if(pR->tJD.jd_step==JD_STEP_QD)
					{
						pR->tJD.tc_result=1;
						pR->tJD.jd_step = JD_STEP_SSFAULT;
					#ifdef XDL_PRINT
						rt_printf("jdxx:sw=%d 零压启动，进入稳态判据！\r\n",sw);
					#endif
						
					}
				}
				else
				{
					jdxx_qd(sw);
				}
			}		
		
			jdxx_fault(sw,dStep);				
		}		
	}	
	else//rst
	{
			jdxx_rst(sw,dStep);
	}
}

/////////////////////////////////////////////////////////////////////////
void _getjdxxdz_inf(void)
{
	int i,file_length;
	struct file * pfile;
	u8 *filebuf;
	loff_t pos;
	
	// 打开文件
	pfile = rt_file_open("/app/data/pcolcfg.ini",O_RDONLY ,0);
	if(IS_ERR(pfile))
	{
		dp_err_n_c_rt("error! 无法打开 pcolcfg.ini\r\n");
		goto jdxx_err;
	}
	
	// 得到文件长度
	file_length = rt_file_getfile_size(pfile);
	
	//file_length = rt_file_getfile_size(pfile);	
	if(file_length <= 0)
	{
		rt_file_close(pfile,0);
		goto jdxx_err;	
	}
	// 分配内存
	filebuf = rt_malloc(file_length);
	if((filebuf) == NULL)
	{
		rt_file_close(pfile,0);
		goto jdxx_err;	
	}
	pos = 0;
	if(rt_file_read(pfile,filebuf,file_length,&pos) != file_length)
	{
		rt_file_close(pfile,0);
		rt_free(filebuf);
		goto jdxx_err;	
	}
	//找到\r\n位置，得到一行长度
	for(i = 0; i < file_length; i++)
	{
		if(strncmp(&filebuf[i],"TT_U0yx", 7) == 0) 
		{
			TT_U0yx = getstrval(&filebuf[i]);
		}	
		else if(strncmp(&filebuf[i],"TT_Ipwl", 7) == 0) 
		{
			TT_Ipwl = getstrval(&filebuf[i]);
		}
		else if(strncmp(&filebuf[i],"TT_Ipph", 7) == 0) 
		{
			TT_Ipph = getstrval(&filebuf[i]);
		}
		else if(strncmp(&filebuf[i],"TT_Ulyy", 7) == 0) 
		{
			TT_Ulyy = getstrval(&filebuf[i]);
		}
		else if(strncmp(&filebuf[i],"TT_U0jd", 7) == 0) 
		{
			TT_U0jd = getstrval(&filebuf[i]);
			break;
		}
	}
	if(i >= file_length)
	{
		TT_U0yx = 0;
		TT_Ipwl = 0;
		TT_Ipph = 0;
		TT_Ulyy = 0;
		TT_U0jd = 0;
	}
	#ifdef XDL_PRINT
	rt_printf("TT_U0yx = %d\r\n", TT_U0yx);
	rt_printf("TT_Ipwl = %d\r\n", TT_Ipwl);		
	rt_printf("TT_Ipph = %d\r\n", TT_Ipph);	
	rt_printf("TT_Ulyy = %d\r\n", TT_Ulyy);	
	rt_printf("TT_U0jd = %d\r\n", TT_U0jd);	
	#endif
	
	if(TT_U0jd)
	{
		log_str_time(LOG_ERR,"U0接地投入",1,1);		
		rt_printf("U0接地投入！\r\n");	
	}
		
	rt_file_close(pfile,0); // 关闭文件
	rt_free(filebuf);			// 释放内存
	return;
jdxx_err:
	TT_U0yx = 0;
	TT_Ipwl = 0;
	TT_Ipph = 0;
	TT_Ulyy = 0;
	TT_U0jd = 0;
	#ifdef XDL_PRINT
	rt_printf("ERR!TT_U0yx = %d\r\n", TT_U0yx);
	rt_printf("ERR!TT_Ipwl = %d\r\n", TT_Ipwl);		
	rt_printf("ERR!TT_Ipph = %d\r\n", TT_Ipph);	
	rt_printf("ERR!TT_Ulyy = %d\r\n", TT_Ulyy);	
	rt_printf("ERR!TT_U0jd = %d\r\n", TT_U0jd);	
	#endif
}

//////////////////////////////////////////////////////////////////////////////
#endif //FUN_JDXX
/*------------------------------ 文件结束 -------------------------------------
*/
