PlotterHMI/machine/comm/comm.cpp
2024-02-06 14:19:53 +08:00

439 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//-------------------------------------------------------------------------------
// File Name: comm.cpp
// Brief:
// Version: 1.0.0
// Create Date: 2017/05/08
// Create by: Marshal Lee
// Copyright:
// Copyright (c) 2017, Richpeace Co., LTD.
// All rights reserved.
//
// Modify by: Marshal Lee
// Modify Date: 2017/05/08
//-------------------------------------------------------------------------------
#define _IN_COMM_CPP
#include "comm.h"
#include "crc16.h"
//--------------------------------------------------------------------------------------------------
// 读空缓冲区
void readBuffEmpty(DataExFuns * funs)
{
int rslt, len;
u8 temp;
len = funs->getRsvLen();
while (len > 0)
{
rslt = funs->getCommData(&temp, 1);
if (rslt != 1)
{
rslt = 0;
break;
}
len--;
}
}
//--------------------------------------------------------------------------------------------------
// 功能: 从通讯口接收缓冲区中得到一个数据包, 如果有附加数据,包括附加数据
// 参数: pPacket, 数据包指针
// 返回: >=0, 成功取得一个数据包,包括定长数据包和可变长度数据包,返回值为数据包长度
// -1, 参数错误
// -2, CRC错误
// -3, 数据不足
// -4, 没有找到同步序列
// -5等待接收数据超时
// -6, 数据包参数错误
// -7, 附加数据CRC错误
// -8, 发生未知错误
// 结果: 如果正确取得数据包,或通讯口没有命令, 循环队列尾指针回向后移动
int getANormalPacket(DataExFuns * funs, DataPacket * pPacket)
{
int rslt, len;
int i;
int phase;
int status;
int exlen;
static int rdstatus = 0;
static u8 odBuf[LEN_NORMAL_PACKET];
u8 temp;
u8 rdBuf[LEN_NORMAL_PACKET];
DataPacket * pDat;
u8 getBuf[LEN_NORMAL_PACKET-DP_SYNC_LEN];
int getBuflen;
int getIdx;
u8 tmpBuf[LEN_NORMAL_PACKET-DP_SYNC_LEN];
int tmpBuflen;
if (funs == NULL || pPacket == NULL)
{
return -1;
}
rslt = 0;
i = 0; // 扫描字节计数器
getBuflen = 0;
getIdx = 0;
tmpBuflen = 0;
pDat = (DataPacket *)rdBuf;
if (rdstatus == 0)
{
do
{
len = funs->getRsvLen(); // 得到接收长度
len += getBuflen; // 加上已经获取的长度
if (len < LEN_NORMAL_PACKET)
{
rslt = -3;
break; // 没有足够数据
}
phase = 0;
status = 0;
rslt = 0;
// 从接收缓冲区中找数据包
while(((len + phase) >= LEN_NORMAL_PACKET) && (phase < LEN_NORMAL_PACKET))
{
if (getBuflen == 0)
{
if (phase == 0 && i > MAX_ONCE_SCAN)
{
rslt = -4;
break; // 查找同步序列超出最大单次扫描字节数
}
rslt = funs->getCommData(&temp, 1);
if (rslt != 1)
{
printf("error at GetCommData rslt\r\n");
rslt = -8;
break;
}
rslt = 0;
i++; // 扫描字数增加
}
else
{
temp = getBuf[getIdx];
getIdx++;
getBuflen--;
}
len--; // 剩余长度减小
pDat->buff.normal[phase] = temp;
if (phase < DP_SYNC_LEN) // 识别同步序列
{
tmpBuflen = 0;
if (phase == 0)
{
if (temp == FLDP_SYNC[0])
{
status = 1;
}
else if (temp == VLDP_SYNC[0])
{
status = 2;
}
else
{
status = 0;
phase = 0;
rslt = 0; // 非同步序列
break;
}
}
else
{
if (status == 1)
{
if (temp != FLDP_SYNC[phase])
{
status = 0;
phase = 0;
rslt = 0;
break;
}
}
else if (status == 2)
{
if (temp != VLDP_SYNC[phase])
{
status = 0;
phase = 0;
rslt = 0;
break;
}
}
else
{
printf("error status in GetANormalPacket\r\n");
rslt = -8;
break;
}
}
}
else
{
tmpBuf[tmpBuflen] = temp;
tmpBuflen++;
}
phase++;
}
if (rslt != 0)
{
break;
}
if (phase >= LEN_NORMAL_PACKET) // 得到数据包
{
u16 crc;
crc = calcCrc16(pDat->normal.content, DP_CONT_LEN);
if (crc == pDat->normal.crc)
{
// 得到正确数据包
memcpy(pPacket, pDat, LEN_NORMAL_PACKET);
// printf("GetANormalPacket ok\r\n");
rslt = LEN_NORMAL_PACKET;
break;
}
else
{
// CRC 不正确
printf("crc error in GetANormalPacket\r\n");
// 拷贝需要再判断的数据
if (tmpBuflen != 0)
{
memcpy(getBuf, tmpBuf, tmpBuflen);
}
getBuflen = tmpBuflen;
getIdx = 0;
// continue;
}
}
else
{
// 没有找到同步序列的情况
getBuflen = 0;
getIdx = 0;
// continue;
}
}while(1);
}
if (rdstatus == 1)
{
memcpy(pPacket, odBuf, LEN_NORMAL_PACKET);
rslt = LEN_NORMAL_PACKET;
}
// 附加数据
if (rslt == LEN_NORMAL_PACKET)
{
if (memcmp(pPacket->normal.sync, VLDP_SYNC, DP_SYNC_LEN) == 0) // 是可变长度数据包
{
exlen = pPacket->vldp.exlen;
if (exlen > MAX_EXDP_LEN)
{
printf("data exlen error, len=%d\r\n", exlen);
return -6; // 数据包参数错误
}
memset(pPacket->buff.exData, 0, MAX_EXDP_LEN);
i = 0;
status = 0; // 作为历史计数器
// 读取附加数据
do
{
rslt = funs->getCommData(pPacket->buff.exData, exlen);
if (rslt == exlen)
{
u16 crc;
// 校验CRC
crc = calcCrc16(pPacket->buff.exData, exlen);
if (crc == pPacket->vldp.excrc)
{
// printf("get exdata ok\r\n");
rslt = exlen+LEN_NORMAL_PACKET;
}
else
{
printf("crc error at get exdata\r\n");
rslt = -7; // CRC错误
}
rdstatus = 0;
break; // 得到数据
}
else if (rslt == 0)
{
memcpy(odBuf, pPacket, LEN_NORMAL_PACKET);
rdstatus = 1;
rslt = -3;
break;
/*
// 数据不足
if (funs->delay != NULL)
{
funs->delay(1); // 延时等待
}
len = funs->getRsvLen(); // 得到接收数据长度
qDebug()<<"getRsvLen"<<len;
if (len != status) // 和上次长度比较
{
status = len;
i = 0;
}
else // 如果没有变化,则计数器增加
{
i++;
if (i > GTEX_TIME_OUT) // 如果无变化计数器值大于超时值
{
qDebug()<<"call GetCommData timeout";
rslt = -5;
break;
}
}
*/
}
else
{
qDebug()<<"error after call GetCommData";
break;
}
}while(1);
}
}
return rslt;
}
//--------------------------------------------------------------------------------------------------
// 功能: 添加数据到发送队列中, 通过通讯口发送数据
// 参数: pPacket, 需要发送的数据,已经正确存放在了相应字段。
// 结果:
// 0, 可以发送, 添加到了发送数据队列中
// -1, 参数错误
// -2发送错误
// 1, 队列已满, 不能发送
int sendAPacket(DataExFuns * funs, DataPacket * pPacket)
{
int rslt;
int freelen, sendlen;
if (pPacket == NULL)
{
return -1;
}
if (memcmp(pPacket->normal.sync, FLDP_SYNC, DP_SYNC_LEN) == 0)
{
sendlen = LEN_NORMAL_PACKET;
}
else if (memcmp(pPacket->normal.sync, VLDP_SYNC, DP_SYNC_LEN) == 0)
{
sendlen = LEN_NORMAL_PACKET + pPacket->vldp.exlen;
}
else
{
printf("para err, not a corrected packet\r\n");
return -1;
}
freelen = funs->getTrsFreeLen();
if (freelen < sendlen)
{
// printf("buff is full in SendAPacket\r\n");
return 1;
}
rslt = funs->sendCommData(pPacket->datbuff, sendlen);
if (rslt != sendlen)
{
printf("error at call SendCommData, rslt=%d\r\n", rslt);
return -2;
}
return 0;
}
//--------------------------------------------------------------------------------------------------
// 功能: 打包一个固定长度数据包
// 参数:
// pPacket, 需要打包的数据包其中除了sync和crc的部分已经就绪
// 结果:
// 0, 打包好数据
// -1, 参数错误
int packetAFLDP(DataPacket * pPacket)
{
if (pPacket == NULL)
{
return -1;
}
memcpy(pPacket->normal.sync, FLDP_SYNC, DP_SYNC_LEN);
pPacket->normal.crc = calcCrc16(pPacket->normal.content, DP_CONT_LEN);
return 0;
}
//--------------------------------------------------------------------------------------------------
// 功能: 打包一个可变长度数据包
// 参数: pPacket, 需要打包的数据包,需要填充其中的 SYNC EXLEN EXCRC 和 EXDAT 等部分
// pExdat, 附加数据,可以为空
// exlen附加数据长度可以为0
// 结果:
// 0, 打包好数据
// -1, 参数错误
// -2
int packetAVLDP(DataPacket * pPacket, u8 * pExdat, u16 exlen)
{
if (pPacket == NULL)
{
return -1;
}
if (pExdat == NULL)
{
exlen = 0;
}
memcpy(pPacket->vldp.sync, VLDP_SYNC, DP_SYNC_LEN);
pPacket->vldp.exlen = exlen;
pPacket->vldp.excrc = calcCrc16(pExdat, exlen);
pPacket->vldp.crc = calcCrc16(pPacket->normal.content, DP_CONT_LEN);
if (exlen != 0)
{
memcpy(pPacket->vldp.exData, pExdat, exlen);
}
return 0;
}
//--------------------------------------------------------------------------------------------------