当前文档版本为 v1.0.1,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

PRF: BLE SCAN

1 功能概述

此项目演示了2.4G模拟蓝牙广播包扫描功能,每隔1s在37、38、39信道上扫描空中广播包,并将广播地址和广播数据打印出来

2 环境要求

  • board: 支持 2.4G 功能的开发板

  • uart: 显示串口输出log

  • PC串口工具:Panchip Serial Assistant V0.0.009.exe

3 编译和烧录

例程位置:zephyr\samples_panchip\proprietary_radio\prf_ble_scan

目前可使用ZAL工具或quick build脚本进行编译和下载。

使用 ZAL 工具可以对其进行编译、烧录、打开 VS Code 调试等操作。关于 ZAL 工具的详细介绍请参考:Zephyr APP Launcher 工具介绍

4 演示说明

  1. 将ble scan接收端的串口(P00和P01)接到PC的USB端口上。

  2. 观察PC串口工具的输出结果。

4.1 演示结果

  1. 串口输出的log:

image

扫描到广播数据Log

5 开发说明

广播包扫描在37、38、39信道上每隔1s扫描一次。接收payload数据包含蓝牙地址和广播数据。

5.1 BLE扫描初始化

pan_prf_config_t rx_config = {
	.work_mode			= PRF_MODE_NORMAL_M1,
	.chip_mode			= PRF_CHIP_MODE_SEL_NORDIC,
	.trx_mode			= PRF_RX_MODE,
	.phy				= PRF_PHY_1M,
	.crc				= PRF_CRC_SEL_CRC24,
	.src				= PRF_SRC_SEL_EN,
	.dev				= PRF_DEV_BLE,
	.rx_timeout			= DISABLE,
	.rf_channel			= ADV_CHANNEL_1,
	.tx_no_ack			= ENABLE,
	.nrf52_mode			= ENABLE,
	.rx_length			= 0,
	.addr_length			= 4,
	.addr				= { 0xd6, 0xbe, 0x89, 0x8e },
	.tx_power			= 0,
	.pid_manual_flag		= DISABLE,
	.crc_include_addr		= DISABLE,
};

2.4G初始化配置说明如下:

初始化配置的结构体“pan_prf_config_t”

Type

Description

work_mode

使用帧结构自定义模式

chip_mode

帧结构兼容NORDIC协议

trx_mode

2.4g接收模式

phy

1M PHY

crc

CRC 24bit

src

开扰码

dev

devation兼容蓝牙模式

rx_timeout

关闭RX超时

rf_channel

蓝牙广播的37信道,2402

tx_no_ack

无作用

nrf52_mode

打开NORDIC协议长包模式

rx_length

接收payload长度为0,后面会设置动态payload

addr_length

接入地址的长度4

addr

接入地址设为蓝牙包的接入地址0x8e89bed6

tx_power

无作用

pid_manual_flag

无作用

crc_include_addr

crc作用域不包括地址

5.2 BLE扫描频点、帧格式设置

设置代码如下:

void set_ble_frame_format(void)
{
	PRI_RF->R01_INT_CTL &= ~R01_INT_PRI_ENDIAN_Msk;//使用小端模式
	PRI_RF->R04_RX_ADDR_M |= R04_RX_ADDR_M_HDR_LEN_EXIST_Msk;//使能长度字段
	PRI_RF->R04_RX_ADDR_M &= ~R04_RX_ADDR_M_HDR_LEN_NUMB_Msk;//使能header字段
	PRI_RF->R04_RX_ADDR_M |= (2 << 9);
	PRI_RF->R06_TX_ADDR_M |= (0x02 << 16);/* tx header0x2,ADV_NONCONN_IND;
	0x0,ADV_IND;0x3,scan_req;0x4,SCAN_RSP; */ //往tx header字段填入广播报文类型(不可连接广播)
	PRI_RF->R01_INT_CTL |= R01_INT_PRI_RX_GOON_Msk;//使能rx goon,提高扫描效率
	PRI_RF_AutoAnlsPayloadEn(PRI_RF, ENABLE);//使能动态payload
}

__ramfunc void set_ble_channel(uint16_t channel)
{
	uint8_t channel_id = 0;
	uint8_t sca_value = 0;

	if (channel == 2402) {
		channel_id = 37;
	} else if ((channel < 2426) && (channel > 2402)) {
		channel_id = (channel - 2404) / 2;
	} else if (channel == 2426) {
		channel_id = 38;
	} else if ((channel < 2480) && (channel > 2426)) {
		channel_id = (channel - 2406) / 2;
	} else if (channel == 2480) {
		channel_id = 39;
	}//不同的频点映射不同的channel id,例程只使用2402、2426、2480三个频点

	sca_value = (bit_reverse(channel_id) >> 1) | 0x01;//根据channel id计算扰码初始值

	panchip_prf_set_chn(channel);//设置频点,RX模式此接口会重新初始化prf

	panchip_white_init_value(sca_value);//设置扰码初始值

	set_ble_frame_format();//扫描帧格式设置
}

5.3 中断处理

例程只有rx中断,其他中断无响应。扫描到数据后,将adv header、adv length、adv data分别打印出来,然后继续进入RX。

void event_rx_fun(void)
{
	panchip_prf_payload_t rx_payload;

	uint8_t adv_header;

	adv_header = PRI_RF_READ_REG_VALUE(PRI_RF, R04_RX_ADDR_M, RX_HEADER);

	rx_payload.data_length = panchip_prf_data_rec(&rx_payload);

	printk("adv header:0x%02x, ", adv_header);

	printk("adv length:%d, ", rx_payload.data_length);

	printk("adv data:");
	data_printk(rx_payload.data, rx_payload.data_length);
	printk("\n");

	panchip_prf_reset();								//防止RX完成后进入TX中断

	panchip_prf_trx_start();
}

6 RAM/Flash资源使用情况

Memory region         Used Size  Region Size  %age Used
           FLASH:       29472 B       384 KB      7.50%
            SRAM:       11016 B        64 KB     16.81%