当前页面为 开发中 版本,查看特定版本的文档,请在页面左下角的下拉菜单中进行选择。

PRF Dongle

1 功能概述

此sample为在pan271x上演示Dongle配合pan10xx作为鼠标端控制功能

2 环境要求

  • 硬件设备与线材:

    • PAN271x EVB 核心板底板各一块

    • JLink 仿真器(用于烧录例程程序)

    • USB-TypeC 线一条(用于底板供电和查看串口打印 Log)

    • 杜邦线数根或跳线帽数个(用于连接各个硬件设备)

  • 硬件接线:

    • 将 EVB 核心板插到底板上

    • 连接串口转USB调试模块:

      • 使用 USB-TypeC 线,将 PC USB 插口与 EVB 底板 USB->UART 插口相连

      • 使用杜邦线或跳线帽将 EVB 底板 J8 排针对 (P06 & TXD) 和 J9 排针对 (P05 & RXD) 分别短接起来

    • 连接 Jlink,使用杜邦线将 JLink 仿真器的:

      • SWD_CLK 引脚与 EVB 底板的 P00 排针相连

      • SWD_DAT 引脚与 EVB 底板的 P01 排针相连

      • SWD_GND 引脚与 EVB 底板的 GND 排针相连

  • PC 软件:

    • 串口调试助手(UartAssist)或终端工具(SecureCRT),波特率 115200(用于串口交互)

3 编译和烧录

例程位置:01_SDK\samples\solutions\prf_dongle\keil\prf_dongle

使用keil打开项目进行编译烧录。

4 演示说明

  1. keil编译烧录prf_dongle程序,此时进入对码状态,dongle端在2412频点 { 0x7b, 0x41, 0x29, 0x71 }地址(PIPE0)进行扫描,并根据本地mac地址的后四位计算出私有的8个跳频地址。

  2. pan10xx鼠标按下左中右三个按键进入配对模式,在2412频点 { 0x7b, 0x41, 0x29, 0x71 }发送鼠标端的mac地址。

  3. pan271x dongle收到对码地址频点的鼠标端mac地址后,回复本地mac地址,并且把鼠标端mac地址后四位设置为PIPE1地址,如果在PIPE1地址上任意私有频点收取到数据,结束对码状态,如果没有收到私有地址频点的通信包,timeout中仍有机会切换到配对频点(鼠标端收到对码地址频点的dongle mac地址后,计算出私有的8个跳频地址,切换到鼠标mac地址后四位作为地址,跳频发送数据)。

  4. 对码成功后鼠标可以控制PC。

    串口LOG如下所示:

    [11:27:05.484]收←◆CPU @ 48000000Hz
    usb_init
    plug in
    
    [11:27:05.535]收←◆get_mac_addr: 0x11 0x22 0x33 0x44 0x55 0x66
    calculate_combo_freq use 0x33 0x44 0x55 0x66
    x = 1 y = 5
    2464 abandon
    calculate private freq: 2428 2446 2466 2402 2420 2438 2456 2474
    
    [11:27:05.566]收←◆0x0 0x0 0x0 0x0 0x0 0x0
    0x0 0x0 0x0 0x0 0x0 0x0
    0x0 0x0 0x0 0x50
    USB isr in: Reset evt
    
    [11:27:05.637]收←◆USB isr in: Reset evt
    
    [11:27:14.782]收←◆hop end @ 2438
    
    [11:27:14.816]收←◆save new pair addr1: 0xE1 0xA0 0x0 0xA 0x1B 0x9B
    

5 开发说明

5.1 配对信息存储及接口说明

PAN271x使用EEPROM来保存配对信息,配对信息主要包含配对后的通信地址。EEPROM使用GPIO模拟IIC控制。

EEPROM读写接口:

P24C02_ReadSequential(0x10, read_addr0, 6);
P24C02_ReadSequential(0x20, read_addr1, 6);

data_printf(read_addr0, 6);
data_printf(read_addr1, 6);
memcpy(&prf_state.pair_private_addr[0][0], read_addr0, 6);
memcpy(&prf_state.pair_private_addr[1][0], read_addr1, 6);

