站内搜索
更多
杰理AC63_BT_SDK 学习笔记 (10 Dongle)

分类

其他

杰理AC63_BT_SDK 学习笔记 (10 Dongle)

13
0
0
0

简介

基于杰理官方的通用蓝牙软件包 fw-AC63_BT_SDK-master,学习和了解AC695/6系列芯片的功能和应用。主要从SPP_BLE、MASH、HID三个方面学习和了解相关的协议和应用。

简介: 基于杰理官方的通用蓝牙软件包 fw-AC63_BT_SDK-master,学习和了解AC695/6系列芯片的功能和应用。主要从SPP_BLE、MASH、HID三个方面学习和了解相关的协议和应用。
更新时间:2026-07-31 09:44:00

// USB → BLE 数据转发 (HID输出)

void dongle_hid_output_handler(u8 report_type, u8 report_id, u8 *packet, u16 size)

{   #if (TCFG_USER_EDR_ENABLE)

        edr_hid_data_send_ext(report_type, report_id, packet, size);

    #elif (TCFG_USER_BLE_ENABLE)

        ble_hid_data_send_ext(report_type, report_id, packet, size);

    #endif

}

2 BLE中央设备 - ble_dg_central.c

2.1 扫描配置

// 搜索参数

#define SET_SCAN_TYPE       SCAN_ACTIVE      // 主动扫描

#define SET_SCAN_INTERVAL   ADV_SCAN_MS(24)  // 24 * 0.625ms = 15ms

#define SET_SCAN_WINDOW     ADV_SCAN_MS(8)   // 8 * 0.625ms = 5ms

// 连接参数

#define SET_CONN_INTERVAL   (BASE_INTERVAL_MIN*3)  // 18 * 1.25ms = 22.5ms

#define SET_CONN_LATENCY    0

#define SET_CONN_TIMEOUT    100  // 1秒超时

// 匹配设备列表

static const client_match_cfg_t dg_match_device_table[] =

    {.create_conn_mode = BIT(CLI_CREAT_BY_NAME),  // 按名称匹配

        .compare_data_len = sizeof(dg_test_remoter_name1) - 1,

        .compare_data = dg_test_remoter_name1,       // "AC695X_1(BLE)"

        .filter_pdu_bitmap = 0,

    },

    {.create_conn_mode = BIT(CLI_CREAT_BY_NAME),

        .compare_data_len = sizeof(dg_test_remoter_name2) - 1,

        .compare_data = dg_test_remoter_name2,       // "AC897N_MX(BLE)"

        .filter_pdu_bitmap = 0,

    },

    { .create_conn_mode = BIT(CLI_CREAT_BY_TAG),   // 按自定义Tag匹配

        .compare_data_len = sizeof(user_config_tag_string) - 1,

        .compare_data = user_config_tag_string,      // "abc123"

        .filter_pdu_bitmap = 0,

    },

3.2.2 GATT服务搜索配置

static const target_uuid_t dongle_search_ble_uuid_table[] = {

    // 设备名称 (GAP服务)

    {.services_uuid16 = 0x1800,

        .characteristic_uuid16 = 0x2a00,

        .opt_type = ATT_PROPERTY_READ,

    },

    // PNP信息 (设备信息服务)

    {.services_uuid16 = 0x180a,

        .characteristic_uuid16 = 0x2a50,

        .opt_type = ATT_PROPERTY_READ,

    },

    // 报告映射 (HID服务)

    {.services_uuid16 = 0x1812,

        .characteristic_uuid16 = 0x2a4b,

        .opt_type = ATT_PROPERTY_READ,

        .read_long_enable = 1,

    },

    // 输入报告 (HID服务 - Notify)

    {.services_uuid16 = 0x1812,

        .characteristic_uuid16 = 0x2a4d,

        .opt_type = ATT_PROPERTY_NOTIFY,

        .read_report_reference = 1,

    },

    // RCSP OTA服务 (自定义)

    #if RCSP_BTMATE_EN

    {.services_uuid16 = 0xae00,

        .characteristic_uuid16 = 0xae01,

        .opt_type = ATT_PROPERTY_WRITE_WITHOUT_RESPONSE,

    },

    {.services_uuid16 = 0xae00,

        .characteristic_uuid16 = 0xae02,

        .opt_type = ATT_PROPERTY_NOTIFY,

    },

    #endif

};

3.2.3 配对信息管理

// 配对信息结构

struct ctl_pair_info_t {

    u8 head_tag;              // PAIR_BOND_TAG (0x53)

    u8 match_dev_id;          // 匹配设备ID

    u8 pair_flag;             // 配对标志

    u8 peer_address_info[7];  // 对端地址 (addr_type + address)

    u16 conn_handle;          // 连接句柄

    u16 conn_interval;        // 连接间隔

    u16 conn_latency;         // 延迟

    u16 conn_timeout;         // 超时

    u16 write_handle;         // 写特征值句柄 (OTA用)

// VM存储 (ID 30)

#define CFG_BLE_BONDING_REMOTE_INFO2  30

// 读取/写入配对信息

static int dg_pair_vm_do(struct ctl_pair_info_t *info, u8 rw_flag)

    if (rw_flag == 0)         // 从VM读取

