/**
  ******************************************************************************
  * @file    BlV_Bus_Dev_PB20_Relay_Fun.c
  * @author  BLW RCU  development Team
  * @version V1.0
  * @date    2023年10月19日
  * @brief  
  *          PB20_Relay驱动
  ******************************************************************************
  */


#include "includes.h"

#if RS485_PB20_Relay_Flag

/*本地函数定义开始*/
void BLV_PB20_Relay_Control_State(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t devaddr,uint16_t loop,uint16_t start);
uint16_t BLV_PB20_Relay_Read_State(uint32_t devaddr,uint16_t loop);
uint8_t BLV_PB20_Relay_Rccv_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len);
void BLV_PB20_Relay_Dis(uint32_t dev_addr);

/*本地函数定义结束*/


void PB20_Relay_AddToPB(uint32_t devaddr, Device_Public_Information_G *BUS_Public)
{
	Device_Public_Information_G BUS_Public_PB;
	RS485_PB20_INFO Rs485PB20;
	
	if(devaddr != NULL)
	{
		SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public_PB,sizeof(Device_Public_Information_G),devaddr);				
		SRAM_DMA_Read_Buff((uint8_t *)&Rs485PB20,sizeof(RS485_PB20_INFO),devaddr+Dev_Privately);
		
		if(Rs485PB20.RelayDevNum < PB20_RELAY_MAX)
		{
			Rs485PB20.Relay_List[Rs485PB20.RelayDevNum].Type = BUS_Public->type;
			Rs485PB20.Relay_List[Rs485PB20.RelayDevNum].Addr = BUS_Public->addr;
			Rs485PB20.Relay_List[Rs485PB20.RelayDevNum].Port = BUS_Public->port;
			
			Rs485PB20.RelayDevNum++;
		}
		
		BUS_Public_PB.check = 0x00;
		BUS_Public_PB.check = DoubleData_CheckSum((uint8_t *)&BUS_Public_PB, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485PB20, sizeof(RS485_PB20_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public_PB, sizeof(Device_Public_Information_G),devaddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485PB20,sizeof(RS485_PB20_INFO),devaddr+Dev_Privately);
	}
}


/*******************************************************************************
* @name  :  BLV_RS485_PB20_Relay_Data_Init
* @para  : 
*   DataLen :数据长度
*   Data:    数据数组
* @attention :代码配置
*******************************************************************************/
void BLV_RS485_PB20_Relay_Data_Init(uint8_t devaddr)
{
	Device_Public_Information_G BUS_Public;
	RS485_PB20_Relay_INFO Rs485PB20Relay;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485PB20Relay,0,sizeof(RS485_PB20_Relay_INFO));
	
	BUS_Public.addr = devaddr;		                                            //设备485地址
	BUS_Public.type = Dev_Rs485_PB20_Relay;		                                            //设备类型
	BUS_Public.baud = 0x00;//Data[3] + (Data[4]<<8) + (Data[5]<<16) + (Data[6]<<24);   //设备发送波特率9600
//	BUS_Public.retry_num = 0x03;	                                            //设备数据重发次数
//	BUS_Public.wait_time = 0x0064;	                                            //设备数据发送等待回复时间 - 100ms
	BUS_Public.Protocol = 0x01;	                                            //设备协议
	
	BUS_Public.DevFunInfo.Dev_Data_Process = BLV_PB20_Relay_Dis;             
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = BLV_PB20_Relay_Control_State;
	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = BLV_PB20_Relay_Read_State;

	Rs485PB20Relay.PB20DevType = 0x30;
	Rs485PB20Relay.PB20DevAddr = 0x01;
	Rs485PB20Relay.PB20DevPort = 0x03;
	Rs485PB20Relay.PB20Addr = Find_AllDevice_List_Information2(Rs485PB20Relay.PB20DevPort,Rs485PB20Relay.PB20DevType,Rs485PB20Relay.PB20DevAddr);
	
	Rs485PB20Relay.LoopValidNum = 0x04;
	Rs485PB20Relay.DevOffline = Rs485PB20Relay.DevOfflineLast = DEV_IS_LINEUNINIT;   //在线状态初始化
	
//	switch(Data[2])
//	{
//		case 0x00:
			Add_Nor_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485PB20Relay,sizeof(RS485_PB20_Relay_INFO));
//			break;
//		default:
//			break;
//	}
	
	PB20_Relay_AddToPB(Rs485PB20Relay.PB20Addr,&BUS_Public);

}



