/**
  ******************************************************************************
  * @file    BLV_485_Dev_C5RELAYFun.c
  * @author  BLW RCU  development Team
  * @version SongHan
  * @date    2022年03月27日
  * @brief  
	*    C5RELAY继电器扩展模块 最多24路继电器
  ******************************************************************************
  */



#include "BLV_485_Dev_C5RELAYFun.h"
#include "string.h"
#include "SPI_SRAM.h"
#include "usart.h"
#include "check_fun.h"
#include "DBG.h"
#include "rw_logging.h"
#include "SRAM_Variable_Address.h"
#include "Log_api.h"
#include "BLV_Dev_Action.h"
#include "PC_DeviceTest_Fun.h"
#include "BLV_BUS_Dev_C5IOFun.h"


/*C5RELAY扩展板驱动代码*/

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

#define   C5EXPANDTYPE           0xF1	    //C5RELAY类型
#define C5RelayAddrDefault       0x01   //默认为1地址  与外设通讯仍然用默认地址

#define C5RELAYSnMin                 0x00            //最小Sn号
#define C5RELAYSnMax                 0x0F            //最大Sn号

/*本地函数调用开始*/
uint8_t BLW_C5RELAYCycleCtrl(uint32_t dev_addr); 
uint8_t BLW_Rs485_C5RELAY_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len);
void BLW_Rs485_C5RELAY_Ctrl(Device_Public_Information_G *BUS_Public, NOR_HVOUT_INFO* DevHVoutInfo, BUS_C5IO_INFO *C5IO_Info);
void BLW_Rs485_C5RELAY_Read(Device_Public_Information_G *BUS_Public, NOR_HVOUT_INFO* DevHVoutInfo, BUS_C5IO_INFO *C5IO_Info);
/*本地函数调用结束*/

/*******************************************************************************
* Function Name  : BLW_RS485_C5RELAY_Data_Init 
* Description    : 添加设备到链表 - 轮询设备
* Input          : 
	type	: 添加的设备类型
	addr	: 添加的设备地址
	polling_cf		：设备的轮询数据发送回调函数
	processing_cf	：设备的数据处理回调函数
* Return         : None
*******************************************************************************/
void BLW_RS485_C5RELAY_Data_Init(Device_Public_Information_G *BUS_Public, NOR_HVOUT_INFO *DevHVoutInfo)
{
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"%s",__func__);
	
	BUS_Public->polling_cf = (uint32_t)&BLW_C5RELAYCycleCtrl;
	BUS_Public->processing_cf = (uint32_t)&BLW_Rs485_C5RELAY_Check;
	
	/* 继电器需要知道CSIO的设备地址，才能控制继电器
		现在将这个获取CSIO地址放到设备全部初始化完成后，在去查找CSIO的设备地址，保存到该继电器设备中。
		查找函数：Dev_Coord_Get*/
	//DevHVoutInfo->DevC5IOAddr = Find_AllDevice_List_Information(DEV_C5IO_Type, 0x00);
	
}



