/**
  ******************************************************************************
  * @file    BLV_485.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2021年11月01日
  * @brief   服务信息初始化   设备服务信息控制
  * @attention 设备服务信息
  *									输入检测：  有
  *                 输入类型：  有	
  *                 执行函数：  有		
  *            			执行方式：
  *															开 
  *															关
  * @log     
			202205241551   SongHan   SERVICEVALUESET 宏参数用的是整型，整型是uint32_t 需要强转为uint64_t 
			202509011617	曹聪	
				1、修改服务信息回路状态、上一次回路状态、回路改变状态的变量类型
				2、修改服务信息回路上限 24 -> 64
				3、取消服务信息结构体中 Dev_Name_Struct DevNameStruct 服务信息别名，没有使用
				4、增加服务信息 回路1 取电服务 事件以及控制方式
					增加事件：首次取电事件(0x03)
					增加方法：置位首次取电标志位(0x03)、上报服务器播放欢迎词(0x04)
  ******************************************************************************
  */
#include "includes.h"



/*T1插卡取电*/
#define CtrlValid            0x01    //控制有效
#define CtrlInvalid          0x00    //控制无效

#define CARDACTIONCONVER(data)   (*(uint16_t *)&data)  //实际u16的值    当一个变量来用 可以用来比较和赋值

#define REPEATSENDTIMEMAX         0x03  //重发次数上限
#define READ_LEN    9

#define Dev_Card_RecvData_Len_Max	0x20


/*函数指针宏定义*/
typedef void (*DevFunP)(Device_Public_Information_G *BUS_Public, RS485_CARD_INFO *Rs485CardInfo);	//传递共用数据指针 私有数据指针

/*设备驱动宏定义开始*/
#define RS485_DEV_PRO_FUN_01    DevExistJudgge(Dev_485_Card_Polling_Flag,BLV_RS485_Card_Polling_Init)      //轮训端口
#define RS485_DEV_PRO_FUN_02    DevExistJudgge(Dev_485_Card_Active_Flag,BLV_RS485_Card_Active_Init)        //主动端口
#define RS485_DEV_PRO_FUN_03    ((DevFunP)NULL)          
#define RS485_DEV_PRO_FUN_04    ((DevFunP)NULL)
/*设备驱动宏定义结束*/


/**/
uint8_t BLV_RS485_Card_Cycle_Dis(uint32_t dev_addr);
uint8_t BLV_Rs485_Card_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len);

uint8_t Dev_Rs485_Card_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType);


/*主动端口接收和发送*/
void BLV_RS485_Card_Active_Init(Device_Public_Information_G *BUS_Public, RS485_CARD_INFO *Rs485CardInfo)
{
	BUS_Public->polling_cf = (uint32_t)&BLV_RS485_Card_Cycle_Dis;
	BUS_Public->processing_cf = (uint32_t)&BLV_Rs485_Card_Check;
	
	Rs485CardInfo->DevPort = Active_Port;		//2025-08-21 项目2164 定制修改
	//设备端口初始化 - 主动端口下，上电不会上报最新的状态
	Rs485CardInfo->DevInitFlag = 0x01;
	
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"增加主动端口插卡取电:%d",Rs485CardInfo->DevPort);
}

/*轮训端口接收和发送*/
void BLV_RS485_Card_Polling_Init(Device_Public_Information_G *BUS_Public, RS485_CARD_INFO *Rs485CardInfo)
{
	BUS_Public->polling_cf = (uint32_t)&BLV_RS485_Card_Cycle_Dis;
	BUS_Public->processing_cf = (uint32_t)&BLV_Rs485_Card_Check;
	
	Rs485CardInfo->DevPort = Polling_Port;
	//设备端口初始化 - 轮询可以读取最新的状态
	Rs485CardInfo->DevInitFlag = 0x00;
					
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"增加轮训端口插卡取电:%d",Rs485CardInfo->DevPort);
}

