/** * @file app_hart.c * @author xxx * @date 2023-07-06 13:08:52 * @brief 此文件主要实现板卡的HART功能 * @copyright Copyright (c) 2023 by xxx, All Rights Reserved. */ #include "app.h" #include "uarts.h" #include "test_bsp.h" #include "at_hc24.h" #include "bootload.h" #include "ymodem.h" #include "flow.h" #define HART_UART1 USART1 #define HART_UART2 UART5 #define HART_UART_RXSIZE (240u) #define BLE_UART_RXSIZE (1100u) // 接收1100个字节,考虑到BOOTLOAD需要接收大量数据,在RAM允许的情况下,可以适当增大 #define HART_UART_TXSIZE (240u) // 发送240个字节 uart_t *uarts[APP_UART_MAX]; static struct flow hart_handle_fw; // HART处理流程 static struct flow_sem hart_msg_sem; // 消息信号量,用于同步 int8_t hart_msg_uart_index; // 消息来源的串口索引,会有并发问题,不能蓝牙和HART同时来数据 static uint8_t hart_recv_msg[HART_UART_RXSIZE]; // HART接收数据缓存 static uint16_t hart_recv_msg_len; // HART接收数据长度 app_dynamics_t app_dynamics; static __IO BOOL hart_idle = TRUE; /** * @brief 蓝牙输出 * @param {uint8_t} *data * @param {uint16_t} len * @return {*} * @note */ void h24_bluetooth_output(uint8_t *data, uint16_t len) { DBG_ASSERT(data != NULL __DBG_LINE); if (len == 0) { return; } else { if (uarts[APP_UART_2] != NULL) { uart_send_data(uarts[APP_UART_2], data, len); } } } void h24_bluetooth_output_dbg(uint8_t *data, uint16_t len) { DBG_ASSERT(data != NULL __DBG_LINE); if (len == 0) { return; } else { #if H24_BLE_OUTPUT_DBG == TRUE if (BIT_IS_SET(hc_24_state, BIT2)) { h24_bluetooth_output(data, len); } #endif } } /** * @brief 蓝牙H24模块配置工作 * @return {*} * @note */ void h24_bluetooth_work(uint8_t index) { uint8_t len = 0; char data[128]; osel_memset((uint8_t *)data, 0, 128); #ifdef V4 char device_id[] = "LP4-???"; #elif V5 char device_id[] = "LP5-???"; #elif BOOTLOAD char device_id[] = "BOOTLOAD"; #else char device_id[] = "LP3-???"; #endif char *test_cmd[AT_END] = { "AT", "AT+NAME", "AT+NAME=%s", "AT+RESET", }; switch (index) { case 1: // 测试指令 { hc_24_state = 0; sprintf(data, test_cmd[AT_CMD_TEST]); len = osel_mstrlen((unsigned char *)data); h24_bluetooth_output((uint8_t *)data, len); break; } case 2: // 获取设备名称 { at_set_memcmp_cache((unsigned char *)device_id, osel_mstrlen((unsigned char *)device_id)); sprintf(data, test_cmd[AT_CMD_NAME_REQ]); len = osel_mstrlen((unsigned char *)data); h24_bluetooth_output((uint8_t *)data, len); break; } case 3: // 设置设备名称 { at_set_memcmp_cache((unsigned char *)device_id, osel_mstrlen((unsigned char *)device_id)); sprintf(data, test_cmd[AT_CMD_NAME], device_id); len = osel_mstrlen((unsigned char *)data); h24_bluetooth_output((uint8_t *)data, len); break; } case 4: // 复位 { hc_24_state = 0; sprintf(data, test_cmd[AT_CMD_DISA]); len = osel_mstrlen((unsigned char *)data); h24_bluetooth_output((uint8_t *)data, len); break; } case 100: { sprintf(data, "%f,%f,%f\r\n", 1.1, 2.2, 3.3); len = osel_mstrlen((unsigned char *)data); h24_bluetooth_output((uint8_t *)data, len); break; } default: break; } } // HART处理流程 static uint8_t hart_handle_inspection(struct flow *fl) { FL_HEAD(fl); for (;;) { FL_LOCK_WAIT_SEM_OR_TIMEOUT(fl, &hart_msg_sem, FL_CLOCK_SEC * 3600); if (FL_SEM_IS_RELEASE(fl, &hart_msg_sem) && hart_recv_msg_len != 0) { // hart_handle(hart_msg_uart_index, hart_recv_msg, hart_recv_msg_len); hart_recv_msg_len = 0; } } FL_TAIL(fl); } // HART接收处理 void hart_rx_process(void) { hart_handle_inspection(&hart_handle_fw); } // 串口1、5接收中断回调函数 static void hart_rx_cb(uint8_t uart_index, uint8_t *data, uint16_t len) { DBG_ASSERT(uart_index < APP_UART_MAX __DBG_LINE); hart_idle = FALSE; if (data[0] == 'O' && data[1] == 'K') // 蓝牙协议 { data[0] = 'A'; data[1] = 'T'; at_cmd_parse(data, len); } else if (data[0] == 'B' && data[1] == 'T') // 收到BOOTLOAD启动命令 { if (osel_memcmp(data, "BT RUN", 6) == 0) { if (get_app_preload_bootload_flag() == FALSE) // 如果已经在BOOTLOAD模式下,不再重复启动 { set_app_preload_bootload_flag(TRUE); // 设置BOOTLOAD标志 bootload_transmit_from(uart_index); // 从指定位置开始发送数据 } } else if (osel_memcmp(data, "BT STOP", 7) == 0) { set_app_preload_bootload_flag(FALSE); // 设置BOOTLOAD标志 } } else { // 注:在BOOTLOAD模式下,不接收HART数据 #ifndef BOOTLOAD // 通过消息的方式存在蓝牙和HART模块并发冲突,实际情况不会发生,HART协议传输速度慢,存储的数据可以使用全局的方式 hart_msg_uart_index = uart_index; osel_memcpy(hart_recv_msg, data, len); hart_recv_msg_len = len; FLOW_SEM_RELEASE(&hart_msg_sem); #else rym_receive(uart_index, data, len); #endif } hart_idle = TRUE; } static void hart_tx_complete_cb(void) { // 串口1发送完成回调函数 HART_RTS_ON(); } // HART协议的使用的串口 --- 串口1 void hart_uart_init(void) { LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); GPIO_SET_OUTPUT(HART_PWR_GPIO_Port, HART_PWR_Pin); GPIO_SET_OUTPUT(HART_RST_GPIO_Port, HART_RST_Pin); GPIO_SET_OUTPUT(HART_RTS_GPIO_Port, HART_RTS_Pin); GPIO_SET_ALTERNATE(HART_TX_GPIO_Port, HART_TX_Pin); GPIO_SET_ALTERNATE(HART_RX_GPIO_Port, HART_RX_Pin); LL_mDelay(10); // 串口1初始化开始 HART_RTS_ON(); HART_RST_OFF(); LL_mDelay(20); HART_RST_ON(); HART_EN_DISABLE(); HART_EN_ENABLE(); HART_RTS_ON(); if (uarts[APP_UART_1] == NULL) { LL_mDelay(100); uarts[APP_UART_1] = uart_create(HART_UART1, TRUE, HART_UART_RXSIZE, hart_rx_cb, TRUE, HART_UART_TXSIZE, hart_tx_complete_cb); uarts[APP_UART_1]->uart_index = APP_UART_1; uarts[APP_UART_1]->dma = DMA2; uarts[APP_UART_1]->dma_rx_channel = LL_DMA_CHANNEL_7; uarts[APP_UART_1]->dma_tx_channel = LL_DMA_CHANNEL_6; uart_recv_en(uarts[APP_UART_1]); } // 串口1初始化结束 } // HART协议使用的串口,为模拟IO口 void hart_uart_dinit(void) { HART_EN_DISABLE(); LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_USART1); LL_USART_Disable(USART1); GPIO_SET_ANALOG(HART_PWR_GPIO_Port, HART_PWR_Pin); GPIO_SET_ANALOG(HART_RST_GPIO_Port, HART_RST_Pin); GPIO_SET_ANALOG(HART_CD_GPIO_Port, HART_CD_Pin); GPIO_SET_ANALOG(HART_TX_GPIO_Port, HART_TX_Pin); GPIO_SET_ANALOG(HART_RX_GPIO_Port, HART_RX_Pin); } // 蓝牙模块串口初始化 void hart_ble_init(void) { LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART5); GPIO_SET_OUTPUT(BLE_PWR_GPIO_Port, BLE_PWR_Pin); GPIO_SET_INPUT(BLE_RST_GPIO_Port, BLE_RST_Pin); GPIO_SET_ALTERNATE(BLE_TX_GPIO_Port, BLE_TX_Pin); GPIO_SET_ALTERNATE(BLE_RX_GPIO_Port, BLE_RX_Pin); BLE_EN_ENABLE(); if (uarts[APP_UART_2] == NULL) { LL_mDelay(100); uarts[APP_UART_2] = uart_create(HART_UART2, TRUE, BLE_UART_RXSIZE, hart_rx_cb, TRUE, HART_UART_TXSIZE, NULL); uarts[APP_UART_2]->uart_index = APP_UART_2; uarts[APP_UART_2]->dma = DMA2; uarts[APP_UART_2]->dma_rx_channel = LL_DMA_CHANNEL_2; uarts[APP_UART_2]->dma_tx_channel = LL_DMA_CHANNEL_1; uart_recv_en(uarts[APP_UART_2]); } } // 蓝牙模块端口IO口反初始化 void hart_ble_dinit(void) { // 关闭蓝牙串口 BLE_EN_DISABLE(); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_UART5); LL_USART_Disable(UART5); // 端口转成模拟IO口 GPIO_SET_ANALOG(BLE_PWR_GPIO_Port, BLE_PWR_Pin); GPIO_SET_ANALOG(BLE_RST_GPIO_Port, BLE_RST_Pin); GPIO_SET_ANALOG(BLE_TX_GPIO_Port, BLE_TX_Pin); GPIO_SET_ANALOG(BLE_RX_GPIO_Port, BLE_RX_Pin); } // 判断是否闲置的结果 BOOL app_hart_is_idle(void) { return hart_idle; } // HART初始化 BOOL app_hart_init(void) { uarts[APP_UART_1] = NULL; uarts[APP_UART_2] = NULL; FL_INIT(&hart_handle_fw); // 系统检测 // 判断当前电流 >=8mA启动蓝牙 >=3.8mA启动uart // 注:串口初始化移动到all_flow // hart_uart_init(); // hart_ble_init(); return TRUE; }