/*******************************************************************************
* @name  :  PB20Relay设备初始化
* @para  : 
*   dev_info :逻辑文件指针
*   data     :数据指针
*   data_len :数据长度
* @attention :逻辑配置
*******************************************************************************/
void BLV_RS485_PB20_Relay_For_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len)
{
	Device_Public_Information_G BUS_Public;
	RS485_PB20_Relay_INFO Rs485PB20Relay;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485PB20Relay,0,sizeof(RS485_PB20_Relay_INFO));
	
	BUS_Public.addr = dev_info->addr;	      //设备485地址
	BUS_Public.type = dev_info->type;		  //设备类型
	BUS_Public.baud = dev_info->baud;		  //设备发送波特率9600
//	BUS_Public.retry_num = 0x03;			  //设备数据重发次数
//	BUS_Public.wait_time = 0x0064;			  //设备数据发送等待回复时间 - 100ms
	BUS_Public.Protocol = dev_info->version;  //协议号
	
	BUS_Public.DevFunInfo.Dev_Data_Process = BLV_PB20_Relay_Dis;             
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = BLV_PB20_Relay_Control_State;
	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = BLV_PB20_Relay_Read_State;
	
	Rs485PB20Relay.PB20DevType = dev_info->parent_type;
	Rs485PB20Relay.PB20DevAddr = dev_info->parent_addr;
	Rs485PB20Relay.PB20DevPort = dev_info->parent_port;
	Rs485PB20Relay.PB20Addr = Find_AllDevice_List_Information2(Rs485PB20Relay.PB20DevPort,Rs485PB20Relay.PB20DevType,Rs485PB20Relay.PB20DevAddr);
	
	Rs485PB20Relay.LoopValidNum = dev_info->output_num;
	Rs485PB20Relay.DevOffline = Rs485PB20Relay.DevOfflineLast = DEV_IS_LINEUNINIT;   //在线状态初始化
	
	switch(dev_info->port)
	{
		case 0x00:
			Add_Nor_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485PB20Relay,sizeof(RS485_PB20_Relay_INFO));
			break;
		default:
			break;
	}
	
	PB20_Relay_AddToPB(Rs485PB20Relay.PB20Addr,&BUS_Public);

}



/*******************************************************************************
* Function Name  : BLV_PB20_Relay_Control_State 
* Description    : PB20Relay控制函数
* Input          : 
	devaddr	: 设备信息地址
	loop    : 回路
	start   : 状态
* Return  : 无
* attention : temp1非0才会进行保存
*******************************************************************************/
void BLV_PB20_Relay_Control_State(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t devaddr,uint16_t loop,uint16_t start)
{
	Device_Public_Information_G BUS_Public;
	RS485_PB20_Relay_INFO Rs485PB20Relay;
	
	uint8_t CtrlMode;     //控制模式
//	uint8_t CtrlContect;  //控制内容
	
	uint8_t temp1 = 0x00;
	
	if(devaddr == 0x00)	return;
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),devaddr);				
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485PB20Relay,sizeof(RS485_PB20_Relay_INFO),devaddr+Dev_Privately);
	
	if(loop >= Rs485PB20Relay.LoopValidNum)    //有效回路
	{
		return ;
	}
	
	CtrlMode = start&0x00ff;    //控制模式
//	CtrlContect = start>>8;     //控制内容
	
	switch(CtrlMode)
	{
		case PB20_Relay_OPEN:
		case PB20_Relay_CLOSE:
			Rs485PB20Relay.RelayState[loop] = CtrlMode;
			//Dbg_Println(DBG_BIT_SYS_STATUS_bit,"PB20_Relay loop%d Ctrl:%d - %d",loop,Rs485PB20Relay.RelayState[loop],Rs485PB20Relay.RelayState_Last[loop]);
			temp1++;
			break;
		default:
			break;
	}
	
	
	if(temp1 != 0x00)
	{
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485PB20Relay, sizeof(RS485_PB20_Relay_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),devaddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485PB20Relay,sizeof(RS485_PB20_Relay_INFO),devaddr+Dev_Privately);
	}
}


/*******************************************************************************
* Function Name  : BLV_PB20_Relay_Read_State 
* Description    : PB20Relay状态读取函数
* Input          : 
	devaddr	: 设备信息地址
	loop    :回路
* Return  : 无
*******************************************************************************/
uint16_t BLV_PB20_Relay_Read_State(uint32_t devaddr,uint16_t loop)
{
	
	if(devaddr == 0x00)
		return 0x00;
	
	RS485_PB20_Relay_INFO Rs485PB20Relay;
	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485PB20Relay,sizeof(RS485_PB20_Relay_INFO),devaddr+Dev_Privately);	
	
	if(loop >= PB20_Relay_BUFF_SIZE)
	{
		//Dbg_Println(DBG_BIT_SYS_STATUS_bit,"BLV_PB20_Relay_Read_State loop >= PB20_Relay_BUFF_SIZE");
		return 0x00;    //超出范围 直接返回0
	}
	
	return Rs485PB20Relay.RelayState[loop];
}