/*******************************************************************************
* Function Name  : BLV_RS485_Card_Data_Init 
* Description    : BLV插卡取电设备信息初始化
*******************************************************************************/
void BLV_RS485_Card_Data_Init(uint16_t DataLen, uint8_t *Data)
{
	Device_Public_Information_G BUS_Public;
	RS485_CARD_INFO 	Rs485CardInfo;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CardInfo,0,sizeof(RS485_CARD_INFO));
	
	BUS_Public.addr = Data[1];			//设备地址
	BUS_Public.type = Data[0];		//设备类型
	BUS_Public.port = Polling_Port;			//设备发送端口
	BUS_Public.baud = 9600;			//设备发送波特率
	BUS_Public.retry_num = 0x03;		//设备数据重发次数
	BUS_Public.wait_time = 0x0064;		//设备数据发送等待回复时间 - 100ms
	BUS_Public.polling_cf = (uint32_t)&BLV_RS485_Card_Cycle_Dis;
	BUS_Public.processing_cf = (uint32_t)&BLV_Rs485_Card_Check;
	Rs485CardInfo.DevOffline = Rs485CardInfo.DevOfflineLast = DEV_IS_LINEUNINIT;	//在线初始化
	BUS_Public.DevFunInfo.Dev_Input_Type_Get = Dev_Rs485_Card_InType_Get;
	Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO));
	Poll485_Info.device_num += 1;
}

/*******************************************************************************
* Function Name  : BLV_RS485_Card_Data_For_Logic_Init 
* Description    : 继电器初始化信息来自逻辑文件
*******************************************************************************/
void BLV_RS485_Card_Data_For_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len)
{
	Device_Public_Information_G BUS_Public;
	RS485_CARD_INFO 	Rs485CardInfo;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CardInfo,0,sizeof(RS485_CARD_INFO));
	
	BUS_Public.addr = dev_info->addr;	  //设备地址
	BUS_Public.type = dev_info->type;	  //设备类型
	BUS_Public.port = dev_info->port;	  //设备发送端口
	BUS_Public.baud = 9600;			      //设备发送波特率
	BUS_Public.retry_num = dev_info->retry;		  //设备数据重发次数
	BUS_Public.wait_time = dev_info->writ_time;		  //设备数据发送等待回复时间 - 100ms
	
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"增加插卡取电_111:%d,%d",dev_info->retry,dev_info->writ_time);
	BUS_Public.Protocol = dev_info->version;
	Rs485CardInfo.DevOfflineLast = DEV_IS_ONLINE;	//在线初始化
	Rs485CardInfo.DevOffline = Rs485CardInfo.DevOfflineLast;
	BUS_Public.DevFunInfo.Dev_Input_Type_Get = Dev_Rs485_Card_InType_Get;
	
