R1_up/User/device/nuc.c
2025-06-12 17:07:28 +08:00

199 lines
5.3 KiB
C

#include "nuc.h"
#include <string.h>
#include "crc_ccitt.h"
static osThreadId_t thread_alert;
uint8_t nucbuf[32];
uint8_t packet[32]; // 假设最大数据包长度为 32 字节
static void NUC_IdleCallback(void) {
osThreadFlagsSet(thread_alert,SIGNAL_NUC_RAW_REDY);
}
int8_t NUC_Init(NUC_t *nuc){
if(nuc == NULL) return DEVICE_ERR_NULL;
if((thread_alert = osThreadGetId()) == NULL ) return DEVICE_ERR_NULL;
BSP_UART_RegisterCallback(BSP_UART_AI,BSP_UART_IDLE_LINE_CB,
NUC_IdleCallback);
return DEVICE_OK;
}
int8_t NUC_StartReceiving(void) {
if (HAL_UARTEx_ReceiveToIdle_DMA(BSP_UART_GetHandle(BSP_UART_AI),
(uint8_t *)nucbuf,
sizeof(nucbuf)) == HAL_OK)
return DEVICE_OK;
return DEVICE_ERR;
}
int8_t NUC_Restart(void) {
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_AI));
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_AI));
return DEVICE_OK;
}
bool_t NUC_WaitDmaCplt(void) {
return (osThreadFlagsWait(SIGNAL_NUC_RAW_REDY, osFlagsWaitAll,500) ==
SIGNAL_NUC_RAW_REDY);
}
int8_t NUC_SendPacket(void *data, uint16_t length) {
if (data == NULL || length == 0) {
return DEVICE_ERR_NULL; // 数据为空或长度为 0
}
uint8_t packet[32]; // 假设最大数据包长度为 32 字节
if (length + 5 > sizeof(packet)) { // 帧头 + 帧类型 + 数据 + CRC + 帧尾
return DEVICE_ERR_OVERFLOW; // 数据包长度超出限制
}
// 构建数据包
packet[0] = HEAD; // 帧头
packet[1] = SEND; // 发送帧类型
memcpy(&packet[2], data, length); // 数据内容
uint16_t crc = do_crc_table(data, length); // 计算 CRC 校验
packet[length + 2] = (crc >> 8) & 0xFF; // CRC 高字节
packet[length + 3] = crc & 0xFF; // CRC 低字节
packet[length + 4] = TAIL; // 帧尾
// 发送数据包
if (HAL_UART_Transmit(BSP_UART_GetHandle(BSP_UART_AI), packet, length + 5, HAL_MAX_DELAY) != HAL_OK) {
return DEVICE_ERR; // 发送失败
}
return DEVICE_OK; // 发送成功
}
int8_t NUC_RawParse(NUC_t *n) {
if (n == NULL) return DEVICE_ERR_NULL;
union {
float x[3];
char data[12];
} instance; // 方便在浮点数和字符数组之间进行数据转换
// 校验数据包头
if(nucbuf[0]!=HEAD) goto error; //发送ID不是底盘
else
{
n->status_fromnuc = nucbuf[1];
n->ctrl_status = nucbuf[2];
switch (n->status_fromnuc) {
case VISION:
/* 协议格式
0xFF HEAD
0x02 控制帧
0x01 相机帧
x fp32
y fp32
z fp32
0xFE TAIL
*/
if (nucbuf[7] != TAIL) goto error;
instance.data[3] = nucbuf[6];
instance.data[2] = nucbuf[5];
instance.data[1] = nucbuf[4];
instance.data[0] = nucbuf[3];
n->vision.x = instance.x[0];
instance.data[7] = nucbuf[7];
instance.data[6] = nucbuf[8];
instance.data[5] = nucbuf[9];
instance.data[4] = nucbuf[10];
n->vision.y = instance.x[1];
instance.data[11] = nucbuf[11];
instance.data[10] = nucbuf[12];
instance.data[9] = nucbuf[13];
instance.data[8] = nucbuf[14];
n->vision.z = instance.x[2];
break;
}
return DEVICE_OK;
}
error:
return DEVICE_ERR;
}
// int8_t NUC_RawParse(NUC_t *n) {
// if (n == NULL) return DEVICE_ERR_NULL;
// union {
// float x[3];
// char data[12];
// } instance; // 方便在浮点数和字符数组之间进行数据转换
// // 校验数据包头
// if (nucbuf[0] != HEAD) {
// return DEVICE_ERR;
// }
// // 提取数据包中的 CRC 值(假设 CRC 值在数据包的最后两个字节)
// uint16_t received_crc = (nucbuf[16] << 8) | nucbuf[17]; // 假设 CRC 在第 16 和 17 字节
// uint16_t calculated_crc = do_crc_table(nucbuf, 16); // 计算前 16 字节的 CRC
// // 校验 CRC
// if (received_crc == calculated_crc) {
// n->status_fromnuc = nucbuf[1];
// n->ctrl_status = nucbuf[2];
// switch (n->status_fromnuc) {
// case VISION:
// /* 协议格式
// 0xFF HEAD
// 0x02 控制帧
// 0x01 相机帧
// x fp32
// y fp32
// z fp32
// 0xFE TAIL
// */
// if (nucbuf[15] != TAIL) goto error;
// instance.data[3] = nucbuf[3];
// instance.data[2] = nucbuf[4];
// instance.data[1] = nucbuf[5];
// instance.data[0] = nucbuf[6];
// n->vision.x = instance.x[0];
// instance.data[7] = nucbuf[7];
// instance.data[6] = nucbuf[8];
// instance.data[5] = nucbuf[9];
// instance.data[4] = nucbuf[10];
// n->vision.y = instance.x[1];
// instance.data[11] = nucbuf[11];
// instance.data[10] = nucbuf[12];
// instance.data[9] = nucbuf[13];
// instance.data[8] = nucbuf[14];
// n->vision.z = instance.x[2];
// break;
// }
// return DEVICE_OK;
// }
// else
// {
// return DEVICE_ERR;
// }
// error:
// return DEVICE_ERR;
// }
int8_t NUC_HandleOffline(NUC_t *cmd)
{
if(cmd == NULL) return DEVICE_ERR_NULL;
memset(cmd, 0, sizeof(*cmd));
return 0;
}