/******************************************************************************
版权所有：	
文件名称：	led.c
文件版本：	01.01
创建作者：	xxxxxx
创建日期：	2013-05-29
功能说明：	LED处理程序
其它说明：
修改记录：
*/
/*------------------------------- 头文件 --------------------------------------
*/
#include "head.h"
 

/*------------------------------- 宏定义 --------------------------------------
*/


/*------------------------------ 类型结构 -------------------------------------
*/


/*------------------------------ 全局变量 -------------------------------------
*/
struct led_config g_led_hmi_default[HMI_TYPE_NUM]=
{
	// 罩式FTU
	{13,		
    {{0,PUB_LED_ERR}, 	{0,PUB_LED_RUN}, 	{1,SW_LED_DZ}, 		{0,PUB_LED_POWER}, 	
	 {0,PUB_LED_COMM}, 	{0,PUB_LED_BAT}, 	{1,SW_LED_ZHHW},	{1,SW_LED_GL}, 	
	 {1,SW_LED_JD}, 	{1,SW_LED_CHZ}, 	{1,SW_LED_LOCK},	{1,SW_LED_XT},
	 {1,SW_LED_YT},		{0,LED_NULL}, 		{0,LED_NULL}, 		{0,LED_NULL}}},
	 
	// 电缆看门狗
	{12, 	
	{{0,PUB_LED_POWER}, {0,PUB_LED_RUN}, 	{0,PUB_LED_COMM}, 	{0,PUB_LED_BAT}, 	
	{0,PUB_LED_ERR}, 	{1,SW_LED_ZHHW},	{1,SW_LED_GL}, 		{1,SW_LED_JD}, 
	{1,SW_LED_CHZ}, 	{1,SW_LED_LOCK}, 	{1,SW_LED_XT}, 		{1,SW_LED_YT}, 
	{0,LED_NULL}, 		{0,LED_NULL}, 		{0,LED_NULL}, 		{0,LED_NULL}}},
	// 箱式FTU
	{12, 	
	{{0,PUB_LED_POWER}, {0,PUB_LED_RUN}, 	{0,PUB_LED_COMM}, 	{0,PUB_LED_BAT},
	{0,PUB_LED_ERR}, 	{1,SW_LED_ZHHW},	{1,SW_LED_GL}, 		{1,SW_LED_JD}, 
	{1,SW_LED_CHZ}, 	{1,SW_LED_LOCK}, 	{1,SW_LED_XT}, 		{1,SW_LED_YT}, 
	{0,LED_NULL}, 		{0,LED_NULL}, 		{0,LED_NULL}, 		{0,LED_NULL}}},
};


// 基于公共、开关的灯状态，
// 数组第一维为公共、开关，0为公共，1~SWITCH_NUM_MAX为开关
// 数组第二维取公共、开关中灯个数的大值
//noted by sunxi: 20220701 加入(u16),以去除335x的编译告警
u8 g_led_stu[SWITCH_NUM_MAX+1][(((u16)SW_LED_NUM>(u16)PUB_LED_NUM)?SW_LED_NUM:PUB_LED_NUM)];
u8 g_led_save[SWITCH_NUM_MAX+1][(((u16)SW_LED_NUM>(u16)PUB_LED_NUM)?SW_LED_NUM:PUB_LED_NUM)]; 
// 当前面板的LED配置
struct led_config *g_led_hmi;

// 辅助板LED测试状态
u32 g_led_aux_test_st;
u32 g_led_kz_test_st;
int led_save_flag=0;

extern int _led_status_save(void);

/*------------------------------ 函数声明 -------------------------------------
*/


/*------------------------------ 外部函数 -------------------------------------
外部函数供其它实体文件引用，必须仔细检查传入参数的合法性.
*/
/******************************************************************************
函数名称：	led_init
函数版本：	01.01
创建作者：	xxxxxx
创建日期：	2015-04-16
函数说明：	开出类型LED初始化，找到对应的灯配置索引的GPIO
参数说明：	无
返回值：  	成功返回0.
修改记录：	
*/
extern int _led_readfile(void);
int led_init(void)
{
	memset(g_led_stu,0,sizeof(g_led_stu));
	memset(g_led_save,0,sizeof(g_led_stu));
#ifdef STORE_PILOTELAMP
	_led_readfile();
#endif
	return 0;
}


/******************************************************************************
函数名称：	led_init_hmi
函数版本：	01.01
创建作者：	xxxxxx
创建日期：	2015-04-16
函数说明：	LED配置初始化
参数说明：	无
返回值：  	成功返回0.
修改记录：	
*/
int led_init_hmi(void)
{
    u32 slot;
    g_led_hmi=0;
    // 检查状态板是否配置
    slot = equ_get_slot_by_type(BOARD_TYPE_LCD_16LED);
    if(slot ==0)
    {
        slot = equ_get_slot_by_type(BOARD_TYPE_LCD_24LED);
        if(slot==0)     //jack.liu 2020 增加26个灯灯板定义
            slot = equ_get_slot_by_type(BOARD_TYPE_LCD_26LED);
    }
    // 检查状态板是否配置
    if(slot >0)
    {
        g_led_hmi = &g_led_slot[slot];
    }
    strcpy(m_Ledgoose,"退出");
    strcpy(m_Ledbh,"退出");
    strcpy(m_Ledfa,"退出");
    strcpy(m_Ledjzs,"退出");

	strcpy(m_Bh_chr,"----  ");
	strcpy(m_Fa_sl,"----");
	strcpy(m_Fa_chr,"----  ");
	strcpy(m_Goose_chr,"----  ");

#ifdef GD_AREA_ECZD_2020
	strcpy(m_Mode_chr,"----");
	strcpy(m_Tqhz_chr,"退出");
	strcpy(m_Zdjl_chr,"退出");
	strcpy(m_StopFun_chr,"停用所有功能");

	strcpy(m_Zdjl_chr,"退出");
#endif

	return 0;
}


