#include "includes.h"

#include <string.h>

uint8_t Dev_Swi_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType);
void Dev_Swi_Output_Ctrl(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t DevAddr, uint16_t DevOutputLoop, uint16_t DevOutputType);
uint16_t Dev_Swi_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop);

uint8_t BLW_Touch_SwitchCycleDis(uint32_t DevAdd);  
uint8_t BLW_Rs485_Touch_Swi_Check(uint32_t DevAdd ,uint32_t Data_addr, uint16_t DataLen); 

#define RS485_TOUCH_INPUT_QUERY(data,x)  (((data&(0x03<<((x%4)*2)))>>(x%4)*2))   //每次判断两位
#define REPEATSENDTIMEMAX			0x03  	//本设备重发次数上限 
#define BLWTOUCHCTRLTIMEOUT			100		//本设备控制超时时间
#define BLWTOUCHASKTIMEOUT			10		//本设备控制回复超时时间
#define BLW_TOUCH_LOOPIN_NUM		26		//本设备RS485开关输入回路数    6
#define BLW_TOUCH_LOOPOUT_NUM		26		//本设备开关输出回路数        7
#define BLW_SWT_ASK_LEN_M			(((BLW_TOUCH_LOOPOUT_NUM+7)/4)+3)
#define BLW_SWT_BUF_LEN				0x05      //发送数组长度为5  如果开关在16个按键以内
#define BLW_SWT_BUF_LEN_M			(((BLW_TOUCH_LOOPOUT_NUM+7)/8)+3)

#define Dev_TouchSwitch_RecvData_Len_Max	0x18

/*******************************************************************************
* Fail Description	: 485设备 - T1触摸开关驱动文件
* 
*******************************************************************************/

void BLV_485_Dev_Touch_Switch_Init(Device_Public_Information_G *BUS_Public, RS485_SWI_INFO *Rs485SwiInfo)
{

	Rs485SwiInfo->SwtRelayLedCtrlCnt = BUS_Public->retry_num;
   
	BUS_Public->polling_cf = (uint32_t)&BLW_Touch_SwitchCycleDis;
	BUS_Public->processing_cf = (uint32_t)&BLW_Rs485_Touch_Swi_Check;
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"增加485开关T1开关 地址: %d",BUS_Public->addr);										
	
//	BUS_Public.DevFunInfo.Dev_Input_Type_Get = Dev_Swi_InType_Get;
//	BUS_Public.DevFunInfo.Dev_Output_Ctrl = Dev_Swi_Output_Ctrl;
//	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = Dev_Swi_Loop_State;
	
	/*6键开关，7号输出为背光*/
//	Rs485SwiInfo.SwtInputValidNum = DevSwiInputnum;		//初始化开关输入输出数
//	Rs485SwiInfo.SwtOutputValidNum = DevSwiOutputnum;
	
//	Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO));
}



/*******************************************************************************
* Function Name  : BlwTouchSwtRecAsk 
* Description    : 触摸开关确认收到回复函数
* Input          : 
	DevAdd	: 添加的设备类型
	data	: 添加的设备地址
	DataLen		：设备的轮询数据发送回调函数
* Return         : None
*******************************************************************************/
void BlwRelaySwtRecAsk(uint8_t *data)
{
	uint8_t SendBuf[5];
	uint32_t device_addr = 0x00;
	
	device_addr = Find_AllDevice_List_Information2(Active_Port, 0x01, data[0]);
	
	Device_Public_Information_G BUS_Public;   //共用
	NOR_HVOUT_INFO DevHVoutInfo;       //继电器局部变量
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),device_addr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&DevHVoutInfo,sizeof(NOR_HVOUT_INFO),device_addr+Dev_Privately);
	
	if(DevHVoutInfo.HVSwitchFlag==0x01)
	{
		SendBuf[0] = data[0];
		SendBuf[1] = 0x04;
		SendBuf[2] = data[2];
		SendBuf[3] = data[3];
		SendBuf[4] = SOR_CRC(SendBuf,4);
		/*发送函数*/
		MCU485_SendString(0x02,SendBuf,5);
//		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"强电开关回复函数\r\n");
	}
}



