SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0处理器、128kB Flash存储器、以及丰富的数字接口。SYD8801片上集成了Balun无需阻抗匹配网络、高效率DCDC降压转换器,适合用于可穿戴、物联网设备等。具体可咨询:http://www.sydtek.com/
SYD8801连接参数的设置说明
SYD8801关于连接间隔的设置和其他平台的都不一样,主要的不一样就是SYD8801的连接参数的latency是由用户来决定什么时候使能的!
针对不同的平台这里有3个设置连接方式的函数:
SetIosConnectionUpdate:设置和IOS的连接参数,该参数是经过调试过的,ios最大支持的连接参数
SetAndroidConnectionUpdate:设置安卓的连接参数,该参数是直接抄录ios的,基本上ios的参数都能够用在安卓上
SetOtaConnectionUpdate:设置OTA的连接参数,OTA需要快速的连接间隔,所以该参数比较小,这也是ios能支持的最小间隔,安卓还能更小
他们的源代码如下:
void SetIosConnectionUpdate(void){
struct gap_link_params link_app;
struct gap_update_params update;
GetLinkParameters(&link_app);
if((link_app.latency <0x000A) && (link_app.interval <0x0060)){
target_params_interval=0x60;
target_params_latency=0x0a;
/* connection parameters */
update.updateitv_min = 0x0020; //Minimum connection interval (32 * 1.25ms = 40 ms)
update.updateitv_max = 0x0060; //Maximum connection interval (60 * 1.25ms = 75 ms)
update.updatelatency= 0x000A; //40*12.5=300ms
update.updatesvto= 0x03E8; //supervisory timeout (400 * 10 ms = 4s)
SetConnectionUpdate(&update);
start_update_params=1;
start_update_mode=0;
DBGPRINTF(("SetConnectionUpdate ios\r\n"));
}
}
void SetAndroidConnectionUpdate(void){
struct gap_link_params link_app;
struct gap_update_params update;
GetLinkParameters(&link_app);
if((link_app.latency <0x000A) && (link_app.interval <0x0060)){
target_params_interval=0x60;
target_params_latency=0x0a;
/* connection parameters */
update.updateitv_min = 0x0020; //Minimum connection interval (25 * 1.25ms = 31.25 ms)
update.updateitv_max = 0x0060; //Maximum connection interval (60 * 1.25ms = 75 ms)
update.updatelatency= 0x000A; //40*12.5=300ms
update.updatesvto= 0x03E8; //supervisory timeout (400 * 10 ms = 4s)
SetConnectionUpdate(&update);
start_update_params=1;
start_update_mode=0;
DBGPRINTF(("SetConnectionUpdate else\r\n"));
}
}
void SetOtaConnectionUpdate(void){
struct gap_link_params link_app;
struct gap_update_params update;
GetLinkParameters(&link_app);
if((link_app.latency !=0) && (link_app.interval >0x10)){
ConnectionLatencyMode(0x00);
latency_state=0;
target_params_interval=0x10;
target_params_latency=0x00;
/* connection parameters */
update.updateitv_min = 0x0008; //Minimum connection interval (25 * 1.25ms = 31.25 ms)
update.updateitv_max = 0x0010; //Maximum connection interval (60 * 1.25ms = 75 ms)
update.updatelatency= 0x0000; //40*12.5=300ms
update.updatesvto= 0x00c8; //supervisory timeout (400 * 10 ms = 4s)
SetConnectionUpdate(&update);
start_update_params=1;
start_update_mode=1;
DBGPRINTF(("SetConnectionUpdate ota\r\n"));
}
}
在连接完成的时候调用设置连接参数函数设置更大的连接间隔降低功耗:
void ble_evt_callback(struct gap_ble_evt *p_evt)
{
if(p_evt->evt_code == GAP_EVT_ADV_END)
{
RFSleep();
}
else if(p_evt->evt_code == GAP_EVT_CONNECTED)
{
start_tx = 0;
marche_state=1;
timer_0_enable(256, timer0_button_callback); // 250 * 31.25 us = 8000 us = 8 ms
SetIosConnectionUpdate();
led_open(LED1);
}
。。。。。。。。。。。。。。。。
}
这里设置了连接参数,SYD8801会把连接参数的请求发送给主机(手机),但是主机是否接受这个连接请求,这是由主机决定的,主机可以接受请求,也可以拒绝这个请求。当主机做出响应的时候SYD8801会上报GAP_EVT_CONNECTION_UPDATE_RSP事件,这里如果主机接受请求的话就可以进入使能latency的流程,但是如果主机拒绝了请求,这里可以换一个比较让主机接受的连接参数再次发起请求,如下:
else if(p_evt->evt_code == GAP_EVT_CONNECTION_UPDATE_RSP)
{
if(p_evt->evt.connection_update_rsp_evt.result == CONN_PARAM_REJECTED){
struct gap_update_params update;
start_update_params++;
if(start_update_params>4){
start_update_params=0;
finish_update_params=1;
return;
}
if(start_update_mode==1){
target_params_interval +=0x08;
update.updateitv_min = 0x0008;
update.updateitv_max = target_params_interval;
update.updatelatency= target_params_latency;
update.updatesvto= 0x00c8;
SetConnectionUpdate(&update);
}else{
target_params_interval -=0x08;
update.updateitv_min = 0x0020;
update.updateitv_max = target_params_interval;
update.updatelatency= target_params_latency;
update.updatesvto= 0x0190;
SetConnectionUpdate(&update);
}
}else{
start_update_params=0;
finish_update_params=1;
}
// DBGPRINTF(("update rsp:%04x\r\n",p_evt->evt.connection_update_rsp_evt.result));
}
不能够在配置连接参数的时候使能latency,必须要在连接参数更新完成后使能latency,SYD8801使能latency的操作在主循环中执行,这里的思路是隔3秒钟去判断连接参数有没有得到更新,如果连接参数更新了就会使能latency,注意下面的代表必须1S钟执行一次:
while(1)
。。。。。。。。。。。。。。。。
if(timer1s_inting){
timer1s_inting=0
。。。。。。。。。。。。。。。。。。。。。。。。。。。
if(finish_update_params){
finish_update_params++;
if(finish_update_params>=3){
struct gap_link_params link_app;
GetLinkParameters(&link_app);
dbg_printf("interval:%x\r\n",link_app.interval);
dbg_printf("latency:%x\r\n",link_app.latency);
if(start_update_mode==0){
if((target_params_interval<=link_app.interval) && (target_params_latency<=link_app.latency)){
ConnectionLatencyMode(0x01);
latency_state=1;
finish_update_params=0;
dbg_printf("enable latency\r\n");
}else finish_update_params=1;
}else{
if((target_params_interval>=link_app.interval) && (target_params_latency>=link_app.latency))
finish_update_params=0;
else finish_update_params=1;
}
}
}
}
因为根据蓝牙协议栈更新连接间隔需要一些时间,所以这里做了特殊的处理,在app对我们蓝牙芯片进行写操作的时候这里要失能掉latency:
static void ble_gatt_write(struct gap_att_write_evt evt)
{
if(evt.uuid== BLE_SERVICE_UUID_UART_WRITE)
{
// rx data
led_turn(LED3);
if(latency_state) update_latency_mode=1;
if(latency_state==1) {
ConnectionLatencyMode(0x00);
latency_state=2;
}
}
else if(evt.uuid== BLE_SERVICE_UUID_OTA_READ_WRITE)
{
ota_cmd(evt.data, evt.sz);
}
}
在没有数据发送的1秒后再次把latency使能:
if(update_latency_mode){
update_latency_mode++;
if(update_latency_mode>=3){
if(latency_state==2) {
ConnectionLatencyMode(0x01);
latency_state=1;
// dbg_printf("enable latency\r\n");
}
update_latency_mode=0;
}
}
这样就能够兼容连接得时候以更快的速度进行通信,而不需要传输数据的时候使用更慢的连接间隔进行降低功耗!