/******************************************************************************
函数名称：	led_polling_app
函数版本：	01.01
创建作者：	xxxxxx
创建日期：	2015-04-16
函数说明：	LED应用功能
参数说明：	无
返回值：  	成功返回0.
修改记录：	
*/
void _led_update_status(void)
{
	int i,exerr;
		 
	// 电源灯
	if(!g_run_stu.dcjlsd)
	{
		led_set_pub(PUB_LED_POWER, LED_ON);	
	}
#if defined GD_AREA_GUANGZHOU_FTU
	else
	{
		led_set_pub(PUB_LED_POWER, LED_OFF);//FTU外置电源灯一般用继电器开出，灯闪烁容易损坏继电器	
	}
#else	
	else if (g_run_stu.dcjlsd && (!g_run_stu.dcqy))
	{
		led_set_pub(PUB_LED_POWER, LED_SLOW);	
	}
	else if (g_run_stu.dcjlsd && g_run_stu.dcqy)
	{
		led_set_pub(PUB_LED_POWER, LED_QUICK);	
	}
#endif
	// 运行灯
	if(rt_err_count())
	{
		led_set_pub(PUB_LED_RUN, LED_ON);
	}
	else
	{
		led_set_pub(PUB_LED_RUN, LED_SLOW);
	}

	//异常灯,以内部异常优先级高
	exerr=0;
#ifndef GD_AREA_ZHUHAI_V2	//未储能异常	
	for(i=0;i<g_sw_num;i++)
	{
		RUN_STU_SW *prun=&g_tRelay[i].run_stu;
		
		if (prun->exerr)
		{
			exerr =1;
			break;
		}
	}
#endif
	if (rt_err_count())
	{
		led_set_pub(PUB_LED_ERR, LED_ON);
	#if defined FUNC_DRIVE || defined FUNC_DRIVE_JY
		gb_drive.b_err = true;
	#endif
	}
#ifdef GD_AREA_ZHUHAI_V2
	else if((soe_check(EV_FUNALL_CHECK+0*EV_SW_NUM)==true)||(soe_check(EV_CHZ_CHECK+0*EV_SW_NUM)==true)||
		    (soe_check(EV_GOOSE_CHECK+0*EV_SW_NUM)==true)||(soe_check(EV_FA_CHECK+0*EV_SW_NUM)==true)||(soe_check(EV_BH_CHECK+0*EV_SW_NUM)==true))
	{
		led_set_pub(PUB_LED_ERR, LED_ON);
	}
#elif defined GD_AREA_ZHONGSHAN_2020
	else if (exerr||soe_check(EV_GOOSE_CONFIG_ERR)==true)//中山2020要求通信异常不允许亮异常灯
	{
		led_set_pub(PUB_LED_ERR, LED_ON);
	}
#else
	else if (exerr||(tFAg.commerr>0)) //中山要求，只有本机通信异常点告警灯，系统异常不点灯
	{
		led_set_pub(PUB_LED_ERR, LED_ON);
	#if defined FUNC_DRIVE || defined FUNC_DRIVE_JY
		gb_drive.b_err = true;
	#endif
	}
#endif
	else if (soe_check(EV_61850_ERR)==true)	
	{
		led_set_pub(PUB_LED_ERR, LED_ON);
	#if defined FUNC_DRIVE || defined FUNC_DRIVE_JY
		gb_drive.b_err = true;
	#endif
	}		
	else
	{
		led_set_pub(PUB_LED_ERR, LED_OFF);
	#if defined FUNC_DRIVE || defined FUNC_DRIVE_JY
		gb_drive.b_err = false;
	#endif
	}

//#ifdef GD_AREA_ECZD_2020
#if defined GD_AREA_ECZD_2020 || defined GD_AREA_MAIN_2020
    for(i=0; i<g_sw_num; i++)
    {
        RUN_STU_SW *prun=&g_tRelay[i].run_stu;

        if (prun->exerr||prun->qyd_bs||prun->qyd_bs||tPT.uPT1DX.bFlag.bPTYC||tPT.uPT2DX.bFlag.bPTYC)
        {
            exerr =1;
            break;
        }
    }
    if(exerr||(tFAg.commerr>0))
    {
        led_set_pub(PUB_LED_RUN_GJ, LED_ON);
    #if defined FUNC_DRIVE || defined FUNC_DRIVE_JY
		gb_drive.b_warning = true;
	#endif
    }
    else
    {
        led_set_pub(PUB_LED_RUN_GJ, LED_OFF);
    #if defined FUNC_DRIVE || defined FUNC_DRIVE_JY
		gb_drive.b_warning = false;
	#endif
    }
#endif
	//if(g_run_stu.pubdz==1)  // ==1 闭锁
	//{
		//led_set_pub(PUB_LED_DZ,LED_ON);
	//}
	//else 
	if(g_run_stu.pubdz==2) // ==2故障动作
	{
		led_set_pub(PUB_LED_DZ,LED_QUICK);
	}
	else
	{
		led_set_pub(PUB_LED_DZ,LED_OFF);
	}	

	if(g_run_stu.yf)
	{
		led_set_pub(PUB_LED_YF,LED_ON);
	}
	else
	{
		led_set_pub(PUB_LED_YF,LED_OFF);
	}

#ifdef	KZ_OUT_TT
	if(!g_run_stu.kz_out_tt)
	{
		led_set_pub(PUB_LED_KZ_OUT,LED_ON);
	}
	else
	{
		led_set_pub(PUB_LED_KZ_OUT,LED_OFF);
	}
#endif
	if(getIecLink101Status()||getCommStatus())
	{
		led_set_pub(PUB_LED_IEC_ERR,LED_ON);
	}
	else
	{
		led_set_pub(PUB_LED_IEC_ERR,LED_OFF);
	}
	if(g_bCommStatus)
		led_set_pub(PUB_LED_COMM_STATUS, LED_ON);	
	else
		led_set_pub(PUB_LED_COMM_STATUS, LED_OFF);	

	if(g_run_stu.jd)
	{
		led_set_pub(PUB_LED_JD,LED_ON);
	}
	else
	{
		led_set_pub(PUB_LED_JD,LED_OFF);
	}	

	for(i=0;i<g_sw_num;i++)
	{
		RUN_STU_SW *prun=&g_tRelay[i].run_stu;
		// 综合合位灯
		if (prun->sw == 0x2)
		{
			led_set_sw(i,SW_LED_ZHHW, LED_ON);
		}
		else if (prun->sw == 0x3)
		{
			led_set_sw(i,SW_LED_ZHHW, LED_SLOW);	
		}		
		else 
		{
			led_set_sw(i,SW_LED_ZHHW, LED_OFF);	
		}	

		if (prun->sw == 0x1)
		{
			led_set_sw(i,SW_LED_ZHTW, LED_ON);
		}
		else if (prun->sw == 0x3)
		{
			led_set_sw(i,SW_LED_ZHTW, LED_SLOW);	
		}		
		else 
		{
			led_set_sw(i,SW_LED_ZHTW, LED_OFF);	
		}	
	#ifdef GD_AREA_ZHUHAI_V2
		//通讯异常
		if(tFAg.bComErr>0)
		{
			led_set_sw(i,SW_LED_COMMERR, LED_ON);
		}		
		else
		{
			led_set_sw(i,SW_LED_COMMERR, LED_OFF);
		}
	#endif
		// 合位灯、跳位灯
		if (prun->hw)
		{			 
			sw_do(i,SW_DO_BHDZ,SW_DO_TYPE_OFF);
			led_set_sw(i,SW_LED_HW, LED_ON);
		}
		else
		{	
			led_set_sw(i,SW_LED_HW, LED_OFF);
		}		
		if (prun->tw)
		{
			led_set_sw(i,SW_LED_TW, LED_ON);
		}		
		else
		{
			led_set_sw(i,SW_LED_TW, LED_OFF);
		}
		
		// 过流灯
		if (prun->gl == 1)
		{
			led_set_sw(i,SW_LED_GL, LED_ON);
		}
		else if (prun->gl == 2)
		{
			led_set_sw(i,SW_LED_GL, LED_QUICK);
		}

		// 接地灯
		if (prun->jd == 1)
		{
			led_set_sw(i,SW_LED_JD, LED_ON);
		}
		else if (prun->jd == 2)
		{
			led_set_sw(i,SW_LED_JD, LED_QUICK);
		}

		//隔离刀闸灯
		if(prun->gldz)
		{
			led_set_sw(i,SW_LED_GLDZ, LED_ON);
		}
		else
		{
			led_set_sw(i,SW_LED_GLDZ, LED_OFF);
		}

		//接地刀闸灯
		if(prun->jddz)
		{
			led_set_sw(i,SW_LED_JDDZ, LED_ON);
		}
		else
		{
			led_set_sw(i,SW_LED_JDDZ, LED_OFF);
		}
#if defined GD_AREA_GUANGZHOU_FTU
		if (prun->gj_led)
			led_set_sw(i,SW_LED_FAULT_GJ, LED_ON);
	#endif
	
	#ifdef GD_AREA_ZHUHAI_V2
		if((prun->gj_led)|| //故障
		    (soe_check(EV_TH_WCN+i*EV_SW_NUM)==true)|| //弹簧未储能
		    (soe_check(EV_KZHL+i*EV_SW_NUM)==true)||//控制回路
		    (soe_check(EV_FUNALL_CHECK+0*EV_SW_NUM)==true||soe_check(EV_CHZ_CHECK+0*EV_SW_NUM)==true||soe_check(EV_GOOSE_CHECK+0*EV_SW_NUM)==true||soe_check(EV_FA_CHECK+0*EV_SW_NUM)==true||soe_check(EV_BH_CHECK+0*EV_SW_NUM)==true)||//压板不一致
		    (soe_check(EV_CTYC+i*EV_SW_NUM)==true||soe_check(EV_CTXXYC+i*EV_SW_NUM)==true)||//CT异常+相序异常  
			(soe_check(EV_PT1ERR)||soe_check(EV_PT2ERR)))//珠海局要求PT断线当做异常告警
		{
			led_set_sw(i,SW_LED_FAULT_GJ, LED_ON);
		}	
		else//无故障时熄灭
		{
			led_set_sw(i,SW_LED_FAULT_GJ, LED_OFF);
		}	
    #endif
		// 重合闸灯
		if (prun->chzdz)
		{			 
			led_set_sw(i,SW_LED_CHZ, LED_ON);	
		}

		// 重合闸充电灯
		if (prun->chzcd||prun->fa_ll_cd||prun->goose_qccd||prun->goose_glcd||prun->goose_ll_cd)
		{			 
			led_set_sw(i,SW_LED_CD, LED_ON);
			//led_set_sw(i,SW_LED_CHZBS, LED_OFF);//重合闸闭锁灯与充电灯功能相反
		}
		else
		{
			led_set_sw(i,SW_LED_CD, LED_OFF);
			//led_set_sw(i,SW_LED_CHZBS, LED_ON);//重合闸闭锁灯与充电灯功能相反
		}		
		if (prun->chzcd)
			led_set_sw(i,SW_LED_CHZ_CD, LED_ON);
		else
			led_set_sw(i,SW_LED_CHZ_CD, LED_OFF);

		//重合闸闭锁灯跟FA闭锁灯合并
		#if 0
		if(g_tRelay[i].run_stu.bhtt && !prun->chzcd)//保护与FA区分闭锁灯处理
			led_set_sw(i,SW_LED_CHZBS_LOCK, LED_ON);
		else if(g_tRelay[i].run_stu.fatt && prun->bs)
			led_set_sw(i,SW_LED_CHZBS_LOCK, LED_ON);
		else 
			led_set_sw(i,SW_LED_CHZBS_LOCK, LED_OFF);
		#endif
#ifdef GD_AREA_ZHONGSHAN_FTU //中山FTU要求手柄手分的时候退出自动化功能，亮闭锁灯 
		if(prun->bs || prun->bs_bhz||prun->chzbs)
#else
		if (prun->bs||prun->chzbs)
#endif
		{
			led_set_sw(i,SW_LED_CHZBS_LOCK, LED_ON);
		}
		else 
		{
			led_set_sw(i,SW_LED_CHZBS_LOCK, LED_OFF);
		}
		// 动作灯
		if (prun->dz == RY_DZ_XYBS)	//xj 闭锁合闸长亮
		{
			led_set_sw(i,SW_LED_DZ, LED_ON);
            led_set_sw(i,SW_LED_TZ, LED_ON);
		}	
		#ifdef GD_AREA_ZHUHAI_V2
		else if ((prun->dz == RY_DZ_BHT)||(prun->dz == RY_DZ_HZ))  //动作灯常亮,手动复归
		{
			led_set_sw(i,SW_LED_DZ, LED_ON);
		}			
		#else
		else if (prun->dz == RY_DZ_BHT)	 //xj 故障状态闪烁
		{
			led_set_sw(i,SW_LED_DZ, LED_QUICK);
            led_set_sw(i,SW_LED_TZ, LED_ON);
		}	
		else 
		{
			led_set_sw(i,SW_LED_DZ, LED_OFF);
		}
		#endif

		if(BH_GOOSE_EN(i))  //智能FA逻辑，联络开关自动查找
		{
			if(g_tRelay[i].tgoc.tllcd.sta.bFlag.bCD) //本开关为联络开关
			{
				led_set_sw(i,SW_LED_LL, LED_ON);
				led_set_sw(i,SW_LED_FD, LED_OFF);
			}
			else
			{
				led_set_sw(i,SW_LED_LL, LED_OFF);
				led_set_sw(i,SW_LED_FD, LED_ON);
			}
		}
		else if (FA_ALL_EN(i))
		{
			if (prun->fa_ls)	// 联络
			{
				led_set_sw(i,SW_LED_LL, LED_ON);
				led_set_sw(i,SW_LED_FD, LED_OFF);
			}	
			else
			{
				led_set_sw(i,SW_LED_LL, LED_OFF);
				led_set_sw(i,SW_LED_FD, LED_ON);
			}
		}
		else
		{
			led_set_sw(i,SW_LED_FD, LED_OFF);
			led_set_sw(i,SW_LED_LL, LED_OFF);
		}
		//运行模式压板灯		
		if(BH_GOOSE_EN(i)) 
		{
			#ifdef GD_AREA_ZHONGSHAN_2020 // 中山要求智能分布式充电完成，亮模式灯，分支亮保护灯
			if((prun->goose_qccd||prun->goose_glcd||prun->goose_ll_cd)&&!pRunSet->tSwSet[i].tGocSet.bsw_fz) 
			{
				led_set_sw(i,SW_LED_MODE_GOOSE, LED_ON);
				led_set_sw(i,SW_LED_MODE_BH, LED_OFF);
				led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
			}
			else if(pRunSet->tSwSet[i].tGocSet.bsw_fz)
			{
				led_set_sw(i,SW_LED_MODE_GOOSE, LED_OFF);
				led_set_sw(i,SW_LED_MODE_BH, LED_ON);
				led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
			}
			else
			{
				led_set_sw(i,SW_LED_MODE_GOOSE, LED_OFF);
				led_set_sw(i,SW_LED_MODE_BH, LED_OFF);
				led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
			}
			#else
			led_set_sw(i,SW_LED_MODE_GOOSE, LED_ON);
			led_set_sw(i,SW_LED_MODE_BH, LED_OFF);
			led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
			#endif
			strcpy(m_Ledgoose,"投入");
			strcpy(m_Ledbh,"退出");
			strcpy(m_Ledfa,"退出");

			#ifdef GD_AREA_ECZD_2020
                #ifdef GD_AREA_ZHONGSHAN_2020
					strcpy(m_Mode_chr,"智能分布式");
				#else
					strcpy(m_Mode_chr,"智能FA");
                #endif
			#endif

			if(prun->goose_qccd||prun->goose_glcd||prun->goose_ll_cd)
			{
				strcpy(m_Goose_chr,"已充电");
			}
			else
			{
				strcpy(m_Goose_chr,"未充电");
			}	
			strcpy(m_Bh_chr,"----  ");
			strcpy(m_Fa_sl,"----");
			strcpy(m_Fa_chr,"----  ");
		}
		else if(BH_GOOSE_COMMERR(i))
		{
			led_set_sw(i,SW_LED_MODE_GOOSE, LED_OFF);
			strcpy(m_Ledgoose,"退出");
			if(pRunSet->tSwSet[i].tGocSet.bsw_fz)
			{
				led_set_sw(i,SW_LED_MODE_BH, LED_ON);
				led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
				strcpy(m_Ledbh,"投入");
				strcpy(m_Ledfa,"退出");

				#ifdef GD_AREA_ECZD_2020
	                #ifdef GD_AREA_ZHONGSHAN_2020
						strcpy(m_Mode_chr,"电流型");
					#else
						strcpy(m_Mode_chr,"常规保护");
	                #endif
				#endif

				if(prun->chzcd)
				{
					strcpy(m_Bh_chr,"已充电");
				}
				else
				{
					strcpy(m_Bh_chr,"未充电");
				}
				strcpy(m_Fa_sl,"----");
				strcpy(m_Fa_chr,"----  ");
				strcpy(m_Goose_chr,"----  ");
			}
			else 
			{
			#ifdef GD_AREA_ZHONGSHAN_2020//中山2020要求联络自转电功能未投入不亮FA灯
				if(prun->fa_ls)
				{
					if(soe_check(EV_FA_LL_EN+i*EV_SW_NUM)==true)
						led_set_sw(i,SW_LED_MODE_FA, LED_ON);
					else
						led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
				}
				else
				{
					led_set_sw(i,SW_LED_MODE_FA, LED_ON);
				}
				//闭锁时灭fa模式灯
				if(prun->bs)
				{
					led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
				}
			#else
				led_set_sw(i,SW_LED_MODE_FA, LED_ON);
			#endif
			
				led_set_sw(i,SW_LED_MODE_BH, LED_OFF);
				
				strcpy(m_Ledfa,"投入");
				strcpy(m_Ledbh,"退出");

				#ifdef GD_AREA_ECZD_2020
	                #ifdef GD_AREA_ZHONGSHAN_2020
						strcpy(m_Mode_chr,"电压电流型");
					#else
						strcpy(m_Mode_chr,"常规FA");
	                #endif
				#endif

				if(prun->fa_ls)
				{
					strcpy(m_Fa_sl,"联络");

					if(prun->fa_ll_cd)
					{
						strcpy(m_Fa_chr,"已充电");
					}
					else					
					{
						strcpy(m_Fa_chr,"未充电");
					}					
				}
				else
				{
					strcpy(m_Fa_sl,"分段");
					strcpy(m_Fa_chr,"----  ");
				}
				strcpy(m_Bh_chr,"----  ");
				strcpy(m_Goose_chr,"----  ");
			}
		}
		else
		{
			
			//BH
            strcpy(m_Ledjzs,"退出");
			if (BH_ALL_EN(i))
			{
				led_set_sw(i,SW_LED_MODE_BH, LED_ON);
				if(JZS_ALL_EN(i))
				{
					strcpy(m_Ledjzs,"投入");
					strcpy(m_Ledbh,"退出");
				}
				else
				{
					strcpy(m_Ledbh,"投入");
				}
			}
			else
			{
				led_set_sw(i,SW_LED_MODE_BH, LED_OFF);
				strcpy(m_Ledbh,"退出");
			}
			if(!CHZ_ALL_EN(i))
			{
				strcpy(m_Bh_chr,"----  ");
			}
			else
			{
				if(prun->chzcd)
				{
					strcpy(m_Bh_chr,"已充电");
				}
				else
				{
					strcpy(m_Bh_chr,"未充电");
				}
			}
			//FA
			if (FA_ALL_EN(i))
			{
			#ifdef GD_AREA_ZHONGSHAN_2020//中山2020要求联络自转电功能未投入不亮FA灯
				if(prun->fa_ls)
				{
					if(soe_check(EV_FA_LL_EN+i*EV_SW_NUM)==true)
						led_set_sw(i,SW_LED_MODE_FA, LED_ON);
					else
						led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
				}
				else
				{
					led_set_sw(i,SW_LED_MODE_FA, LED_ON);
				}
				//闭锁时灭fa模式灯
				if(prun->bs)
				{
					led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
				}	
			#else
				led_set_sw(i,SW_LED_MODE_FA, LED_ON);
			#endif
				strcpy(m_Ledfa,"投入");
				
				#ifdef GD_AREA_ECZD_2020
	                #ifdef GD_AREA_ZHONGSHAN_2020
						strcpy(m_Mode_chr,"电压电流型");
					#else
						strcpy(m_Mode_chr,"常规FA");
	                #endif
				#endif
			}
			else
			{
				led_set_sw(i,SW_LED_MODE_FA, LED_OFF);
				strcpy(m_Ledfa,"退出");
			}
			if(!FA_ALL_EN(i))
			{
				strcpy(m_Fa_sl,"----");
				strcpy(m_Fa_chr,"----  ");
			}
			else
			{
				if(prun->fa_ls)
				{
					strcpy(m_Fa_sl,"联络");
										
					if(prun->fa_ll_cd)
					{
						strcpy(m_Fa_chr,"已充电");
					}
					else					
					{
						strcpy(m_Fa_chr,"未充电");
					}
				}
				else
				{
					strcpy(m_Fa_sl,"分段");
					strcpy(m_Fa_chr,"----  ");
				}				
			}
			//Goose
			led_set_sw(i,SW_LED_MODE_GOOSE, LED_OFF);
			strcpy(m_Ledgoose,"退出");
			strcpy(m_Goose_chr,"----  ");
			//no mode
			if((!FA_ALL_EN(i))&&(!BH_ALL_EN(i)))
			{
				strcpy(m_Mode_chr,"----");
			}
		}
#ifdef GD_AREA_ZHONGSHAN_2020
		if(soe_check(EV_GOOSE_QC_OK+i*EV_SW_NUM)==true		//切除OK
			||soe_check(EV_GOOSE_GL_OK+i*EV_SW_NUM)==true	//隔离OK
			||soe_check(EV_GOOSE_EXT_TZ+i*EV_SW_NUM)==true	//装置越级跳闸
			||soe_check(EV_GOOSE_SDLOST_TZ+i*EV_SW_NUM)==true	//首端失压分闸
			)   // 故障动作后亮闭锁灯
		{	
			g_tRelay[i].run_stu.fgbs=1;
		}
#endif
#ifdef GD_AREA_ZHONGSHAN_FTU //中山FTU要求手柄手分的时候退出自动化功能，亮闭锁灯 
		if(prun->bs || prun->bs_bhz)
#else
		if (prun->bs||prun->fgbs)
#endif
		{
			led_set_sw(i,SW_LED_LOCK, LED_ON);
		#ifdef GD_AREA_ZHONGSHAN_2020//中山2020要求分段的时候，双电源不亮闭锁灯
			if(!prun->fa_ls)//分段
			{
				if(g_tRelay[i].tSDHZ.S_Status == S_BSDOUBLE)
				{
					led_set_sw(i,SW_LED_LOCK, LED_OFF);
					//led_set_sw(i,SW_LED_MODE_FA, LED_OFF);//关闭就地FA灯
				}
			}
		#endif
		}
		else 
		{
			led_set_sw(i,SW_LED_LOCK, LED_OFF);
		#ifdef GD_AREA_ZHONGSHAN_2020
			if(!prun->fa_ls)//分段
			{
				//if(g_tRelay[i].tSDHZ.S_Status == S_BSDOUBLE)
					//led_set_sw(i,SW_LED_MODE_FA, LED_OFF);//关闭就地FA灯
			}
		#endif
		}		
		//储能/未储能灯需分合位合法(有对应遥信点)时才允许点亮
		if(prun->wcn && (prun->sw != 0) && (prun->sw != 3))
		{
			led_set_sw(i,SW_LED_WCN, LED_ON);
		}
		else if(!prun->wcn && (prun->sw != 0) && (prun->sw != 3))
		{
			led_set_sw(i,SW_LED_WCN, LED_OFF);
		}

#if defined GD_AREA_ECZD_2020 || defined GD_AREA_MAIN_2020
		if(JL_ALL_EN(i))
		{
			led_set_sw(i,SW_LED_ZDJL, LED_ON);
			led_set_sw(i,SW_LED_TYZDJL, LED_OFF);

			strcpy(m_Zdjl_chr,"投入");
		}
		else
		{
			led_set_sw(i,SW_LED_ZDJL, LED_OFF);
			led_set_sw(i,SW_LED_TYZDJL, LED_ON);

			strcpy(m_Zdjl_chr,"退出");
		}
		
        if(!FUN_ALL_EN(i))//停用保护功能总
        {
            led_set_sw(i,SW_LED_TYBHTT, LED_ON);

            strcpy(m_StopFun_chr,"停用所有功能");
        }
        else
        {
            led_set_sw(i,SW_LED_TYBHTT, LED_OFF);

            strcpy(m_StopFun_chr,"退出停用功能");
        }

        if(pRunSet->bTT_EDIT_YB)
        {
            strcpy(m_Yftr_chr,"投入");
        }
        else
        {
            strcpy(m_Yftr_chr,"退出");
        }
#endif
#ifdef FUNC_DRIVE
		if(pRunSet->bTT_DRIVE)
		{
			led_set_sw(i,SW_LED_DRIVE, LED_ON);
		}
		else
		{
			led_set_sw(i,SW_LED_DRIVE, LED_OFF);
		}
#endif

    }

}