/*******************************************************************************
* Function Name  : BlwTouchSwtRecAsk 
* Description    : 触摸开关确认收到回复函数
* Input          : 
	DevAdd	: 添加的设备类型
	data	: 添加的设备地址
	DataLen		：设备的轮询数据发送回调函数
* Return         : None
*******************************************************************************/
void BlwTouchSwtRecAsk(uint32_t DevAdd, uint8_t *data, uint16_t DataLen)
{
	uint8_t SendBuf[BLW_SWT_ASK_LEN_M];// = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
	uint8_t port_id = SRAM_Read_Byte(DevAdd+Dev_port);
	
	if(DataLen > BLW_SWT_ASK_LEN_M)
	{
		return ;
	}
	memcpy(SendBuf, data, DataLen);
	
	//RS485_Port_SendFun(DevAdd, SendBuf, DataLen, BLWTOUCHASKTIMEOUT);  
	/*发送函数*/
	MCU485_SendString(port_id,SendBuf,DataLen);
}

/*******************************************************************************
* Function Name  : BLW_Touch_Rs485_Swi_Pro 
* Description    : BLW_Touch接收判断
* Input          : 
	data_addr	: 添加的设备类型
	Switch_Info	: 添加的设备地址
* Return         : None
*******************************************************************************/
/*BLW_Touch接收判断*/
//void BLW_Touch_Rs485_Swi_Pro(uint32_t dev_addr, uint32_t data_addr, RS485_SWI_INFO  *Switch_Info)
//{
//	uint8_t KeyValue = 0x00;
//	uint8_t i;
//	uint8_t temp = 0,temp2 = 0,d_addr = 0;
//	uint16_t temp1 = 0;
//	uint32_t w_addr = SRAM_LOG_Device_Switch1_Status;
//	
//	/*选择开关日志数据保存地址*/
//	d_addr = SRAM_Read_Byte(dev_addr + Dev_Addr);
//	switch(d_addr)
//	{
//		case 0x01:
//			w_addr = SRAM_LOG_Device_Switch1_Status;
//			break;
//		case 0x02:
//			w_addr = SRAM_LOG_Device_Switch2_Status;
//			break;
//		case 0x03:
//			w_addr = SRAM_LOG_Device_Switch3_Status;
//			break;
//	}

//	Switch_Info->DevSendCnt = 0x00;             		//收到回复就清计数
//	Switch_Info->DevOffline = DEV_IS_ONLINE;    		//设备在线
//	
//	temp = SRAM_Read_Byte(data_addr + 1);
//	
//	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"switch Input Num:%02X\r\n", Switch_Info->SwtInputValidNum);
//	switch(temp)   //读
//	{
//		case 0x03: 
//			for(i = 0; i < Switch_Info->SwtInputValidNum; i++)	//6路按键状态赋值
//			{
//				temp = SRAM_Read_Byte(data_addr + (i/4+2));
//				KeyValue = RS485_TOUCH_INPUT_QUERY(temp, i);    //下标从2开始  
//				switch(KeyValue&0x03)
//				{
//					case 1:
//						Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"switch%d Dev%02X KeyPress\r\n",d_addr,i);
//						Switch_Info->DevReadBuf[i] = KeyPress;          //地址从1开始
//						temp2++;
//						break;
//					case 2:
//						Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"switch%d Dev%02X KeyRelease\r\n",d_addr,i);
//						Switch_Info->DevReadBuf[i] = KeyRelease;
//						temp2++;
//						break;
//					case 3:
//						Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"switch%d Dev%02X KeyHold\r\n",d_addr,i);
//						Switch_Info->DevReadBuf[i] = KeyHold;
//						temp2++;
//						break;
//					default:
//			
//						break;	
//				}
//				KeyValue = 0;		
//			}
//			if(temp2 != 0x00)
//			{
//				temp1 = SRAM_Read_Word(data_addr + 2);
//				if(temp1 != SRAM_Read_Word(w_addr))
//				{
//					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Device_Switch%d start_val:%04X\r\n",d_addr,temp1);
//					SRAM_Write_Word(temp1,w_addr);
//					LOG_Save_Global_Parameters();
//				}
//			}
//			
//			break;
//		case 0x06:
//			Switch_Info->SwtRelayLedCtrlFlag = 0x00;	
//			Switch_Info->SwtRelayLedCtrlCnt = REPEATSENDTIMEMAX;
//			break;
//		default:
//			
//			break;
//	}
//}

