forked from gary/BCU
2
0
Fork 0
BCU/library/drv_peripheral/drv_qfc41d.c

462 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
* @file drv_qfc41d.c
* @brief drv_qfc41d driver
* @version V1.0
* @author Gary
* @copyright
******************************************************************************/
#include "drv_qfc41d.h"
uint8_t rev_buff[QFC41D_MAX_RECV_SIZE] = {0};
uint8_t send_buff[QFC41D_MAX_SEND_SIZE] = {0};
char wifiName[40] = "BLUESUNESS", wifiPassWord[40] = "bluesun009", bleName[40] = "bsm1";
#define MAX_PAYLOAD_LEN 128
char cmd[1000] = {0}; //降低栈空间使用
#define TX_DMA_BUFFER_SIZE 2000
uint8_t dma_tx_buffer[TX_DMA_BUFFER_SIZE];
volatile uint8_t dma_tx_busy = 0;
//定义
WifiBleItem qfc41dItem = {
.dev = QFC41D_UART_PORT,
.buf_pos = 0,
.buf_size = QFC41D_MAX_RECV_SIZE,
.buf = rev_buff,
.sendCall = NULL,
};
void parse_mqtt_message(char* message)
{
// 示例消息: +QMTRECV: 0,31,"bluesun/bms/control/123",11,"MQ3156+1MQ"
uint16_t first = 0;
uint16_t second = 0;
char* quotes[4] = {0};
int quote_count = 0;
for(char* p = message; *p && quote_count < 4; p++)
{
if(*p == '\"')
{
quotes[quote_count++] = p;
}
}
// 匹配四个引号
if(quote_count < 4)
{
return;
}
// 提取payload内容
char* payload_start = quotes[2] + 1;
char* payload_end = quotes[3];
size_t payload_len = payload_end - payload_start;
if(payload_len >= MAX_PAYLOAD_LEN)
{
return;
}
char payload[MAX_PAYLOAD_LEN];
strncpy(payload, payload_start, payload_len);
payload[payload_len] = '\0';
char* processed = payload;
size_t len = strlen(processed);
// 去除开头"MQ"
if(len >= 2 && strncmp(processed, "MQ", 2) == 0)
{
processed += 2;
len -= 2;
}
// 去除结尾"MQ"
if(len >= 2 && strcmp(processed + len - 2, "MQ") == 0)
{
processed[len - 2] = '\0';
len -= 2;
}
// 分离参数
char* plus_pos = strchr(processed, '+');
if(!plus_pos)
{
return;
}
// 后续增加对主题部分的解析,读取是全部读取,配置下发,是一条一条下发
// 解析主题
*plus_pos = '\0'; // 分割字符串
first = atoi(processed);
second = atoi(plus_pos + 1);
if((first >= 3000) && (first <= 3168))
{
bcu_data_set_0x06_msg(first, second);
}
else if ((first >= 4000) && (first <= 4999))
{
hmi_write_modbus_cfg(first - 4000, second);
}
}
static void drv_qfc41d_push_data(WifiBleItem* item, uint8_t *buf, uint16_t len)
{
uint16_t i = 0;
if((item != NULL) && (item->buf_pos + len < item->buf_size))
{
item->buf[item->buf_pos++] = buf[i];
// 处理换行符,表示一条完整的 AT 指令返回
if (buf[i] == '\n')
{
item->buf[item->buf_pos] = '\0'; // 添加结束符
if (item->buf_pos < 100)
{
parse_mqtt_message(item->buf); // 解析消息
}
item->buf_pos = 0; // 重置索引,准备下一条数据
}
}
}
static void drv_qf41d_uart_rx_it_call(kit_ret_e res, void *data)
{
OS_TRACE_ISR_ENTER();
drv_qfc41d_push_data(&qfc41dItem, data, 1);
OS_TRACE_ISR_EXIT();
}
// 发送单个字符
void drv_wireless_send_char(char c)
{
while (!(USART2->SR & USART_SR_TXE)); // 等待发送缓冲区空
USART2->DR = c;
}
// 发送字符串
void drv_wireless_send_string(const char *str)
{
while (*str)
{
drv_wireless_send_char(*str++);
}
drv_wireless_send_char('\r'); // 发送 CR
drv_wireless_send_char('\n'); // 发送 LF
}
void drv_wireless_send_string_dma(const char *str)
{
bsp_task_delay_ms(250);
if (dma_tx_busy) return; // 正在发送,丢弃或排队视情况处理
uint16_t len = 0;
// 拷贝数据到 DMA 缓冲区
while (*str && len < TX_DMA_BUFFER_SIZE - 2) {
dma_tx_buffer[len++] = *str++;
}
// 添加 \r\n
dma_tx_buffer[len++] = '\r';
dma_tx_buffer[len++] = '\n';
// 设置 DMA 参数并启动
DMA1_Stream6->CR &= ~DMA_SxCR_EN;
while (DMA1_Stream6->CR & DMA_SxCR_EN);
DMA1_Stream6->M0AR = (uint32_t)dma_tx_buffer;
DMA1_Stream6->NDTR = len;
dma_tx_busy = 1;
DMA1_Stream6->CR |= DMA_SxCR_EN;
USART2->CR3 |= USART_CR3_DMAT; // 开启 DMA 发送
}
// 发送 AT 指令并等待返回值
int drv_at_send_cmd(const char *cmd, const char *response, uint32_t timeout)
{
memset(qfc41dItem.buf, 0, QFC41D_MAX_RECV_SIZE);
qfc41dItem.buf_pos = 0; // 清空接收缓冲区索引
drv_wireless_send_string(cmd);
uint32_t start_time = kit_time_get_tick(); // 获取当前时间
while (kit_time_get_tick() - start_time < timeout)
{
if (strstr((char *)qfc41dItem.buf, response))
{
return 1; // 成功匹配返回值
}
}
return 0; // 超时未收到期望数据
}
static uint8_t drv_wifi_init()
{
// 1. 设置模组波特率
/*
if (!drv_at_send_cmd(QFC41D_SET_BATE, "OK", WIFI_TIMEOUT))
{
KIT_PRINTF("WiFi Module not responding!\r\n");
return 1 ;
}
*/
// 2. 测试 AT 指令
if (!drv_at_send_cmd("AT", "OK", WIFI_TIMEOUT))
{
// KIT_PRINTF("WiFi Module not responding!\r\n");
return 1 ;
}
if (!drv_at_send_cmd("AT+QSTASTOP", "OK", WIFI_TIMEOUT))
{
// KIT_PRINTF("Failed to set WiFi mode!\r\n");
return 1;
}
if (!drv_at_send_cmd("AT+QSOFTAPSTOP", "OK", WIFI_TIMEOUT))
{
// KIT_PRINTF("Failed to set WiFi mode!\r\n");
return 1;
}
// if (!drv_at_send_cmd("AT+QSTAAPINFO=BLUESUNESS,bluesun009", "OK", WIFI_CONNECT_TIMEOUT))
// {
// KIT_PRINTF("Failed to set WiFi mode!\r\n");
// return 1;
// }
// kit_time_dly_ms(2000);
// if (!drv_at_send_cmd("AT+QSTAAPINFO=BLUESUNESS,bluesun009", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to set WiFi mode!\r\n");
// return 1;
// }
// 3. 设置 Wi-Fi 为 DHCP使能
// if (!drv_at_send_cmd(QFC41D_SET_DHCP_ENABLE, "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to set WiFi mode!\r\n");
// return 1;
// }
// 4. 连接 Wi-Fi
// snprintf(cmd, sizeof(cmd), "AT+QSTAAPINFODEF=%s,%s", wifiName, wifiPassWord);
// if (!drv_at_send_cmd(cmd, "WIFI CONNECTED", WIFI_TIMEOUT * 2))
// {
// KIT_PRINTF("Failed to connect to WiFi!\r\n");
// //return 1; //错误不返回-防止影响主任务执行
// }
// // 5. 获取 IP 地址
// if (!drv_at_send_cmd("AT+QGETIP=station", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to get IP address!\r\n");
// //return 1; //错误不返回-防止影响主任务执行
// }
// KIT_PRINTF("WiFi Initialization Successful!\r\n");
return 0;
}
uint8_t drv_ble_init()
{
// 1. 初始化,蓝牙作为服务器
// if (!drv_at_send_cmd("AT+QBLEINIT=3", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to power off BLE!\r\n");
// return 1;
// }
//
// // 2. 设置蓝牙名称
// snprintf(cmd, sizeof(cmd), "AT+QBLENAME=%s", bleName);
// if (!drv_at_send_cmd(cmd, "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to set BLE name!\r\n");
// return 1;
// }
// // 3. 设置广播参数
// if (!drv_at_send_cmd("AT+QBLEADVPARAM=2048,2048", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to enable BLE!\r\n");
// return 1;
// }
//
// // 4. 设置广播数据
// if (!drv_at_send_cmd("AT+QBLEADVDATA=06094643343144", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to enable BLE!\r\n");
// return 1;
// }
// // 5. 创建服务
// if (!drv_at_send_cmd("AT+QBLEGATTSSRV=FFF0", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to set BLE role!\r\n");
// return 1;
// }
//
// // 6. 创建特征值
// if (!drv_at_send_cmd("AT+QBLEGATTSSRV=FFF1", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to set BLE role!\r\n");
// return 1;
// }
// // 7. 开始广播
// if (!drv_at_send_cmd("AT+QBLEADVSTART", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to start BLE advertising!\r\n");
// return 1;
// }
// KIT_PRINTF("BLE Initialization Successful!\r\n");
if (!drv_at_send_cmd("AT+QBLEINIT=3", "OK", WIFI_TIMEOUT))
{
// KIT_PRINTF("Failed to set BLE role!\r\n");
return 1;
}
//设置wifi名称必须以BSM开头后缀可以加sn码
if (!drv_at_send_cmd("AT+QBLENAME=BSM11223344", "OK", WIFI_TIMEOUT))
{
// KIT_PRINTF("Failed to start BLE advertising!\r\n");
return 1;
}
return 0;
}
uint8_t drv_qfc41d_init(void)
{
//初始化串口
drv_uart_init((UartDev)qfc41dItem.dev, 115200, 0 | UART_CFG_STOP_BIT_1, kGpioType_WIRELESSUart_Tx, kGpioType_WIRELESSUart_Rx);
USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_UE;
//设置接收回调函数
drv_uart_set_interrupt(QFC41D_UART_PORT, kUartInterrupt_Rx, APP_CFG_INT_PRIO_UART2_RX, drv_qf41d_uart_rx_it_call);//#define SIM_UART_PORT kUartDev_2
//初始化wifi
// if(drv_wifi_init() != 0)
// {
// return 1;
// }
//初始化蓝牙BLE
if (drv_ble_init() != 0)
{
return 1;
}
return 0;
}
#define MQTT_BROKER "47.120.14.45" // 你的 MQTT 服务器地址
#define MQTT_PORT 3011 // MQTT 端口
#define MQTT_CLIENT_ID "fc41d_client" // 客户端 ID
#define MQTT_USER "user" // MQTT 用户名
#define MQTT_PASSWORD "password" // MQTT 密码
#define MQTT_TOPIC "bluesun/bms/period/11223344" // 订阅/发布的主题
#define MQTT_MESSAGE "Hello from FC41D!" // 发送的消息
// 连接 MQTT 服务器
//uint8_t drv_mqtt_connect()
//{
//
// //1、设置 MQTT 协议的版本号为 V4
//// snprintf(cmd, sizeof(cmd), "AT+QMTCFG=\"version\",1,4");
//// if (!drv_at_send_cmd(cmd, "OK", WIFI_TIMEOUT))
//// {
//// KIT_PRINTF("Failed to set MQTT server!\r\n");
//// return 1;
//// }
//
// //2、建立 MQTT 客户端与服务器之间的会话连接
// snprintf(cmd, sizeof(cmd), "AT+QMTOPEN=0,\"%s\",%d",MQTT_BROKER,MQTT_PORT);
// if (!drv_at_send_cmd(cmd, "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to set MQTT server!\r\n");
// return 1;
// }
//
// //2、MQTT 客户端与服务器之间建立 MQTT 连接 AT+QMTCONN=<clientID>,<client_identity>,<username>,<password>
// //snprintf(cmd, sizeof(cmd), "AT+QMTCONN=0,%s,%s,%s",MQTT_CLIENT_ID,MQTT_USER, MQTT_PASSWORD);
// if (!drv_at_send_cmd("AT+QMTCONN=0,\"clientBCUwifi03\"", "OK", WIFI_TIMEOUT))
// {
// KIT_PRINTF("Failed to set MQTT client credentials!\r\n");
// return 1;
// }
// KIT_PRINTF("MQTT Connection Successful!\r\n");
// return 0;
//}
// 订阅 MQTT 主题
static uint8_t drv_mqtt_subscribe()
{
snprintf(cmd, sizeof(cmd), "AT+MQTTSUB=0,1,\"%s\",2", MQTT_TOPIC);
drv_wireless_send_string(cmd);
return 0;
}
// 发布 MQTT 消息
/*
* AT+QMTPUB=<clientID>,<msgID>,<QoS>,<retain>,<topic>,<payload_len gth>,<payload>
* length 范围0~1500
* str 是mqtt传输的json串
*/
uint8_t drv_mqtt_publish(char* str,uint16_t length)
{
snprintf(cmd, sizeof(cmd), "AT+QMTPUB=1,1,2,0,%s,%d,%s",MQTT_TOPIC, length, str);
if (!drv_at_send_cmd(cmd, "OK\0", WIFI_TIMEOUT))
{
// KIT_PRINTF("Failed to publish message!\r\n");
return 1;
}
// KIT_PRINTF("MQTT Message Published Successfully!\r\n");
return 0;
}
uint8_t drv_mqtt_publish_no_respose(char* str,uint16_t length)
{
// snprintf(cmd, sizeof(cmd), "AT+QMTPUB=0,1,2,0,%s,%d,%s",MQTT_TOPIC, length, str);
snprintf(cmd, sizeof(cmd), "AT+QMTPUB=1,1,2,0,\"%s\",%d,\"%s\"", MQTT_TOPIC, length, str);
// drv_wireless_send_string(cmd); // 未使用DMA
drv_wireless_send_string_dma(cmd); // 使用DMA
// kit_time_dly_ms(100);
return 0;
}
// MQTT 初始化
//uint8_t drv_mqtt_init()
//{
// if (drv_mqtt_connect() != 0)
// {
// return 1;
// }
// if (drv_mqtt_subscribe() != 0)
// {
// return 1;
// }
// return 0;
//}