302 lines
7.5 KiB
C
302 lines
7.5 KiB
C
/******************************************************************************
|
||
* @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] = "bluesun-ess-XJ-5G", wifiPassWord[40] = "bluesun007", bleName[40] = "bsm1";
|
||
|
||
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.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 "aa" // 订阅/发布的主题
|
||
#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;
|
||
}
|