void BLW_Touch_Rs485_Swi_Pro(Device_Public_Information_G* BUS_Public, uint8_t *data, RS485_SWI_INFO  *Switch_Info, uint8_t lens)
{
	uint8_t KeyValue = 0x00;
	uint8_t i;
	uint8_t temp = 0,temp2 = 0;
	
	uint8_t loopnum = 0x00;
	
	/*选择开关日志数据保存地址*/
//	d_addr = SRAM_Read_Byte(dev_addr + Dev_Addr);
	
	if(Switch_Info->DevOffline == DEV_IS_OFFLINE)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_TouchSwitch LogInfo_Device_Online...........");
		LOG_Device_Online_Record(DEV_SWI_TYPE,BUS_Public->addr,LogInfo_Device_Online);	//记录设备在线
		DevActionGlobal.OffLineDevType = 0xff;        //2023-10-08
	}
	
	BLV_Communication_Record(&Switch_Info->comm_record,0x02,0x01);		//记录通讯成功
	Switch_Info->DevSendCnt = 0x00;             		//收到回复就清计数
	Switch_Info->DevOffline = DEV_IS_ONLINE;    		//设备在线
	if(Switch_Info->DevOffline != Switch_Info->DevOfflineLast)	//当前在线状态不等于上一次在线状态
	{
		Switch_Info->DevOfflineLast = Switch_Info->DevOffline;	//更新上一次在线状态
		Write_Device_Fault_State(BUS_Public->type,BUS_Public->addr,In_ErrFun_LineState,DEV_IS_ONLINE);	//保存设备在线状态到SRAM
	}
//	temp = SRAM_Read_Byte(data_addr + 1);
	
	loopnum = (lens - 3) * 4;    //除去地址、命令字、校验和   一个字节表示4个按键状态    
	
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"T1 switch Input Num:%d",loopnum);
	
	switch(data[1])   //读
	{
		case 0x03: 
			for(i = 0; i < loopnum; i++)	//6路按键状态赋值
			{
				temp = data[i/4+2];  //SRAM_Read_Byte(data_addr + (i/4+2));
				KeyValue = RS485_TOUCH_INPUT_QUERY(temp, i);    //下标从2开始  
				switch(KeyValue&0x03)
				{
					case 1:
						Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"switch%d Dev%02X KeyPress Coord:%d",BUS_Public->addr, (i + 1), BUS_Public->DevCoord);
						Switch_Info->DevReadBuf[i] = KeyPress;          //地址从1开始
						DevActionGlobal.Devi = BUS_Public->DevCoord;     //直接跳到指定的下标去处理
						temp2++;
					
						Udp_Addtion_Roomstate(DEV_RS485_SWT,BUS_Public->addr,i,KeyPress);
						break;
					case 2:
						Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"switch%d Dev%02X KeyRelease Coord:%d",BUS_Public->addr, (i + 1), BUS_Public->DevCoord);
						Switch_Info->DevReadBuf[i] = KeyRelease;
						DevActionGlobal.Devi = BUS_Public->DevCoord;     //直接跳到指定的下标去处理					
						temp2++;

						Udp_Addtion_Roomstate(DEV_RS485_SWT,BUS_Public->addr,i,KeyRelease);
						break;
					case 3:
						Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"switch%d Dev%02X KeyHold  Coord:%d",BUS_Public->addr, (i + 1), BUS_Public->DevCoord);
						Switch_Info->DevReadBuf[i] = KeyHold;
						DevActionGlobal.Devi = BUS_Public->DevCoord;     //直接跳到指定的下标去处理					
						temp2++;
						
						Udp_Addtion_Roomstate(DEV_RS485_SWT,BUS_Public->addr,i,KeyHold);
						break;
					default:
			
						break;	
				}
				KeyValue = 0;		
			}
			DevActionGlobal.People_Flag = 0x01;        //2024-03-01
			break;
		case 0x06:
			Switch_Info->SwtRelayLedCtrlFlag = 0x00;	
			Switch_Info->SwtRelayLedCtrlCnt = BUS_Public->retry_num;
			break;
		default:
			
			break;
	}
}



