/**
  ******************************************************************************
  * @file    Blv_485_Dev_BinShen_Curtain.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2024年12月04日
  * @brief   丙申电机驱动
	*       
  ******************************************************************************
  */

#include "includes.h"


uint8_t BLV_RS485_BinShen_Curtain_Cycle_Dis(uint32_t devaddr);
uint8_t BLV_RS485_BinShen_Curtain_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len);


void BLV_485_Dev_BinShen_Curtain_Init(Device_Public_Information_G *BUS_Public, RS485_Cur_INFO *Rs485CurtainInfo)
{
	BUS_Public->polling_cf = (uint32_t)&BLV_RS485_BinShen_Curtain_Cycle_Dis;
	BUS_Public->processing_cf = (uint32_t)&BLV_RS485_BinShen_Curtain_Check;
}


uint16_t CRC_Cal(uint8_t *data,uint8_t lens)
{
	uint16_t sum = 0x00;
	
	for(uint8_t i = 0; i < lens; i++)
	{
		if((i != 0x04) && (i != 0x05))
		{
			sum += data[i];
		}
	}
	
	return (sum + 0x2017);
}


void BinShen_Action_Ctrl_Send(Device_Public_Information_G *BUS_Public, RS485_Cur_INFO *Rs485CurtainInfo)
{
	uint8_t lens = 22;
	uint8_t data[lens];
	uint16_t crc = 0x00;
	
	memset(data,0,sizeof(data));
	
	data[0] = 0x55;    //头码
	data[1] = 0xAA;
	data[2] = 0xAA;
	data[3] = 0x55;
	
	data[6] = 0x02;    //命令类型
	data[7] = 0x0A;
	
	data[8] = 0x0A;    //数据长度 
	data[9] = 0x00;
	
	data[10] = 0x00;   //协议版本
	data[11] = 0x00;
	
	data[12] = 0x01;   //产品型号
	
	if(Rs485CurtainInfo->control_flag == 0x01)       //打开
	{
		if(Rs485CurtainInfo->reverse_enable == 0x01)
		{
			data[13] = 0x00;   //动作数据 反向 
		}else {
			data[13] = 0x01;   //动作数据
		}
		
	}
	else if(Rs485CurtainInfo->control_flag == 0x02)  //关闭
	{
		if(Rs485CurtainInfo->reverse_enable == 0x01)
		{
			data[13] = 0x01;   //动作数据 反向 
		}else {
			data[13] = 0x00;   //动作数据
		}
	}
	else if(Rs485CurtainInfo->control_flag == 0x06)  //停止
	{
		data[13] = 0x02;   //动作数据
	}
	else if(Rs485CurtainInfo->control_flag == 0x04)  //互切
	{
		if(Rs485CurtainInfo->DYCurtainNextState == CUR_OPEN)
		{
			if(Rs485CurtainInfo->reverse_enable == 0x01)
			{
				data[13] = 0x00;   //动作数据 反向 
			}else {
				data[13] = 0x01;   //动作数据
			}
		}
		else if(Rs485CurtainInfo->DYCurtainNextState == CUR_CLOSE)
		{
			if(Rs485CurtainInfo->reverse_enable == 0x01)
			{
				data[13] = 0x01;   //动作数据 反向 
			}else {
				data[13] = 0x00;   //动作数据
			}
		}
	}
	
	data[14] = 0x00;     //位置数据
	
	data[15] = BUS_Public->addr;     //序列号
	data[16] = 0x01;
	data[17] = 0x01;
	
	data[18] = 0x00;      //命令参数
	data[19] = 0x00;
	data[20] = 0x00;
	data[21] = 0x00;
	
	crc = CRC_Cal(data,lens);
	
	data[4] = crc & 0xff;
	data[5] = (crc >> 8) & 0xff;
	
	Dbg_Print_Buff(DBG_BIT_DEVICE_STATUS_bit,"BinShen_Action_Ctrl_Send:",data,lens);
	MCU485_SendString(BUS_Public->port,data,lens);
	
	/*日志记录*/
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port,BUS_Public->baud,data,lens);
	
}


