/**
  ******************************************************************************
  * @file    BLV_485_Dev_CardStateFun.c
  * @author  BLW RCU  development Team
  * @version YHF
  * @date    2022年11月01日
  * @brief  
	*    插卡状态轮询总表
	*    输入：有
	*    输出：有
  ******************************************************************************
  */


#include "APP_SwitchCtrl.h"

#include <string.h>
#include "BLV_485_Protocol.h"
#include "SPI_SRAM.h"
#include "usart.h"
#include "CH57x_common.h"
#include "check_fun.h"
#include "rw_logging.h"
#include "SRAM_Variable_Address.h"
#include "DBG.h"
#include "Log_api.h"
#include "includes.h"

/*外设驱动列表开始*/
#include "BLV_485_Dev_CardStateFun.h"

/*外设驱动列表结束*/

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

/*设备驱动宏定义开始*/
#define RS485_DEV_PRO_FUN_01    DevExistJudgge(RS485_CardState_Flag, BLV_485_Dev_CardStateA_Init)      //主动端口
#define RS485_DEV_PRO_FUN_02    DevExistJudgge(RS485_CardState_Flag, BLV_485_Dev_CardStateB_Init)      //轮询端口
#define RS485_DEV_PRO_FUN_03    ((DevFunP)NULL)          
#define RS485_DEV_PRO_FUN_04    ((DevFunP)NULL)
/*设备驱动宏定义结束*/

uint8_t BLW_CardState_CycleDis(uint32_t DevAdd);
void BLW_CardState_Send(uint8_t port);        //旧协议
void BLW_CardState_New_Send(uint8_t port);    //新协议

/*******************************************************************************
* @name  :  插卡状态同步初始化
* @para  : 
*   DataLen :数据长度
*   Data：   数据数组
*
*******************************************************************************/

void BLW_RS485_CardState_Init(uint16_t DataLen, uint8_t *Data)
{
	Device_Public_Information_G BUS_Public;
	RS485_CARDSTATE_INFO Rs485CardStateInfo;       //插卡状态同步局部参数
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CardStateInfo,0,sizeof(RS485_CARDSTATE_INFO));
	
	BUS_Public.addr = Data[1];			//设备地址
	BUS_Public.type = Data[0];		//设备类型
	BUS_Public.baud = 9600;			//设备发送波特率
	BUS_Public.retry_num = 0x00;		//设备数据重发次数
	BUS_Public.wait_time = 0xC8;		//设备数据发送等待回复时间 

	Rs485CardStateInfo.CardState_SN = TIME_MAX;

	switch(Data[7])
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485CardStateInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485CardStateInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485CardStateInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: if(NULL!=RS485_DEV_PRO_FUN_04) RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485CardStateInfo);break;
	}

	switch(Data[2])
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));   
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
	}
}


/*******************************************************************************
* Function Name  : BLW_RS485_CardState_For_Logic_Init
* Description    : 插卡状态同步始化信息来自逻辑文件
*******************************************************************************/
void BLW_RS485_CardState_For_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len)
{
	Device_Public_Information_G BUS_Public;
	RS485_CARDSTATE_INFO Rs485CardStateInfo;       //插卡状态同步局部参数
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CardStateInfo,0,sizeof(RS485_CARDSTATE_INFO));
	
	BUS_Public.addr = dev_info->addr;			//设备地址
	BUS_Public.type = dev_info->type;			//设备类型
	BUS_Public.baud = dev_info->baud;				//设备发送波特率
	BUS_Public.retry_num = 0x00;		//设备数据重发次数
	BUS_Public.wait_time = 0x64;		//设备数据发送等待回复时间    

	BUS_Public.Protocol = dev_info->version;
	
	Rs485CardStateInfo.CardState_SN = TIME_MAX;
	
	switch(BUS_Public.Protocol)
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485CardStateInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485CardStateInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485CardStateInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: if(NULL!=RS485_DEV_PRO_FUN_04) RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485CardStateInfo);break;
		default:
			break;
	}

	switch(dev_info->port)
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));   
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
		default:
			break;
	}
}


