/**
  ******************************************************************************
  * @file    BLV_485_Dev_Rotary_SwitchFun.c
  * @author  BLW RCU  development Team
  * @version YHF
  * @date    2024年01月26日
  * @brief  
	*    485旋钮开关驱动总表
	*    输入：有
	*    输出：有
  ******************************************************************************
  */


#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_BLVP1_Rotary_Switch.h"
#include "BLV_485_Dev_BLVP2_Rotary_Switch.h"

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

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

/*设备驱动宏定义开始*/
#define RS485_DEV_PRO_FUN_01    DevExistJudgge(RS485_Switch_Rotary_P1_Flag, BLVP1_485_Dev_Rotary_Switch_Init) 
#define RS485_DEV_PRO_FUN_02    DevExistJudgge(RS485_Switch_Rotary_P2_Flag, BLVP2_485_Dev_Rotary_Switch_Init) 
#define RS485_DEV_PRO_FUN_03    ((DevFunP)NULL)      
#define RS485_DEV_PRO_FUN_04    ((DevFunP)NULL)          
/*设备驱动宏定义结束*/

uint8_t Dev_Rotary_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType);
void Dev_Rotary_Output_Ctrl(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t DevAddr, uint16_t DevOutputLoop, uint16_t DevOutputType);
uint16_t Dev_Rotary_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop);



/*******************************************************************************
* @name  :  旋钮开关设备驱动总表
* @para  : 
*   DataLen :数据长度
*   Data：   数据数组
* @attention   : 将开关的所有设备参数传进来，
*
*******************************************************************************/

void BLW_RS485_Rotary_Switch_Init(uint16_t DataLen, uint8_t *Data)
{
	Device_Public_Information_G BUS_Public;
	RS485_SWI_INFO Rs485RotaryInfo;       //开关局部变量
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485RotaryInfo,0,sizeof(RS485_SWI_INFO));
	
	BUS_Public.addr = Data[1];			//设备地址
	BUS_Public.type = Data[0];		    //设备类型
//	BUS_Public.port = Active_Port;		//设备发送端口
	BUS_Public.baud = 9600;			    //设备发送波特率
	BUS_Public.retry_num = 0x00;		//设备数据重发次数
	BUS_Public.wait_time = 100;		    //设备数据发送等待回复时间    
//	BUS_Public.polling_cf = (uint32_t)&BLW_Touch_SwitchCycleDis;
//	BUS_Public.processing_cf = (uint32_t)&BLW_Rs485_Touch_Swi_Check;
	
	BUS_Public.DevFunInfo.Dev_Input_Type_Get = Dev_Rotary_InType_Get;
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = Dev_Rotary_Output_Ctrl;
	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = Dev_Rotary_Loop_State;
				
	Rs485RotaryInfo.SwtInputValidNum = 0x01;
	Rs485RotaryInfo.SwtOutputValidNum = 0x00;

	Rs485RotaryInfo.DevOffline = Rs485RotaryInfo.DevOfflineLast = DEV_IS_LINEUNINIT;   //在线状态初始化
	
	
	switch(Data[7])
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485RotaryInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485RotaryInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485RotaryInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: if(NULL!=RS485_DEV_PRO_FUN_04) RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485RotaryInfo);break;
	}

	switch(Data[2])
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO));   //将填充后的数据添加到链表
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
	}
}


/*******************************************************************************
* Function Name  : BLW_RS485_Rotary_Switch_For_Logic_Init 
* Description    : 开关初始化信息来自逻辑文件
*******************************************************************************/
void BLW_RS485_Rotary_Switch_For_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len)
{
	Device_Public_Information_G BUS_Public;
	RS485_SWI_INFO Rs485RotaryInfo;       //开关局部变量
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485RotaryInfo,0,sizeof(RS485_SWI_INFO));
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"%s -%d",__func__,dev_info->addr);	
	
	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 = 100;		//设备数据发送等待回复时间    
//	BUS_Public.polling_cf = (uint32_t)&BLW_Touch_SwitchCycleDis;
//	BUS_Public.processing_cf = (uint32_t)&BLW_Rs485_Touch_Swi_Check;
	
	BUS_Public.Protocol = dev_info->version;
	
	BUS_Public.DevFunInfo.Dev_Input_Type_Get = Dev_Rotary_InType_Get;
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = Dev_Rotary_Output_Ctrl;
	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = Dev_Rotary_Loop_State;
				
	
	Rs485RotaryInfo.SwtInputValidNum = dev_info->input_num;
	Rs485RotaryInfo.SwtOutputValidNum = dev_info->output_num;
	
	Rs485RotaryInfo.DevOfflineLast = DEV_IS_ONLINE;   //在线状态初始化
	Rs485RotaryInfo.DevOffline = Rs485RotaryInfo.DevOfflineLast;
	
	
	switch(BUS_Public.Protocol)
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485RotaryInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485RotaryInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485RotaryInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: if(NULL!=RS485_DEV_PRO_FUN_04) RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485RotaryInfo);break;
	}

	switch(dev_info->port)
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO));   //将填充后的数据添加到链表
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
	}
}