void led_polling_app(void)
{
	static uint32_t us0=0;
	uint32_t us;
		 
	// 平时1秒处理一次，AUX板测试时0.5S一次
	us =(g_led_aux_test_st ||g_led_kz_test_st)? (USTIMER_SEC/4) : USTIMER_SEC;
	if(ustimer_delay_origin2(&us0,us) != 1)
	{
		return;
	}
	
	// 更新灯状态
	_led_update_status();
#ifdef STORE_PILOTELAMP
	_led_status_save();
#endif

	// 输出灯状态到can接口的子板(人机板、状态板在各自通讯接口的处理)
	// led_to_sub_board();
}


/******************************************************************************
函数名称：	led_set_sw
函数版本：	01.01
创建作者：	xxxxxx
创建日期：	2014-12-16
函数说明：	设置开出类LED灯的状态
参数说明：	led: 灯的序号 LED_RUN,...,KC_LED_NUM
			status: 灯的状态 LED_ON, LED_SLOW, LED_QUICK, LED_OFF
返回值：  	无
修改记录：	
*/
void led_set_pub(u8 no, u8 st)
{
	g_led_stu[0][no] = st;
}

void led_set_sw(u8 sw,u8 no, u8 st)
{
	g_led_stu[sw+1][no] = st;
}