uint8_t BLW_Rs485_CardState_Check(uint32_t DevAdd ,uint32_t Data_addr, uint16_t DataLen) 
{
	uint8_t ret = 0x01;
	uint8_t data[6];	
	uint8_t keepflag = 0x00;

	Device_Public_Information_G BUS_Public;   //共用	
	RS485_CARDSTATE_INFO Rs485CardStateInfo;       //插卡状态同步局部参数
	
	if(DataLen > 6)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"CardState Recv Lens Over Max!!");
		return ret;     //长度
	}
	
	SRAM_DMA_Read_Buff(data,DataLen,Data_addr);   //拷贝482数据
		
	
	if((data[1] != 0x08)||(data[DataLen - 1] != SOR_CRC(data, DataLen-1)))   //匹配开关地址数据  
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Not CardStateFun Data，DevAdd:%d,len:%d",BUS_Public.addr,DataLen);
		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 *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO),DevAdd+Dev_Privately);
		
		switch(data[1])
		{
			case 0x08:
				ret = 0x00;
				break;
			default:
				break;
		}
		
		/*日志记录*/
		LOG_Device_COMM_Control_Reply_Record(BUS_Public.port,BUS_Public.baud,data,DataLen);
		
		if(keepflag==0x01)
		{
			BUS_Public.check = 0x00;
			BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CardStateInfo, sizeof(RS485_CARDSTATE_INFO));
			SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAdd);/*将数据保存*/
			SRAM_DMA_Write_Buff((uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO),DevAdd+Dev_Privately);
		}
		
	}

	return ret;
}



void BLV_485_Dev_CardStateA_Init(Device_Public_Information_G *BUS_Public, RS485_CARDSTATE_INFO *Rs485CardStateInfo)
{
	
	BUS_Public->polling_cf = (uint32_t)&BLW_CardState_CycleDis;
	BUS_Public->processing_cf = (uint32_t)&BLW_Rs485_CardState_Check;
								
}


void BLV_485_Dev_CardStateB_Init(Device_Public_Information_G *BUS_Public, RS485_CARDSTATE_INFO *Rs485CardStateInfo)
{
	BUS_Public->polling_cf = (uint32_t)&BLW_CardState_CycleDis;
	BUS_Public->processing_cf = (uint32_t)&BLW_Rs485_CardState_Check;
}



uint8_t BLW_CardState_CycleDis(uint32_t DevAdd)  
{
	uint8_t temp_flag = 0x00;
	Device_Public_Information_G BUS_Public;
	RS485_CARDSTATE_INFO Rs485CardStateInfo;       //插卡状态同步局部参数

	uint8_t Ret = RS485OCCUPYNOTIME;
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAdd);			
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO),DevAdd+Dev_Privately);/*拷贝设备私有信息*/
	
	if(DevActionGlobal.DevActionU64Cond.EleState == 0x01)             //插卡 
	{
		Rs485CardStateInfo.CardState = 0x01;
	}
	else if(DevActionGlobal.DevActionU64Cond.EleState == 0x02)        //拔卡
	{
		Rs485CardStateInfo.CardState = 0x02;
	}
	
	
	if(Rs485CardStateInfo.CardStateLast != Rs485CardStateInfo.CardState)
	{
		Rs485CardStateInfo.CardStateLast = Rs485CardStateInfo.CardState;
		Rs485CardStateInfo.CardAction = 0x01;
	}
	
	if(Rs485CardStateInfo.SleepFlag != DevActionGlobal.Service_16)    //2024-12-09
	{
		Rs485CardStateInfo.SleepFlag = DevActionGlobal.Service_16;
		Rs485CardStateInfo.CardAction = 0x01;
	}
	
	
	//旧协议广播
	if((Rs485CardStateInfo.CardAction == 0x01) && (Rs485CardStateInfo.CardState_SN > 0))     
	{
		BLW_CardState_Send(BUS_Public.port);
		Rs485CardStateInfo.CardState_SN--;
		if(Rs485CardStateInfo.CardState_SN == 0x00)
		{
			Rs485CardStateInfo.CardState_SN = TIME_MAX;
			Rs485CardStateInfo.CardAction = 0x02;
		}
		Rs485CardStateInfo.CardState_Tick = SysTick_1s;
		Ret = RS485OCCUPYTIME;
		temp_flag = 0x01;
	}
	//新协议广播
	else if((Rs485CardStateInfo.CardAction == 0x02) && (Rs485CardStateInfo.CardState_SN > 0))    
	{
		BLW_CardState_New_Send(BUS_Public.port);
		Rs485CardStateInfo.CardState_SN--;
		if(Rs485CardStateInfo.CardState_SN == 0x00)
		{
			Rs485CardStateInfo.CardState_SN = TIME_MAX;
			Rs485CardStateInfo.CardAction = 0x03;
		}
		Rs485CardStateInfo.CardState_Tick = SysTick_1s;
		Ret = RS485OCCUPYTIME;
		temp_flag = 0x01;
	}

	//旧协议定期广播
	if((SysTick_1s - Rs485CardStateInfo.CardState_Tick > 20) && (Rs485CardStateInfo.CardAction == 0x03))
	{
		Rs485CardStateInfo.CardState_Tick = SysTick_1s;
		BLW_CardState_Send(BUS_Public.port);
		Rs485CardStateInfo.CardAction = 0x04;        //切换至新协议定期广播
		Ret = RS485OCCUPYTIME;
		temp_flag = 0x01;
	}
	
	//新协议定期广播
	if((SysTick_1s - Rs485CardStateInfo.CardState_Tick > 20) && (Rs485CardStateInfo.CardAction == 0x04))
	{
		Rs485CardStateInfo.CardState_Tick = SysTick_1s;
		BLW_CardState_New_Send(BUS_Public.port);
		Rs485CardStateInfo.CardAction = 0x03;        //切换至旧协议定期广播
		Ret = RS485OCCUPYTIME;
		temp_flag = 0x01;
	}

	
	
	if(temp_flag != 0x00)
	{
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CardStateInfo, sizeof(RS485_CARDSTATE_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAdd);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO),DevAdd+Dev_Privately);
	}
		
	return Ret;
}

