跳转至

B80 BLE OTP SDK


SDK概述

SDK为用户提供基于B80芯片开发的自拍器的demo,及非HID的demo,客户可以在此基础上开发。

SDK文件架构

ble: BLE协议相关的常量

Bluelight: 生成的目标文件

lib: 协议栈库文件,有4个版本如下:

  • liblib.a         OTP, UUID16bit

  • liblib128.a       OTP, UUID128bit

  • liblibFlash.a     Flash, UUID16bit

  • liblibFlash128.a   Flash, UUID128bit

proj: 驱动源文件

  • proj\common:数据结构相关

  • proj\drivers:外设驱动

  • proj\mcu:mcu驱动

proj_lib: 第三方库文件

vendor: 与具体应用相关的,用户编些的源码

  • vendor\blueLight\app_config.h:项目相关常量

  • vendor\blueLight\attributes.c:BLE属性表定义

  • vendor\blueLight\attributes.h:BLE属性表定义头文件

  • vendor\blueLight\bluelight.h: BLE封包结构定义

  • vendor\blueLight\blueLight-128-uuid.h:BLE 128比特属性表的例子。要注意为了使得bin文件最小,目前liblib.a只支持16bit的UUID。如果要支持128bit的属性,请链接liblib128.a

  • vendor\blueLight\emi.c:EMI测试

  • vendor\blueLight\main.c:用户逻辑代码,初始化/主循环函数

project: project为工程文件夹,其中的.cproject,.project文件为对应的工程文件,其中的文件夹为编译生成的文件,例如bluelight文件夹里面会生成bluelight.bin和bluelight.lst。

SDK开发简略步骤

Step 1 实现user_init函数:配置IO,RF参数;

Step 2 构造gAttributes表,根据业务构造属性表以读写交互。实现attWriteCallback回调,实现写控制;

Step 3 实现user_loop,实现业务逻辑。调用其他驱动(LED, PWM, UART回调等);

Step 4 实现userGpioInputInit和gpioSuspendSet回调,以减少IO漏电;

Step 5 调试:打开SWS的输入使能,user_allowSleep返回0。这样关闭低功耗,就可以使用BDT查看寄存器和变量值了。

初始化及主循环

初始化和主循环都在main.c文件里。

初始化

MCU在系统初始化后会调用user_init进行用户应用的初始化,用户在此函数中,一般会初始化IO,配置RF参数。例如下面的例子:

用户应用初始化

注:userGpioInputInit()这个函数,在后面介绍。

主循环

主循环函数void user_loop(u8 connected, u32 wakeuptime),在系统每个循环周期调用一次。用户实现自己的逻辑,SDK里默认为空函数。参数connected表示当前是连接(1)/广播(0)状态。RF Wakeuptime下次唤醒触发的时间。

睡眠控制

void suspendWakeup (u32 deepsleep, u32 wakeup_tick, u32 wakeup_src);

参数deepsleep:SUSPEND_MODE == 0表示suspend。DEEPSLEEP_MODE == 0x30表示deepsleep。

参数wakeup_tick:需要唤醒的tick。

参数wakeup_src:唤醒类型(定时/IO唤醒)。

睡眠函数有两个回调,分别为userGpioSuspendSet,userGpioInputInit()。前者在进入睡眠前调用,后者在suspend唤醒后调用(deep唤醒则会重启,进行系统初始化)。通常userGpioSuspendSet只需要关闭gpio的input enable属性,用以节省功耗;而userGpioInputInit()则恢复GPIO的设置。如果用户需要在睡眠前/后进行其他操作,也放在这里。例如,IO的上拉,PWM重新初始化,重新设置发射功率等。

int user_allowSleep(void)

此回调函数通常的用法是,在用户需要关闭低功耗的时候返回0,例如蜂鸣器在触发的时候要关闭低功耗。默认返回1,表示允许低功耗。

int wakeupButton_dn(void)

此回调函数用以告诉系统,唤醒按键是否已经按下。目的是避免在唤醒按键按下的时候频繁进入睡眠和唤醒,使得系统不稳定和增加功耗。在wakeupButton_dn返回1的时候,系统将暂时关闭IO唤醒,以定时器唤醒,以此来节省长时间按键时候的功耗。

ATT属性表

使用方法

ATT属性表:const attribute_t gAttributes[]数组由用户自行定义。其数据结构如下:

数据结构

请参考源码。

源码

第一行,35是总条目数。

后面的每部分的第一行第一个字段是本组的条目数(上图中的4和7),其他字段根据数据结构分别为attrLen(属性长度),uuid(属性唯一标识), pAttrValue(属性值的指针)正确配置后,手机就可以进行读写和发送notify。