//	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"增加主动端口插卡取电_111:%d",Rs485CardInfo.DevPort);
	
	switch(BUS_Public.Protocol)
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485CardInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485CardInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485CardInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: if(NULL!=RS485_DEV_PRO_FUN_04) RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485CardInfo);break;
		default:
			break;
	}
	
	/*RCU根据MCU复位状态进行设备初始化 - 
		保存标志位成立的情况下，如果是看门狗复位、软件复位、外部手动复位，将之前保存的状态进行设备初始化
		否则采用默认状态初始化(默认状态可通过RCU_POWER_Deivce_State_Init 宏定义 修改默认初始化状态)
	*/
	if( (DevActionGlobal.sram_save_flag == 0xA8) && ((SRAM_Read_DW(SRAM_LOG_RCU_Reboot_Reason) == 0x01) || (SRAM_Read_DW(SRAM_LOG_RCU_Reboot_Reason) == 0x03) || (SRAM_Read_DW(SRAM_LOG_RCU_Reboot_Reason) == 0x05)) )
	{
		Rs485CardInfo.Rs485CardFlag = DevActionGlobal.CardState;
		Rs485CardInfo.Rs485CardFlagLast = DevActionGlobal.CardState;
		Rs485CardInfo.Rs485CardType = DevActionGlobal.Rs485CardType;
		Rs485CardInfo.Rs485CardTypeLast = DevActionGlobal.Rs485CardType;
		
		//初始化
		if(Rs485CardInfo.Rs485CardFlag == 0x01){
			SRAM_Write_Byte(0x01,SRAM_UDP_ELEReport_CardState);				//给UDP 上报取电状态使用
			SRAM_Write_Byte(0x01,SRAM_UDP_ELEReport_CardState_Last);			//给UDP 上报取电状态使用
		}else{
			SRAM_Write_Byte(0x02,SRAM_UDP_ELEReport_CardState);				//给UDP 上报取电状态使用
			SRAM_Write_Byte(0x02,SRAM_UDP_ELEReport_CardState_Last);			//给UDP 上报取电状态使用
		}

	}else {
		
#if RCU_POWER_Deivce_State_Init		
		//上电默认状态为有人状态
		Rs485CardInfo.Rs485CardFlag = 0x01;
		Rs485CardInfo.Rs485CardFlagLast = 0x01;
		Rs485CardInfo.Rs485CardType = CARD_Guest_Identity;
		Rs485CardInfo.Rs485CardTypeLast = CARD_Guest_Identity;
#else
		//上电默认状态为无人状态
		Rs485CardInfo.Rs485CardFlag = 0x00;
		Rs485CardInfo.Rs485CardFlagLast = 0x00;
		Rs485CardInfo.Rs485CardType = CARD_Anonymous_Identity;
		Rs485CardInfo.Rs485CardTypeLast = CARD_Anonymous_Identity;
#endif			
		
		//初始化
		SRAM_Write_Byte(Rs485CardInfo.Rs485CardFlag,SRAM_UDP_ELEReport_CardState);				//给UDP 上报取电状态使用
		SRAM_Write_Byte(Rs485CardInfo.Rs485CardFlag,SRAM_UDP_ELEReport_CardState_Last);			//给UDP 上报取电状态使用

	}
	
	//初始化
	SRAM_Write_Byte(Rs485CardInfo.Rs485CardType,SRAM_UDP_ELEReport_CardType);				//给UDP 上报取电状态使用
	SRAM_Write_Byte(Rs485CardInfo.Rs485CardType,SRAM_UDP_ELEReport_CardType_Last);			//给UDP 上报取电状态使用
	SRAM_Write_DW(SysTick_1ms,SRAM_UDP_ELEReport_CardState_Tick);							//2026-01-20 增加插卡状态改变时间戳记录
	SRAM_Write_DW(SysTick_1ms,SRAM_UDP_ELEReport_CardType_Tick);							//2026-01-20 增加身份信息改变时间戳记录
	
	switch(dev_info->port)
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO));   
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
		default:
			break;
	}
	
}


/*轮训端口轮训发送函数*/
void BLV_RS485_Card_Polling_Send(Device_Public_Information_G *BUS_Public, RS485_CARD_INFO *Rs485CardInfo)
{
	uint8_t Cbuf[READ_LEN] = {0x55,0x55,0xee, 0x06, 0x07, 0x00, 0x01}; //0x18, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

	Cbuf[5] = BUS_Public->addr;  
	NetCRC16(&Cbuf[3],Cbuf[3]);
	
	MCU485_SendString(BUS_Public->port,Cbuf,READ_LEN); 
	
	/*通讯统计记录*/
	Rs485CardInfo->inquire_tick = SysTick_1ms;
	BLV_Communication_Record(&Rs485CardInfo->comm_record,0x01,0x00);
}