#define RECDATALENMAX   10   //接收数据最大长度

/*******************************************************************************
* Function Name  : BLW_Rs485_Touch_Swi_Check 
* Description    : BLW触摸开关485接收处理函数

* Return         : 
	0x01：数据处理失败
	0x00：数据处理成功
*******************************************************************************/
uint8_t BLW_Rs485_Touch_Swi_Check(uint32_t DevAdd ,uint32_t Data_addr, uint16_t DataLen) 
{
//	uint8_t Crc_buf = 0;
	uint8_t ret = 0x01;
	uint8_t data[RECDATALENMAX];	
//	uint32_t SwiDevAdd;    //开关
	Device_Public_Information_G BUS_Public;   //共用	
	RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量
	
	if(DataLen > RECDATALENMAX)
	{
		//Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"Rs485_Touch接收数据长度超出范围!!\r\n");
		return ret;     //长度
	}
	
	SRAM_DMA_Read_Buff(data,DataLen,Data_addr);   //拷贝482数据
		
	
	if((DataLen < 0x05)||((data[1] != 0x03)&&(data[1] != 0x06))||(data[DataLen - 1] != SOR_CRC(data, DataLen-1)))   //匹配开关地址数据  
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"不是触摸开关的数据，DevAdd:%d,len:%d",BUS_Public.addr,DataLen);
		return ret;    //不是就直接返回
	}
	
	if(data[0] == SRAM_Read_Byte(DevAdd+Dev_Addr))   //地址刚好匹配上BUS_Public.addr
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"开关地址匹配上 DevAdd:%d,len:%d",data[0],DataLen);
		SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAdd);		
	}
	else       //地址没有匹配上
	{
		DevAdd = Find_AllDevice_List_Information2(Active_Port, 0x06, data[0]);   //地址重新赋值
		if(NULL != DevAdd)
		{
			SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAdd);		
		}
		else
		{
			return ret;
		}
	}
	 
//	if(data[DataLen - 1] == SOR_CRC(data, DataLen-1))	//校验通过
	{
//		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"校验通过 DevAdd:%d,len:%d\r\n",data[0],DataLen);
		SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAdd+Dev_Privately);
		
		switch(data[1])
		{
			case 0x03:   //按键上报 -- 目前
				//BlwTouchSwtRecAsk(CfgDevAdd, data, DataLen); //接收到按键上报，原样返回
				
				BlwRelaySwtRecAsk(data);    //强电开关收到按键上报立即回复，普通开关不回复 2022-11-29
			
			case 0x06:   //反馈灯控制
				ret = 0x00;
				//Dbg_Print_Buff(DBG_BIT_DEVICE_STATUS_bit,"T1 Input Data:",data,DataLen);
				BLW_Touch_Rs485_Swi_Pro(&BUS_Public, data, &Rs485SwiInfo,DataLen);
				break;
		}
		
		/*日志记录*/
		LOG_Device_COMM_Control_Reply_Record(BUS_Public.port,BUS_Public.baud,data,DataLen);
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485SwiInfo, sizeof(RS485_SWI_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAdd);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAdd+Dev_Privately);
		
	}
	
	return ret;
}