        ret = syscfg_read (CFG_BLE_BONDING_REMOTE_INFO2, (u8 *)&record_bond_info,

                             uint_len * SUPPORT_MAX_GATT_CLIENT);

     else                     // 写入VM

               syscfg_write(CFG_BLE_BONDING_REMOTE_INFO2, (u8 *)&record_bond_info,

                              uint_len * SUPPORT_MAX_GATT_CLIENT);

3.2.4 事件处理 - 核心回调

static int dg_central_event_packet_handler(int event, u8 *packet, u16 size, u8 *ext_param)

{switch (event)

    // 1. 扫描到匹配设备

    case GATT_COMM_EVENT_SCAN_DEV_MATCH:

        log_info("match_dev:addr_type= %d", packet[0]);

        // 保存设备信息,准备发起连接

        cur_conn_info.match_dev_id = packet[9];

        if (packet[9] < SUPPORT_MAX_GATT_CLIENT)  // 已配对设备 → 使用记录的连接参数

            dg_scan_conn_config_set(&record_bond_info[packet[9]]);

         else                                       // 新设备 → 使用默认参数

            dg_scan_conn_config_set(NULL);

        break;

    // 2. 连接完成

    case GATT_COMM_EVENT_CONNECTION_COMPLETE:

        log_info("connection_handle:%04x", little_endian_read_16(packet, 0));

        // 保存连接信息

        memcpy(cur_conn_info.peer_address_info, &ext_param[7], 7);

        cur_conn_info.conn_handle = little_endian_read_16(packet, 0);

        bt_connected = 1;

        break;

    // 3. 加密完成 (配对)

    case GATT_COMM_EVENT_ENCRYPTION_CHANGE:

        if (packet[3] == LINK_ENCRYPTION_RECONNECT)

            log_info("reconnect...");            // 回连:直接使能通知

            dg_enable_notify_ccc(little_endian_read_16(packet, 0));

         else

            log_info("first pair...");            // 首次配对:搜索GATT服务

            dg_client_bond_config.search_uuid_count =

                (sizeof(dongle_search_ble_uuid_table) / sizeof(target_uuid_t));

// 保存配对信息到VM

        cur_conn_info.head_tag = PAIR_BOND_TAG;

        cur_conn_info.pair_flag = 1;

        dg_pair_vm_do(&cur_conn_info, 1);

        break;

    // 4. 收到数据 (Notify)

    case GATT_COMM_EVENT_GATT_DATA_REPORT:

        report_data = (void *)packet;

        if (report_data->packet_type == GATT_EVENT_NOTIFICATION)

            // 根据handle识别设备类型

            if (report_data->value_handle == mouse_notify_handle[0])

                usb_send_packet[0] = 1;  // Report ID 1

                dongle_ble_hid_input_handler(usb_send_packet, blob_length + 1);

             else if (report_data->value_handle == standard_keyboard_notify_handle[0])

                usb_send_packet[0] = 4;  // Report ID 4

                dongle_second_ble_hid_input_handler(usb_send_packet, blob_length + 1);

     break;

    // 5. 断开连接

    case GATT_COMM_EVENT_DISCONNECT_COMPLETE:

        log_info("disconnect_handle:%04x, reason= %02x",

                 little_endian_read_16(packet, 0), packet[2]);

        // 清空连接句柄,重新开启扫描

        if (conn_handle == dg_conn_handle)

            dg_conn_handle = 0;

            bt_connected = 0;

        break;

    return 0;

3.2.5 USB唤醒处理

// USB挂起时,需要唤醒后再发送数据

static u8 wait_usb_wakeup = 1;

// 收到BLE数据时检查USB状态

if (usb_status_ret == USB_SUSPEND)

    wait_usb_wakeup = 0;

    usb_remote_wakeup(0);  // 发送远程唤醒

    break;

 else if (usb_status_ret == USB_RESUME_OK)     // USB已唤醒,正常发送

    wait_usb_wakeup = 1;

// 发送数据前检查

if (wait_usb_wakeup)

    memcpy(&usb_send_packet[1], report_data->blob, report_data->blob_length);

else     // USB未唤醒,发送空包(保持连接)

    memset(&usb_send_packet[1], 0                , report_data->blob_length);

八、完整工作流程

  1. 上电启动 (app_main)

选择 "dongle" 应用

  1. 应用启动 (dongle_app_start)

├── 初始化BLE协议栈 (btstack_init)      

├── 注册USB HID描述符 (鼠标/键盘/消费类)

├── 启动USB设备 (usb_start)

└── 扫描匹配设备 (BLE扫描) 

  1. BLE扫描与匹配 (ble_dg_central.c)

├── 主动扫描 (SCAN_ACTIVE) 

├── 匹配设备名称: "AC695X_1(BLE)" 或 "AC897N_MX(BLE)"  

├── 匹配自定义Tag: "abc123"

└── 发现匹配 → 自动发起连接

  1. 连接与配对

├── 建立BLE连接         

├── 加密配对 (如果使能SM)

├── 保存配对信息到VM (断电不丢失)       

└── 搜索GATT服务 (HID服务等)

添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1
按时间排序|按热度排序

底部导航