/*设置端口类型*/
void BLV_RS485_Card_PortType_Send(Device_Public_Information_G *BUS_Public, RS485_CARD_INFO *Rs485CardInfo)
{
	uint8_t lens = 0x0A;
	uint8_t data[lens];
	
	data[0] = 0x55;
	data[1] = 0x55;
	data[2] = 0xee;
	data[3] = lens - 3;   //除去包头3个字节
	data[4] = 0x07;       //Type
	data[5] = BUS_Public->addr;
	data[6] = 0x07;       //CMD
	data[7] = Rs485CardInfo->DevPort;
	
	NetCRC16(&data[3],data[3]);
	
	
	MCU485_SendString(BUS_Public->port,data,lens); 
	
	Dbg_Print_Buff(DBG_BIT_DEVICE_STATUS_bit,"BLV_RS485_Card_PortType_Send:",data,lens);
}	


/*******************************************************************************
* Function Name  : BLV_RS485_Card_Cycle_Dis 
* Description    : 插卡取电轮询发送函数
* Return         :
	0x00：没问题
	0x01：错误
*******************************************************************************/
uint8_t BLV_RS485_Card_Cycle_Dis(uint32_t dev_addr)
{
	uint8_t ret = RS485OCCUPYNOTIME;
	Device_Public_Information_G BUS_Public;
	RS485_CARD_INFO 	Rs485CardInfo;
	
	uint8_t keepflag = 0x00;
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),dev_addr);				
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO),dev_addr+Dev_Privately);
	
	if(Rs485CardInfo.DevPort != Rs485CardInfo.DevPort_Last)
	{
		Rs485CardInfo.DevPort_Last = Rs485CardInfo.DevPort;
		Rs485CardInfo.DevPort_Flag = 0x01;
		keepflag = 0x01;
	}
	
	if(Rs485CardInfo.DevPort_Flag == 0x01)
	{
		BLV_RS485_Card_PortType_Send(&BUS_Public,&Rs485CardInfo);
		ret = RS485OCCUPYTIME;
	}
	else
	{
		if(BUS_Public.port == Polling_Port)
		{
			BLV_RS485_Card_Polling_Send(&BUS_Public,&Rs485CardInfo);
			ret = RS485OCCUPYTIME;
		}else {
			
			//项目2164 - 定制功能
//			if( (DevActionGlobal.DevActionU64Cond.EleState == 0x01) || (Rs485CardInfo.Rs485CardType != 0x00) )             //插卡
//			{
//				if(SysTick_1ms - Rs485CardInfo.inquire_state_tick >= 10000)
//				{
//					Rs485CardInfo.inquire_state_tick = SysTick_1ms;
//					
//					BLV_RS485_Card_Polling_Send(&BUS_Public,&Rs485CardInfo);
//					
//					keepflag = 0x01;
//					ret = RS485OCCUPYTIME;
//				}
//			}else{
//				if(SysTick_1ms - Rs485CardInfo.inquire_state_tick >= 1000)
//				{
//					Rs485CardInfo.inquire_state_tick = SysTick_1ms;
//					
//					BLV_RS485_Card_Polling_Send(&BUS_Public,&Rs485CardInfo);
//					
//					keepflag = 0x01;
//					ret = RS485OCCUPYTIME;
//				}
//			}

			/* 根据协议版本判断当前使用的是那一版本插卡取电 */


			
		}
	}

	if(ret == RS485OCCUPYTIME)
	{
		keepflag = 0x01;
		if(Rs485CardInfo.DevSendCnt > REPEATSENDTIMEMAX)
		{
			if(Rs485CardInfo.DevOffline != DEV_IS_OFFLINE)	//第一次离线记录
			{
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_Card LogInfo_Device_Offline...........");
				LOG_Device_Online_Record(DEV_RS485_CARD,SRAM_Read_Byte(dev_addr+Dev_Addr),LogInfo_Device_Offline);	//记录设备离线
			}
			
			Rs485CardInfo.DevOffline = DEV_IS_OFFLINE;   //判为离线
			if(Rs485CardInfo.DevOffline != Rs485CardInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
			{
				Rs485CardInfo.DevOfflineLast = Rs485CardInfo.DevOffline;	//更新上一次在线状态
				Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_OFFLINE);	//保存设备在线状态到SRAM
			}
			
			Rs485CardInfo.DevPort_Flag = 0x00; 
		}
		else
		{
			Rs485CardInfo.DevSendCnt++;   //发送次数累计
		}
	}
	
	if(keepflag == 0x01)
	{
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CardInfo, sizeof(RS485_CARD_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO),dev_addr+Dev_Privately);
	}
	
	return ret;
}