/******************************************************************************
函数名称：	led_to_hmi
函数版本：	01.01
创建作者：	xxxxxx
创建日期：	2014-12-16
函数说明：	获取面板LED灯的状态
参数说明：	
返回值：  	无
修改记录：	
*/
int led_to_hmi(void)  
{
	int i;
	u8 led_tmp=0, stu=0;
	u32 dw[2];
	int ret=0;
	u32 *pdw;

	// 如果没有HMI配置，不执行
	if(g_led_hmi == 0)
	{
		return ret;
	}	
	dw[0] = 0;
	dw[1] = 0;
	pdw=&dw[0];
	for (i=0; i<g_led_hmi->num; i++)
	{
		// 未配置灯继续循环
		if (g_led_hmi->sn[i].no == LED_NULL)
		{
			continue;
		}

		// 取出灯状态
		stu = g_led_stu[g_led_hmi->sn[i].sw][g_led_hmi->sn[i].no];

		// 取出灯对应位置
		if(i<16)
		{
			led_tmp = i;
			pdw=&dw[0];
		}
		else
		{
			led_tmp = i-16;
			pdw=&dw[1];
		}
		led_tmp *= 2;		

		// 按位置将灯状态置入dwled
		switch(stu)
		{
			case LED_ON:
				*pdw |= (0x3<<led_tmp);
			break;

			case LED_SLOW:
				*pdw |= (0x2<<led_tmp);
			break;

			case LED_QUICK:
				*pdw |= (0x1<<led_tmp);
			break;

			case LED_OFF:
				*pdw |= (0x0<<led_tmp);
			break;
		}
		
	}

	// 更新面板全局LED状态
	g_dw_led[0] = dw[0];
	g_dw_led[1] = dw[1];
	return ret;
}

