var SlaveCtr = new Object;
SlaveCtr.delay = 0;
SlaveCtr.superdelay = 20000;
SlaveCtr.uid = [];
SlaveCtr.pwd = [];
SlaveCtr.addr = 1;
SlaveCtr.state = [];
SlaveCtr.firmware = [];
SlaveCtr.amendv = 0;
SlaveCtr.regv = [];
SlaveCtr.cfire = 0.0;

var SlaveCmd = {
 A_ERROR_S		:          0 , //从机应答错误状态
 RA_WRITE_ID    :          1 , //主机写入UUID param=15字节
 RA_WRITE_PSW   :          2 , //主机写入密码 param=8字节
 RA_EQUAL_ID    :          3 , //主机验证UUID param=15字节
 RA_EQUAL_PSW   :          4 , //主机验证密码 param=8字节
 RA_SET_DELAY   :          5 , //主机设置单发雷管的延时 param=2字节
 RA_SET_ADDR    :          7 , //设置从机的通讯地址 param=2字节 或 15+2（广播通过UID设置地址）
 RA_OPER_CMD    :          8 ,  //主机发送操作命令 param=1字节
 RA_REQUEST_ACK :          9 , //主机发送的应答请求 param=0字节
 RA_SET_BAUDRATE:          10, //设置通讯速率 param=2字节
 R_SET_LOCAL    :          11, //设置使用位置 param=8字节
 R_SET_USETIME  :          12, //设置使用时间 param=2字节
 R_HEARTBEAT    :          13, //心跳包 param=0字节
 R_FACTORY_SET  :          14, //释放工厂模式 param=4字节
 UID_REQUEST    :          15, //利用UID进行访问，只能用广播访问 param = {UID+(10bit地址+6bit功能码)+功能码参数}
//#define UID_SEARCH               16 //UID搜索功功能码
 RA_EQUAL_UID_F :          17, //UID特征码验证
 RA_SETSUPER_T  :          18,//设置复位保存延时起爆时间
 RA_RAMSETTING  :          19, //运行配置 param = 4字节 bit0 应答数据1有效
 RA_REGISTER	:		   62, //读寄存器 
 WA_REGISTER	:		   63, //写4字节寄存器 
//操作命令
 CMD_READ_ID    :          1,   //主机读取UUID
 CMD_READ_PSW   :          2,   //主机读取PSWD
 CMD_READ_SYS_S :          3,   //主机读取系统状态
 CMD_READ_VERSION :        4,   //主机读取系统版本
 CMD_READ_LOCAL   :        5,   //读取位置信息
 CMD_READ_OPERTIME:        6,  //读取操作时间
 CMD_READ_ADDR    :        7,   //读取通讯地址
 CMD_READ_DELAY   :        8,   //主机读取延时设置
 CMD_READ_SYS_F   :        9,   //读取备份区的状态信息

 CMD_CHARGE       :        10,  //充电
 CMD_DISCHARGE    :        11,  //放电
 CMD_CLK_CHECK    :        12,  //时钟校准
 CMD_BLAST        :        13,  //起爆
 CMD_SLEEP        :        14, //强制休眠，不在监听总线
 CMD_INSPECT      :        15,  //巡检
 CMD_SYS_CHECK    :        16,  //执行自检
 CMD_READ_FEATURE :        17,  //读特征值
 CMD_STOP_CHARGE  :        18,  //停止充电
 CMD_FAC_CHECK1   :        19,  //工厂自检
 CMD_FAC_CHECK2   :        20,  //工厂自检
 CND_READ_AMEND   :        21,   //读校准值
 CMD_FAC_CHECK3   :        22,  //工厂自检
 CMD_READ_BUSV    :        23,  //读总线电压
 CMD_EQUEL_PWD    :        24,  //密码验证置位
 CMD_READ_COM     :        25,  //
 CMD_BOOTLOADER_RUN :      0xFE, //运行bootloader
 CMD_APP_ERASE    :        0xFC, //擦除APP
 CMD_APP_RUN      :        0xFD, //运行APP
};
/*
 * 异或校验
 */
SlaveCtr.Check8 =  function (src_data)
{
	var check = 0X00;
	for(i = 0; i < src_data.length; i++)
	{
		check ^= src_data[i];
		check &= 0xFF;
	}
	return check;
}
/*
 * 校验验证
 */