void write_pair_addr(void)
{
	if(pair_addr0_write) {
		pair_addr0_write = false;
		P24C02_WritePage(0x10, &prf_state.pair_private_addr[0][0], 6);
		mini_printf("save new pair addr1: ");
		data_printf(&prf_state.pair_private_addr[0][0], 6);
	}

	if(pair_addr1_write) {
		pair_addr1_write = false;
		P24C02_WritePage(0x20, &prf_state.pair_private_addr[1][0], 6);
		mini_printf("save new pair addr2: ");
		data_printf(&prf_state.pair_private_addr[1][0], 6);
	}
}

5.2 PRF说明

5.2.1 初始化

pan_prf_config_t __align(4) rf_config =
{
	.work_mode			= PRF_MODE_ENHANCE,//PRF_MODE_NORMAL,PRF_MODE_ENHANCE
	.chip_mode			= PRF_CHIP_MODE_SEL_XN297,//PRF_CHIP_MODE_SEL_NRF,//PRF_CHIP_MODE_SEL_XN297,
	.trx_mode			= PRF_RX_MODE,
	.phy				= PRF_PHY_2M,//PRF_PHY_250K,//PRF_PHY_1M,PRF_PHY_2M
	.crc				= PRF_CRC_SEL_CRC16,
	.scr				= PRF_SCR_SEL_EN,
	.mode_conf			= PRF_BLE_CONF,//PRF_BLE_CONF
	.pipe				= PRF_PIPE0,
	.rx_timeout			= 10000,			//us
	.rf_channel			= PAIR_PUBLIC_CHANNEL,
	.tx_no_ack			= DISABLE,
	.rx_length			= 30,
	.sync_length		= 4,
	.sync				= PAIR_PUBLIC_ADDR,
	.crc_include_sync	= ENABLE,
	.scr_include_sync	= ENABLE,
	.auto_pyl_flag		= ENABLE,
	.pid_manual_flag	= ENABLE,
	.endian				= PRF_BIG_ENDIAN,
	.tx_power			= 8,
};


