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
(2) 链接uuid128版本的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_start(0), pwm_stop(0) 开关PWM。
I2C:
下面是一个配置和应用的例子。注意,驱动里面使用的是单字节的地址。如果需要2字节地址,请修改i2c.c里面源码。
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的例子:
在user_loop里面调用spp_check:
然后再实现回调,在收到UART数据的时候做处理如下:
SDK调试说明
Tdebug调试
通过wtcdb工具查看对应的变量,通过变量观察对应的变量来debug。需要打开sws的input使能,和关闭低功耗。
串口打印调试说明
在printf.c中设置大于baudrate和gpio,就可以用printf打印了。由于性能关系,baudrate一般不大于256000bps。
使用Flash版本调试
由于用OTP调试是十分不方便的。如果需要Flash版本来调试,则需要以下步骤。
(1) 在asmConfig.h里面打开 #define RUN_ON_FLASH 1
(2) 链接flash版本的lib,如下图。
(3) Clean,重新编译。