【Silicon Labs BG22-EK4108A 蓝牙开发评测】四:NCP Mode 上位机开发

jj1989   2022-2-9 09:03 楼主

【Silicon Labs BG22-EK4108A 蓝牙开发评测】四:NCP Mode 上位机开发

前言

原本计划进行功耗测试,看到有网友已经做了相关测试,并且需要使用额外的板子才能使用 power 工具,遂作罢。

在之前的文章中提到, QSG169:《蓝牙 SDK v3.x 快速入门指南》中关于蓝牙协议栈,介绍了三种工作模式。本人对其中的 NCP 模式比较感兴趣,这次就来研究一下。

NCP Mode

NCP 全称为:network Co-Processor(NCP) Mode,官方对其介绍如下:

Network Co-Processor (NCP) mode, where the Bluetooth stack runs in an EFR32 and the application runs on a separate host MCU. For this use case, the Bluetooth stack can be configured into NCP mode where the API is exposed over a serial inter- face such as UART.

其功能结构框图如下:

ncp-fig2-2.png

如上图,蓝牙 SOC 只负责协议栈相关的处理。我们的应用程序运行在单独的设备上,可以是其它 MCU 或者 PC 上位机。可以通过名为 BGAPI 的软件接口,使用 UART 硬件接口进行蓝牙协议栈的配置。

在第二篇文章【Silicon Labs BG22-EK4108A 蓝牙开发评测】二:开发环境初体验 中,我们简单体验了一下 NCP 模式,当时使用官方提供的图形化工具 -- Bluetooth NCP Commander 进行蓝牙协议栈的配置。

继续研究,发现官方提供了一个名为 PyBGAPI 的 python 库。对 PyBGAPI 的介绍如下:

This package provides a Python interface for the BGAPI binary protocol. It reads the BGAPI definition file and dynamically generates a parser for it.

这意味着我们可以通过 python 语言来很方便地进行蓝牙协议栈的配置。接下来就以我们上一篇中介绍的官方例程 Bluetooth-Soc Blinky 为参考,通过 python 控制运行于 NCP 模式下的 EFR32BG22 SOC 来实现 Blinky 例程功能。

代码解析

关于 PyBGAPI 库的使用,可以参考官方给出的例程。这里在 empty 例程的基础上添加代码,实现我们需要的功能。 修改蓝牙名字等这些简单操作就不一一介绍了,这里讲一下关于蓝牙服务的添加及控制数据的处理。

GATT 配置

首先是添加蓝牙 Blinky 服务,服务 UUID 可以在官方 Blinky 例程中找到。然后是添加 Button 和 LED 两个特征,特征 UUID 同样参考官方例程。注意这里的 Button 特征属性为 Read 和 Notify,LED 特征属性为 Write 和 Read。 在 gattdb_init 方法中增加如下代码:

   # Blinky service
        _, service = self.lib.bt.gattdb.add_service(
            session,
            self.lib.bt.gattdb.SERVICE_TYPE_PRIMARY_SERVICE,
            self.lib.bt.gattdb.SERVICE_PROPERTY_FLAGS_ADVERTISED_SERVICE,
            b"x24x12xb5xcbxd4x60x80x0cx15xc3x9bxa9xacx5ax8axde"
        )
        # Report button 
        _, self.gattdb_report_button = self.lib.bt.gattdb.add_uuid128_characteristic(
            session,
            service,
            self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_READ |
            self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_NOTIFY,
            0,
            0,
            b"x9cxd2x70x2ax65x6dx53x9axd0x60xc3x41xa4x85xa8x61",
            self.lib.bt.gattdb.VALUE_TYPE_FIXED_LENGTH_VALUE,
            1,
            b"x00"
        )
        self.lib.bt.gattdb.start_service(session, service)

        # LED Contorl
        _, self.gattdb_led_control = self.lib.bt.gattdb.add_uuid128_characteristic(
            session,
            service,
            self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_READ |
            self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_WRITE,
            0,
            0,
            b"x7ax08x6ax73x6cxbexd8x46x97xc2x88x40x10x65x02x5b",
            self.lib.bt.gattdb.VALUE_TYPE_FIXED_LENGTH_VALUE,
            1,
            b"x00"
        )
        self.lib.bt.gattdb.start_service(session, service)

用户控制响应

这里仅介绍 LED 控制状态的处理。在 event_handler 方法中添加如下代码:

        elif evt == "bt_evt_gatt_server_attribute_value":
            if evt.att_opcode == self.lib.bt.gatt.ATT_OPCODE_WRITE_REQUEST:
                led_status_update(evt.value)

当 LED 特征执行写入请求操作时,就会调用 led_status_update 方法,进行 LED 状态的更新操作。这里仅通过打印日志反应 LED 状态,代码如下:

def led_status_update(value):
    if value== b'x00':
        print("led off.")
    elif value == b'x01':
        print("led on.")
    else:
        print("Invalid value.")

演示

原计划是基于 python 开发一个桌面端的图形上位机,结合 EFR Connect 进行更直观的功能演示。奈何 iOS 端的 EFR Connect 最近更新后似乎有 bug,在 Demo 页面搜索不到对应的设备,记得上一个版本是可以的。于是乎一切从简,就做一个简单的演示吧。

注:开发板需要提前烧录好 NCP 固件。

ncp_480p.gif

总结

EFR32BG22 的这个 NCP 模式给应用开发提供了更多的选择,同时可玩性也大大提高。比如我们可以将开发板作为一个蓝牙鼠标接收器。由于提供了 python 库,因此开发也变得很简单,可轻松实现跨平台。

 

本帖最后由 jj1989 于 2022-2-9 09:04 编辑

回复评论 (1)

关于CP 模式谢谢解析

点赞  2022-2-10 07:45
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复