作为主设备去连接其他蓝牙设备

This commit is contained in:
lmx
2025-12-03 10:44:14 +08:00
parent 754a529211
commit 86199b822e
24 changed files with 18 additions and 16 deletions

View File

@ -0,0 +1,238 @@
#include "task_func.h"
#include "./nvs/nvs.h"
#include "timer.h"
#include "system/includes.h"
// 包含BLE HID相关的API
#include "earphone.h" // 宏定义 EARPHONE_STATE_...
// =================================================================================
// 宏定义与日志
// =================================================================================
#define RC_LOG_ENABLE 1
#if RC_LOG_ENABLE
#define rc_log(format, ...) printf("[RC_APP] " format, ##__VA_ARGS__)
#else
#define rc_log(format, ...)
#endif
// =================================================================================
// 外部函数声明
// =================================================================================
extern void TYPE_V_EVENT(char* uid);
extern void TYPE_A_EVENT(char* uid);
// =================================================================================
// 静态函数声明
// =================================================================================
static RFID_Device_Type_t get_rfid_device_type(const u8* uid);
// BLE 状态转换的辅助函数
static void rc_ble_state_set_connecting(void);
static void rc_ble_state_set_connected(void);
static void rc_ble_state_set_disconnected(void);
// =================================================================================
// 全局变量
// =================================================================================
static RC_Context_t g_rc_context; // 全局上下文实例
static u16 g_rfid_timer_id = 0; // RFID 定时器ID
static u16 g_ble_timer_id = 0; // BLE 定时器ID
extern const struct ble_client_operation_t client_operation;
// =================================================================================
// 核心回调函数 (Core Callback Handlers)
// =================================================================================
/**
* @brief RFID回调处理函数 (由定时器周期性调用)
*/
void rc_rfid_callback_handler(void *priv)
{
u8 uid[UID_LENGTH] = {0};
//读id卡
// TYPE_V_EVENT((char *)uid);
TYPE_A_EVENT((char *)uid);
//是否有rfid卡靠近
u8 is_new_data = 0;
for (int i = 0; i < UID_LENGTH; i++) {
if (uid[i] != 0x00) {
is_new_data = 1;
break;
}
}
if (!is_new_data) {
return; //没有rfid卡靠近返回
}
rc_log("New RFID card detected.\n");
RFID_Device_Type_t device_type = get_rfid_device_type(uid);
switch (device_type) {
case RFID_DEVICE_TYPE_MAIN_BOARD: //船主板上的rfid卡
rc_log("Device is Main Board. Storing MAC...\n");
if (ble_hid_is_connected()) {
// 先停止扫描和连接尝试,实现断开
EARPHONE_STATE_CANCEL_PAGE_SCAN();
}
// 将新的MAC地址写入Flash
nvs_write_main_board_mac(uid);
// 重新启动扫描,以连接到新的主板
EARPHONE_STATE_SET_PAGE_SCAN_ENABLE();
break;
case RFID_DEVICE_TYPE_REMOTE_CONTROL:
rc_log("Device is another Remote Control.\n");
if (g_rc_context.state == RC_STATE_CONNECTED) {
rc_log("Sending teaming request to main board...\n");
// report_id 1 通常用于标准键盘/消费者报告
ble_hid_data_send(1, uid, UID_LENGTH);
} else {
rc_log("Not connected to main board, ignoring teaming request.\n");
}
break;
default:
rc_log("Unknown RFID device type.\n");
break;
}
}
/**
* @brief BLE回调处理函数 (由定时器周期性调用)
*/
void rc_ble_callback_handler(void *priv)
{
bool is_connected = ble_hid_is_connected();
// 状态机转换
if (is_connected && g_rc_context.state != RC_STATE_CONNECTED) {
rc_ble_state_set_connected();
} else if (!is_connected && g_rc_context.state != RC_STATE_DISCONNECTED) {
rc_ble_state_set_disconnected();
}
// 状态机行为
switch (g_rc_context.state) {
case RC_STATE_DISCONNECTED:
{
u8 target_mac[MAC_ADDR_LENGTH] = {0};
// 检查Flash中是否有已配对的MAC
if (nvs_read_main_board_mac(target_mac) > 0) {
rc_log("Found paired MAC. Start scanning...\n");
// 启动扫描和连接。SDK的HID实现会自动连接到已配对的设备。
EARPHONE_STATE_SET_PAGE_SCAN_ENABLE();
} else {
rc_log("No paired MAC found. Waiting for RFID pairing...\n");
}
}
break;
case RC_STATE_CONNECTING:
// 在这个状态下,我们只是等待 is_connected 变为 true
rc_log("Waiting for connection result...\n");
break;
case RC_STATE_CONNECTED:
// 已连接,目前无需周期性操作
// rc_log("BLE is connected.\n");
break;
default:
break;
}
}
/**
* @brief 根据UID前缀判断设备类型
*/
static RFID_Device_Type_t get_rfid_device_type(const u8* uid)
{
if (uid == NULL) {
return RFID_DEVICE_TYPE_UNKNOWN;
}
// 根据 RC_app_main.h 中定义的UID前缀进行判断
if (uid[0] == UID_PREFIX_MAIN_BOARD) {
return RFID_DEVICE_TYPE_MAIN_BOARD;
} else if (uid[0] == UID_PREFIX_REMOTE_CONTROL) {
return RFID_DEVICE_TYPE_REMOTE_CONTROL;
}
return RFID_DEVICE_TYPE_UNKNOWN;
}
// =================================================================================
// 辅助函数 (Helper Functions)
// =================================================================================
/**
* @brief 进入 CONNECTING 状态的逻辑
*/
static void rc_ble_state_set_connecting(void)
{
rc_log("State transition to -> CONNECTING\n");
g_rc_context.state = RC_STATE_CONNECTING;
// 可以在这里控制LED灯效例如黄灯呼吸闪烁
}
/**
* @brief 进入 CONNECTED 状态的逻辑
*/
static void rc_ble_state_set_connected(void)
{
rc_log("State transition to -> CONNECTED\n");
g_rc_context.state = RC_STATE_CONNECTED;
// 停止扫描以省电
EARPHONE_STATE_CANCEL_PAGE_SCAN();
// 发送指令,要求主板连接遥控器的经典蓝牙
u8 classic_conn_req_payload[] = {0x01, 0x02, 0x03};
rc_log("Sending request for classic BT connection.\n");
ble_hid_data_send(0xFE, classic_conn_req_payload, sizeof(classic_conn_req_payload));
// 在这里控制LED灯效例如蓝灯呼吸闪烁三次后熄灭
}
/**
* @brief 进入 DISCONNECTED 状态的逻辑
*/
static void rc_ble_state_set_disconnected(void)
{
rc_log("State transition to -> DISCONNECTED\n");
g_rc_context.state = RC_STATE_DISCONNECTED;
// 在这里控制LED灯效例如黄灯呼吸闪烁
}
// 初始化函数 (Initialization Function)
// =================================================================================
/**
* @brief 遥控器应用主初始化函数
*/
void rc_app_main_init(void)
{
rc_log("Initializing Remote Control App...\n");
// 1. 初始化全局上下文
memset(&g_rc_context, 0, sizeof(RC_Context_t));
g_rc_context.state = RC_STATE_DISCONNECTED; // 初始状态为未连接
// 2. 检查并启动RFID处理定时器
if (g_rfid_timer_id == 0) {
g_rfid_timer_id = sys_timer_add(NULL, rc_rfid_callback_handler, RC_RFID_CALLBACK_INTERVAL_MS);
rc_log("RFID handler timer started (ID: %d).\n", g_rfid_timer_id);
}
// 3. 检查并启动BLE处理定时器
if (g_ble_timer_id == 0) {
g_ble_timer_id = sys_timer_add(NULL, rc_ble_callback_handler, RC_BLE_CALLBACK_INTERVAL_MS);
rc_log("BLE handler timer started (ID: %d).\n", g_ble_timer_id);
}
}