//旧协议
void BLW_CardState_Send(uint8_t port)
{
	uint8_t sendbuff[5];
	
	sendbuff[0] = 0xFF;
	sendbuff[1] = 0x08;
	if(DevActionGlobal.DevActionU64Cond.EleState==0x02)
	{
		sendbuff[2] = 0x00;  //拔卡断电
	}
	else if(DevActionGlobal.DevActionU64Cond.EleState==0x01)
	{
		sendbuff[2] = 0x01;  //插卡取电
	}
	sendbuff[3] = 0x00;
	sendbuff[4] = SOR_CRC(sendbuff,4);
		/*发送函数*/
	MCU485_SendString(port,sendbuff,5);
}


//新协议
void BLW_CardState_New_Send(uint8_t port)
{
	uint8_t sendbuff[10];
	
	sendbuff[0] = 0xFF;
	sendbuff[1] = 0x08;
	sendbuff[2] = 0x0A;
	if(DevActionGlobal.DevActionU64Cond.EleState==0x02)
	{
		sendbuff[3] = 0x00;  //拔卡断电
	}
	else if(DevActionGlobal.DevActionU64Cond.EleState==0x01)
	{
		sendbuff[3] = 0x01;  //插卡取电
	}
	
	SRAM_Read_Buff(&sendbuff[4],1,SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET);  //房态
	
	sendbuff[5] = 0x00;
	sendbuff[6] = 0x00;
	
	if( DevActionGlobal.SleepMode_State == 0x01 )    //2024-05-30
	{
		sendbuff[7] = 0x04;
	}
	else
	{
		sendbuff[7] = 0x00;//SRAM_Read_Byte(SRAM_Global_Sense_No);   //模式
	}
	
	NetCRC16(sendbuff,10);  //CRC校验
	
	MCU485_SendString(port,sendbuff,10);

}



void BLW_RS485_CardState_AddTo_ActivePort(void)
{
	Device_Public_Information_G BUS_Public;
	RS485_CARDSTATE_INFO Rs485CardStateInfo;       //插卡状态同步局部参数
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CardStateInfo,0,sizeof(RS485_CARDSTATE_INFO));
	
	BUS_Public.addr = 0x00;			//设备地址
	BUS_Public.type = Dev_RS485_CardState;		//设备类型
	BUS_Public.baud = 9600;			//设备发送波特率
	BUS_Public.retry_num = 0x00;		//设备数据重发次数
	BUS_Public.wait_time = 0xC8;		//设备数据发送等待回复时间 

	Rs485CardStateInfo.CardState_SN = TIME_MAX;
	
	BUS_Public.Protocol = 0x01;

	BUS_Public.port = Active_Port;
	
	switch(BUS_Public.Protocol)
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485CardStateInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485CardStateInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485CardStateInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: if(NULL!=RS485_DEV_PRO_FUN_04) RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485CardStateInfo);break;
		default:
			break;
	}

	switch(BUS_Public.port)
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));   
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
		default:
			break;
	}
	
}


void BLW_RS485_CardState_AddTo_PollingPort(void)
{
	
	Device_Public_Information_G BUS_Public;
	RS485_CARDSTATE_INFO Rs485CardStateInfo;       //插卡状态同步局部参数
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CardStateInfo,0,sizeof(RS485_CARDSTATE_INFO));
	
	BUS_Public.addr = 0x01;			//设备地址
	BUS_Public.type = Dev_RS485_CardState;		//设备类型
	BUS_Public.baud = 9600;			//设备发送波特率
	BUS_Public.retry_num = 0x00;		//设备数据重发次数
	BUS_Public.wait_time = 0xC8;		//设备数据发送等待回复时间 

	Rs485CardStateInfo.CardState_SN = TIME_MAX;
	
	BUS_Public.Protocol = 0x02;

	BUS_Public.port = Polling_Port;
	
	switch(BUS_Public.Protocol)
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485CardStateInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485CardStateInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485CardStateInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: if(NULL!=RS485_DEV_PRO_FUN_04) RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485CardStateInfo);break;
		default:
			break;
	}

	switch(BUS_Public.port)
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CardStateInfo,sizeof(RS485_CARDSTATE_INFO));   
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
		default:
			break;
	}
	
	
}
