/**
  ******************************************************************************
  * @file    BLV_Nor_Dev_LVinputFun.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2021年11月04日
  * @brief   弱电输入初始化   设备弱电输入控制
	* @attention 设备弱电输入
	*									输入检测：  有
	*                 输入类型：  有	
	*                 执行函数：  无		
	*            			执行方式：  无
	*															 
	*															
  ******************************************************************************
  */
  

#include "includes.h"

#include "BLV_Nor_Dev_LVinputFun.h"

void Dev_LVinput_Dis(uint32_t DevAddr);
uint8_t Dev_LVinput_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType);


/*弱电输入新增到普通设备链表*/
void BLV_Nor_Dev_LVinput_Init(uint8_t devaddr, uint16_t LoopMax)
{
	Device_Public_Information_G BUS_Public;
	NOR_LVINPUT_INFO DevLVinputInfo;       //弱电输入局部变量
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&DevLVinputInfo,0,sizeof(NOR_LVINPUT_INFO));
	
	BUS_Public.addr = devaddr;			//设备地址
	BUS_Public.type = Dev_Host_LVinput;		//设备类型
//	BUS_Public.port = Active_Port;			//设备发送端口
//	BUS_Public.baud = 9600;			//设备发送波特率
//	BUS_Public.retry_num = 0x03;		//设备数据重发次数
//	BUS_Public.wait_time = 0x0064;		//设备数据发送等待回复时间
//	BUS_Public.polling_cf = (uint32_t)&BLW_Touch_SwitchCycleDis;
//	BUS_Public.processing_cf = (uint32_t)&BLW_Rs485_Touch_Swi_Check;
	
	BUS_Public.DevFunInfo.Dev_Data_Process = Dev_LVinput_Dis;                 //
	BUS_Public.DevFunInfo.Dev_Input_Type_Get = Dev_LVinput_InType_Get;        //
	
	if(LoopMax > LVINPUTNUMMAX)
	{
		 DevLVinputInfo.LVinputValidNum = LVINPUTNUMMAX;
	}
	else
	{
		DevLVinputInfo.LVinputValidNum = LoopMax;  //C1_LVINPUTNUMMAX;
	}
	DevLVinputInfo.DevC5IOAddr = Find_AllDevice_List_Information(DEV_C5IO_Type, 0x00);
	Add_Nor_Device_To_List2(&BUS_Public,(uint8_t *)&DevLVinputInfo,sizeof(NOR_LVINPUT_INFO));
}


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

uint8_t Dev_LVinput_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType)
{
	Device_Public_Information_G BUS_Public;   //共用	
	NOR_LVINPUT_INFO DevLVinputInfo;       //弱电输入局部变量
	uint8_t Ret = CtrlInvalid;         //控制无效
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&DevLVinputInfo,sizeof(NOR_LVINPUT_INFO),DevAddr+Dev_Privately);	/*拷贝设备私有信息*/
	
	if(DevInputLoop >= DevLVinputInfo.LVinputValidNum)
	{
		return Ret;
	}   
	   
	if(DevInputType == DevLVinputInfo.DevReadBuf[DevInputLoop])  //找到类型
	{
		DevLVinputInfo.DevReadBuf[DevInputLoop] = 0x00;							//将动作清空
		Ret = CtrlValid;
	}
	
	if(CtrlValid == Ret)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"%s %d: %d 动作清空",__func__,DevInputLoop, DevInputType);
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&DevLVinputInfo, sizeof(NOR_LVINPUT_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&DevLVinputInfo,sizeof(NOR_LVINPUT_INFO),DevAddr+Dev_Privately);
				
	}
	
	return Ret;
	
}

/**
*@name 弱电输入扫描函数
*@para
*  DevAddr      设备地址
*@brief 拿到扫描按键的实时状态，并转换为动作
*/

