#include "nuc.h" #include #include "crc_ccitt.h" static osThreadId_t thread_alert; volatile uint32_t drop_message = 0; uint8_t nucbuf[18]; uint8_t packet[32]; // 假设最大数据包长度为 32 字节 static void NUC_CBLTCallback(void) { osThreadFlagsSet(thread_alert, SIGNAL_NUC_RAW_REDY); } uint32_t error_code; static void NUC_ERRORCALLBACK(void) { NUC_Restart(); error_code = HAL_UART_GetError(BSP_UART_GetHandle(BSP_UART_AI)); } 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_RX_CPLT_CB, NUC_CBLTCallback); BSP_UART_RegisterCallback(BSP_UART_AI, BSP_UART_ERROR_CB, NUC_ERRORCALLBACK); return DEVICE_OK; } int8_t NUC_StartReceiving(void) { if (HAL_UART_Receive_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,20) == 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 // 0x07 // 控制帧 // 0x01 相机帧 // x 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[10]; // instance.data[6] = nucbuf[9]; // instance.data[5] = nucbuf[8]; // instance.data[4] = nucbuf[7]; // n->vision.y = instance.x[1]; // break; // } // return DEVICE_OK; // } // error: // drop_message++; // return DEVICE_ERR; // } /* 协议格式 0xFF HEAD x fp32 y fp32 0xFE TAIL */ 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 { if (nucbuf[17] != TAIL) goto error; instance.data[3] = nucbuf[8]; instance.data[2] = nucbuf[7]; instance.data[1] = nucbuf[6]; instance.data[0] = nucbuf[5]; n->vision.x = instance.x[0]; instance.data[7] = nucbuf[16]; instance.data[6] = nucbuf[15]; instance.data[5] = nucbuf[14]; instance.data[4] = nucbuf[13]; n->vision.y = instance.x[1]; } return DEVICE_OK; error: drop_message++; 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; }