使用方法128bit UUID版本

如果UUID是128bit版本,那么gAttributes数组就需要重新定义。有三个步骤:

(1) App_confg.h里面打开宏 #define ATT_128UUID_ENABLE 1

define ATT_128UUID_ENABLE

(2) 链接uuid128版本的lib

链接lib

(3) 修改gAttributes数组,满足uuid128要求。vendor -> blueLight -> blueLight-128-uuid.h有个例子。然后clean重新编译。

ATT属性读写回调

(1) 回调:int attWriteCallback (void *pp)

pp指针的类型是rf_packet_att_write_t,从pp指针可以获得,handle的值和data。然后根据handle和data用户可以进行逻辑处理。此函数返回0则系统会将data写入到att属性表handle对应的pAttrValue中,返回1则不写(表示用户已经处理,系统忽略)。

(2) 回调:int attReadCallback (void *pp, void *pRsp)

通常此函数直接返回0,交由系统处理。系统会从属性表pAttrValue中读得数值后返回。

(3) void spp_notify (u8* buf, u16 len)

用户调用spp_notify可以发送notify到手机。此函数只是个示例,需要用户在pkt_sppNoti中填写正确的handle值。

RF参数设置

Mac地址: void blc_ll_initAdvertising_module (u8 *public_adr)

默认情况下,系统会从OTP参数区读取mac地址。此函数不需要调用。如用户需要设置mac,则调用此函数。

广播使能: int bls_ll_setAdvEnable (int en)

默认为1,如要关闭,设置0。

广播间隔: int bls_ll_setAdvParam (u16 interval)

默认为200ms,单位毫秒。

广播内容设置: int bls_ll_setAdvData (u8 *data, u8 len)

设置广播内容。长度不大于31字节。

广播回复内容设置: int bls_ll_setScanRspData (u8 *data, u8 len)

设置扫描回复内容。长度不大于31字节。

链接参数: void bls_l2cap_requestConnParamUpdate (u16 min_interval, u16 max_interval, u16 latency, u16 timeout)

当全部参数为0的时候,关闭此功能。

配对使能: int bls_smp_enableParing (u8 encrypt_en)

默认打开,如要关闭请设置0。

其他驱动

IO控制:

  • IO输入输出:为节省空间,建议直接使用寄存器设置,例如: reg_gpio_pa_oen = ~GPIO_LED; reg_gpio_pc_out |= GPIO_C5

  • 上下拉:直接使用模拟寄存器和宏。例如: analog_write(areg_pull_b4_b7, B4_1M | B5_1M | B6_1M)

  • 唤醒:直接使用模拟寄存器和宏。例如: analog_write(areg_pb_wakeup_en, GPIO_B4 | GPIO_B5 | GPIO_B6)

键盘:

用户可以自行实现,简单的按键检测(IO高低电平判断),也可以参照kb_scan_key,此函数是一个IO接2个按键的应用示例。由于OTP大小限制,没有实现键盘行列扫描的示例。

PWM:

这是PWM设置的例子:

PWM设置

然后可以调用pwm_start(0), pwm_stop(0) 开关PWM。

I2C:

下面是一个配置和应用的例子。注意,驱动里面使用的是单字节的地址。如果需要2字节地址,请修改i2c.c里面源码。

I2C配置

ADC:

  • 普通chn测量,先调用 adc_general_init(chn)函数,然后调用adc_simple_get获得数值。

  • 电池测量,先调用adc_vbat_init()函数,然后调用adc_simple_get获得数值。

UART:

在app_config.h中设置宏UART_BAUD_RATE。然后重新编译。下面是一个在user_init里面IO配置UART的例子:

配置UART

在user_loop里面调用spp_check:

调用spp_check

然后再实现回调,在收到UART数据的时候做处理如下:

处理UART数据

SDK调试说明

Tdebug调试

通过wtcdb工具查看对应的变量,通过变量观察对应的变量来debug。需要打开sws的input使能,和关闭低功耗。

wtcdb调试

串口打印调试说明

串口打印调试

在printf.c中设置大于baudrate和gpio,就可以用printf打印了。由于性能关系,baudrate一般不大于256000bps。

使用Flash版本调试

由于用OTP调试是十分不方便的。如果需要Flash版本来调试,则需要以下步骤。

(1) 在asmConfig.h里面打开 #define RUN_ON_FLASH 1

#define RUN_ON_FLASH

(2) 链接flash版本的lib,如下图。

link to lib

(3) Clean,重新编译。