为什么手机APP读取的蓝牙地址和FICR->DEVICEADDR寄存器读出的地址不同?

本文探讨了手机APP(如nRF Connect)显示的蓝牙静态设备地址与通过FICR->DEVICEADDR寄存器读取的地址为何不同的问题。分析了蓝牙地址的类型,并通过实例展示了地址读取过程。最终指出,两者最高字节的差异在于蓝牙协议对地址的特定要求,转换后可以得到一致的地址。

弄清楚这个问题之前我们需要先了解一下蓝牙地址的类型,在蓝牙规格书上对于地址类型有较详细的说明(参看:Core v5.0-> Vol 6-> Part B ->1.3) 简单归类如下:

手机App 用nRF Connect  显示的地址是static Device Address 类型,如下图所示地址最高字节为FF

 进一步验证地址是否正确,我们通过API函数sd_ble_gap_addr_get读取MAC address并打印出来, 代码如下:

对应的log信息中打印出的地址如下:

 我们发现地址和APP上显示地址相同,最高字节都是FF 

 

接下来我们用nrfjprog --memrd命令读出FICR中的DEVICEADDR,显示如下,如绿框所标示按6 Bytes MAC来看,最高地址是BF

static rt_err_t EP9510L_e_arc_vol_set(struct hdmi_repeat *rpt, void *data) { rt_kprintf("================EP9510L_e_arc_vol_set====================, EP9510.c: 1243\n"); struct rk_rpt_volume_info *info = (struct rk_rpt_volume_info *)data; rt_uint8_t temp; EP9510L_read_regs(EP_GENERAL_CTL_0, 1, &temp); uint8_t model_name = app_get_tl_model(); if (TL_MODEL_SONY2_0 == model_name) { //0~50 if (info->volume > EP9510L_VOL_MAX_SONY2P0) { info->volume = EP9510L_VOL_MAX_SONY2P0; } info->volume = info->volume * 2; } else { //0~100 if (info->volume > EP9510L_VOL_MAX) { info->volume = EP9510L_VOL_MAX; } } if (info->is_mute) { temp |= BIT(1); } else { temp &= ~BIT(1); } EP9510L_write_regs(EP_GENERAL_CTL_0, 1, &temp); EP9510L_write_regs(EP_GENERAL_CTL_3, 1, &info->volume); g_EP9510L_dev->gc.ctl = info->is_mute; g_EP9510L_dev->gc.cec_volume = info->volume; rk_rpt_info("ep9510_vol:%d, %s\n", info->volume, info->is_mute ? "mute" : "unmute"); return RT_EOK; } static void EP9510L_get_general_control(EP9510L_device_t *EP9510L) { rt_uint8_t old, change; rt_uint8_t val; rt_uint8_t ado_change = 0; rt_uint8_t arc_on_change = 0; rt_uint8_t hot_plug_change = 0; rt_uint8_t last_audio_type = 0; old = EP9510L->gi.tx_info; EP9510L_read_regs(EP_GENER_INF_0, 1, &EP9510L->gi.tx_info); EP9510L_read_regs(EP_GENERAL_CTL_1, 1, &g_EP9510L_dev->gc.rx_sel); rk_rpt_dbg("EP9510_0x08=%x,old=%x\n",EP9510L->gi.tx_info,old); if (EP9510L->gi.tx_info == 0x00) { rk_rpt_dbg("EP9510_0x08=%x\n",EP9510L->gi.tx_info); //EP9510L->gi.tx_info = old; } change = EP9510L->gi.tx_info ^ old; if (change) { rk_rpt_dbg("GI[0x08] old: 0x%02x, new: 0x%02x\n", old, EP9510L->gi.tx_info); } if (change & EP_GI_TX_HOT_PLUG_MASK) { val = (EP9510L->gi.tx_info >> EP_GI_TX_HOT_PLUG_SHIFT) & EP_2CHOICE_MASK; rk_rpt_dbg("tx hotplug changed to %d\n", val); g_EP9510L_dev->hdmi_tx_plug_in = val; hot_plug_change = 1; } if ((change & EP_GI_ARC_ON_MASK)||(change & EP_GI_EARC_ON_MASK)) { if(((EP9510L->gi.tx_info) & 0x01) || ((EP9510L->gi.tx_info) & 0x02)) val = 1; else val = 0; arc_on_change = 1; rk_rpt_dbg("tx (e)arc_on changed to %d,val=%d\n", arc_on_change,val); EP9510L_arc_earc_change_callback(val); if(change & EP_GI_ARC_ON_MASK) { if(EP9510L->gi.tx_info & 0x01) EP9510L->cur_arc_en = 1; else EP9510L->cur_arc_en = 0; ado_change = 1; } if(change & EP_GI_EARC_ON_MASK) { if(EP9510L->gi.tx_info & 0x02) EP9510L->cur_earc_en = 1; else EP9510L->cur_earc_en = 0; ado_change = 1; } } old = g_EP9510L_dev->gc.link; EP9510L_read_regs(EP_GENERAL_CTL_4, 1, &g_EP9510L_dev->gc.link); rk_rpt_dbg("EP9510_0x14=%x,old=%x\n",g_EP9510L_dev->gc.link,old); if (g_EP9510L_dev->gc.link == 0xff) { rk_rpt_dbg("EP_GENERAL_CTL_4 read 0xff\n"); //g_EP9510L_dev->gc.link = old; } change = g_EP9510L_dev->gc.link ^ old; if (change & EP_GC_LINK_MASK) { val = g_EP9510L_dev->gc.link & EP_GC_LINK_MASK; //rk_rpt_dbg("rx hotplug changed to 0x%x\n", val); //g_EP9510L_dev->hdmi_rx_plug_in = (val > 0) ? 1 : 0; //hot_plug_change = 1;//wuning mark } EP9510L_read_regs(EP_GENER_INF_1, 1, &val); rk_rpt_dbg("EP9510_0x09=%x\n",val); if (val == 0x00) { /* workaround for Nak'ed first read */ EP9510L_read_regs(EP_GENER_INF_1, 1, &val); if (val == 0xff) { rk_rpt_dbg("EP9510_0x09 read 0xff,return\n"); return; /* assume device not present */ } } if (val & EP_GI_ADO_CHF_MASK) { ado_change = 1; } if (val & EP_GI_CEC_ECF_MASK) { EP9510L_parsing_cec_events(); } if (val & EP_GI_EARC_VENDORCMD_ECF) { EP9510L_vendorcmd_change_callback(); } old = g_EP9510L_dev->ai.system_status_0; EP9510L_read_regs(EP_SYSTEM_STAT_0, 1, &g_EP9510L_dev->ai.system_status_0); rk_rpt_dbg("EP9510_0x20=%x,old=%x\n",g_EP9510L_dev->ai.system_status_0,old); if (EP9510L->ai.system_status_0 == 0) { rk_rpt_dbg("EP_SYSTEM_STAT_0 read 0\n"); //g_EP9510L_dev->ai.system_status_0 = old; } change = g_EP9510L_dev->ai.system_status_0 ^ old; if (change & EP_AI_MCLK_ON_MASK) { val = (g_EP9510L_dev->ai.system_status_0 >> EP_AI_MCLK_ON_SHIFT) & EP_2CHOICE_MASK; rk_rpt_dbg("i2s mclk on changed to %d\n", val); ado_change = 1; } if (last_audio_type != EP9510L_get_audio_type()) { last_audio_type = EP9510L_get_audio_type(); ado_change = 1; } old = EP9510L->gi.video_latency; EP9510L_read_regs(EP_GENER_INF_4, 1, &EP9510L->gi.video_latency); rk_rpt_dbg("EP9510_0x0C=%x,old=%x\n",EP9510L->gi.video_latency,old); if (EP9510L->gi.video_latency == 0) { rk_rpt_dbg("EP_GENER_INF_4 read 0\n"); EP9510L->gi.video_latency = old; } change = EP9510L->gi.video_latency ^ old; if (change & EP_GI_VIDEO_LATENCY_MASK) { val = EP9510L->gi.video_latency; if (val > 0) val = (val - 1) * 2; rk_rpt_dbg("video latency changed to %d\n", val); } old = EP9510L->gc.ctl; EP9510L_read_regs(EP_GENERAL_CTL_0, 1, &EP9510L->gc.ctl); rk_rpt_dbg("EP9510_0x10=%x,old=%x\n",EP9510L->gc.ctl,old); if (EP9510L->gc.ctl == 0x80) { rk_rpt_dbg("EP_GENERAL_CTL_0 read 0x80\n"); //EP9510L->gc.ctl = old; } change = EP9510L->gc.ctl ^ old; if (change & EP_GC_POWER_MASK) { val = (EP9510L->gc.ctl >> EP_GC_POWER_SHIFT) & EP_2CHOICE_MASK; rk_rpt_dbg("power changed to %d,%d\n", val,g_EP9510L_dev->init); if(g_EP9510L_dev->init == 1) { EP9510L_power_bit_callback(val); } } if (change & EP_GC_AUDIO_PATH_MASK) { val = (EP9510L->gc.ctl >> EP_GC_AUDIO_PATH_SHIFT) & EP_2CHOICE_MASK; rk_rpt_dbg("audio_path changed to %d\n", val); EP9510L_audio_path_callback(val); } if (change & EP_GC_CEC_MUTE_MASK) { val = (EP9510L->gc.ctl >> EP_GC_CEC_MUTE_SHIFT) & EP_2CHOICE_MASK; rk_rpt_dbg("cec_mute changed to %d <1=mute,0=unmute>\n", val); EP9510L_cecuserctl_mute(); } #if 0 if ((EP9510L->gc.ctl & EP_GC_ARC_EN_MASK) || (EP9510L->gc.ctl & EP_GC_EARC_EN_MASK)) { EP9510L->cur_hdmi_en = 0; val = (EP9510L->gi.tx_info & EP_GI_EARC_ON_MASK) >> EP_GI_EARC_ON_SHIFT; if (EP9510L->cur_earc_en != val) { rk_rpt_dbg("earc_en changed to %d\n", val); EP9510L->cur_earc_en = val; } val = (EP9510L->gi.tx_info & EP_GI_ARC_ON_MASK >> EP_GI_ARC_ON_SHIFT); if (EP9510L->cur_arc_en != val) { rk_rpt_dbg("arc_en changed to %d\n", val); EP9510L->cur_arc_en = val; ado_change = 1; } //if(g_EP9510L_dev->gc.rx_sel & 0x01) { // EP9510L->cur_hdmi_en = 1; //} } else { if (g_EP9510L_dev->gc.rx_sel == 0x00 || g_EP9510L_dev->gc.rx_sel == 0x01 || g_EP9510L_dev->gc.rx_sel == 0x02 || g_EP9510L_dev->gc.rx_sel == 0x03) { EP9510L->cur_earc_en = 0; EP9510L->cur_arc_en = 0; if (EP9510L->cur_hdmi_en != 1) { EP9510L->cur_hdmi_en = 1; rk_rpt_dbg("hdmi_en changed to 1\n"); } } } #endif EP9510L_read_regs(EP_GENERAL_CTL_3, 1, &val); rk_rpt_dbg("EP9510_0x13=%d,%d\n",val,g_EP9510L_dev->gc.cec_volume); if (val != g_EP9510L_dev->gc.cec_volume) { if (val > g_EP9510L_dev->gc.cec_volume) { if(g_EP9510L_dev->init == 1) EP9510L_cecuserctl_volumeup(); } else { if(g_EP9510L_dev->init == 1) EP9510L_cecuserctl_volumedown(); } g_EP9510L_dev->gc.cec_volume = val; } if (ado_change == 1 || arc_on_change == 1 || hot_plug_change == 1) { EP9510L_update_ado_info(0); } } 结合这两段代码有什么问题
最新发布
11-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值