/*******************************************************************************
* Function Name  : BLV_PB20_Relay_Dis 
* Description    : PB20Relay数据处理函数
* Input          : 
	dev_addr	 : 设备信息地址
* Return         : 
*******************************************************************************/
void BLV_PB20_Relay_Dis(uint32_t dev_addr) 
{
	uint8_t i;     //用于遍历所有回路
	Device_Public_Information_G BUS_Public_PBRelay;
	RS485_PB20_Relay_INFO Rs485PB20Relay;
	
	Device_Public_Information_G BUS_Public_PB;
	RS485_PB20_INFO Rs485PB20;
	
	uint8_t relay_flag = 0x00;
	uint8_t pb20_flag = 0x00;
	
	
	if(NULL == dev_addr)
	{
		return ;
	}
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public_PBRelay,sizeof(Device_Public_Information_G),dev_addr);	//拷贝所有共有数据
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485PB20Relay,sizeof(RS485_PB20_Relay_INFO),dev_addr+Dev_Privately);
	
	if(Rs485PB20Relay.PB20Addr == NULL)
	{
		return ;
	}
	else
	{
		SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public_PB,sizeof(Device_Public_Information_G),Rs485PB20Relay.PB20Addr);				
		SRAM_DMA_Read_Buff((uint8_t *)&Rs485PB20,sizeof(RS485_PB20_INFO),Rs485PB20Relay.PB20Addr+Dev_Privately);
		
		if(BUS_Public_PB.type != Dev_Rs485_PB20)    {
            Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"%s - Type Error %d",BUS_Public_PB.type);
            return ;    //判断设备类型
        }
	}
	
	
	for(i = 0; i < PB20_Relay_BUFF_SIZE; i++)
	{
		if(Rs485PB20Relay.RelayState_Last[i] != Rs485PB20Relay.RelayState[i])
		{
			Rs485PB20Relay.RelayState_Last[i] = Rs485PB20Relay.RelayState[i];
			
			

			
			if(BUS_Public_PBRelay.addr < 8)
			{
				Rs485PB20.Relay_LoopCtrl_Flag[BUS_Public_PBRelay.addr] |= (0x01<<i);
				Rs485PB20.Relay_A00_07_LoopCtrl |= (0x01 << (BUS_Public_PBRelay.addr*4 + i));
			}
			else if((BUS_Public_PBRelay.addr >= 8) && (BUS_Public_PBRelay.addr <= 15))
			{
				Rs485PB20.Relay_LoopCtrl_Flag[BUS_Public_PBRelay.addr] |= (0x01<<i);
				Rs485PB20.Relay_A08_15_LoopCtrl |= (0x01 << (BUS_Public_PBRelay.addr*4 + i - 32));
			}
			
			Rs485PB20.Relay_CtrlLoopNum++;
			
			relay_flag = 0x01;
			pb20_flag = 0x01;
			
//			Dbg_Println(DBG_BIT_SYS_STATUS_bit,"BLV_PB20_Relay %d  Loop:%d  Flag:% 00_07_LoopCtrl:%08X 08_15_LoopCtrl:%08X",\
//			BUS_Public_PBRelay.addr,i,Rs485PB20.Relay_LoopCtrl_Flag[BUS_Public_PBRelay.addr],Rs485PB20.Relay_A00_07_LoopCtrl,Rs485PB20.Relay_A08_15_LoopCtrl);
		}
	}
	

	if(0x01 == relay_flag)
	{
		BUS_Public_PBRelay.check = 0x00;
		BUS_Public_PBRelay.check = DoubleData_CheckSum((uint8_t *)&BUS_Public_PBRelay, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485PB20Relay, sizeof(RS485_PB20_Relay_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public_PBRelay, sizeof(Device_Public_Information_G),dev_addr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485PB20Relay,sizeof(RS485_PB20_Relay_INFO),dev_addr+Dev_Privately);
	}
	
	if(0x01 == pb20_flag)
	{
		BUS_Public_PB.check = 0x00;
		BUS_Public_PB.check = DoubleData_CheckSum((uint8_t *)&BUS_Public_PB, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485PB20, sizeof(RS485_PB20_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public_PB, sizeof(Device_Public_Information_G),Rs485PB20Relay.PB20Addr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485PB20,sizeof(RS485_PB20_INFO),Rs485PB20Relay.PB20Addr+Dev_Privately);
	}
	
}


/*******************************************************************************
* Function Name  : BLV_PB20_Relay_Rccv_Check 
* Description    : PB20Relay接收数据处理函数
* Input          : 
	dev_addr	 : 设备信息地址
	data_addr	 : 数据地址
	len			 : 数据长度
* Return         : 
	0x00：处理成功
	0x01：处理失败
*******************************************************************************/
uint8_t BLV_PB20_Relay_Rccv_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len)
{

	uint8_t rev = 0x01;

	return rev;
}

#endif

