#ifndef _MODBUS_H
#define _MODBUS_H
 

/*错误应答码定义*/

#define MODBUS_CMD_NUM  120
#define MODBUS_INF_MAX  200

#define MODBUS_TYPE_YX 1
#define MODBUS_TYPE_YC 2
#define MODBUS_TYPE_YK 3
#define MODBUS_TYPE_DD 4

#define MODBUS_INF_DI     1
#define MODBUS_INF_NUM  2
#define MODBUS_INF_BITS  3
#define MODBUS_INF_SENDADDR 4


typedef struct MODBUS_CMD  // modbus规约处理结构体
{
	WORD    slaveaddr;	 //装置地址
	WORD    sendaddr;	//发送地址
	BYTE    cmd;	//命令码
	BYTE     type;
	WORD    di;          //点号
	WORD    num;     //数量
	BYTE      bitbytes;  //
	BYTE      readbit;
	bool       byxfirst;
}MODBUS_CMD_DEF;

typedef struct MODBUS_EXT_INF  // modbus规约信息附加结构体
{
	WORD    slaveaddr;	 //装置地址
	BYTE      type;
	DWORD   val;          //点号
}MODBUS_EXT_INF;


typedef struct MODBUS  // 101规约处理结构体
{
	BYTE	chnl;
	BYTE       type;
	BYTE	nTypeCounter;            //接受帧类型	
	WORD	nRecvLenth;			//通道A 接收到数据计数器
	WORD	nRecvCnt;                  //有效数据记
	WORD	nRecvCounter;
	WORD	slaveaddr;
	bool		bData;
	bool        bRecvOk;
	BYTE      nSendCnt;
	BYTE   recvbuf[512];  // 101规约，接收的报文，最大40个字节
	BYTE *sendbuf;
	WORD    readdi;

	DWORD retrytime;
	DWORD sendinteraltime;
	
	BYTE      yxcmd;
	BYTE      yccmd;
	BYTE     ykcmd;
	BYTE      ddcmd;
	BYTE      yxbitbytes;
	BYTE      ycbitbytes;
	BYTE      ykbitbytes;
	BYTE      ddbitbytes;
	BYTE      yksendindex;
	BYTE      readbit;
#ifdef MODBUS_YX_REG_NUM
	/*遥信寄存器个数的取值（针对遥信按位取的情况）：
	如果为0，则寄存器数量依据点号的范围判断（例如读取0X20~0X35范围内的若干个遥信，则起始地址为0X20，寄存器个数为2）；
	如果为1，则寄存器数量=最大点号-最小点号，可以理解为遥信个数（例如读取0X20~0X35范围内的若干个遥信，则起始地址为0X20，寄存器个数为21）；*/
	BYTE	  yxregnum;
#endif

	WORD    coiladdr;
	WORD    yc_rate;
	WORD    ykval_h; //遥控合
	WORD    ykval_f; //遥控分
	bool       bcfg;
	BYTE cmd_dinum;
	BYTE cmd_datnum;
	BYTE dat_dir;
	
	BYTE      cmdnum;
	BYTE      bCurrent;
	MODBUS_CMD_DEF tcmd[MODBUS_CMD_NUM];

	BYTE     infnum;
	MODBUS_EXT_INF tinf[MODBUS_INF_MAX];

	// 遥控发送标志
	// 每bits代表一个开关，bit0代表公共，一共1个公共和31个开关。
	u32 yk_send_flag;	
	DWORD	dWaitTime;	//发送间隔
	DWORD   dsendtime;	
	REMOTEYKSTATUS tyk;

}MODBUS_DEF;

void modbus_Applay(MODBUS_DEF *pt);
void modbus_Recv(MODBUS_DEF *pt,unsigned char byRevData);
void modbus_AutoTimer(MODBUS_DEF *pt);
void modbus_Init(MODBUS_DEF *pt,BYTE chnl);

extern BYTE  MoDusCRCtableHi[] ; // Modbus 高位校验码
extern BYTE  MoDusCRCtableLo[];
WORD Modbus_CRC16(BYTE *inbytes, WORD CRCnumber);  // 返回，低字节在高位


#endif 


