2024-09-12 08:18:07 +00:00
|
|
|
|
// 透传缆
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include "MultiTimer.h"
|
2024-09-29 01:45:34 +00:00
|
|
|
|
#include "lwrb/lwrb.h"
|
2024-09-29 08:54:27 +00:00
|
|
|
|
#include "linkedlist.h"
|
2024-09-12 08:18:07 +00:00
|
|
|
|
|
|
|
|
|
#define CMD_TRA_MODE 0xA1
|
|
|
|
|
#define CMD_REC_MODE 0xA2
|
|
|
|
|
#define CMD_SLP_MODE 0xA3
|
|
|
|
|
#define CMD_WKP_MODE 0xA4
|
|
|
|
|
#define CMD_ACK_OK 0xAB
|
|
|
|
|
#define CMD_ACK_NOK 0xAF
|
|
|
|
|
|
2024-09-29 08:54:27 +00:00
|
|
|
|
#define USING_ACK 1
|
|
|
|
|
|
|
|
|
|
#define MIN_TR_PERIOD_MS (1000 * 5) // 单字节最小传输时间
|
2024-09-12 08:18:07 +00:00
|
|
|
|
#define HOST_RETRY_PERIOD_MS (MIN_TR_PERIOD_MS + 1000) // 主机重试时间间隔
|
|
|
|
|
#define CLIENT_RETRY_PERIOD_MS (MIN_TR_PERIOD_MS + 1000 * 10) // 客户端重试时间间隔
|
2024-09-29 08:54:27 +00:00
|
|
|
|
#define MAX_RETRY_CNT 3
|
2024-09-29 01:45:34 +00:00
|
|
|
|
#define RING_BUFFER_SIZE (1024 * 3)
|
2024-09-30 07:09:26 +00:00
|
|
|
|
#define MAX_FRAME_LENGTH (200)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
|
|
|
|
|
/// @brief 主从模式,主机拥有更高优先级
|
2024-09-29 01:45:34 +00:00
|
|
|
|
typedef enum
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
|
|
|
|
HOST_MODE = 0,
|
|
|
|
|
CLIENT_MODE
|
2024-09-29 01:45:34 +00:00
|
|
|
|
} devmode_t;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
|
|
|
|
|
/// @brief 工作模式,收、发、休眠、唤醒
|
2024-09-29 01:45:34 +00:00
|
|
|
|
typedef enum
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
|
|
|
|
T_MODE = 0,
|
|
|
|
|
R_MODE,
|
|
|
|
|
SLEEP_MODE,
|
|
|
|
|
WORK_MODE
|
2024-09-29 01:45:34 +00:00
|
|
|
|
} devstatus_t;
|
|
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
ERR_OK = 0,
|
2024-09-30 07:09:26 +00:00
|
|
|
|
ERR_NOK,
|
|
|
|
|
ERR_TIMEOUT,
|
2024-09-29 01:45:34 +00:00
|
|
|
|
ERR_HEADER,
|
|
|
|
|
ERR_TAIL,
|
2024-09-29 08:54:27 +00:00
|
|
|
|
ERR_CRC,
|
2024-09-30 07:09:26 +00:00
|
|
|
|
ERR_LENGTH,
|
|
|
|
|
ERR_NREADY
|
2024-09-29 01:45:34 +00:00
|
|
|
|
} err_t;
|
|
|
|
|
|
|
|
|
|
static devmode_t devMode = HOST_MODE;
|
|
|
|
|
static devstatus_t curMode = R_MODE;
|
|
|
|
|
static devstatus_t tarMode = R_MODE;
|
2024-09-30 07:09:26 +00:00
|
|
|
|
volatile int isOK2Swt = 1; // 是否尝试切换到发送模式
|
2024-09-29 01:45:34 +00:00
|
|
|
|
static devstatus_t tarDevMode = R_MODE; // 目标端工作模式
|
2024-10-17 08:44:45 +00:00
|
|
|
|
static MultiTimer swtModeTimer, retryTimer, timeoutTimer; // 重试定时器、超时定时器
|
|
|
|
|
static int isNewLineRx = 0;
|
2024-09-30 07:09:26 +00:00
|
|
|
|
static uint8_t lstLineRxData[MAX_FRAME_LENGTH]; // 透传缆最后一个接收到的数据
|
2024-09-29 08:54:27 +00:00
|
|
|
|
static uint8_t lstLineRxDataLen = 0; // 透传缆最后一个接收到的数据长度
|
|
|
|
|
static Node *userRxBuffList = NULL; // user端接收缓冲链表
|
|
|
|
|
// static err_t lstState = ERR_OK;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
|
|
|
|
|
// 设置GPIO电平
|
|
|
|
|
void setGpioLevel(int gpio, int level)
|
|
|
|
|
{
|
|
|
|
|
// 设置GPIO电平
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 初始化工作模式,仅设置对应GPIO电平
|
|
|
|
|
/// @param cfg
|
2024-09-29 01:45:34 +00:00
|
|
|
|
void initWorkStatus(devstatus_t cfg)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
|
|
|
|
switch (cfg)
|
|
|
|
|
{
|
|
|
|
|
case T_MODE:
|
|
|
|
|
/* code */
|
|
|
|
|
break;
|
|
|
|
|
case R_MODE:
|
|
|
|
|
/* code */
|
|
|
|
|
break;
|
|
|
|
|
case SLEEP_MODE:
|
|
|
|
|
/* code */
|
|
|
|
|
break;
|
|
|
|
|
case WORK_MODE:
|
|
|
|
|
/* code */
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 通过透传缆串口发送数据
|
|
|
|
|
/// @param data 待发送数据
|
|
|
|
|
/// @param len 待发送数据长度
|
|
|
|
|
void lineTransmitData(uint8_t *data, uint8_t len)
|
|
|
|
|
{
|
|
|
|
|
// 发送数据前后需初始化为发送模式
|
2024-09-29 01:45:34 +00:00
|
|
|
|
initWorkStatus(T_MODE);
|
2024-09-12 08:18:07 +00:00
|
|
|
|
// 发送数据
|
2024-10-17 08:44:45 +00:00
|
|
|
|
|
2024-09-12 08:18:07 +00:00
|
|
|
|
// 发送完毕后需恢复为接收模式
|
2024-09-29 08:54:27 +00:00
|
|
|
|
msdelay(len * 10);
|
2024-09-29 01:45:34 +00:00
|
|
|
|
initWorkStatus(R_MODE);
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
2024-09-29 01:45:34 +00:00
|
|
|
|
// 透传缆发送逻辑
|
2024-09-29 08:54:27 +00:00
|
|
|
|
// 0. 用户串口接收待发送数据,放入缓存链表队列。
|
2024-09-29 01:45:34 +00:00
|
|
|
|
// 1. 通过透传缆串口发送数据
|
|
|
|
|
// 2. 发送完成后切换为接收模式
|
|
|
|
|
// 3. 通过透传缆串口接收回复的ACK
|
|
|
|
|
// 4. ACK正常则发送成功,否则发送失败
|
2024-10-17 08:44:45 +00:00
|
|
|
|
// 5. 发送成功反馈ACK,删除链表数据并准备发送链表中下一帧数据
|
2024-09-29 08:54:27 +00:00
|
|
|
|
// 6. 发送失败则等待指定时间t后重发当前帧
|
2024-10-17 08:44:45 +00:00
|
|
|
|
// 7. 重试次数达到上限则发送失败,删除链表数据并准备发送链表中下一帧数据
|
|
|
|
|
// 8.
|
2024-09-12 08:18:07 +00:00
|
|
|
|
|
|
|
|
|
/// @brief 通过用户串口发送数据
|
|
|
|
|
/// @param data 待发送数据
|
|
|
|
|
/// @param len 待发送数据长度
|
|
|
|
|
void userTransmitData(uint8_t *data, uint8_t len)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 切换为接收模式
|
|
|
|
|
void switchToRecMode()
|
|
|
|
|
{
|
|
|
|
|
lineTransmitData(CMD_REC_MODE, 1);
|
|
|
|
|
// 不需要ACK
|
|
|
|
|
curMode = R_MODE;
|
|
|
|
|
tarMode = R_MODE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 切换为发送模式
|
|
|
|
|
//
|
|
|
|
|
// 以ACK回复判断是否切换成功
|
|
|
|
|
// 切换失败则定时重试
|
|
|
|
|
void switchToTraMode()
|
|
|
|
|
{
|
|
|
|
|
// tarMode = T_MODE;
|
|
|
|
|
|
|
|
|
|
lineTransmitData(CMD_REC_MODE, 1);
|
|
|
|
|
|
|
|
|
|
// 接收ACK
|
|
|
|
|
uint8_t ack[] = {};
|
|
|
|
|
uint8_t len = 0;
|
|
|
|
|
recvData(ack, len, 2000); // 阻塞等待
|
|
|
|
|
if (len == 1 && ack[0] == CMD_ACK_OK)
|
|
|
|
|
{
|
|
|
|
|
// 切换发送模式成功
|
|
|
|
|
curMode = T_MODE;
|
|
|
|
|
tarMode = R_MODE;
|
|
|
|
|
// initWorkMode(T_MODE);
|
|
|
|
|
// return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 切换发送模式失败
|
|
|
|
|
// 恢复为接收模式
|
|
|
|
|
switchToRecMode();
|
|
|
|
|
tarMode = T_MODE; // 触发定时重试
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t getPlatformTicks(void)
|
|
|
|
|
{
|
|
|
|
|
/* Platform-specific implementation */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Callback functions for the timers
|
2024-10-17 08:44:45 +00:00
|
|
|
|
void swtModeTimerCallback(MultiTimer *timer, void *userData)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-30 07:09:26 +00:00
|
|
|
|
isOK2Swt = 1;
|
2024-10-17 08:44:45 +00:00
|
|
|
|
//提示保护期已过,收端可以发送数据
|
|
|
|
|
printf("time of protect expired and can send data.\n");
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 08:54:27 +00:00
|
|
|
|
void timeOutTimerCallback(MultiTimer *timer, void *userData)
|
|
|
|
|
{
|
|
|
|
|
isTimeOut = 1;
|
|
|
|
|
|
|
|
|
|
printf("Timer 1 fired at %lu ms\n", getPlatformTicks());
|
|
|
|
|
}
|
2024-10-17 08:44:45 +00:00
|
|
|
|
void reTryTimerCallback(MultiTimer *timer, void *userData)
|
|
|
|
|
{
|
|
|
|
|
userData = 1;
|
2024-09-29 08:54:27 +00:00
|
|
|
|
|
2024-10-17 08:44:45 +00:00
|
|
|
|
printf("Timer 1 fired at %lu ms\n", getPlatformTicks());
|
|
|
|
|
}
|
2024-09-12 08:44:24 +00:00
|
|
|
|
/// @brief 计算异或XOR校验
|
2024-09-29 01:45:34 +00:00
|
|
|
|
/// @param data 待校验数据
|
|
|
|
|
/// @param len 数据长度
|
2024-09-12 08:44:24 +00:00
|
|
|
|
/// @return 校验结果
|
|
|
|
|
uint8_t bccCRC(uint8_t *data, uint8_t len)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-12 08:44:24 +00:00
|
|
|
|
uint8_t crc = 0;
|
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
|
{
|
|
|
|
|
crc ^= data[i];
|
|
|
|
|
}
|
|
|
|
|
return crc;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 检查数据有效性
|
2024-09-12 08:48:51 +00:00
|
|
|
|
/// @param data 待校验数据
|
|
|
|
|
/// @param len 数据长度
|
2024-09-30 07:09:26 +00:00
|
|
|
|
/// @return 0->有效
|
2024-09-29 01:45:34 +00:00
|
|
|
|
err_t chkDataValid(uint8_t *data, uint8_t len)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
|
|
|
|
// 按帧发送数据
|
|
|
|
|
// 判断帧的完整性及校验位
|
2024-09-30 07:09:26 +00:00
|
|
|
|
if (len > MAX_FRAME_LENGTH)
|
|
|
|
|
{
|
|
|
|
|
return ERR_LENGTH;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-12 08:44:24 +00:00
|
|
|
|
if (data[0] != 0x5A || data[1] != 0xA5) // 帧头校验
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-29 01:45:34 +00:00
|
|
|
|
return ERR_HEADER;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-12 08:44:24 +00:00
|
|
|
|
if (data[len - 1] != 0xED) // 帧尾校验
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-29 01:45:34 +00:00
|
|
|
|
return ERR_TAIL;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-12 08:44:24 +00:00
|
|
|
|
if (bccCRC(data + 2, len - 4) != data[len - 2]) // 校验位校验
|
|
|
|
|
{
|
2024-09-29 01:45:34 +00:00
|
|
|
|
return ERR_CRC;
|
2024-09-12 08:44:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 01:45:34 +00:00
|
|
|
|
return ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-12 08:18:07 +00:00
|
|
|
|
/// @brief 用户接口接收数据回调
|
|
|
|
|
/// @param data
|
|
|
|
|
/// @param len
|
|
|
|
|
void userRecDataCallback(uint8_t *data, uint8_t len)
|
|
|
|
|
{
|
2024-09-30 07:09:26 +00:00
|
|
|
|
//等待时间内不能发送数据
|
|
|
|
|
if (!isOK2Swt)
|
|
|
|
|
{
|
|
|
|
|
userTransmitData(ERR_NREADY,1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err_t rst= chkDataValid(data, len);
|
|
|
|
|
if (rst == ERR_OK)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-30 07:09:26 +00:00
|
|
|
|
//校验通过则加入待发列表
|
2024-09-29 08:54:27 +00:00
|
|
|
|
appendNode(&userRxBuffList, data, len);
|
2024-09-30 07:09:26 +00:00
|
|
|
|
//由发送函数反馈发送结果
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-09-30 07:09:26 +00:00
|
|
|
|
//校验不通过立即反馈
|
|
|
|
|
userTransmitData(rst, 1);
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 透传缆接收数据回调
|
|
|
|
|
/// @param data
|
|
|
|
|
/// @param len
|
|
|
|
|
void lineRecCallback(uint8_t *data, uint8_t len)
|
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
isNewLineRx = 1;
|
2024-09-29 08:54:27 +00:00
|
|
|
|
memcpy(lstLineRxData, data, len);
|
|
|
|
|
lstLineRxDataLen = len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 阻塞方式接收ACK数据
|
|
|
|
|
/// @param timeOut 指定超时时间,单位ms
|
|
|
|
|
/// @return 返回ACK状态
|
|
|
|
|
err_t getACK(int timeOut)
|
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
uint8_t isTimeOut = 0;
|
2024-09-29 08:54:27 +00:00
|
|
|
|
multiTimerStop(&timeoutTimer);
|
2024-10-17 08:44:45 +00:00
|
|
|
|
multiTimerStart(&timeoutTimer, timeOut, timeOutTimerCallback, &isTimeOut); // Start timer
|
2024-09-29 08:54:27 +00:00
|
|
|
|
while (1)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
if (isTimeOut)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-30 07:09:26 +00:00
|
|
|
|
return ERR_TIMEOUT;
|
2024-09-29 08:54:27 +00:00
|
|
|
|
}
|
2024-09-12 08:18:07 +00:00
|
|
|
|
|
2024-10-17 08:44:45 +00:00
|
|
|
|
if (isNewLineRx)
|
2024-09-29 08:54:27 +00:00
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
isNewLineRx = 0;
|
|
|
|
|
//ACK为单个字节
|
2024-09-29 08:54:27 +00:00
|
|
|
|
if (lstLineRxDataLen == 1 && lstLineRxData[0] == CMD_ACK_OK)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
return ERR_OK;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
return ERR_NOK;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-29 01:45:34 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
continue;
|
2024-09-29 01:45:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-12 08:18:07 +00:00
|
|
|
|
/// @brief
|
|
|
|
|
void handleTR()
|
|
|
|
|
{
|
|
|
|
|
// 初始化外设
|
|
|
|
|
|
2024-09-29 08:54:27 +00:00
|
|
|
|
uint16_t time2Retry = 0;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
if (devMode == HOST_MODE)
|
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
// 间隔1s
|
|
|
|
|
time2Retry = 1000;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
time2Retry = 1000 * 10;
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化MultiTimer
|
|
|
|
|
multiTimerInstall(getPlatformTicks);
|
2024-09-29 01:45:34 +00:00
|
|
|
|
|
2024-09-12 08:18:07 +00:00
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
multiTimerYield();
|
2024-09-29 08:54:27 +00:00
|
|
|
|
|
|
|
|
|
// 收到新数据
|
2024-10-17 08:44:45 +00:00
|
|
|
|
if (isNewLineRx)
|
2024-09-12 08:18:07 +00:00
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
if (lstLineRxDataLen == 1)
|
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
/* 判断为无效,只有ACK为单个字节 */
|
2024-09-29 08:54:27 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (chkDataValid(lstLineRxData, lstLineRxDataLen) == ERR_OK)
|
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
//校验通过
|
2024-09-29 08:54:27 +00:00
|
|
|
|
lineTransmitData(CMD_ACK_OK, 1);
|
|
|
|
|
userTransmitData(lstLineRxData, lstLineRxDataLen);
|
2024-09-30 07:09:26 +00:00
|
|
|
|
//每次建立通信后10s内收端不能发起通信
|
|
|
|
|
isOK2Swt = 0;
|
|
|
|
|
multiTimerStop(&retryTimer);
|
2024-10-17 08:44:45 +00:00
|
|
|
|
multiTimerStart(&retryTimer, 10*1000, swtModeTimerCallback, NULL); // Start timer
|
2024-09-29 08:54:27 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
//数据校验不过
|
2024-09-29 08:54:27 +00:00
|
|
|
|
lineTransmitData(CMD_ACK_NOK, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
2024-09-29 08:54:27 +00:00
|
|
|
|
|
|
|
|
|
// 有数据需要发送
|
2024-09-30 07:09:26 +00:00
|
|
|
|
if (isOK2Swt && getListSize(userRxBuffList) > 0)
|
2024-09-29 01:45:34 +00:00
|
|
|
|
{
|
2024-09-29 08:54:27 +00:00
|
|
|
|
// 发送数据
|
|
|
|
|
err_t lstState = ERR_OK;
|
|
|
|
|
while (userRxBuffList != NULL) // 遍历链表
|
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
static uint8_t isRetryTimeOut = 0;
|
|
|
|
|
|
2024-09-30 07:09:26 +00:00
|
|
|
|
if (lstState == ERR_NOK)
|
2024-09-29 08:54:27 +00:00
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
if (!isRetryTimeOut)
|
2024-09-29 08:54:27 +00:00
|
|
|
|
{
|
|
|
|
|
// 跳过后续代码进入下次循环
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-10-17 08:44:45 +00:00
|
|
|
|
isRetryTimeOut = 0;
|
2024-09-29 08:54:27 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lineTransmitData(userRxBuffList->data, userRxBuffList->size);
|
|
|
|
|
if (USING_ACK == 1) // 使用ACK
|
|
|
|
|
{
|
2024-09-30 07:09:26 +00:00
|
|
|
|
err_t rst = getACK(userRxBuffList->size * 10);
|
|
|
|
|
if (rst == ERR_TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
lstState = ERR_TIMEOUT;
|
|
|
|
|
userTransmitData(ERR_TIMEOUT, 1);
|
|
|
|
|
// 超时错误大概率是透传缆损坏,不主动重试,终止发送
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (rst == ERR_OK) // ACK正常
|
2024-09-29 08:54:27 +00:00
|
|
|
|
{
|
|
|
|
|
lstState = ERR_OK;
|
|
|
|
|
userRxBuffList = userRxBuffList->next; // 正常则移动指针
|
|
|
|
|
deleteFirstNode(&userRxBuffList);
|
2024-09-30 07:09:26 +00:00
|
|
|
|
userTransmitData(ERR_OK, 1);
|
2024-09-29 08:54:27 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
lstState = ERR_NOK;
|
2024-10-17 08:44:45 +00:00
|
|
|
|
static uint8_t reTryCnt = 0;//当前重试次数
|
2024-09-29 08:54:27 +00:00
|
|
|
|
reTryCnt++;
|
|
|
|
|
if (reTryCnt > MAX_RETRY_CNT)
|
|
|
|
|
{
|
|
|
|
|
reTryCnt = 0;
|
|
|
|
|
lstState = ERR_OK;
|
2024-09-30 07:09:26 +00:00
|
|
|
|
userRxBuffList = userRxBuffList->next; // 次数超出阈值则移动指针
|
2024-09-29 08:54:27 +00:00
|
|
|
|
deleteFirstNode(&userRxBuffList);
|
2024-09-30 07:09:26 +00:00
|
|
|
|
// userTransmitData(CMD_ACK_NOK, 1);
|
|
|
|
|
userTransmitData(ERR_NOK,1);
|
2024-09-29 08:54:27 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-30 07:09:26 +00:00
|
|
|
|
//失败的原因可能是数据碰撞,需要根据优先级等待不同的时间后进行重试
|
2024-09-29 08:54:27 +00:00
|
|
|
|
multiTimerStop(&timeoutTimer);
|
2024-10-17 08:44:45 +00:00
|
|
|
|
multiTimerStart(&timeoutTimer, time2Retry, reTryTimerCallback, &isRetryTimeOut); // Start timer
|
2024-09-29 08:54:27 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // 无ACK
|
|
|
|
|
{
|
|
|
|
|
lstState = ERR_OK;
|
|
|
|
|
userRxBuffList = userRxBuffList->next; // 移动指针
|
|
|
|
|
deleteFirstNode(&userRxBuffList);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-29 01:45:34 +00:00
|
|
|
|
}
|
2024-09-12 08:18:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void main()
|
|
|
|
|
{
|
|
|
|
|
handleTR();
|
|
|
|
|
}
|