/*------------------------------ 内部函数 -------------------------------------
内部函数以下划线‘_’开头，不需要检查参数的合法性.
*/

/*------------------------------ 测试函数 -------------------------------------
一个实体文件必须带一个本模块的测试函数来进行单元测试，如果的确不方便在本模块中
进行单元测试，必须在此注明实际的测试位置（例如在哪个实体文件中使用哪个测试函数）.
*/

int led_info_printf(void)
{
	int slot,i;
	const char *name;
	struct equ_config_do 	*cdo;

	cdo = g_equ_config_do;
	rt_printf("\r\nslot\tindex\towner\tno\tvalue\tname\r\n");
	for(slot=0; slot<EQU_SLOT_NUM_MAX; slot++)
	{
		rt_printf("slot%02d:num=%d.\r\n",slot,g_led_slot[slot].num);
		for(i=0; i<g_led_slot[slot].num; i++)
		{
			if(g_led_slot[slot].sn[i].no == LED_NULL)
			{
				continue;
			}

			if(g_led_slot[slot].sn[i].sw == 0)
			{
				name = g_pub_led_name[g_led_slot[slot].sn[i].no];
			}
			else
			{
				name = g_sw_led_name[g_led_slot[slot].sn[i].no];
			}
			rt_printf("%02d\t%02d\t%02d\t%d\t%d\t%s\r\n",
			slot,\
			i,\
			g_led_slot[slot].sn[i].sw,
			g_led_slot[slot].sn[i].no,
			g_led_stu[g_led_slot[slot].sn[i].sw][g_led_slot[slot].sn[i].no],
			name);
		}
	}	
	return 0;
}