void BLW_Touch_Switch_ctrl(Device_Public_Information_G *BUS_Public, RS485_SWI_INFO *Rs485SwiInfo)
{
//	Device_Public_Information_G BUS_Public;
//	uint8_t port_id = SRAM_Read_Byte(DevAdd + Dev_port);
	uint8_t i;
	uint8_t SendLen;
											//地址  命令  寄存器
	uint8_t BLW_swt_buf[BLW_SWT_BUF_LEN_M]; //  = {0x01, 0x06, 0x00, 0x00, 0x00};  //定义7个字节数组	
	
	BLW_swt_buf[0] = BUS_Public->addr;//SRAM_Read_Byte(DevAdd + Dev_Addr);  //配置到本地的转换
	BLW_swt_buf[1] = 0x06;   //写
	BLW_swt_buf[2] = 0x00;   //指示灯
	BLW_swt_buf[3] = 0x00;   //指示灯
	
	for(i = 0; i < Rs485SwiInfo->SwtOutputValidNum; i++)
	{
		if(0x00 != Rs485SwiInfo->DevSendBuf[i])  //不为0
		{
			BLW_swt_buf[2+i/8] |= 0x01<<(i%8);
		}
		else
		{
			BLW_swt_buf[2+i/8] &= ~(0x01<<(i%8));
		}
	}
	if(Rs485SwiInfo->SwtOutputValidNum <= 16)
	{
		SendLen = BLW_SWT_BUF_LEN;
	}
	else 
	{
		SendLen = ((Rs485SwiInfo->SwtOutputValidNum+7)/8)+3;  //超过16路，以实际回路数为准
	}

	BLW_swt_buf[SendLen-1] = SOR_CRC(BLW_swt_buf,SendLen-1);
	/*发送函数*/
	MCU485_SendString(BUS_Public->port,BLW_swt_buf,SendLen);

	/*日志记录*/
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port,BUS_Public->baud,BLW_swt_buf,SendLen);
	
}