/*******************************************************************************
* Function Name  : BLW_C5RELAYCycleCtrl 
* Description    : BLWC5RELAY扩展板轮询兼控制发送函数
*******************************************************************************/
uint8_t BLW_C5RELAYCycleCtrl(uint32_t dev_addr) 
{
	uint8_t i;     //用于遍历所有回路
	uint8_t Ret = RS485OCCUPYNOTIME;
	uint8_t keep_flag = 0;
	
	Device_Public_Information_G BUS_Public;	
	NOR_HVOUT_INFO DevHVoutInfo;
	Device_Public_Information_G BUS_PublicC5IO;   //共用		
	BUS_C5IO_INFO C5IO_Info;

	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),dev_addr);				
	SRAM_DMA_Read_Buff((uint8_t *)&DevHVoutInfo,sizeof(NOR_HVOUT_INFO),dev_addr+Dev_Privately);

	if(NULL == DevHVoutInfo.DevC5IOAddr)
	{
		return Ret;
	}
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_PublicC5IO,sizeof(Device_Public_Information_G),DevHVoutInfo.DevC5IOAddr);	//拷贝所有共有数据				
	SRAM_DMA_Read_Buff((uint8_t *)&C5IO_Info,sizeof(BUS_C5IO_INFO),DevHVoutInfo.DevC5IOAddr+Dev_Privately);
	
	if( (DevHVoutInfo.init_flag == 0x00) && (C5IO_Info.DI_Init_flag == 0x01) ){
		/*DI初始化完成 - 读取继电器状态，作为初始化状态*/
		DevHVoutInfo.init_flag = 0x01;
		
		for(i = 0; i < DevHVoutInfo.HVoutLoopValidNum; i++)
		{
			if( (C5IO_Info.Relay_Level_Actual_Start & (0x01<<i)) != 0x00 )
			{
				DevHVoutInfo.DevHVoutState[i] = 0x01;
				DevHVoutInfo.DevHVoutStateLast[i] = 0x01;
				
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"继电器 初始化:第%d路 开", i);
			}else {
				DevHVoutInfo.DevHVoutState[i] = 0x00;
				DevHVoutInfo.DevHVoutStateLast[i] = 0x00;
				
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"继电器 初始化:第%d路 关", i);
			}
		}
		
		keep_flag = 0x01;
	}
	
	for(i = 0; i < DevHVoutInfo.HVoutLoopValidNum; i++)
	{
		if( DevHVoutInfo.DevHVoutStateLast[i] != DevHVoutInfo.DevHVoutState[i] )
		{
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"继电器控制标志置位:第%d路", i);			
			
			DevHVoutInfo.DevChangeFlag |= 0x01 << i;
			DevHVoutInfo.HVoutCtrlCnt = REPEATSENDTIMEMAX;
			DevHVoutInfo.DevHVoutStateLast[i] = DevHVoutInfo.DevHVoutState[i];//同步
			
			keep_flag = 0x01;
		}
	}

	if(keep_flag == 0x01)
	{
		BLW_Rs485_C5RELAY_Ctrl(&BUS_Public, &DevHVoutInfo, &C5IO_Info);           //9路控制，状态控制
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&DevHVoutInfo, sizeof(NOR_HVOUT_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&DevHVoutInfo,sizeof(NOR_HVOUT_INFO),dev_addr+Dev_Privately);
		
		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),DevHVoutInfo.DevC5IOAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&C5IO_Info,sizeof(BUS_C5IO_INFO),DevHVoutInfo.DevC5IOAddr+Dev_Privately);		
	}

	
	return Ret;
}

#define RECDATALENMAX   0x28   //接收数据最大长度

#define IsMyData     0x00  
#define IsNotMyData  0x01
/*******************************************************************************
* Function Name  : BLW_Rs485_C5RELAY_Check 
* Description    : BLWC5RELAY扩展板接收数据处理函数
* Input          : 
	dev_addr	: 设备信息地址
	data_addr	: 数据地址
	len			：数据长度
* Return         : 
	0x00：处理成功
	0x01：处理失败
*******************************************************************************/
uint8_t BLW_Rs485_C5RELAY_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len)
{
	uint8_t rev = IsNotMyData;


	return rev;
}

#define C5EXPANDREADLEN    7    //继电器状态读取报文
/**
	* @name BLW  集中扩展板控制函数
	* @para
	*   dev_addr     设备起始地址   
	* @return         无
  * @attention      发送循环里调用，变量已经被判断
	*/
void BLW_Rs485_C5RELAY_Read(Device_Public_Information_G *BUS_Public, NOR_HVOUT_INFO* DevHVoutInfo, BUS_C5IO_INFO *C5IO_Info)
{
	
}


#define C5EXPANDCTRLLEN    13    //扩展板控制报文
/**
	* @name BLW  集中扩展板控制函数
	* @para
	*   dev_addr     设备起始地址   
	* @return         无
  * @attention      发送循环里调用，变量已经被判断
	*/
void BLW_Rs485_C5RELAY_Ctrl(Device_Public_Information_G *BUS_Public, NOR_HVOUT_INFO* DevHVoutInfo, BUS_C5IO_INFO *C5IO_Info)
{
	/*将控制数据拷贝到CSIO中*/
	if( DevHVoutInfo->HVoutLoopValidNum >= HVoutNumMAX )	DevHVoutInfo->HVoutLoopValidNum = HVoutNumMAX;		//防止溢出
		
	for(uint8_t i = 0; i < DevHVoutInfo->HVoutLoopValidNum; i++)
	{
		if( (DevHVoutInfo->DevChangeFlag & (0x01 << i)) != 0x00 )
		{
			switch(DevHVoutInfo->DevHVoutState[i])
			{
				case 0x01:
					C5IO_Info->Relay_Control[i] = BUS_C5IO_OUT_HIGH;
					C5IO_Info->Relay_Control_Flag |= 0x00000001<<i;

					break;
				case 0x00:
					C5IO_Info->Relay_Control[i] = BUS_C5IO_OUT_LOW;
					C5IO_Info->Relay_Control_Flag |= 0x00000001<<i;
					break;
			}
			
			DevHVoutInfo->DevChangeFlag &= ~(0x01<<i);
		}
	}
	
}