#define LED_FILE_VERSION	0X01010101	//文件版本
struct file * pf_ledsave=NULL;

static int _led_savefile(void)
{
	unsigned int addr,file_length;
	u16 crc;
	char *p;
	loff_t pos;
	struct file * pfile;
	struct cfg_file_head fileled_file;

		
	// 写文件头
	memset(&fileled_file,0,sizeof(fileled_file));
	fileled_file.signature = SIG_LED_SAVE_FILE;
	fileled_file.version = LED_FILE_VERSION;

	addr = FILE_ADDR_ALGIN(sizeof(fileled_file));
	
	// 得到文件长度
	file_length = addr + sizeof(g_led_save);
	file_length = FILE_ADDR_ALGIN(file_length);

	// 分配并初始化空间
	p = rt_malloc(file_length + 2); 
	if(!p)
	{
		return -1;
	}
	memset(p, 0, file_length + 2);
	
	// 写入文件头
	memcpy(p, (char *)&fileled_file, sizeof(fileled_file));
	
	// 写文件列表
	memcpy(p+addr, g_led_save,sizeof(g_led_save));

	// 计算CRC
	crc = CrcStr(p, file_length);
	memcpy(p+file_length, &crc, 2);

	// 创建数据文件
	if(pf_ledsave==NULL)
	{
		pfile = rt_file_open("/app/data/file_led.bin",O_CREAT|O_RDWR,0);
		if(IS_ERR(pfile))
		{
			rt_free(p);
			rt_printf("\r\n create led save file fail");
			return -2;
		}
		pf_ledsave=pfile;
	}
	
	pos = 0;
	rt_file_write(pf_ledsave, p, file_length+2, &pos);
	rt_free(p);
	return 0;
}