/*******************************************************************************
* Function Name  : BLW_Touch_SwitchCycleDis 
* Description    : BLW触摸开关485数据发送处理函数，包括重发

* Return         : 
	0x01：有数据需要发送
	0x00：没有数据需要发送
*******************************************************************************/
uint8_t BLW_Touch_SwitchCycleDis(uint32_t DevAdd)  
{
	Device_Public_Information_G BUS_Public;
	RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量

	uint8_t i;
	uint8_t Ret = RS485OCCUPYNOTIME;
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAdd);			
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAdd+Dev_Privately);/*拷贝设备私有信息*/
	
	/*2022-11-29*/
	if(DevActionGlobal.DevActionU64Cond.EleState==0x01)
	{
		if( DevActionGlobal.SleepMode_State == 0x01 )
		{
			Rs485SwiInfo.DevSendBuf[Rs485SwiInfo.SwtOutputValidNum-1] = 0x00;   //睡眠模式关背光
		}
		else
		{
			Rs485SwiInfo.DevSendBuf[Rs485SwiInfo.SwtOutputValidNum-1] = 0x01;   //插卡开背光
		}
	}
	else if(DevActionGlobal.DevActionU64Cond.EleState==0x02)
	{
		Rs485SwiInfo.DevSendBuf[Rs485SwiInfo.SwtOutputValidNum-1] = 0x00;   //拔卡关背光
	}
	else
	{
		if( DevActionGlobal.SleepMode_State == 0x01 )
		{
			Rs485SwiInfo.DevSendBuf[Rs485SwiInfo.SwtOutputValidNum-1] = 0x00;   //睡眠模式关背光
		}
		else
		{
			Rs485SwiInfo.DevSendBuf[Rs485SwiInfo.SwtOutputValidNum-1] = 0x01;
		} 
	}
	/*2022-11-29*/
	
	
	/*判断设备是否有数据需要发送*/
	for(i = 0; i < Rs485SwiInfo.SwtOutputValidNum; i++)
	{
		if(Rs485SwiInfo.DevSendBuf_last[i] != Rs485SwiInfo.DevSendBuf[i])
		{
			Rs485SwiInfo.SwtRelayLedCtrlFlag = 0x01;
			memcpy(Rs485SwiInfo.DevSendBuf_last, Rs485SwiInfo.DevSendBuf, Rs485SwiInfo.SwtOutputValidNum); 
			break; 
		}
	}
	

	if(0x01 == Rs485SwiInfo.SwtRelayLedCtrlFlag)
	{
		if(0x00 != Rs485SwiInfo.SwtRelayLedCtrlCnt)
		{
			Rs485SwiInfo.SwtRelayLedCtrlCnt--; 
			
			
			BLW_Touch_Switch_ctrl(&BUS_Public, &Rs485SwiInfo);
			Ret = RS485OCCUPYTIME;
		}
		else
		{
			Rs485SwiInfo.SwtRelayLedCtrlCnt = BUS_Public.retry_num;
			Rs485SwiInfo.SwtRelayLedCtrlFlag = 0x00;
			
			//发送结束
			if(Rs485SwiInfo.DevOffline != DEV_IS_OFFLINE)
			{
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_TouchSwitch LogInfo_Device_Offline.....");
				LOG_Device_Online_Record(DEV_SWI_TYPE, BUS_Public.addr,LogInfo_Device_Offline);	//记录设备离线
			}

			Rs485SwiInfo.DevOffline = DEV_IS_OFFLINE;   //判为离线
			DevActionGlobal.OffLineDevType = BUS_Public.type;        
			DevActionGlobal.OffLineDevAddr = BUS_Public.addr;        
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"TouchSwitch Offline,type:%d addr:%d",BUS_Public.type,BUS_Public.addr);
			
			if(Rs485SwiInfo.DevOffline != Rs485SwiInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
			{
				Rs485SwiInfo.DevOfflineLast = Rs485SwiInfo.DevOffline;	//更新上一次在线状态
				Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_OFFLINE);	//保存设备在线状态到SRAM
			}
			
			Ret = RS485OCCUPYNOTIME;
		}
		
		/*通讯统计记录*/
		BLV_Communication_Record(&Rs485SwiInfo.comm_record,0x01,0x00);
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485SwiInfo, sizeof(RS485_SWI_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAdd);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAdd+Dev_Privately);
	}
	
	return Ret;
}

#if 0
/**/
void BLW_Touch_Switch_Feedback(uint32_t devaddr,uint8_t loop,uint8_t start)
{
//	uint8_t val_check = 0;
//	uint16_t dev_datalen = 0x00;
	Device_Public_Information_G BUS_Public;	
	RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量
	
	if(devaddr == 0x00) return;
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),devaddr);			
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),devaddr+Dev_Privately);/*拷贝设备私有信息*/
	
	if(loop < Rs485SwiInfo.SwtOutputValidNum)
	{
		if(Rs485SwiInfo.DevSendBuf[loop] != start)
		{
			Rs485SwiInfo.DevSendBuf[loop] = start;
			
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"DevSendBuf loop:%d,start:%d\r\n",loop,start);
			
			BUS_Public.check = 0x00;
			BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485SwiInfo, sizeof(RS485_SWI_INFO));
			SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),devaddr);/*将数据保存*/
			SRAM_DMA_Write_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),devaddr+Dev_Privately);
		
		}

	}
}


/*获取开关在线状态*/
uint8_t Get_Touch_Switch_Online_Status(uint32_t devaddr)
{
	RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量
	
	/*拷贝设备私有信息*/
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),devaddr+Dev_Privately);
	
	if(Rs485SwiInfo.DevOffline == DEV_IS_ONLINE)
	{
		return 0x01;
	}
	return 0x02;
}