void BinShen_Percent_Ctrl_Send(Device_Public_Information_G *BUS_Public, RS485_Cur_INFO *Rs485CurtainInfo)
{
	uint8_t lens = 22;
	uint8_t data[lens];
	uint16_t crc = 0x00;
	
	memset(data,0,sizeof(data));
	
	data[0] = 0x55;    //头码
	data[1] = 0xAA;
	data[2] = 0xAA;
	data[3] = 0x55;
	
	data[6] = 0x09;    //命令类型
	data[7] = 0x0A;
	
	data[8] = 0x0A;    //数据长度 
	data[9] = 0x00;
	
	data[10] = 0x00;   //协议版本
	data[11] = 0x00;
	
	data[12] = 0x01;   //产品型号
	
	data[13] = 0x00;   //动作数据
	

	data[14] = Rs485CurtainInfo->DooYaCon_data.DATE1;     //位置数据
	
	data[15] = BUS_Public->addr;     //序列号
	data[16] = 0x01;
	data[17] = 0x01;
	
	data[18] = 0x00;      //命令参数
	data[19] = 0x00;
	data[20] = 0x00;
	data[21] = 0x00;
	
	crc = CRC_Cal(data,lens);
	
	data[4] = crc & 0xff;
	data[5] = (crc >> 8) & 0xff;
	
	Dbg_Print_Buff(DBG_BIT_DEVICE_STATUS_bit,"BinShen_Percent_Ctrl_Send:",data,lens);
	MCU485_SendString(BUS_Public->port,data,lens);
	
	/*日志记录*/
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port,BUS_Public->baud,data,lens);
	
}

uint8_t BLV_RS485_BinShen_Curtain_Cycle_Dis(uint32_t devaddr)
{
	uint8_t Ret = RS485OCCUPYNOTIME;
	uint8_t tempfalg = 0x00;
	
	Device_Public_Information_G BUS_Public;
	RS485_Cur_INFO 	Rs485CurtainInfo;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CurtainInfo,0,sizeof(RS485_Cur_INFO));
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),devaddr);		
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),devaddr+Dev_Privately);
	
	
	switch(Rs485CurtainInfo.control_flag)
	{
		case 0x01:    //打开
		case 0x02:    //关闭
		case 0x04:    //互切
		case 0x06:    //停止
			if(Rs485CurtainInfo.control_flag == 0x01)
			{
				Rs485CurtainInfo.DYCurtainNextState = CUR_CLOSE;
			}
			else if(Rs485CurtainInfo.control_flag == 0x02)
			{
				Rs485CurtainInfo.DYCurtainNextState = CUR_OPEN;
			}
			else if(Rs485CurtainInfo.control_flag == 0x06)
			{
				if(Rs485CurtainInfo.DYCurtainStateLast==CUR_OPEN)
				{
					Rs485CurtainInfo.DYCurtainNextState=CUR_CLOSE;
				}
				else if(Rs485CurtainInfo.DYCurtainStateLast==CUR_CLOSE)
				{
					Rs485CurtainInfo.DYCurtainNextState=CUR_OPEN;
				}
			}
			BinShen_Action_Ctrl_Send(&BUS_Public,&Rs485CurtainInfo);
			Ret = RS485OCCUPYTIME;
			break;
		case 0x05:    //百分比控制
			BinShen_Percent_Ctrl_Send(&BUS_Public,&Rs485CurtainInfo);
			Ret = RS485OCCUPYTIME;
			break;
	}
		
	
	if((Ret == RS485OCCUPYTIME) || (tempfalg == 0x01))
	{
		tempfalg = 0x01;
		
		if(Rs485CurtainInfo.DevSendCnt > 3)
		{
			if(Rs485CurtainInfo.DevOffline != DEV_IS_OFFLINE)
			{
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485 BinShen Curtain LogInfo_Device_Offline...........");
				LOG_Device_Online_Record(BUS_Public.type, BUS_Public.addr,LogInfo_Device_Offline);	//记录设备离线
			}

			Rs485CurtainInfo.DevOffline = DEV_IS_OFFLINE;   //判为离线
			if(Rs485CurtainInfo.DevOffline != Rs485CurtainInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
			{
				Rs485CurtainInfo.DevOfflineLast = Rs485CurtainInfo.DevOffline;	//更新上一次在线状态
				Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_OFFLINE);	//保存设备在线状态到SRAM
			}
			
			/*清除发送标记开始*/
			if(Rs485CurtainInfo.control_flag != 0x00)
			{
				Rs485CurtainInfo.control_flag = 0x00;
			}
			/*清除发送标记结束*/
			
			Rs485CurtainInfo.DevSendCnt = 0x00;
		}
		else
		{
			Rs485CurtainInfo.DevSendCnt++;   //发送次数累计
		}

		BLV_Communication_Record(&Rs485CurtainInfo.comm_record,0x01,0x00);
		
		
		if(tempfalg)
		{
			BUS_Public.check = 0x00;
			BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CurtainInfo, sizeof(RS485_Cur_INFO));
			SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),devaddr);/*将数据保存*/
			SRAM_DMA_Write_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),devaddr+Dev_Privately);
		}
	}
	
	return Ret;
}



