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

314 lines
7.5 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};
uint8_t wifiName[40] = {0}, wifiPassWord[40] = {0}, bleName[40] = {0};
char cmd[100] = {0}; //降低栈空间使用
//定义
WifiBleItem qfc41dItem = {
.dev = QFC41D_UART_PORT,
.buf_pos = 0,
.buf_size = QFC41D_MAX_RECV_SIZE,
.buf = rev_buff,
.sendCall = NULL,
};
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'; // 添加结束符
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
}
// 发送 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 ;
}
// 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;
}
static uint8_t drv_ble_init()
{
// 1. 初始化,蓝牙作为服务器
if (!drv_at_send_cmd("AT+QBLEINIT=2", "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");
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);
//设置接收回调函数
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 "mqtt.example.com" // 你的 MQTT 服务器地址
#define MQTT_PORT 1883 // MQTT 端口
#define MQTT_CLIENT_ID "fc41d_client" // 客户端 ID
#define MQTT_USER "user" // MQTT 用户名
#define MQTT_PASSWORD "password" // MQTT 密码
#define MQTT_TOPIC "fc41d/topic" // 订阅/发布的主题
#define MQTT_MESSAGE "Hello from FC41D!" // 发送的消息
// 连接 MQTT 服务器
static 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=1,\"%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=1,%s,%s,%s",MQTT_CLIENT_ID,MQTT_USER, MQTT_PASSWORD);
if (!drv_at_send_cmd(cmd, "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=1,1,\"%s\",0", MQTT_TOPIC);
if (!drv_at_send_cmd(cmd, "OK", WIFI_TIMEOUT))
{
KIT_PRINTF("Failed to subscribe to topic!\r\n");
return 1;
}
KIT_PRINTF("Subscribed to MQTT topic successfully!\r\n");
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,0,0,%s,%d,%s",MQTT_TOPIC, length,str);
if (!drv_at_send_cmd(cmd, "OK", WIFI_TIMEOUT))
{
KIT_PRINTF("Failed to publish message!\r\n");
return 1;
}
KIT_PRINTF("MQTT Message Published Successfully!\r\n");
return 0;
}
// MQTT 初始化
uint8_t drv_mqtt_init()
{
if (drv_mqtt_connect() != 0)
{
return 1;
}
if (drv_mqtt_subscribe() != 0)
{
return 1;
}
return 0;
}