injectorCTL/protocol.c
2024-12-11 23:32:34 +08:00

659 lines
20 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.

#include "protocol.h"
#include <string.h>
static DeviceStatus deviceStatus = {0};
// CRC16 查表法实现
static const uint16_t crcTable[] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
uint16_t CalculateCRC16(uint8_t *data, uint16_t length) {
uint16_t crc = 0xFFFF;
for (uint16_t i = 0; i < length; i++) {
uint8_t index = (crc ^ data[i]) & 0xFF;
crc = (crc >> 8) ^ crcTable[index];
}
return crc;
}
// 更新下挂设备状态
void updateDeviceStatus(DeviceStatus_t status) {
deviceStatus.deviceStatus = status;
}
// 更新三通阀状态
void updateValveStatus(uint8_t index, ValveAngle_t angle) {
if (index == 1) {
deviceStatus.valves.angle1 = angle;
} else if (index == 2) {
deviceStatus.valves.angle2 = angle;
}
}
// 更新泵状态
void updatePumpStatus(uint8_t index, PumpStatus_t status) {
if (index == 1) {
deviceStatus.pumps.status1 = status;
} else if (index == 2) {
deviceStatus.pumps.status2 = status;
}
}
// 更新泵速度状态
void updatePumpSpeedStatus(uint8_t index, uint8_t speed) {
if (index == 1) {
deviceStatus.pumps.speed1 = speed;
} else if (index == 2) {
deviceStatus.pumps.speed2 = speed;
}
}
// 更新气泡传感器读数
void updateBubbleSensor(BubbleStatus_t value) {
deviceStatus.bubbleStatus = value;
}
// 更新急停状态
void updateEmergencyStop(EstopStatus_t status) {
deviceStatus.stopStatus = status;
}
// 更新错误码
void updateErrorCode(ErrorCode_t errorCode) {
deviceStatus.errorCode = errorCode;
}
// 更新初始化状态
void updateInitStatus(InitStatus_t status) {
deviceStatus.initStatus = status;
}
// 初始化设备状态
void InitDeviceStatus() {
// 初始化泵
WriteJogAcc(1, 100);
WriteJogDec(1, 100);
WriteJogSpeed(1, 10);
WriteStepAcc(1, 100);
WriteStepDec(1, 100);
WriteStepSpeed(1, 10);
// 更新设备状态
updateDeviceStatus(DEVICE_ONLINE);
updateValveStatus(1, 120);
updateValveStatus(2, 210);
updatePumpStatus(1, PUMP_CLOCKWISE);
updatePumpStatus(2, PUMP_ANTICLOCKWISE);
updatePumpSpeedStatus(1, 100);
updatePumpSpeedStatus(2, 100);
updateBubbleSensor(BUBBLE_DETECTED);
updateEmergencyStop(ESTOP_NORMAL);
updateInitStatus(INIT_SUCCESS);
}
//modBUS RTU 写命令
void writeCMD(uint8_t *txBuf, uint16_t *txLen) {
}
uint8_t SendToHost(uint8_t *txBuf, uint16_t txLen) {
// 发送数据到主机
// 具体实现
return 0;
}
// 判断系统大端序还是小端序
static uint8_t IsBigEndian() {
uint32_t num = 0x12345678;
return ((*(uint8_t*)&num) == 0x12);
}
// 将数据按大端序填充
static void FillBigEndian32(uint8_t *data, uint32_t value) {
if(!IsBigEndian()) {
for(uint16_t i = 0; i < 4; i++) {
data[i] = (value >> ((4 - i - 1) * 8)) & 0xFF;
}
}
else {
for(uint16_t i = 0; i < 4; i++) {
data[i] = (value >> (i * 8)) & 0xFF;
}
}
}
static void FillBigEndian16(uint8_t *data, uint16_t value) {
if(!IsBigEndian()) {
for(uint16_t i = 0; i < 2; i++) {
data[i] = (value >> ((2 - i - 1) * 8)) & 0xFF;
}
}
else {
for(uint16_t i = 0; i < 2; i++) {
data[i] = (value >> (i * 8)) & 0xFF;
}
}
}
/*
+----------+--------+------------+------------+------------+
| 从机地址 | 功能码 | 寄存器地址 | 寄存器数量 | CRC校验值 |
+----------+--------+------------+------------+------------+
| 1字节 | 1字节 | 2字节 | 2字节 | 2字节 |
+----------+--------+------------+------------+------------+
*/
// pump 读寄存器
uint16_t ReadPump1Reg(uint8_t index, uint16_t reg) {
uint8_t data[8] = {0};
data[0] = index;
data[1] = RTU_PUMP_FUNC_READ_REG;
FillBigEndian16(&data[2], reg);
FillBigEndian16(&data[4], 1);
uint16_t crc = CalculateCRC16(data, 6);
// 小端序填充
memcpy(&data[6], &crc, 2);
writeCMD(data, 8);
}
/*
+----------+--------+------------+----------+------------+
| 从机地址 | 功能码 | 寄存器地址 | 寄存器值 | CRC校验值 |
+----------+--------+------------+----------+------------+
| 1字节 | 1字节 | 2字节 | 2字节 | 2字节 |
+----------+--------+------------+----------+------------+
*/
// 写泵1个寄存器
uint8_t WritePump1Reg(uint8_t index, uint16_t reg, uint16_t value) {
// 写一个寄存器不需要指定寄存器长度
uint8_t data[8] = {0};
data[0] = index;
data[1] = RTU_PUMP_FUNC_WRITE_REG;
FillBigEndian16(&data[2], reg);
FillBigEndian16(&data[4], value);
uint16_t crc = CalculateCRC16(data, 6);
// 小端序填充
memcpy(&data[6], &crc, 2);
writeCMD(data, 8);
}
/*
+----------+--------+------------+------------+----------+----------+------------+
| 从机地址 | 功能码 | 寄存器地址 | 寄存器数量 | 数据长度 | 寄存器值 | CRC校验值 |
+----------+--------+------------+------------+----------+----------+------------+
| 1字节 | 1字节 | 2字节 | 2字节 | 1字节 | 4字节 | 2字节 |
+----------+--------+------------+------------+----------+----------+------------+
*/
// 写泵2个寄存器
uint8_t WritePump2Reg(uint8_t index, uint16_t reg, uint32_t value) {
// 写2个寄存器需要指定寄存器长度
uint8_t data[13] = {0};
data[0] = index;
data[1] = RTU_PUMP_FUNC_WRITE_MULTI_REG;
FillBigEndian16(&data[2], reg);
FillBigEndian16(&data[4], 2);
data[6] = 8;
FillBigEndian32(&data[7], value);
uint16_t crc = CalculateCRC16(data, 11);
// 小端序填充
memcpy(&data[11], &crc, 2);
writeCMD(data, 13);
}
/*
+--------------+--------------------------------+
| jogging设置顺序 |
+--------------+--------------------------------+
| 1. | 设置加速度JA、减速度JL、速度JS |
+--------------+--------------------------------+
| 2. | 启动Jog-CJ |
+--------------+--------------------------------+
| 3. | 停止Jog-SJ |
+--------------+--------------------------------+
*/
static uint8_t WriteJogAcc(uint8_t index, uint16_t acc) {
WritePump1Reg(index, RTU_PUMP_CMD_JA, acc);
}
static uint8_t WriteJogDec(uint8_t index, uint16_t dec) {
WritePump1Reg(index, RTU_PUMP_CMD_JL, dec);
}
static uint8_t WriteJogSpeed(uint8_t index, uint16_t speed) {
WritePump1Reg(index, RTU_PUMP_CMD_JS, speed);
}
// Jog=慢跑
// CJ=start jogging
// 写入命令操作码寄存器(40125)数据0x0096(CJ)即执行启动Jog控制
static uint8_t StartJogControl(uint8_t index) {
WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x0096);
}
// SJ=stop jogging
// 写入命令操作码寄存器(40125)数据0x00D8(SJ)即执行停止Jog控制
// CJ与SJ一一对应单次SJ无法停止所有全部CJ
// 直接停止泵需要使用SK命令
static uint8_t StopJogControl(uint8_t index) {
WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x00D8);
}
/*
+--------------+--------------------------------+
| step设置顺序 |
+--------------+--------------------------------+
| 1. | 设置加速度AC、减速度DE、速度VE |
+--------------+--------------------------------+
| 2. | 设置步进DI |
+--------------+--------------------------------+
| 3. | 启动相对位置FL或绝对位置FP |
+--------------+--------------------------------+
| 4. | 停止泵SK |
+--------------+--------------------------------+
*/
static uint8_t WriteStepAcc(uint8_t index, uint16_t acc) {
WritePump1Reg(index, RTU_PUMP_CMD_AC, acc);
}
static uint8_t WriteStepDec(uint8_t index, uint16_t dec) {
WritePump1Reg(index, RTU_PUMP_CMD_DE, dec);
}
static uint8_t WriteStepSpeed(uint8_t index, uint16_t speed) {
WritePump1Reg(index, RTU_PUMP_CMD_VE, speed);
}
static uint8_t WriteStepTarget(uint8_t index, uint32_t target) {
WritePump2Reg(index, RTU_PUMP_CMD_DI, target);
}
// FL=feed length
// 写入命令操作码寄存器(40125)数据0x0066(FL),即执行相对位置控制
static uint8_t RelativePositionControl(uint8_t index) {
WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x0066);
}
// FP=feed position
// 写入命令操作码寄存器(40125)数据0x0067(FP),即执行绝对位置控制
static uint8_t AbsolutePositionControl(uint8_t index) {
WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x0067);
}
// SK=Stop Move & Kill Buffer, Max Decel
// 写入命令操作码寄存器(40125)数据0x00E1(SK),即执行停止控制
static uint8_t StopPump(uint8_t index) {
WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x00E1);
}
// 获取固件版本
uint8_t ReadHWReg(uint8_t index) {
ReadPump1Reg(index, RTU_PUMP_CMD_HW);
}
// 设置波特率
uint8_t WriteBRReg(uint8_t index, uint16_t br) {
WritePump1Reg(index, RTU_PUMP_CMD_BR, br);
}
// 设置通信协议
uint8_t WritePRReg(uint8_t index, uint16_t pr) {
WritePump1Reg(index, RTU_PUMP_CMD_PR, pr);
}
// 获取泵状态
void ReadPumpStatus(uint8_t index) {
ReadPump1Reg(index, RTU_PUMP_CMD_SC);
}
// 获取泵告警信息
void ReadPumpAlarm(uint8_t index) {
ReadPump1Reg(index, RTU_PUMP_CMD_AL);
}
// 解码告警信息
void DecodePumpAlarmMsg(uint16_t reg4001) {
static AlarmCode_t alarmCode = {0};
// 与上次告警信息相同,则不更新,仅打印一次
if (alarmCode.all == reg4001)
{
return 0;
}
alarmCode.all = reg4001;
if(alarmCode.all == 0) {
//暂时屏蔽,避免刷屏
// printf("\r\n%s无报警信息\r\n", pumpName[index]);
return 0;
}
// 打印表格头部
printf("\r\n+--------+------------------+\r\n");
printf("| 告警位 | 告警信息 |\r\n");
printf("+--------+------------------+\r\n");
for(uint16_t i = 0; i < 16; i++) {
if(alarmCode.all & (1 << i)) {
printf("| %6d | %-14s |\r\n", i, alarmInfo[i]);
printf("+--------+------------------+\r\n");
}
}
return 1;
}
// 解码状态信息
void DecodePumpStatusMsg(uint16_t reg4002) {
static StatusCode_t statusCode = {0};
// 与上次状态信息相同,则不更新,仅打印一次
if (statusCode.all == reg4002)
{
return 1;
}
statusCode.all = reg4002;
printf("\r\n+--------+------------------+\r\n");
printf("| 状态位 | 状态信息 |\r\n");
printf("+--------+------------------+\r\n");
for(uint16_t i = 0; i < 16; i++) {
if(statusCode.all & (1 << i)) {
printf("| %6d | %-14s |\r\n", i, statusInfo[i]);
printf("+--------+------------------+\r\n");
}
}
return 0;
}
// valve
/*
# 轮廓位置模式,配置流程
1.配置模式:
00B1h=0、运行模式 03C2h=0x01使设备工作在轮廓位置模式
1.1(设置为 CIA402 模式)
1.2(设置为轮廓位置模式)
2.参数配置:
2.1写目标位置 03E7h用户单位
2.2写当前段位移指令匀速运行速度 03F8h (用户单位/s)
2.3设置位移的加速度 03FCh(用户单位/s2)
2.4设置位移的减速度 03FEh(用户单位/s2)
3.写控制字使电机使能
0380h= 0x06→0x07→ 0x0F电机使能
4.使电机运行
0380h= 0x2F→0x3F电机运行
5.监控参数:
实际位置反馈03C8h (用户单位)
# 堵转找寻原点方式,配置流程
1.设置原点回归方式
0416h=37;17=负限位18=正限位
2.设置堵转检测力矩和堵转检测时间
0170h=3000172h=50
3.设置模式
00B1h=0、运行模式 03C2h=0x06使其工作在原点回归模式
4.写寻找限位开关速度和寻找原点信号速度
0417h= 10000 (0419h)=1000;
5.设置回零加速度
041Bh=200000
6.写控制字
(0380h)= 0x06→0x07→0x0F→0x1F电机运行
*/
static uint8_t SetValveMode(uint8_t index, uint16_t mode) {
WritePump1Reg(index, RTU_VALVE_CMD_CTL_MODE, mode);
}
static uint8_t SetValveRunMode(uint8_t index, uint16_t mode) {
WritePump1Reg(index, RTU_VALVE_CMD_RUN_MODE, mode);
}
// PP=轮廓位置模式
static uint8_t SetValvePPPos(uint8_t index, uint16_t pos) {
WritePump1Reg(index, RTU_VALVE_CMD_PP_POS, pos);
}
static uint8_t SetValvePPSpeed(uint8_t index, uint16_t speed) {
WritePump1Reg(index, RTU_VALVE_CMD_PP_SPEED, speed);
}
static uint8_t SetValvePPAcc(uint8_t index, uint16_t acc) {
WritePump1Reg(index, RTU_VALVE_CMD_PP_ACCEL, acc);
}
static uint8_t SetValvePPDec(uint8_t index, uint16_t dec) {
WritePump1Reg(index, RTU_VALVE_CMD_PP_DECEL, dec);
}
// HM=原点回归模式
static uint8_t SetValveHomeMode(uint8_t index, uint16_t mode) {
WritePump1Reg(index, RTU_VALVE_CMD_HOME_MODE, mode);
}
static uint8_t SetValveHomeSpeed(uint8_t index, uint16_t speed) {
WritePump1Reg(index, RTU_VALVE_CMD_HOME_SPEED, speed);
}
static uint8_t SetValveHomeAcc(uint8_t index, uint16_t acc) {
WritePump1Reg(index, RTU_VALVE_CMD_HOME_ACCEL, acc);
}
static uint8_t SetValveFunc(uint8_t index, uint16_t func) {
WritePump1Reg(index, RTU_VALVE_CMD_FUNC, func);
}
// 定时1s更新设备状态
// 活度计通过网口获取
// 下挂设备通过485获取
void UpdatePumpStatus() {
// 更新设备状态
ReadPumpStatus(0);
ReadPumpStatus(1);
ReadPumpAlarm(0);
ReadPumpAlarm(1);
}
// 初始化处理
static uint8_t HandleInit(uint8_t *rxBuf, uint8_t *txBuf, uint16_t *txLen) {
// 实现初始化逻辑
InitDeviceStatus();
return 1;
}
// 状态查询处理
static uint8_t HandleStatusQuery(void) {
// 填充并返回数据
uint8_t txBuf[sizeof(DeviceStatus)] = {0};
memcpy(txBuf, &deviceStatus, sizeof(DeviceStatus));
SendToHost(txBuf, sizeof(txBuf));
return 0;
}
// 三通阀控制处理
static uint8_t HandleValveControl(uint8_t *Buff, uint8_t len) {
// 实现三通阀控制逻辑
if(len != 8) {
printf("三通阀控制错误\r\n");
return 0;
}
uint8_t index = Buff[0];
uint8_t direction = Buff[1];
uint16_t angle = (Buff[2]<<8) | Buff[3];
if(angle > 360) {
printf("三通阀控制错误\r\n");
return 1;
}
if (angle != VALVE_ANGLE_120 && angle != VALVE_ANGLE_210) {
printf("三通阀控制错误\r\n");
return 1;
}
// 具体实现
// 更新三通阀状态
updateValveStatus(index, angle);
return 0;
}
// 泵时长控制处理
static uint8_t HandlePumpTimeControl(uint8_t *Buff, uint8_t len) {
// 实现泵时长控制逻辑
// 暂未知控制方法,是直接设置泵运行时间,还是设置泵运行步数
return 1;
}
// 泵速度设置处理
static uint8_t HandlePumpSpeedControl(uint8_t *Buff, uint8_t len) {
// 实现泵速度设置逻辑
if(len != 4) {
printf("泵速度设置错误\r\n");
return 0;
}
uint8_t index = Buff[0];
uint16_t speed = Buff[1];
if (speed > 100) {
printf("泵速度设置错误\r\n");
return 0;
}
WriteJogSpeed(index, speed);
index = Buff[2];
speed = Buff[3];
if (speed > 100) {
printf("泵速度设置错误\r\n");
return 0;
}
WriteJogSpeed(index, speed);
return 1;
}
static uint8_t HandlePumpStepControl(uint8_t *Buff, uint8_t len) {
if(len != 10) {
printf("泵步进设置错误\r\n");
return 0;
}
uint8_t index = Buff[0];
int32_t step = (Buff[1]<<24) | (Buff[2]<<16) | (Buff[3]<<8) | Buff[4];
WriteStepTarget(index, step);
return 0;
}
// 软急停功能处理
static uint8_t HandleSoftStop(uint8_t *rxBuf, uint16_t rxLen) {
if(rxLen != 1) {
printf("软急停设置错误\r\n");
return 1;
}
// 实现软急停功能逻辑
if(rxBuf[0] == 0) {
// 正常状态
updateEmergencyStop(ESTOP_NORMAL);
}
else {
// 急停状态
StopPump(0);
StopPump(1);
StopJogControl(0);
StopJogControl(1);
updateEmergencyStop(ESTOP_PRESSED);
}
return 0;
}
CmdFrameError_t checkHostCmd(uint8_t *rxBuf, uint16_t rxLen) {
// 检查命令是否正确
if (memcmp(rxBuf, FRAME_HEADER, 4) != 0)
{
return CMD_FRAME_HEADER_ERROR;
}
if (memcmp(rxBuf + rxLen - 4, FRAME_TAIL, 4) != 0)
{
return CMD_FRAME_TAIL_ERROR;
}
uint16_t crc = CalculateCRC16(rxBuf+4, rxLen - 8);// 计算crc不包含帧头和帧尾
if (memcmp(rxBuf + rxLen - 4, &crc, 2) != 0)
{
return CMD_FRAME_CHECK_ERROR;
}
return CMD_FRAME_OK;
}
// 上位机命令处理函数采用的自定协议非modbus协议
// rxBuf: 接收到的数据
// rxLen: 接收到的数据长度
CmdFrameError_t ProcessHostCommand(uint8_t *rxBuf, uint16_t rxLen) {
CmdFrameError_t error = checkHostCmd(rxBuf, rxLen);
if (error != CMD_FRAME_OK)
{
return error;
}
uint16_t cmdCode = (rxBuf[sizeof(FRAME_HEADER)] << 8) | rxBuf[sizeof(FRAME_HEADER)+1];//提取命令码
uint8_t dataLen = rxBuf[sizeof(FRAME_HEADER)+2];//提取数据长度
uint8_t *data = &rxBuf[sizeof(FRAME_HEADER)+3];//提取数据
switch(cmdCode) {
case CMD_STATUS_QUERY:
error = HandleStatusQuery();
break;
case CMD_VALVE_CTRL:
error = HandleValveControl(data, dataLen);
break;
case CMD_PUMP_RUN_TIME:
error = HandlePumpTimeControl(data, dataLen);
break;
case CMD_PUMP_RUN_SPEED:
error = HandlePumpSpeedControl(data, dataLen);
break;
case CMD_SOFT_STOP:
error = HandleSoftStop(data, dataLen);
break;
case CMD_PUMP_RUN_STEP:
error = HandlePumpStep(data, dataLen);
break;
case CMD_SYSTEM_INIT:
error = HandleInit(data, dataLen);
break;
default:
error = CMD_FRAME_CMD_ERROR;
break;
}
return error;
}