/* * usart_biz.c * * Created on: 2026-02-26 * Author: wangfq * Updated: 2026-07-02 — 使用 loop_uart_proto 帧解析器替代 timeout heuristic */ #include "config.h" #include "cmcng.h" #include "loop_uart_proto.h" #include #include "dbn_ble_srv.h" void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void uart_init(void){ GPIO_InitTypeDef GPIO_InitStructure = {0}; USART_InitTypeDef USART_InitStructure = {0}; NVIC_InitTypeDef NVIC_InitStructure = {0}; // usart1 : peripheral / DEBUG //usart2 :loop mcu RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Tx GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // Rx GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 192000; // Loop MCU 实际波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART2, &USART_InitStructure); // USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_Cmd(USART2, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化帧解析器 lup_frame_reset(); } /********************************************************************* * @fn USART1_IRQHandler * * @brief This function handles USART1 global interrupt request. * * @return none */ void USART1_IRQHandler(void) { } /********************************************************************* * @fn USART2_IRQHandler * * @brief USART2 RX — 使用 lup_feed_byte() 帧解析器 * 当解析出完整帧时,复制到 g_pkg_uart_2.pkg 并设置 flag * * @return none */ void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { uint8_t _dat = USART_ReceiveData(USART2); // 喂给帧解析器 if (lup_feed_byte(_dat)) { // 帧接收完成,复制到 g_pkg_uart_2 const uint8_t *frame = lup_frame_data(); uint16_t frame_len = lup_frame_len(); if (frame_len <= BUFF_STACK_SIZE) { memcpy(g_pkg_uart_2.pkg, frame, frame_len); g_pkg_uart_2.offset = frame_len; g_pkg_uart_2.flag = 1; g_pkg_uart_2.tick = 0; } lup_frame_reset(); } else if (g_lup_parser.state != LUP_FRAME_STATE_IDLE) { // 正在接收帧中,tick 归零 g_pkg_uart_2.tick = 0; } } } void UART2_SendString(uint8_t *buf, uint16_t len) { uint16_t _len = len; while(_len){ while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); USART_SendData(USART2, *buf++); _len--; } while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); } void UART1_SendString(uint8_t *buf, uint16_t len) { uint16_t _len = len; while(_len){ while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_SendData(USART1, *buf++); _len--; } } /* * uart_srv — 主循环中调用,处理已接收完整的 UART2 帧 * * 处理流程: * 1. 0x7F + 0xC0/0x0C → 传感器数据上报 * - 若无 BLE 连接 → 标记 `_report_flag`,在 TCP JSON 中处理 * - 若有 BLE 连接且 acs_enable → 转 0x8F 前缀发给 BLE * 2. 0x7F + 其他 CMD → 响应帧,交给 lup_process_frame() 匹配挂起命令 * 3. 非 0x7F → 调试打印(可能是字符串等) */ void uart_srv(void) { uint8_t i; uint8_t _report_flag = 0; // 检查命令超时 lup_cmd_check_timeout(); if(g_pkg_uart_2.flag){ if(g_flag_counter_ota.flag == 0){ if(g_pkg_uart_2.pkg[0] == 0x7F){ uint8_t cmd = g_pkg_uart_2.pkg[3]; // --- 所有 0x7F 帧先经过 lup_process_frame 校验 --- // 0xC0: 校验后通过回调直接推送 TCP JSON // 其他: 校验后匹配挂起命令 lup_process_frame(g_pkg_uart_2.pkg, g_pkg_uart_2.offset); // --- 传感器上报 (0xC0) 分流 --- // 回调已处理 TCP 推送,此处仅处理 BLE 转发 if(cmd == LUP_CMD_SENSOR_REPORT) { if(g_dbn_ble_state_acs_enable.flag != 0){ // BLE ACS 已连接 → 改 Magic 为 0x8F 发给 BLE g_pkg_uart_2.pkg[0] = 0x8F; _report_flag = 1; // 保留给 BLE } // else: 回调已推送 TCP,直接清理 } // 调试打印 for(i = 0; i < g_pkg_uart_2.offset; i++){ PRINT(" %02X", g_pkg_uart_2.pkg[i]); } PRINT("\n"); if(_report_flag){ // 传感器帧保留在 pkg 中供上层 (tcp_json_srv) 处理 // 不 InitPkgUart — 由 tcp_json_push_sensor 消费后清理 } } else { // 非 0x7F 魔法字节 PRINT("Rcv_len:%d,dat: %s\n", g_pkg_uart_2.offset, g_pkg_uart_2.pkg); } } else{ // OTA 模式 — 忽略 Loop MCU 数据 } if(g_flag_bt_state){ g_flag_notify_temp = set_response_tran_to_notify(g_pkg_uart_2.pkg, g_pkg_uart_2.offset, &g_notify_buftemp); } else{ g_dbn_ble_state_acs_enable.flag = 0; } // 只有非 _report_flag 时才立即清空 // _report_flag 的帧由 tcp_json_push_sensor 消费后清理 if (!_report_flag) { InitPkgUart(&g_pkg_uart_2); } } }