void dongle_prf_init(void)
{
	panchip_prf_init(&rf_config);

	/* enable len err isr */
	panchip_prf_rx_length_irq_cfg(rf_config.rx_length);

	SYS_SET_MFP(P2,1,LL_DEBUG_0);		//tx_on
	SYS_SET_MFP(P2,0,LL_DEBUG_1);		//rx_on
	SYS_SET_MFP(P0,4,LL_DEBUG_9);		//match

	dongle_prf_pair_init();

	panchip_prf_trx_start();
}
  1. 全局变量rf_config基本包含了2.4g的所有配置,定义好后就可以使用panchip_prf_init(&rf_config);接口对RF初始化。

  2. RF初始化完后,开启len err中断,rf状态可控,增强型模式下,一定会进行完成r->t/timeout/crc/len err状态,中断内控制好下一次trx start之前进行数据存储操作、状态控制,不会引起rf死机状态

  3. LL DEBUG信号可以抓取rf工作中的时序,但需要注意,开启debug信号时会一定程度影响rf,crc率会变高。调试阶段可以打开,正常使用要关闭。

  4. dongle_prf_pair_init();中获取dongle mac地址,计算出配对频点(通过dongle mac后四字节),并且设置可能存储过的配对地址作为rf 收取地址

     /* set PRI_RF_MODE_SEL_RX addr will set the rx addr & pipe */
     /* set PRI_RF_MODE_SEL_TX addr will set the single tx addr, no set tx will use init tx addr */
     /* set PRI_RF_MODE_SEL_TRX addr will set the trx addr both, no set tx will use init tx addr */
    panchip_prf_set_addr(addr_format, 4, PRF_PIPE1, PRI_RF_MODE_SEL_RX);
    panchip_prf_set_addr(addr_format, 4, PRF_PIPE2, PRI_RF_MODE_SEL_RX);
    

    设置PRI_RF_MODE_SEL_RX地址仅设置接收PIPE,不会设置发送地址

    rx isr中需要设置payload并且设置回复时的tx地址,设置发送地址参考

     /* set addr will set the tx addr, if want to ack data from dynamic rx pipe ,rx isr must set tx addr */
     CONFIG_RAM_CODE void app_prf_set_tx_addr(uint8_t *addr)
     {
     #if SET_TX_ADDR_DIRECT
     /* 1.25us */
     uint32_t tx_addr;
    
     tx_addr = (addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
    
     PRI_RF_WRITE_REG_VALUE(PRI_RF, R05_TX_ADDR_L, L32B, tx_addr);
     #else
     /* 6us no used third param */
     panchip_prf_set_addr(addr, 4, PRF_PIPE0, PRI_RF_MODE_SEL_TX);
     #endif
    
    

}

  1. 最后进行panchip_prf_trx_start();开启tx;

5.2.2 时间说明

为了适配pan10xx的键鼠,pan271x dongle的rx转tx的时间配置成30us。如果往大了调鼠标端会收不到ack。如下图所示:

image

rx isr中需要设置payload并且设置回复时的tx地址,设置地址时,可以快速设置4字节地址或者调用底层封装接口设置,分别占用1us或者6us,影响还好,就算当前次不能及时设置好地址,依然会在下次配对地址收到数据后在对应地址回复出

/* set addr will set the tx addr, if want to ack data from dynamic rx pipe ,rx isr must set tx addr */
CONFIG_RAM_CODE void app_prf_set_tx_addr(uint8_t *addr)
{
 #if SET_TX_ADDR_DIRECT
 /* 1.25us */
 uint32_t tx_addr;

 tx_addr = (addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);

 PRI_RF_WRITE_REG_VALUE(PRI_RF, R05_TX_ADDR_L, L32B, tx_addr);
 #else
 /* 6us no used third param */
 panchip_prf_set_addr(addr, 4, PRF_PIPE0, PRI_RF_MODE_SEL_TX);
 #endif
}

5.2.3 多pipe使用说明

多pipe地址读取的功能,灵活使用可以实现配对地址和多通道地址同时可以收取回复数据,基于此feature可以扩展多个主机设备配对同一dongle,目前主机端最快速度在250us内可以完成发收,所以多设备自行处理的条件下,通过重传可以做到至少2个设备配对同一dongle后,可以达到1000hz上报率

演示说明:

  1. 准备2个pan1080 8k鼠标,鼠标1下载默认程序,鼠标2下载 PAIR_COMBO_DG_DEV2=1的第二设备程序

  2. 编译下载PAIR_ONLY_ONE=0的pan271x dongle程序

  3. 鼠标1进入配对状态,复位pan271x,鼠标1配对成功,鼠标1不移动情况下鼠标2进入配对或者上电状态,鼠标2配对成功

  4. 鼠标1可以达到1000hz上报率,鼠标2默认配对后125hz上报率

对码说明参考演示说明部分的第四点,补充说明鼠标1和鼠标2的区别在于,配对过程数据字段,回复的数据除了各自mac地址,还有额外的数据字段区分对应配对到哪一个pipe,pan271x rf中确认私有mac搜索到数据通信后不再添加其他地址,重新上电会重新进入可添加pipe地址状态

	pkt_pair.magic = PAIR_MAGIC;
	#if PAIR_COMBO_DG_DEV2
	pkt_pair.type = 0x20;
	#else
	pkt_pair.type = PAIR_MOUSE_8K_FLAG;
	#endif
	memcpy(pkt_pair.mac, pair_ctrl.pair_own_addr, 6);
	memcpy(tx_payload.data, &pkt_pair, 9);

5.3 USB说明

USB init软件过程基本与pan10xx一致,其他部分使用也一致

void usb_init(void)
{
	uint32_t reg_tmp;

	SYS->SYS_CTRL |= (SYS_CTRL_USB_PU_Msk | SYS_CTRL_USB_PU2_Msk | SYS_CTRL_USB_EN_Msk);
	/*usb debounce time*/
	SYS->SYS_CTRL = ((SYS->SYS_CTRL & ~SYS_CTRL_VALID_REMOVAL_CYCLES_Msk) | 100);

	reg_tmp = READ_REG(USB->INT_USBE);
	reg_tmp |= 0x10;
	WRITE_REG(USB->INT_USBE,reg_tmp);

//	NVIC_EnableIRQ(USB_IRQn);

	mini_printf("usb_init\n");
	NVIC_SetPriority(USB_IRQn, 1);
	NVIC_EnableIRQ(USB_IRQn);
}

6 RAM/Flash资源使用情况

PAN271x:

- Flash Size:  14.79kB
- RAM Size:  1.80kB