/*获取旋钮开关在线状态*/
uint8_t Get_Rotary_Switch_Online_Status(uint32_t devaddr)
{
	RS485_SWI_INFO Rs485RotaryInfo;       //开关局部变量
	
	/*拷贝设备私有信息*/
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO),devaddr+Dev_Privately);
	
	if(Rs485RotaryInfo.DevOffline == DEV_IS_ONLINE)
	{
		return 0x01;
	}
	return 0x02;
}


/**
*@name 开关输入检测函数
*@para
*  DevAddr      设备地址
*  DevInputLoop 回路输入地址  范围1~RS_SWITCH_CH_MAX  
*  DevInputType 输入类型
*/

uint8_t Dev_Rotary_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType)
{
	Device_Public_Information_G BUS_Public;   //共用
	RS485_SWI_INFO Rs485RotaryInfo;       //开关局部变量
	uint8_t Ret = CtrlInvalid;         //控制无效

	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);/*拷贝设备私有信息*/
	
	if(DevInputLoop >= RS_SWITCH_CH_MAX)
	{
		return Ret;
	}

	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"Dev_Rotary_InType_Get,Input:%02X  Read:%02X  Loop:%d",DevInputType,Rs485RotaryInfo.DevReadBuf[DevInputLoop],DevInputLoop);
	
	
	if(DevInputType == Rs485RotaryInfo.DevReadBuf[DevInputLoop])
	{
		Rs485RotaryInfo.DevReadBuf[DevInputLoop] = KeyNoAction;
		Ret = CtrlValid;
		
		//Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"旋钮开关动作清空");
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485RotaryInfo, sizeof(RS485_SWI_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);
	}
	
	return Ret;
}
/**
	*@name 开关输出控制函数
	*@para
	*  DevAddr      设备地址
	*  DevOutputLoop 回路输出地址  范围0~
	*  DevInputType 输入类型
	*/

void Dev_Rotary_Output_Ctrl(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t DevAddr, uint16_t DevOutputLoop, uint16_t DevOutputType)
{
//	uint8_t CtrlWay = 0x00;
//	uint8_t CtrlContect = 0x00;

	Device_Public_Information_G BUS_Public;   //共用	
	RS485_SWI_INFO Rs485RotaryInfo;       //开关局部变量
	uint8_t KeepFlag = 0x00;   //保存标志
	
	if(NULL == DevAddr)
	{
		return ;
	}
	
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);/*拷贝设备私有信息*/
	
//	if(DevOutputLoop >= Rs485RotaryInfo.SwtOutputValidNum)
//	{
//		return ;
//	}

//	
//	CtrlWay = DevOutputType&0x00ff;   //取低字节
//	CtrlContect = DevOutputType>>8;     //控制内容
	
//	switch(CtrlWay)  //不为0
//	{
//		case 0x05:      //设置旋钮调光上限
//			Rs485RotaryInfo.RL_Upper_limit = CtrlContect;
//		    KeepFlag = 0x01;
//			break;
//		case 0x06:      //设置旋钮调光下限
//			Rs485RotaryInfo.RL_Lower_limit = CtrlContect;
//		    KeepFlag = 0x01;
//			break;
//		default: 
//			break;	
//	}

	
	if(0x01 == KeepFlag)
	{ 
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485RotaryInfo, sizeof(RS485_SWI_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO),DevAddr+Dev_Privately);		
	}
	
}

/**
  * @name  指定回路状态得到
  * @param  
  *    devaddr             当前设备的地址
  *    DevOutputLoop       需要查找的服务信息回路
  * @retval 
  *    ret                 回路状态返回    1 开   2关   0为不存在
  * @brief

  */
uint16_t Dev_Rotary_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop)
{	
	RS485_SWI_INFO Rs485RotaryInfo;       //开关局部变量

	if(devaddr == 0x00)
		return 0x00;
	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485RotaryInfo,sizeof(RS485_SWI_INFO),devaddr+Dev_Privately);	
	
	if(DevOutputLoop >= Rs485RotaryInfo.SwtOutputValidNum)
	{
		return 0x00;
	}
	
	if(Rs485RotaryInfo.DevSendBuf[DevOutputLoop])
	{
		return 0x01;
	}
	else
	{
		return 0x02;
	}
	
}