int _led_readfile(void)
{
	u32 len;
	u16 crc;
	u8 *buf;
	loff_t pos;
	struct file * pfile;
	struct cfg_file_head *brh;	
	// 创建并打开文件
	pfile = rt_file_open("/app/data/file_led.bin",O_RDONLY,0);
	if(IS_ERR(pfile))
	{
		return -1;
	}

	// 得到文件长度
	len = rt_file_getfile_size(pfile);
	if(len <= 0)
	{
		rt_file_close(pfile,0);
		return -11;
	}

	// 分配内存
	buf = rt_malloc(len);
	if((buf) == NULL)
	{
		rt_file_close(pfile,0);
		return -2; 	
	}

	// 读出内容
	pos = 0;
	if(rt_file_read(pfile,buf,len,&pos) != len)
	{
		rt_file_close(pfile,0);
		rt_free(buf);
		return -3;
	}

	// 关闭文件
	rt_file_close(pfile,0);

	// 检查CRC
	crc = CrcStr(buf,len-2);
	if(crc != *(u16*)(buf+len-2))
	{
		rt_free(buf);
		return -4;
	}

	// 检查文件签名
	brh = (struct cfg_file_head*)buf;
	if(brh->signature != SIG_LED_SAVE_FILE)
	{
		rt_free(buf);
		return -5;
	}

	// 校验一下文件长度，防止灯配置变化，文件读取正确，导致的灯状态异常
	{  
		int filelenth;
		filelenth = FILE_ADDR_ALGIN(sizeof(struct cfg_file_head))+sizeof(g_led_save);
		filelenth = FILE_ADDR_ALGIN(filelenth)+2;
		if(filelenth!=len)
		{
			rt_free(buf);
			return -6;
		}
	}	
	memcpy(g_led_stu,buf+FILE_ADDR_ALGIN(sizeof(struct cfg_file_head)),sizeof(g_led_stu));
	//根据保存的灯状态，预置动作标志
	{
		int sw,led;
		for(sw=0;sw<SWITCH_NUM_MAX+1;sw++)
		{
			if(sw==0)
			{
				if(g_led_stu[sw][PUB_LED_DZ]==LED_ON)
				{
					g_run_stu.pubdz=1;
				}
				else if(g_led_stu[sw][PUB_LED_DZ]==LED_QUICK)
				{
					g_run_stu.pubdz=2;
				}					
			}
			else
			{
				RUN_STU_SW *prun=&g_tRelay[sw-1].run_stu;
				u8 *pstatus;
				u8 val=0;
				for(led=0;led<SW_LED_NUM;led++)
				{
					pstatus=NULL;
					val=0;
					if(led==SW_LED_GL)pstatus=&prun->gl;
					if(led==SW_LED_JD)pstatus=&prun->jd;
					if(led==SW_LED_CHZ)pstatus=&prun->chzdz;
					if(led==SW_LED_DZ)pstatus=&prun->dz;				
					if(g_led_stu[sw][led]==LED_ON)
					{
						val=1;
					}
					else if(g_led_stu[sw][led]==LED_QUICK)
					{
						val=2;
					}
					if(pstatus!=NULL)	*pstatus=val;					
				}
			}
		}
	}
	_led_update_status();
	memcpy(g_led_save,g_led_stu,sizeof(g_led_stu));	
	rt_free(buf);	
	return 0;

}
int _led_status_save(void)
{
	int sw,led;
	static uint32_t led_save_us0;
	if(led_save_flag==0)
	{
		for(sw=0;sw<SWITCH_NUM_MAX+1;sw++)
		{
			if(sw==0)
			{
				for(led=0;led<PUB_LED_NUM;led++)
				{
					if(led==PUB_LED_DZ)
					{
						if(g_led_stu[sw][led]!=g_led_save[sw][led])
						{
							led_save_flag=1;
							led_save_us0 = ustimer_get_origin();
							break;
						}
					}
					
				}
			}
			else
			{
				for(led=0;led<SW_LED_NUM;led++)
				{
					if(led==SW_LED_GL||led==SW_LED_JD||led==SW_LED_CHZ||led==SW_LED_DZ)
					{
						if(g_led_stu[sw][led]!=g_led_save[sw][led])
						{
							led_save_flag=1;
							led_save_us0 = ustimer_get_origin();
							break;
						}
					}
				}
			}
		}
	}
	if(led_save_flag)
	{	
		if(ustimer_get_duration(led_save_us0) > USTIMER_SEC*5)  // led灯变化10秒后保存灯状态
		{
			memcpy(g_led_save,g_led_stu,sizeof(g_led_stu));
			rt_printf("\r\n led save len=%d",sizeof(g_led_stu));
			_led_savefile();
			led_save_flag=0;
		}
	}
	return 0;
}

int led_exit(void)
{
	if(pf_ledsave != 0)
	{
		rt_file_close(pf_ledsave,0);	
	}
	return 0;
}


/*------------------------------ 文件结束 -------------------------------------
*/