/*******************************************************************************
* Function Name  : BLV_Rs485_Card_Check 
* Description    : BLV插卡取电数据处理函数
* Input          : 
	dev_addr	: 设备信息地址
	data_addr	: 数据地址
	len			：数据长度
* Return         : 
	0x00：处理成功
	0x01：处理失败
	
       头    LEN TYPE  ADDR FUN 有人 卡类型 卡号L 卡号H  栋 单元  楼层 房号 校验
    55 55 EE 0E   07   01   01  01   00     00    00     00  00   00   00   0A 38 
	
*******************************************************************************/
uint8_t BLV_Rs485_Card_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len)
{
	uint8_t rev = 0x01;
//	uint8_t temp = 0;
	uint8_t data[Dev_Card_RecvData_Len_Max];	
	Device_Public_Information_G BUS_Public;   //共用	
	RS485_CARD_INFO 	Rs485CardInfo;
	
//	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"BLV_Rs485_Card_Check");

//	uint8_t card_addr = SRAM_Read_Word(dev_addr+Dev_Addr);
//	uint16_t crc_val = SRAM_Read_Word(data_addr+len-2);
	//Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"BLV_Rs485_Card_Check -- \r\n");
	
//	uint16_t deal_len = len;
	if(len > Dev_Card_RecvData_Len_Max)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_Card Check_Len Fail!");
		return 0x01;	//和校验
	}
	
	if(len < 0x07)	{
		return 0x01;
	}
	
//	uint8_t deal_buff[deal_len + 2];
	memset(data,0,sizeof(Dev_Card_RecvData_Len_Max));
	SRAM_Read_Buff(data, len, data_addr);
	
	if((data[0] != 0x55) || (data[1] != 0x55) || (data[2] != 0xEE) || ((data[3] + 0x03) != len) \
		|| (data[4] != 0x07) || (data[5] != 0x01)	\
		|| ((data[len-2] + (data[len-1]<<8)) != NetCRC16_2(&data[3], len - 5))
		)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"校验文件头不对或校验不对!!");
		return rev;
	}
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),dev_addr);
	
//	if(deal_buff[0] != 0x55)	
//	{
//		Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"校验文件头不对!!\r\n");
//		return rev;				//校验文件头
//	}

//	if(deal_buff[1] != 0x55)	
//	{
//		Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"校验文件头不对!!\r\n");
//		return rev;				//校验文件头
//	}

//	if(deal_buff[2] != 0xEE)	
//	{
//		Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"校验文件头不对!!\r\n");
//		return rev;				//校验文件头
//	}

//	if((deal_buff[3] + 0x03) != len)	
//	{
//		Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"校验数据长度不对 实际长度:%d,数据长度:%d!!\r\n",len,temp);
//		return rev;					//校验数据长度
//	}

//	if(deal_buff[4] != 0x07)	
//	{
//		Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"校验类型不对:%d!!\r\n",temp);
//		return rev;				//校验类型
//	}
	