uint8_t BLV_RS485_BinShen_Curtain_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len)
{
	uint8_t rev = 0x01;     //默认失败
	uint8_t data[30]={0};
	uint16_t crc_val;
	
	Device_Public_Information_G BUS_Public;
	RS485_Cur_INFO 	Rs485CurtainInfo;
	
	
	if((len != 22) || ( (data[8] + (data[9] << 8)) != 0x0A ) )
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Lens Err,Not BinShen Curtain Data");
		return 0x01;
	}
	
	SRAM_DMA_Read_Buff(data,len,data_addr);   //拷贝482数据
	
	
	if((data[0] != 0x55) || (data[1] != 0xAA) || (data[2] != 0xAA) || (data[3] != 0x55))	
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Head Err,Not BinShen Curtain Data");
		return 0x01;		
	}
	
//	if((data[6] != 0x02) || (data[7] != 0x0A))
//	{
//		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"CMD Type Err,Not BinShen Curtain Data");
//		rev=0x01;				
//	}
	
	if(0x00 != (data[10] + (data[11] << 8)) )
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Protocol Err,Not BinShen Curtain Data");
		return 0x01;
	}
	
	if(data[12] != 0x01)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Pro Ver Err,Not BinShen Curtain Data");
		return 0x01;
	}
	
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),dev_addr);
	
	if((data[15] != BUS_Public.addr) || (data[16] != BUS_Public.addr) || (data[17] != BUS_Public.addr))
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev Addr Err,Not BinShen Curtain Data");
		return 0x01;
	}
	
	crc_val = data[4] + (data[5] << 8);
	
	if(crc_val == CRC_Cal(&data[0],len))            //CRC校验成功
	{
		rev = 0x00;
		SRAM_DMA_Read_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),dev_addr+Dev_Privately);
		if(Rs485CurtainInfo.DevOffline != DEV_IS_ONLINE)
		{
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"BinShen Curtain LogInfo_Device_Online...........");
			LOG_Device_Online_Record(DEV_RS485_CURTAIN,BUS_Public.addr,LogInfo_Device_Online);	//记录设备在线
		}
		Rs485CurtainInfo.DevOffline = DEV_IS_ONLINE;    		//设备在线
		if(Rs485CurtainInfo.DevOffline != Rs485CurtainInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
		{
			Rs485CurtainInfo.DevOfflineLast = Rs485CurtainInfo.DevOffline;	//更新上一次在线状态
			Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_ONLINE);	//保存设备在线状态到SRAM
		}
		BLV_Communication_Record(&Rs485CurtainInfo.comm_record,0x02,0x01);		//记录通讯成功
		Rs485CurtainInfo.DevSendCnt = 0x00;             		//收到回复就清计数
		
		
		if((data[6] == 0x03) && (data[7] == 0x0A))
		{
			switch(data[13])
			{
				case 0x01:
				case 0x00:
				case 0x02:
					Rs485CurtainInfo.control_flag = 0x00;
					break;
			}
		}
		
		/*日志记录*/
		LOG_Device_COMM_Control_Reply_Record(BUS_Public.port,BUS_Public.baud,data,len);
	
	
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CurtainInfo, sizeof(RS485_Cur_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),dev_addr+Dev_Privately);
	}
	
	return rev;

}