SlaveCtr.isCheck = function (src_data)
{
	var check = SlaveCheck8(src_data);
	if(check != 0)
	{
		return 0x0A;
	}
}
/*
 * rec_data 接收源
 * send_data 发送源
 * rtv 0x05 超时 0x00 通过 0x0A校验错误
 */
SlaveCtr.isAck =  function (rec_data,send_data)
{
	if(rec_data.length < 2)
		return 0x05;
	if(rec_data[0] == 0 && rec_data[1] == 0)
		return 0x00;
	if(rec_data[0] == send_data[0] && rec_data[1] == send_data[1])
		return 0x00;
	return 0X0A;
}
/*
 * addr 通讯地址
 * code 功能码
 * cmd  命令码
 * param 参数
 */
SlaveCtr.GetSlaveSendData =  function (addr,code,cmd,param)
{
	var head = 0xFFFF & ((addr << 6)|(code & 0X3F))
	var cmd_buf = [];
	cmd_buf[0] = head & 0xFF;
	cmd_buf[1] = (head >> 8) & 0xFF;
	if(code == 8)
	{
		cmd_buf[2] = cmd;
	}
	for(i = cmd_buf.length, count = 0; count < param.length;count++,i++)
	{
		cmd_buf[i] = param[count];
	}
	cmd_buf[cmd_buf.length]  = SlaveCheck8(cmd_buf);
	return cmd_buf;
}
SlaveCtr.Uint16ToArray = function(u16data)
{
	var param = [];
	param[0] = u16data & 0xFF;
	param[1] = (u16data  >> 8 )& 0xFF;
	return param;
	
}
SlaveCtr.ArrayToUint16 = function(buf,offset)
{
	var data = 0;
	data = (buf[offset + 1] & 0xFF)<< 8;
	data |= (buf[offset] & 0xFF);
	return data;
}
/*
 * RA_WRITE_ID
 * 
 */
SlaveCtr.WriteUID = function(addr,uid)
{
	return this.GetSlaveSendData(addr,SlaveCmd.RA_WRITE_ID,0,uid);
}
SlaveCtr.WritePwd = function(addr,pwd)
{
	return this.GetSlaveSendData(addr,SlaveCmd.RA_WRITE_PSW,0,pwd);
}
SlaveCtr.EquelUID = function(addr,ui)
{
	return this.GetSlaveSendData(addr,SlaveCmd.RA_EQUAL_ID,0,uid);
}
SlaveCtr.EquelPwd = function(addr,pwd)
{
	return this.GetSlaveSendData(addr,SlaveCmd.RA_EQUAL_PSW,0,pwd);
}
 
SlaveCtr.SetDelay = function(addr,delay)
{
	var param = this.Uint16ToArray(delay);
	return this.GetSlaveSendData(addr,SlaveCmd.RA_SET_DELAY,0,param);
}
SlaveCtr.SetAddr = function(slave_addr,uid)
{
	var param = this.Uint16ToArray(slave_addr);
	var len = uid.length;
	uid[len]   = param[0];
	uid[len+1] = param[1];
	return this.GetSlaveSendData(0,SlaveCmd.RA_SET_ADDR,0,uid);
}
 SlaveCtr.OperCmd = function(addr,cmd)
 {
 	var param = [];
 	return this.GetSlaveSendData(addr,SlaveCmd.RA_OPER_CMD,0,param);
 }
 SlaveCtr.RequestAck = function(addr)  
 {
  	var param = [];
 	return this.GetSlaveSendData(addr,SlaveCmd.RA_REQUEST_ACK,0,param);
 }
  
 SlaveCtr.UIDRequest = function(uid,code,cmd,param)
 {
 	var param = [];
 	var len = uid.length;
 	uid[len++] = code;
 	if(code == 8)
 	{
 		uid[len++] = cmd;
 	}
 	for(count = 0; count < param.length;count++)
 	{
 		uid[len++]  = param[count];
 	}
 	return this.GetSlaveSendData(0,SlaveCmd.UID_REQUEST,0,uid);
 }
 
