//=================================================//
#define	ALLOCATE_EXTERN
#include "stdio.h"
#include "bsp.h"
#include "typedef.h"
#include "ModBusRTUSlave.h"
#include "intrins.h"
//==============接口定义==========================

void load_set_from_slave(void);

bit wait_slave_res = 0;
u8 prev_board=0,cur_board=1;
u8 cur_board_sid=1;
u8 modbus_send_buf[20]={0};
u16 regIndex;
void deal_modbusrtu_master(u8 *recvData,u8 datalen)
{
	u16 index,i;
	u16 ioValue;
	if(recvData[0] == cur_board_sid)//如果是正确的回复
	{
		if(datalen == 8 && recvData[1] == 0x05){
			index=(cur_board_sid-1)+(cur_board-1)*6;
			if(index <= 7) Modbus_OutputIO[0] &= ~(1<<index);
			else if(index >7 && index <16) Modbus_OutputIO[1] &= ~(1<<(index%8));
			else Modbus_OutputIO[2] &= ~(1<<(index%8));
			wait_slave_res = 0;
			load_set_from_slave();
		}
		else if(recvData[1] == 0x06 && datalen==8  &&HoldReg_Changed==1)//修改下位机阈值
		{
			if(HoldReg_Board_stationId == 1) index = (HoldReg_BoardId-1)*81+HoldReg_Board_addr;
			else index = (HoldReg_BoardId-1)*81+11+(HoldReg_Board_stationId-2)*14+HoldReg_Board_addr;
			Modbus_HoldReg[index] = (u16)recvData[4]<<8;
			Modbus_HoldReg[index] |= recvData[5];
			wait_slave_res = 0;
			HoldReg_Changed = 0;
		}else if(recvData[1] == 0x02 && recvData[2] == 0x02){//读取下位机状态
			ioValue = (u16)recvData[4]<<8 | recvData[3];
			if(cur_board < 3){
				if(cur_board_sid == 1){
					index = (cur_board -1)*96;
					for(i = 0; i<11;i++){
						Set_InputIO_Value(index+i,(ioValue & (u16)(1<<i))?1:0);
					}
				}else{
					index = (cur_board -1)*96+11+(cur_board_sid -2)*14;
					for(i=0;i<14;i++)
					{
						Set_InputIO_Value(index+i,(ioValue & (u16)(1<<i))?1:0);
					}
				}
			}else{
				if(cur_board_sid == 1){
					index = 192;
					for(i = 0;i<8;i++){
						Set_InputIO_Value(index+i,(ioValue & (u16)(1<<i))?1:0);
					}
					index = 200;
					for(i=8;i<11;i++){
						Set_InputIO_Value(index+i,(ioValue & (u16)(1<<i))?1:0);
					}
				}else if( cur_board_sid==2){
					index = 211;
					for(i = 0;i<14;i++){
						Set_InputIO_Value(index+i,(ioValue & (u16)(1<<i))?1:0);
					}					
				}else if(cur_board_sid == 3){
					index = 225;
					for(i = 0;i<14;i++){
						Set_InputIO_Value(index+i,(ioValue & (u16)(1<<i))?1:0);
					}
				}else if(cur_board_sid == 4){
					Set_InputIO_Value(239,(ioValue & 0x0001)?1:0);
					Set_InputIO_Value(240,(ioValue & 0x0002)?1:0);
					index = 256;
					for(i = 2;i<14;i++){
						Set_InputIO_Value(index+i-2,(ioValue & (u16)(1<<i))?1:0);
					}
				}else{
					index = 268+(cur_board_sid-5)*14;
					for(i = 0;i<14;i++){
						Set_InputIO_Value(index+i,(ioValue & (u16)(1<<i))?1:0);
					}						
				}					
			}
			wait_slave_res = 0;
			if(cur_board_sid<6) cur_board_sid++;
			else
			{
				cur_board_sid=1;
				if(cur_board<3) cur_board++;
				else cur_board=1;
			}
		}
	}
}
//void load_set_from_flash(void)
//{
//	u16 i;
//	Flash_ReadArr(BOARD1_SET_ADD,126,(u8*)&Modbus_HoldReg[1]);
//	Modbus_HoldReg[0] = Modbus_HoldReg[1];
//	Modbus_HoldReg[64]=Modbus_HoldReg[63];
//	Flash_ReadArr(BOARD2_SET_ADD,126,(u8*)&Modbus_HoldReg[66]);
//	Modbus_HoldReg[65] = Modbus_HoldReg[66];
//	Modbus_HoldReg[129]=Modbus_HoldReg[128];
//	Flash_ReadArr(BOARD3_SET_ADD,126,(u8*)&Modbus_HoldReg[131]);
//	Modbus_HoldReg[130] = Modbus_HoldReg[131];
//	Modbus_HoldReg[194]=Modbus_HoldReg[193];
//	if(Modbus_HoldReg[0] == 0 || Modbus_HoldReg[0] == 0xFFFF)
//	{
//		for(i=0;i<195;i++){
//			Modbus_HoldReg[i] = 2048;
//		}
//		Flash_EraseBlock(BOARD1_SET_ADD);
//		Flash_WriteArr(BOARD1_SET_ADD,126,(u8*)&Modbus_HoldReg[1]);
//		Flash_EraseBlock(BOARD2_SET_ADD);
//		Flash_WriteArr(BOARD2_SET_ADD,126,(u8*)&Modbus_HoldReg[66]);
//		Flash_EraseBlock(BOARD3_SET_ADD);
//		Flash_WriteArr(BOARD3_SET_ADD,126,(u8*)&Modbus_HoldReg[131]);
//	}
//}
void send_collect_frame(void)
{
	u16 calCRC;
	
	modbus_send_buf[0]=cur_board_sid;
	modbus_send_buf[1]=0x02;
	modbus_send_buf[2]=0;
	modbus_send_buf[3]=0;
	modbus_send_buf[4]=0;
	modbus_send_buf[5]=14;
	calCRC=crc16(modbus_send_buf,6);
	modbus_send_buf[6]=(calCRC>>8)&0xFF;
	modbus_send_buf[7]=calCRC&0xFF;
	if(cur_board != prev_board)
	{
		bsp_uart2_init(cur_board);
		prev_board = cur_board;
	}
	wait_slave_res = 1;
	reset_timeout_countdown(50);
	bsp_uart2_send(modbus_send_buf,8,cur_board);
	
}
void build_slave_adj(u8 id)
{
	u16 calCRC;
	modbus_send_buf[0]=id;
	modbus_send_buf[1]=0x05;
	modbus_send_buf[2]=0;
	modbus_send_buf[3]=0;
	modbus_send_buf[4]=0;
	modbus_send_buf[5]=0xFF;
	calCRC=crc16(modbus_send_buf,6);
	modbus_send_buf[6]=(calCRC>>8)&0xFF;
	modbus_send_buf[7]=calCRC&0xFF;	
}
void workprocess(void)
{
	
	u16 calCRC;
	u8 i;
	u32 setSlaveAdjustCmd=((u32)(Modbus_OutputIO[2])<<16)|((u32)(Modbus_OutputIO[1])<<8) | Modbus_OutputIO[0];
	//1、检查输出开关量
	if(wait_slave_res == 0 && setSlaveAdjustCmd != 0)
	{
		for(i=0;i<18;i++)
		{
			if((setSlaveAdjustCmd>>i) & 0x00000001) break;
		}
		if(i!=18)
		{
			cur_board = i/6 +1;
			cur_board_sid = i%6+1;
			build_slave_adj(cur_board_sid);
			if(cur_board != prev_board)
			{
				bsp_uart2_init(cur_board);
				prev_board = cur_board;
			}
			wait_slave_res = 1;
			reset_timeout_countdown(50);
			bsp_uart2_send(modbus_send_buf,8,cur_board);
		}
	}
	//2、检查保持寄存器是否被修改
	if(HoldReg_Changed == 1 && wait_slave_res == 0)
	{
		if(HoldReg_BoardId != prev_board)
		{
			bsp_uart2_init(HoldReg_BoardId);
			cur_board=HoldReg_BoardId;
		}
		if(HoldReg_Board_stationId == 1) 
			regIndex = (HoldReg_BoardId-1)*81 + HoldReg_Board_addr;
		else
			regIndex = (HoldReg_BoardId-1)*81+11+(HoldReg_Board_stationId -2)*14 + HoldReg_Board_addr;
		modbus_send_buf[0]=HoldReg_Board_stationId;
		modbus_send_buf[1]=0x06;
		modbus_send_buf[2]=0;
		modbus_send_buf[3]=HoldReg_Board_addr;
		modbus_send_buf[4]=(HoldReg_new_value>>8)&0xFF;
		modbus_send_buf[5]=HoldReg_new_value&0xFF;
		calCRC=crc16(modbus_send_buf,6);
		modbus_send_buf[6]=(calCRC>>8)&0xFF;
		modbus_send_buf[7]=calCRC&0xFF;
		wait_slave_res = 1;
		prev_board=cur_board;
		cur_board_sid=HoldReg_Board_stationId;
		reset_timeout_countdown(50);		
		bsp_uart2_send(modbus_send_buf,8,prev_board);
	}

}
void build_read_slave_set(u8 id)
{
	u16 calCRC;
	modbus_send_buf[0]=id;
	modbus_send_buf[1]=0x03;
	modbus_send_buf[2]=0;
	modbus_send_buf[3]=0;
	modbus_send_buf[4]=0;
	modbus_send_buf[5]=14;
	calCRC=crc16(modbus_send_buf,6);
	modbus_send_buf[6]=(calCRC>>8)&0xFF;
	modbus_send_buf[7]=calCRC&0xFF;	
}
void load_set_from_slave(void)
{
	u32 cur_ms;
	u8 i,j,k;
	bit timeout = 0;
	for(i=1;i<4;i++)
	{
		bsp_uart2_init(i);
		for(j=1;j<7;j++)
		{
			cur_ms = g_clock_ms;
			build_read_slave_set(j);
			bsp_uart2_send(modbus_send_buf,8,i);
			timeout = 0;
			while( rs485_has_recv_timeout2() == 0)
			{
				if(g_clock_ms - cur_ms > 50){
					timeout = 1;
					break;
				}
			}
			if(timeout==0)
			{
				if(guc_Uartcnt2==33 && guc_Uartbuf2[0] == j && guc_Uartbuf2[1] == 0x03)
				{
					if(j==1){
						for(k=0;k<11;k++){
							Modbus_HoldReg[(i-1)*81+k] = ((u16)guc_Uartbuf2[3+k*2]<<8)|guc_Uartbuf2[4+k*2];
						}
					}else{
						for(k=0;k<14;k++)
						{
							Modbus_HoldReg[(i-1)*81+11+(j-2)*14+k] = ((u16)guc_Uartbuf2[3+k*2]<<8)|guc_Uartbuf2[4+k*2];
						}
					}
				}
			}
			delay_ms(50);
		}
		
	}
	cur_board = 1;

}
void main(void)
{
	bsp_init();
	Modbus_RTU_Init(guc_Uartbuf,guc_UartTxbuf,bsp_uart_send_buff);
	//load_set_from_flash();
	delay_ms(500);
	//读取各下位机阈值
	load_set_from_slave();
	delay_ms(500);
	load_set_from_slave();
	while(1)
	{
//		check_modbus_request_frame();
		if(ms100_flag)
		{
			ms100_flag = 0;
			if(wait_slave_res == 0) send_collect_frame();
		}
		if(s1_flag)
		{
			s1_flag = 0;
		}
		if(rs485_has_recv_timeout())
		{
			ModBusRtuSlave_Service(guc_Uartcnt);
			guc_Uartcnt = 0;
		}
		if(wait_slave_res ==1){//如果正在等待下位机回复
			if(rs485_has_recv_timeout2())
			{
				stop_timeout_countdown();
				deal_modbusrtu_master(guc_Uartbuf2,guc_Uartcnt2);
				guc_Uartcnt2=0;
			}
			if(timeout_flag==1)
			{
				wait_slave_res = 0;
				if(cur_board_sid<5) cur_board_sid++;
				else
				{
					cur_board_sid=1;
					if(cur_board<3) cur_board++;
					else cur_board=1;
				}				
			}
		}
		workprocess();
		hal_feed_dog();
	}
}