/**
*@name 开关输入检测函数
*@para
*  DevAddr      设备地址
*  DevInputLoop 回路输入地址  范围1~RS_SWITCH_CH_MAX  
*  DevInputType 输入类型
*/

uint8_t Dev_Swi_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType)
{
	Device_Public_Information_G BUS_Public;   //共用
	RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量
	uint8_t Ret = CtrlInvalid;         //控制无效
//	uint16_t dev_datalen;
//	uint8_t val_check;
	
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);/*拷贝设备私有信息*/
	
	if(DevInputLoop >= RS_SWITCH_CH_MAX)
	{
		return Ret;
	}
//	if((0x00 == DevInputLoop) || (DevInputLoop > RS_SWITCH_CH_MAX))
//	{
//		return Ret;
//	}
//	DevInputLoop--;  //转换到本地
	
	if(DevInputType == Rs485SwiInfo.DevReadBuf[DevInputLoop])
	{
		Rs485SwiInfo.DevReadBuf[DevInputLoop] = KeyNoAction;
		Ret = CtrlValid;
		
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"开关动作清空");
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485SwiInfo, sizeof(RS485_SWI_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);
		
	}
	
	return Ret;
}
/**
	*@name 开关输出控制函数
	*@para
	*  DevAddr      设备地址
	*  DevOutputLoop 回路输出地址  范围0~
	*  DevInputType 输入类型
	*/

void Dev_Swi_Output_Ctrl(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t DevAddr, uint16_t DevOutputLoop, uint16_t DevOutputType)
{
	uint8_t start = 0x00;
	uint8_t CtrlWay;
//	uint8_t val_check = 0;
//	uint16_t dev_datalen = 0x00;
	Device_Public_Information_G BUS_Public;   //共用	
	RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量
	
	if(NULL == DevAddr)
	{
		return ;
	}
	
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);/*拷贝设备私有信息*/
	
	if(DevOutputLoop >= Rs485SwiInfo.SwtOutputValidNum)
	{
		return ;
	}

//	
	CtrlWay = DevOutputType&0x00ff;   //取低字节

	switch(CtrlWay)  //不为0
	{
		case 0x01:start = 0x01;break;
		case 0x02:start = 0x00;break;
		case 0x04:      //闪烁
			start = Rs485SwiInfo.DevSendBuf[DevOutputLoop];
			if(0x01 == start)
			{
				start = 0x00;
			}
			else
			{
				start = 0x01;
			}	
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485开关闪烁赋值,start:%d\r\n",start);
			break;
		default: return;   //其他情况直接返回  
			
	}

	

	
	
	if(Rs485SwiInfo.DevSendBuf[DevOutputLoop] != start)
	{
		Rs485SwiInfo.DevSendBuf[DevOutputLoop] = start;
		
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"DevSendBuf loop:%d,start:%d\r\n",DevOutputLoop,start);
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485SwiInfo, sizeof(RS485_SWI_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);
		
	}

		
	
//	BLW_Touch_Switch_Feedback(DevAddr, DevOutputLoop, State);
}

/**
  * @name  指定服务信息回路状态得到
  * @param  
  *    devaddr             当前设备的地址
  *    DevOutputLoop       需要查找的服务信息回路
  * @retval 
  *    ret                 回路状态返回    1 开   2关   0为不存在
  * @brief

  */
uint16_t Dev_Swi_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop)
{	
	RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量

	if(devaddr == 0x00)
		return 0x00;
	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),devaddr+Dev_Privately);	
	
	if(DevOutputLoop >= Rs485SwiInfo.SwtOutputValidNum)
	{
		return 0x00;
	}

	if(Rs485SwiInfo.DevSendBuf[DevOutputLoop])
	{
		return 0x01;
	}
	else
	{
		return 0x02;
	}
	
}
#endif