SlaveCtr.EquelUIDFutrue = function(slave_addr,uid)
{
	var index1 = 0;
 	var us_temp = 0;
 	var uidfeatrue = [];
  //拷贝特征值
  uidfeatrue[0] = (buf[9] & 0xFF);
  //合并年月
  uidfeatrue[1] = (buf[3] & 0xFF) -  0x30;
  uidfeatrue[1] <<= 4;
  if(buf[5] > '0')
  {
     uidfeatrue[1] += 0x0A;
  }
  uidfeatrue[1] += ((buf[6] & 0xFF) - 0x30 );
  
  //特征码于日期调整
  buf[9] =  buf[8];
  buf[8] =  buf[7];
  //将日期和流水号转为3字节int
  us_temp = 0;
  for(index1 = 8; index1 < 15; index1++)
  {
    us_temp *= 10;
    us_temp +=  ((buf[index1] & 0xFF) - 0x30 );
  }
  for(index1 = 0; index1 < 3; index1++)
  {
    uidfeatrue[2+index1] = us_temp & 0xFF;
    us_temp >>= 8;
  }
  return this.GetSlaveSendData(slave_addr,SlaveCmd.RA_EQUAL_UID_F,0,uidfeatrue);
}

SlaveCtr.SetSuperTime = function(addr,delay)
{
	var param = this.Uint16ToArray(delay);
	return this.GetSlaveSendData(addr,SlaveCmd.RA_SETSUPER_T,0,param);
}
SlaveCtr.ReadReg = function(slave_addr,reg_addr,reg_len)
{
	reg_addr >>= 2;
	reg_addr &= 0xFF;
	var param = this.Uint16ToArray(reg_addr);
	param[2] = reg_len & 0xFF;
	return this.GetSlaveSendData(slave_addr,SlaveCmd.RA_REGISTER,0,param);
}
SlaveCtr.WriteReg = function(slave_addr,reg_addr,reg_len,erase_flag,data)
{
	reg_addr >>= 2;
	reg_addr &= 0xFF;
	var param = this.Uint16ToArray(reg_addr);
	param[2] = reg_len & 0xFF;
	param[3] = erase_flag & 0xFF;
	var len = 4;
	for(count = 0; count < data.length;count++)
	{
		param[len++] = data[count++];
	}
	return this.GetSlaveSendData(slave_addr,SlaveCmd.WA_REGISTER,0,param);
}

SlaveCtr.GetDelay = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0)
	{
		return rtv;
	}
	SlaveCtr.delay = SlaveCtr.ArrayToUint16(src_data,3);
	return 0;
}
SlaveCtr.GetUid = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0)
	{
		return rtv;
	}
	var uid = [];
	for(count = 0 ; count < 15; count++)
	{
		uid[count] = src_data[3+count];
		count++;
	}
	SlaveCtr.uid = uid;
	return 0;
}
SlaveCtr.GetPwd = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0)
	{
		return rtv;
	}
	var pwd = [];
	for(count = 0 ; count < 8; count++)
	{
		pwd[count] = src_data[3+count];
		count++;
	}
	SlaveCtr.pwd= pwd;
	return 0;
}
SlaveCtr.GetAddr = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0)
	{
		return rtv;
	}
	SlaveCtr.addr = SlaveCtr.ArrayToUint16(src_data,3);
	return 0;
}

SlaveCtr.GetState = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0){
		return rtv;
	}
	var state = [];
	for(count = 0 ; count < 4; count++)
	{
		state[count] = src_data[3+count];
		count++;
	}
	SlaveCtr.state= state;
	return 0;
}
SlaveCtr.GetFirmware = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0){
		return rtv;
	}
	var firmware = [];
	for(count = 0 ; count < 4; count++)
	{
		firmware[count] = src_data[3+count];
		count++;
	}
	SlaveCtr.firmware= firmware;
	return 0;
}

SlaveCtr.GetAmendV = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0)
	{
		return rtv;
	}
	var amendv = SlaveCtr.ArrayToUint16(src_data,3);
	if((amendv & 0X8000) > 0 )
	{
		amendv = (65536 - amendv) * -1;
	}
	SlaveCtr.amendv = amendv;
	return 0;
}

SlaveCtr.GetAmendV = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0)
	{
		return rtv;
	}
	var cfire = SlaveCtr.ArrayToUint16(src_data,3);
	cfire = (((cfire/4096) * 3.3)/0.43)*3.43;
	SlaveCtr.cfire = cfire;
	return 0;
}
SlaveCtr.GetRegData = function(src_data)
{
	var rtv = SlaveCtr.Check8(src_data);
	if(rtv != 0){
		return rtv;
	}
	var Regdata = [];
	var Reglen = src_data[4];
	for(count = 0 ; count < Reglen; count++)
	{
		Regdata[count] = src_data[5+count];
		count++;
	}
	SlaveCtr.regv= Regdata;
	return 0;
}