//	if(crc_val == NetCRC16_2(&deal_buff[3],deal_len - 5))
	{
		SRAM_DMA_Read_Buff((uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO),dev_addr+Dev_Privately);
		
		if(Rs485CardInfo.DevOffline == DEV_IS_OFFLINE)
		{
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_Card LogInfo_Device_Online...........");
			LOG_Device_Online_Record(DEV_RS485_CARD,BUS_Public.addr, LogInfo_Device_Online);	//记录设备离线
		}
		
		BLV_Communication_Record(&Rs485CardInfo.comm_record,0x02,0x01);		//记录通讯成功
		Rs485CardInfo.DevSendCnt = 0x00;              	//收到回复就清计数
		Rs485CardInfo.DevOffline = DEV_IS_ONLINE;    	//设备在线
		if(Rs485CardInfo.DevOffline != Rs485CardInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
		{
			Rs485CardInfo.DevOfflineLast = Rs485CardInfo.DevOffline;	//更新上一次在线状态
			Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_ONLINE);	//保存设备在线状态到SRAM
		}
		if(data[6] == 0x01)	
		{
			if(len >= 8)	
			{
			
				if(BUS_Public.port == Active_Port)       //2024-11-26
				{
					BLV_RS485_Card_Polling_Send(&BUS_Public,&Rs485CardInfo);
				} 
				switch(data[7])
				{
					case 0x02:	//有人 2025-09-03 读取到M0卡
						Rs485CardInfo.Rs485CardFlag = 0x01;
						//Udp_Addtion_Roomstate(BUS_Public.type,BUS_Public.addr,0x00,0x02);
						break;
					case 0x01:	//有人 2025-09-03 读取到M1卡
						Rs485CardInfo.Rs485CardFlag = 0x01;
						//Udp_Addtion_Roomstate(BUS_Public.type,BUS_Public.addr,0x00,0x01);
						break;
					case 0x00:	//无人
						Rs485CardInfo.Rs485CardFlag = 0x00;
						//Udp_Addtion_Roomstate(BUS_Public.type,BUS_Public.addr,0x00,0x00);
						break;	
					default:	//无人 2025-09-26 上报未知状态，取卡标志位不发生变化
						//Rs485CardInfo.Rs485CardFlag = 0x00;
						break;
				}

				Rs485CardInfo.Rs485CardType = data[8];
				
				/*2025-08-04 以第一次通讯读取状态为初始化状态，且不执行动作*/
				if( (BUS_Public.port == Polling_Port) && (Rs485CardInfo.DevInitFlag == 0x00) )
				{
					Rs485CardInfo.DevInitFlag = 0x01;
					
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"第一次通讯 %d %d %d",DevActionGlobal.DevActionU64Cond.EleState,Rs485CardInfo.Rs485CardType,Rs485CardInfo.Rs485CardTypeLast);
					
					Rs485CardInfo.Rs485CardFlagLast = Rs485CardInfo.Rs485CardFlag;
					Rs485CardInfo.Rs485CardTypeLast = Rs485CardInfo.Rs485CardType;
				}
			}
		}
		else if(data[6] == 0x07)
		{
			Rs485CardInfo.DevPort_Flag = 0x00;
		}
		
		/*插卡取电动作处理*/
		if( (Rs485CardInfo.DevInitFlag == 0x01) 
			&&  ( (Rs485CardInfo.Rs485CardFlag != Rs485CardInfo.Rs485CardFlagLast) 
			|| (Rs485CardInfo.Rs485CardTypeLast != Rs485CardInfo.Rs485CardType) ) )	//卡状态比较
		{
			Rs485CardInfo.Rs485CardFlagLast = Rs485CardInfo.Rs485CardFlag;
			Rs485CardInfo.Rs485CardTypeLast = Rs485CardInfo.Rs485CardType;

			DevActionGlobal.Rs485CardType = Rs485CardInfo.Rs485CardType;
			DevActionGlobal.CardState = Rs485CardInfo.Rs485CardFlag;
			
			if(Rs485CardInfo.Rs485CardFlag == 0x01)
			{
				SRAM_Write_Byte(0x01,SRAM_UDP_ELEReport_CardState);			//给UDP 上报取电状态使用
			}else {
				SRAM_Write_Byte(0x02,SRAM_UDP_ELEReport_CardState);			//给UDP 上报取电状态使用
			}
			
			SRAM_Write_Byte(Rs485CardInfo.Rs485CardType,SRAM_UDP_ELEReport_CardType);			//给UDP 上报取电状态使用
			
			SRAM_Write_DW(SysTick_1ms,SRAM_UDP_ELEReport_CardState_Tick);	//2026-01-20 增加插卡状态改变时间戳记录
			SRAM_Write_DW(SysTick_1ms,SRAM_UDP_ELEReport_CardType_Tick);	//2026-01-20 增加身份信息改变时间戳记录
			
			Dbg_Print_Buff(DBG_BIT_DEVICE_STATUS_bit,"485插卡取电数据变化：",data,len);
			
			Udp_Addtion_Roomstate(BUS_Public.type,BUS_Public.addr,0x00,Rs485CardInfo.Rs485CardFlagLast);
			LOG_Device_COMM_ASK_TO_Reply_Record2(dev_addr+Dev_port,dev_addr+Dev_baud,(SysTick_1ms - Rs485CardInfo.inquire_tick),data,len);
			
//			switch(Rs485CardInfo.Rs485CardType)     //需要判断身份，来执行不同的场景
//			{
//				case CARDIDNOBODY:         //无卡  
//				case CARDIDM1:   
//				case CARDIDGUEST:          //客人
//				case CARDIDWAITER:         //服务员
//				case CARDIDMANAGER:        //经理
//				case CARDIDENGINEER:       //工程
//				case CARDIDHEADER:         //总管
//					DevActionGlobal.Devi = BUS_Public.DevCoord;     //直接跳到指定的下标去处理					
//					break;
//			}
//			switch(Rs485CardInfo.Rs485CardType)     //需要判断身份，来执行不同的场景
//			{
//				case CARDIDNOBODY:         //无卡  
//					Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"拔卡\r\n");
//					Rs485CardInfo.Rs485CardAction = 0x01;  //拔卡
//					break;
//				case CARDIDM1:   
//					Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"高频卡插入\r\n");
//					Rs485CardInfo.Rs485CardAction = 0x02;  //高频卡
//					break;
//				case CARDIDGUEST:          //客人
//					Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"客人卡插入\r\n");
//					Rs485CardInfo.Rs485CardAction = 0x03;  //客人卡
//					break;
//				case CARDIDWAITER:         //服务员
//					Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"服务员卡插入\r\n");
//					Rs485CardInfo.Rs485CardAction = 0x04;  //服务员
//					break;
//				case CARDIDMANAGER:        //经理
//					Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"经理卡插入\r\n");
//					Rs485CardInfo.Rs485CardAction = 0x05;  //经理
//					break;
//				case CARDIDENGINEER:       //工程
//					Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"工程卡插入\r\n");
//					Rs485CardInfo.Rs485CardAction = 0x06;  //工程
//					break;
//				case CARDIDHEADER:         //总管
//					Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"总管插入\r\n");
//					Rs485CardInfo.Rs485CardAction = 0x07;  //总管		
//					break;
//			}
			
			
			DevActionGlobal.Devi = BUS_Public.DevCoord;     //直接跳到指定的下标去处理	
			if(Rs485CardInfo.Rs485CardFlag == 0x01)
			{
				if(Rs485CardInfo.Rs485CardType != 0x00)
				{
					Rs485CardInfo.Rs485CardAction = 0x02 + Rs485CardInfo.Rs485CardType;		//
				}else {
					Rs485CardInfo.Rs485CardAction = 0x01;		//插卡事件产生
				}
			}else {
				Rs485CardInfo.Rs485CardAction = 0x02;		//拔卡事件产生
			}
			
		}
		
		/*将数据保存进入SRAM中*/
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CardInfo, sizeof(RS485_CARD_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO),dev_addr+Dev_Privately);
		
		rev = 0x00;
	}


	return rev;	
}