void Dev_LVinput_Dis(uint32_t DevAddr)
{
	Device_Public_Information_G BUS_PublicLVinput;   //共用
	NOR_LVINPUT_INFO DevLVinputInfo;       //弱电输入局部变量
	Device_Public_Information_G BUS_PublicC5IO;   //共用		
	BUS_C5IO_INFO C5IO_Info;
	uint8_t KeepFlag = 0x00;

	if(NULL == DevAddr)
	{
		return ;
	}
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_PublicLVinput,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据			
	SRAM_DMA_Read_Buff((uint8_t *)&DevLVinputInfo,sizeof(NOR_LVINPUT_INFO),DevAddr+Dev_Privately); 
	
	if(NULL == DevLVinputInfo.DevC5IOAddr)
	{
		return ;
	}
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_PublicC5IO,sizeof(Device_Public_Information_G),DevLVinputInfo.DevC5IOAddr);	//拷贝所有共有数据			
	SRAM_DMA_Read_Buff((uint8_t *)&C5IO_Info,sizeof(BUS_C5IO_INFO),DevLVinputInfo.DevC5IOAddr+Dev_Privately);
	
	for(uint8_t i = 0;i<C5IO_DI_CH_MAX;i++)
	{
		switch((C5IO_Info.DI_Type[i] & 0x0F))
		{
			case BUS_C5IO_DI_Key_Type:	
				if(C5IO_Info.DI_Start[i] != 0x00)  //按键有效
				{
					KeepFlag = 0x01;
					DevActionGlobal.Devi = BUS_PublicLVinput.DevCoord;     //直接跳到指定的下标去处理
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"%s Key_Type:%d 回路:%d 状态:%d",__func__, (C5IO_Info.DI_Type[i] & 0x0F), i, C5IO_Info.DI_Start[i]);
				
					DevLVinputInfo.DevReadBuf[i] = C5IO_Info.DI_Start[i];
					DevLVinputInfo.DevReadBufLast[i] = C5IO_Info.DI_Start[i];
					
					if(C5IO_Info.DI_Start[i]==0x02)     //2023-10-09
					{
						DevActionGlobal.InputType = BUS_PublicLVinput.type;         
						DevActionGlobal.InputAddr = BUS_PublicLVinput.addr;           
						DevActionGlobal.InputLoop = i;                                
					}else if(C5IO_Info.DI_Start[i]==0x03)
					{
						DevActionGlobal.InputType = 0xff;           
						DevActionGlobal.InputAddr = 0x00;           
						DevActionGlobal.InputLoop = 0x00;                         
					}
					
					/*测试状态上报*/
					if(g_pc_test.test_flag == 0x01)
					{
						uint8_t ack_buff[5] = {0};
										
						ack_buff[(i/4)] = (C5IO_Info.DI_Start[i]&0x03) << (i%4)*2;
						
						//Dbg_Print(DBG_BIT_LOGIC_STATUS_bit,"上报串口测试\r\n");
						
						BLV_PC_Testing_Data_Reported2(0x01,DEV_C5IO_Type,0x00,ack_buff,4);
					}else if(g_pc_test.test_flag == 0x11)
					{
						uint8_t ack_buff[8] = {0};
						ack_buff[0] = g_pc_test.test_flag;
						ack_buff[1] = DEV_C5IO_Type;
						ack_buff[2] = 0x00;
						
						ack_buff[3 + (i/4)] = (C5IO_Info.DI_Start[i]&0x03) << (i%4)*2;
						
						//Dbg_Print(DBG_BIT_LOGIC_STATUS_bit,"上报PC测试\r\n");
						Udp_Internal_PC_Testing_Reported(ack_buff,0x07,g_pc_test.pc_ip,g_pc_test.pc_port);
					}
					C5IO_Info.DI_Start[i] = 0;	 //按键类型产生动作
				}
				break;
			case BUS_C5IO_DI_Pir_Type:
			case BUS_C5IO_DI_Dry_Type:
				/*
					干节点与PIR类型，需要初始化状态;按键类型，因为是动作事件，有事件就需要处理，不需要初始化状态
				*/
				if( (C5IO_Info.DI_Start[i] != C5IO_Info.DI_LastStart[i]) || ( (DevLVinputInfo.Dev_Init_Flag == 0x00) && (C5IO_Info.DI_Init_flag == 0x01) ) )
				{
					KeepFlag = 0x01;
					C5IO_Info.DI_LastStart[i] = C5IO_Info.DI_Start[i];
								
					switch(C5IO_Info.DI_Start[i])
					{
						case 0x00:    //释放
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"%s,Loop:%d Release",__func__, i);
							
							DevLVinputInfo.DevReadBuf[i] = 0x00;
							DevLVinputInfo.DevReadBufLast[i] = KeyRelease;
						
							if(DevLVinputInfo.Dev_Init_Flag == 0x01)
							{
								DevLVinputInfo.DevReadBuf[i] = KeyRelease;				//初始化完成后，才赋值动作
								
								DevActionGlobal.Devi = BUS_PublicLVinput.DevCoord;     //直接跳到指定的下标去处理
								DevActionGlobal.InputType = 0xff;      //2023-10-09   
								DevActionGlobal.InputAddr = 0x00;      //2023-10-09    
								DevActionGlobal.InputLoop = 0x00;      //2023-10-09
							}
							break;
						case 0x01:    //按下
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"%s,Loop:%d Press",__func__, i);						
							
							DevLVinputInfo.DevReadBuf[i] = 0x00;
							DevLVinputInfo.DevReadBufLast[i] = KeyPress;
							DevLVinputInfo.HoldTick[i] = SysTick_1s;
						
							if(DevLVinputInfo.Dev_Init_Flag == 0x01)
							{
								DevLVinputInfo.DevReadBuf[i] = KeyPress;				//初始化完成后，才赋值动作
								
								DevActionGlobal.Devi = BUS_PublicLVinput.DevCoord;     //直接跳到指定的下标去处理
								DevActionGlobal.InputType = BUS_PublicLVinput.type;      //2023-10-09    
								DevActionGlobal.InputAddr = BUS_PublicLVinput.addr;      //2023-10-09  
								DevActionGlobal.InputLoop = i;                           //2023-10-09
							}
							break;
					}
					
					/*测试状态上报*/
					if(g_pc_test.test_flag == 0x01)
					{
						uint8_t ack_buff[5] = {0};
										
						ack_buff[(i/4)] = (C5IO_Info.DI_Start[i]&0x03) << (i%4)*2;
						
						//Dbg_Print(DBG_BIT_LOGIC_STATUS_bit,"上报串口测试\r\n");
						
						BLV_PC_Testing_Data_Reported2(0x01,DEV_C5IO_Type,0x00,ack_buff,4);
					}else if(g_pc_test.test_flag == 0x11)
					{
						uint8_t ack_buff[8] = {0};
						ack_buff[0] = g_pc_test.test_flag;
						ack_buff[1] = DEV_C5IO_Type;
						ack_buff[2] = 0x00;
						
						ack_buff[3 + (i/4)] = (C5IO_Info.DI_Start[i]&0x03) << (i%4)*2;
						
						//Dbg_Print(DBG_BIT_LOGIC_STATUS_bit,"上报PC测试\r\n");
						Udp_Internal_PC_Testing_Reported(ack_buff,0x07,g_pc_test.pc_ip,g_pc_test.pc_port);
					}
				}
				break;
		}

		//2024-06-13  增加针对干接点触发时定期1s触发并保持机制
		if( ( ( (C5IO_Info.DI_Type[i] & 0x0F) == BUS_C5IO_DI_Dry_Type ) && (DevLVinputInfo.DevReadBuf[i] == 0x00) \
			&& (SysTick_1s > DevLVinputInfo.HoldTick[i] + 1) && (DevLVinputInfo.DevReadBufLast[i] == KeyPress) ) )
		{
			DevLVinputInfo.HoldTick[i] = SysTick_1s;
			DevLVinputInfo.DevReadBuf[i] = KeyHold;
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"%s Loop:%d Hold",__func__,i);
			KeepFlag = 0x01;			
		}
	}
	
	
	if(0x01 == KeepFlag)
	{
		if( DevLVinputInfo.Dev_Init_Flag == 0x00 )
		{
			DevLVinputInfo.Dev_Init_Flag = 0x01;	
		}
		
		BUS_PublicLVinput.check = 0x00;
		BUS_PublicLVinput.check = DoubleData_CheckSum((uint8_t *)&BUS_PublicLVinput, sizeof(Device_Public_Information_G), (uint8_t *)&DevLVinputInfo, sizeof(NOR_LVINPUT_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_PublicLVinput, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&DevLVinputInfo,sizeof(NOR_LVINPUT_INFO),DevAddr+Dev_Privately);
		
		/*保存C5IO的数据*/		
		BUS_PublicC5IO.check = 0x00;
		BUS_PublicC5IO.check = DoubleData_CheckSum((uint8_t *)&BUS_PublicC5IO, sizeof(Device_Public_Information_G), (uint8_t *)&C5IO_Info, sizeof(BUS_C5IO_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_PublicC5IO, sizeof(Device_Public_Information_G),DevLVinputInfo.DevC5IOAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&C5IO_Info,sizeof(BUS_C5IO_INFO),DevLVinputInfo.DevC5IOAddr+Dev_Privately);
	}
	
	
}



