2023-06-10 11:52:00 +08:00
|
|
|
#include "stdio.h"
|
|
|
|
#include "rtthread.h"
|
|
|
|
#include "board.h"
|
|
|
|
#include "mystdlib.h"
|
|
|
|
#include "list.h"
|
|
|
|
#include "mystring.h"
|
|
|
|
#include "signal.h"
|
|
|
|
#include "prot_uc.h"
|
|
|
|
#include "buff.h"
|
|
|
|
#include "bytearray.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "crc.h"
|
|
|
|
#include "dev_flash.h"
|
|
|
|
#include "codec.h"
|
2023-10-06 18:47:05 +08:00
|
|
|
#include "elec_det.h"
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*rc{ 协议编解码器,用于适配各种协议 }*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 二代批检仪协议解码
|
|
|
|
array_def *protu_decode(protu_def *p,array_def *data)
|
|
|
|
{
|
|
|
|
array_def *r=arr_creat();
|
|
|
|
param_check(r);
|
|
|
|
DBG_LOG("decode for checker");
|
|
|
|
str_set(p->str_err,"ok");
|
|
|
|
if(arr_length(data)<9)
|
|
|
|
{
|
|
|
|
// 主机一帧数据至少9字节
|
|
|
|
DBG_WARN("recv data len too less.");
|
|
|
|
str_set(p->str_err,"recv data len too less.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
if((arr_get(data,0)!=0x59)||(arr_get(data,1)!=0x6d))
|
|
|
|
{
|
|
|
|
// 帧头不对
|
|
|
|
DBG_WARN("frame head not 0x59 0x6d.");
|
|
|
|
str_set(p->str_err,"frame head not 0x59 0x6d.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
int len=arr_get(data,2)|(arr_get(data,3)<<8);
|
|
|
|
if(len==65535)
|
|
|
|
{
|
|
|
|
// 重新设置数据长度
|
|
|
|
len=arr_get(data,7)|(arr_get(data,8)<<8)|(arr_get(data,9)<<16)|(arr_get(data,10)<<24);
|
|
|
|
p->is_big_data=1;
|
|
|
|
}else{
|
|
|
|
p->is_big_data=0;
|
|
|
|
}
|
|
|
|
if(len+6!=arr_length(data))
|
|
|
|
{
|
|
|
|
// 如果长度不相等则产生了数据丢失
|
|
|
|
DBG_WARN("recv data have lossed.");
|
|
|
|
str_set(p->str_err,"recv data have lossed.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
uint8_t chk_a,chk_b;
|
|
|
|
crc_crc16(arr_data(data)+2,len+2,&chk_a,&chk_b);
|
|
|
|
if(chk_a!=arr_get(data,-2)||chk_b!=arr_get(data,-1))
|
|
|
|
{
|
|
|
|
// crc校验不对
|
|
|
|
DBG_WARN("recv data check error.h_crc=%02x %02x,crc=%02x %02x",chk_a,chk_b,arr_get(data,-2),arr_get(data,-1));
|
2023-12-26 18:08:59 +08:00
|
|
|
str_set(p->str_err,"recv data check error.");
|
2023-06-10 11:52:00 +08:00
|
|
|
}
|
2023-07-14 18:50:38 +08:00
|
|
|
int cmd_no=arr_get(data,5)|(arr_get(data,6)<<8);
|
2023-07-20 18:00:29 +08:00
|
|
|
// if(p->cmd_no==cmd_no)
|
|
|
|
// {
|
|
|
|
// // 重复的cmd_no
|
|
|
|
// DBG_WARN("duplicate sequence number.");
|
|
|
|
// str_set(p->str_err,"duplicate sequence number.");
|
|
|
|
// }
|
2023-08-18 18:53:09 +08:00
|
|
|
p->cmd_no=cmd_no;
|
2023-06-10 11:52:00 +08:00
|
|
|
p->cmd=arr_get(data,4);
|
2023-11-15 18:11:39 +08:00
|
|
|
p->silent=0;
|
2023-06-10 11:52:00 +08:00
|
|
|
// 数据负载
|
|
|
|
arr_delete(r);
|
|
|
|
if(p->is_big_data==0)
|
|
|
|
{
|
|
|
|
return arr_mid(data,7,len-3);
|
|
|
|
}else{
|
|
|
|
return arr_mid(data,11,len-7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 二代批检仪协议编码
|
|
|
|
array_def *protu_encode(protu_def *p,array_def *data)
|
|
|
|
{
|
|
|
|
array_def *t=arr_creat();
|
|
|
|
param_check(t);
|
|
|
|
uint16_t len=arr_length(data)+3;
|
|
|
|
|
|
|
|
arr_append(t,0x59);
|
|
|
|
arr_append(t,0x6d);
|
|
|
|
arr_append(t,0x43);
|
|
|
|
arr_append(t,len&0xff);
|
|
|
|
arr_append(t,len>>8);
|
|
|
|
arr_append(t,p->cmd);
|
|
|
|
arr_append(t,p->cmd_no&0xff);
|
|
|
|
arr_append(t,p->cmd_no>>8);
|
|
|
|
arr_appends_from(t,data);
|
|
|
|
uint8_t chk_a,chk_b;
|
|
|
|
crc_crc16(arr_data(t)+3,len+2,&chk_a,&chk_b);
|
|
|
|
arr_append(t,chk_a);
|
|
|
|
arr_append(t,chk_b);
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protuc_codec_export(ym_checker,protu_decode,protu_encode);
|
|
|
|
// 注码仪和批检仪协议相同
|
|
|
|
//protuc_codec_export(ym_coder2,protu_decode,protu_encode);
|
|
|
|
|
|
|
|
|
|
|
|
// 赋码仪协议解码
|
|
|
|
array_def *protu_decode2(protu_def *p,array_def *data)
|
|
|
|
{
|
|
|
|
array_def *r=arr_creat();
|
|
|
|
param_check(r);
|
|
|
|
DBG_LOG("decode for coder");
|
|
|
|
str_set(p->str_err,"ok");
|
|
|
|
if(arr_length(data)<6)
|
|
|
|
{
|
|
|
|
// 主机一帧数据至少9字节
|
|
|
|
DBG_WARN("recv data len too less.");
|
|
|
|
str_set(p->str_err,"recv data len too less.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
if((arr_get(data,0)!='Y')||(arr_get(data,1)!='m'))
|
|
|
|
{
|
|
|
|
// 帧头不对
|
|
|
|
DBG_WARN("frame head not 'Y' 'm'.");
|
|
|
|
str_set(p->str_err,"frame head not 'Y' 'm'.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
int len=arr_get(data,2)|(arr_get(data,3)<<8);
|
|
|
|
p->is_big_data=0;
|
|
|
|
if(len+6!=arr_length(data))
|
|
|
|
{
|
|
|
|
// 如果长度不相等则产生了数据丢失
|
|
|
|
DBG_WARN("recv data have lossed.");
|
|
|
|
str_set(p->str_err,"recv data have lossed.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
uint8_t chk_a,chk_b;
|
|
|
|
crc_sumcheck(arr_data(data)+4,len,&chk_a,&chk_b);
|
|
|
|
if(chk_a!=arr_get(data,-2)||chk_b!=arr_get(data,-1))
|
|
|
|
{
|
|
|
|
// crc校验不对
|
|
|
|
DBG_WARN("recv data check error.h_crc=%02x %02x,crc=%02x %02x",chk_a,chk_b,arr_get(data,-2),arr_get(data,-1));
|
|
|
|
str_set(p->str_err,"recv data check error.");
|
|
|
|
}
|
|
|
|
p->cmd_no=arr_get(data,5)|(arr_get(data,6)<<8);
|
|
|
|
p->cmd=arr_get(data,4);
|
2023-11-15 18:11:39 +08:00
|
|
|
p->silent=0;
|
2023-06-10 11:52:00 +08:00
|
|
|
// 数据负载
|
|
|
|
arr_delete(r);
|
|
|
|
if(p->is_big_data==0)
|
|
|
|
{
|
|
|
|
return arr_mid(data,7,len-3);
|
|
|
|
}else{
|
|
|
|
return arr_mid(data,11,len-7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 赋码仪协议编码
|
|
|
|
array_def *protu_encode2(protu_def *p,array_def *data)
|
|
|
|
{
|
|
|
|
array_def *t=arr_creat();
|
|
|
|
param_check(t);
|
|
|
|
uint16_t len=arr_length(data)+3;
|
|
|
|
|
|
|
|
arr_append(t,0x59);
|
|
|
|
arr_append(t,0x6d);
|
|
|
|
arr_append(t,0x43);
|
|
|
|
arr_append(t,len&0xff);
|
|
|
|
arr_append(t,len>>8);
|
|
|
|
arr_append(t,p->cmd);
|
|
|
|
arr_append(t,p->cmd_no&0xff);
|
|
|
|
arr_append(t,p->cmd_no>>8);
|
|
|
|
arr_appends_from(t,data);
|
|
|
|
uint8_t chk_a,chk_b;
|
|
|
|
crc_sumcheck(arr_data(t)+5,len,&chk_a,&chk_b);
|
|
|
|
arr_append(t,chk_a);
|
|
|
|
arr_append(t,chk_b);
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-10-12 23:37:12 +08:00
|
|
|
//protuc_codec_export(ym_coder,protu_decode2,protu_encode2);
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2023-12-07 22:56:07 +08:00
|
|
|
// 计算在第n为之前,bit为1的个数
|
|
|
|
static int calc_bit_num(int bits,int n)
|
|
|
|
{
|
|
|
|
int num=0;
|
|
|
|
for(int i=0;i<n;i++){
|
|
|
|
if(bits&(1<<i))
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
return num;
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
2023-10-06 18:47:05 +08:00
|
|
|
// 小板协议解码
|
|
|
|
array_def *protm_decode(protu_def *p,array_def *data)
|
|
|
|
{
|
|
|
|
array_def *r=arr_creat();
|
|
|
|
param_check(r);
|
|
|
|
str_set(p->str_err,"ok");
|
|
|
|
if(arr_length(data)<10)
|
|
|
|
{
|
|
|
|
DBG_WARN("recv data len too less.");
|
|
|
|
DBG_WARN("data=%s",str_temp(arr_string(data)));
|
|
|
|
str_set(p->str_err,"recv data len too less.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
uint8_t src=arr_get(data,4);
|
|
|
|
uint8_t dst=arr_get(data,5);
|
2023-11-15 18:11:39 +08:00
|
|
|
if((src!=0)||((dst!=elec_local_addr())&&(dst!=0x1f))){
|
2023-10-06 18:47:05 +08:00
|
|
|
DBG_WARN("src_addr/dst_addr not allowed.");
|
|
|
|
DBG_WARN("data=%s",str_temp(arr_string(data)));
|
|
|
|
str_set(p->str_err,"src_addr/dst_addr not allowed.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
uint16_t len=arr_get(data,2)|(arr_get(data,3)<<8);
|
|
|
|
uint8_t crc=crc_crc8(arr_data(data),arr_length(data)-1);
|
|
|
|
if(len!=arr_length(data))
|
|
|
|
{
|
|
|
|
// 如果长度不相等则产生了数据丢失
|
|
|
|
DBG_WARN("recv data have lossed.");
|
|
|
|
str_set(p->str_err,"recv data have lossed.");
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
uint16_t no=arr_get(data,7)|(arr_get(data,8)<<8);
|
|
|
|
uint16_t h_no=p->cmd_no;
|
|
|
|
if(no!=h_no)
|
|
|
|
{
|
|
|
|
// 发送一条指令等待其返回,此时流水号应相同
|
|
|
|
//DBG_WARN("slave_addr=%d cmd_no error:h_no=%d,no=%d.",src,h_no,no);
|
|
|
|
//str_set(p->str_err,"cmd no err.");
|
|
|
|
//return r;
|
|
|
|
}
|
|
|
|
if(crc!=arr_get(data,-1))
|
|
|
|
{
|
|
|
|
DBG_WARN("recv data crc check error:%02x,%02x.",crc,arr_get(data,-1));
|
|
|
|
str_set(p->str_err,"crc check err.");
|
|
|
|
}
|
|
|
|
p->cmd=arr_get(data,6);
|
2023-12-04 18:17:48 +08:00
|
|
|
arr_delete(r);
|
|
|
|
r=arr_mid(data,9,len-10);
|
2023-11-15 18:11:39 +08:00
|
|
|
if(dst==0x1f){
|
2023-12-04 18:17:48 +08:00
|
|
|
// 广播命令需判断额外字节
|
|
|
|
int self_addr=elec_local_addr();
|
|
|
|
int dst_addrs=arr_get(r,0)|(arr_get(r,1)<<8)|(arr_get(r,2)<<16);
|
|
|
|
if((dst_addrs&(1<<(self_addr-1)))!=0){
|
|
|
|
p->silent=1;
|
2024-01-08 18:04:05 +08:00
|
|
|
p->timer->write(p->timer,0);
|
|
|
|
// p->timer->init(p->timer);
|
2023-12-07 22:56:07 +08:00
|
|
|
p->rank=calc_bit_num(dst_addrs,self_addr-1);
|
|
|
|
p->num=calc_bit_num(dst_addrs,32);
|
2023-12-04 18:17:48 +08:00
|
|
|
arr_remove(r,0,3);
|
|
|
|
}else{
|
|
|
|
arr_delete(r);
|
|
|
|
r=arr_creat();
|
|
|
|
str_set(p->str_err,"bordcast without this.");
|
|
|
|
}
|
2023-11-15 18:11:39 +08:00
|
|
|
}else{
|
2023-12-07 22:56:07 +08:00
|
|
|
p->rank=dst-1;
|
|
|
|
p->num=20;// 最多支持20个设备
|
2023-11-15 18:11:39 +08:00
|
|
|
p->silent=0;
|
|
|
|
}
|
2023-12-04 18:17:48 +08:00
|
|
|
return r;
|
2023-10-06 18:47:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 编码
|
|
|
|
array_def *protm_encode(protu_def *p,array_def *data)
|
|
|
|
{
|
|
|
|
array_def *t=arr_creat();
|
|
|
|
param_check(t);
|
2023-12-07 22:56:07 +08:00
|
|
|
// if(p->silent==0){
|
2023-12-04 18:17:48 +08:00
|
|
|
uint16_t len=arr_length(data)+10;
|
|
|
|
arr_append(t,'Y');
|
|
|
|
arr_append(t,'e');
|
|
|
|
arr_append(t,len&0xff);
|
|
|
|
arr_append(t,len>>8);
|
|
|
|
arr_append(t,elec_local_addr());// 源地址
|
|
|
|
arr_append(t,0);// 目标地址
|
|
|
|
arr_append(t,p->cmd);// 命令码
|
|
|
|
arr_append(t,p->cmd_no&0xff);
|
|
|
|
arr_append(t,p->cmd_no>>8);
|
|
|
|
arr_appends_from(t,data);
|
|
|
|
arr_append(t,crc_crc8(arr_data(t),arr_length(t)));
|
2023-12-07 22:56:07 +08:00
|
|
|
// }else{
|
|
|
|
// // 广播命令只需回复本机地址
|
|
|
|
// arr_append(t,elec_local_addr());
|
|
|
|
// }
|
2023-10-06 18:47:05 +08:00
|
|
|
return t;
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
2023-10-06 18:47:05 +08:00
|
|
|
protuc_codec_export(ym_slave,protm_decode,protm_encode);
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
2023-12-14 18:57:04 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|