/*获取插卡取电在线状态*/
uint8_t Get_BLV485_CARD_Online_Status(uint32_t devaddr)
{
	RS485_CARD_INFO 	Rs485CardInfo;
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO),devaddr+Dev_Privately);
	
	if(Rs485CardInfo.DevOffline == DEV_IS_ONLINE)
	{
		return 0x01;
	}
	return 0x02;
}

/**
*@name 插卡取电输入检测函数
*@para
*  DevAddr      设备地址
*  DevInputLoop 回路输入地址  范围0~ServiceLoopValidNum  
*  DevInputType 输入类型
*/

uint8_t Dev_Rs485_Card_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType)
{
	RS485_CARD_INFO Rs485CardInfo;       //插卡取电局部变量
	uint8_t Ret = CtrlInvalid;         //控制无效
	uint16_t dev_datalen;
	uint8_t val_check;

	/*拷贝设备私有信息*/
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO),DevAddr+Dev_Privately);
	
//	CARDACTIONCONVER(Rs485CardInfo.Rs485CardCond) = DevInputType;  
//	
//	if((0x01 == Rs485CardInfo.Rs485CardCond.CardGuestState)&&(0x03 == Rs485CardInfo.Rs485CardAction)){Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"客人卡判断通过"); Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x01 == Rs485CardInfo.Rs485CardCond.CardWaiterState)&&(0x04 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"服务员卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x01 == Rs485CardInfo.Rs485CardCond.CardManagerState)&&(0x05 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"经理卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x01 == Rs485CardInfo.Rs485CardCond.CardEngineerState)&&(0x06 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"工程卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x01 == Rs485CardInfo.Rs485CardCond.CardHeaderState)&&(0x07 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"总管卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x01 == Rs485CardInfo.Rs485CardCond.CardIDM1State)&&(0x02 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"高频卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x02 == Rs485CardInfo.Rs485CardCond.CardGuestState)&&(0x01 == Rs485CardInfo.Rs485CardAction)){Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"拔卡判断通过"); Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x02 == Rs485CardInfo.Rs485CardCond.CardWaiterState)&&(0x01 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"拔卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x02 == Rs485CardInfo.Rs485CardCond.CardManagerState)&&(0x01 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"拔卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x02 == Rs485CardInfo.Rs485CardCond.CardEngineerState)&&(0x01 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"拔卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x02 == Rs485CardInfo.Rs485CardCond.CardHeaderState)&&(0x01 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"拔卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
//	else if((0x02 == Rs485CardInfo.Rs485CardCond.CardIDM1State)&&(0x01 == Rs485CardInfo.Rs485CardAction)) {Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"拔卡判断通过");Rs485CardInfo.Rs485CardAction = 0x00; Ret = CtrlValid;}
			
	if(Rs485CardInfo.Rs485CardAction == DevInputType)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"插卡取电动作产生:%d ",Rs485CardInfo.Rs485CardAction);
		Rs485CardInfo.Rs485CardAction = 0x00;
		Ret = CtrlValid;
	}
	
	if(CtrlValid == Ret)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"插卡取电动作清空");

		/*将数据保存，重新计算校验值 注意：一般数据有变动时，才重新计算校验值*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485CardInfo,sizeof(RS485_CARD_INFO),DevAddr+Dev_Privately);
		
		SRAM_Write_Byte(0x00,DevAddr+Dev_Check);				//校验值清零
		dev_datalen = sizeof(RS485_CARD_INFO) + Dev_Privately;
		val_check = Dev_CheckSum(DevAddr,dev_datalen);
		
		SRAM_Write_Byte(val_check,DevAddr+Dev_Check);		//校验值重新写入
	}
	
	return Ret;
	
}
