318 lines
8.8 KiB
C
318 lines
8.8 KiB
C
/**
|
||
* @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;
|
||
}
|
||
|