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

PRF Dongle

重要

此例程仅存在于特殊版本的SDK中,如有需要请联系Panchip。

1 功能概述

此sample为pan107/pan101上演示Dongle配合108鼠标端控制功能

2 环境要求

  • board: pan107QFN32核心板/ pan101MSOP10核心板 + evb底板

  • uart0: 设置P16,P17作为默认的LOG输出端口,波特率921600

3 编译和烧录

例程位置:<home>\nimble\samples\solutions_hid\prf_dongle\keil_107x

使用keil进行打开项目进行编译烧录,需要先移植确认flm文件(modules\hal\panchip\panplat\pan1070_hal_release\mcu_misc)拷贝至keil安装目录

4 演示说明

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

  2. 108鼠标进入强制配对,在2412频点 { 0x7b, 0x41, 0x29, 0x71 }发送鼠标端的mac地址

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

  4. 对码后可以进行控制

5 开发说明

5.1 Flash配置及接口说明

PAN107(512K 32pin)芯片作为调试芯片,最终PAN101(仅4个IO:P00 P01作为烧录脚,可以复用;P13 P14作为USB通信线,无Reset脚,reset需要重新上电;16K RAM 256K flash)作为实际使用芯片

为确保PAN107编译的程序可以直切切换到PAN101芯片中

BOOT默认划分40k flash,APP默认划分440k flash,可在samples\solutions_hid\keil_107x\configuration\sdk_config.h中查看

CONFIG_ENABLE_BOOTLOADER=1:程序从boot启动后跳转到APP编译地址0xA000,需要先进行boot烧录

CONFIG_ENABLE_BOOTLOADER=0:设置0可以将APP编译到0x0地址,rebuild烧录后,芯片不含boot区域

其他配置可以参考,不建议改动

// <h> Flash Partition Config

// <e> Enable Bootloader
// <i> Enable bootloader for current App Project.
// <i> That means, App Image would not be generated (linked) at Flash 0 address, instead, it would be generated (linked) at flash address right after Bootloader Flash Partition.
#define CONFIG_ENABLE_BOOTLOADER                            1

// <o> Bootloader Flash Partition Size (KB)
// <i> Note that partition size should be multiple of 4KB!
#define CONFIG_FLASH_PARTITION_BOOTLOADER_SIZE_KB           40

// <s> Bootloader Project Path (Directory)
// <i> Specify relative or absolute path of Bootloader project.
// <i> NOTE here we should use slash ('/') as path separator instead of backslash ('\')!
#define CONFIG_BOOTLOADER_PROJECT_PATH                      "../../bootloader/keil_107x"

// <e> Forcibly Build Bootloader Project
// <i> Build bootloader project:
// <i> - AFTER current App Image build done
// <i> - BEFORE Bootloader/App image merging (if enabled).
#define CONFIG_FORCE_BUILD_BOOTLOADER_PROJECT               0

// <o> Select Bootloader Build Command
// <i> Here prvides two build commands for selection, they are completely equal with corresponding buttons on Keil UI.
// <0=> Build
// <1=> Rebuild
#define CONFIG_BOOTLOADER_BUILD_COMMAND                     0

// <q> Show Bootloader Build Logs
// <i> Show bootloader build logs in Build Output window of current App project.
#define CONFIG_SHOW_BOOTLOADER_BUILD_LOG                    1
// </e> Forcibly Build Bootloader Project End

// <e> Merge Bootloader and App Into One Single Image
// <i> Copy bootloader image to App 'Images' folder and then merge bootloader and app into one single image.
// <i> It is recommended to flash the Merged Image when using PanLink or JFlash Tool.
#define CONFIG_MERGE_IMAGES                                 1

// <s> Merged Image Name
// <i> Specify the name of generated merged image.
#define CONFIG_MERGED_IMAGE_NAME                            "nImageMerged"
// </e> Enable App Image Header End

// <o> App Flash Partition Size (KB)
// <i> Note that partition size should be multiple of 4KB!
#define CONFIG_FLASH_PARTITION_APP_SIZE_KB                  440

// <o> App Backup Flash Partition Size (KB)
// <i> Note that partition size should be multiple of 4KB!
#define CONFIG_FLASH_PARTITION_APP_BACKUP_SIZE_KB           0

// <o> KVStore Flash Partition Size (KB)
// <i> Note that partition size should be multiple of 8KB!
#define CONFIG_FLASH_PARTITION_KVSTORE_SIZE_KB              16

// <o> User Custom Flash Partition Size (KB)
// <i> Note that partition size should be multiple of 4KB!
#define CONFIG_FLASH_PARTITION_USER_CUSTOM_SIZE_KB          12

samples\solutions_hid\bootloader\Keil_107x\project.sct 中限制了RAM使用大小16K

#! armcc -E
#include ".\configuration\sdk_config.h"
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LOAD_FLASH CONFIG_FLASH_PARTITION_BOOTLOADER_ADDR CONFIG_FLASH_PARTITION_BOOTLOADER_SIZE
{
    FLASH_TEXT +0
    {
        *.o (RESET, +First)
        *(InRoot$$Sections)
        .ANY (+RO)
        .ANY (+XO)
    }

    SRAM_DATA_TEXT 0x20000000 0x0000C000  // 48KB Common SRAM for PAN107x SoC
    {
        .ANY (+RW +ZI)
        *.o (.ramfunc)
    }
}

以上,确保107芯片上编译验证后可以进行直接切换下载到101芯片中

BOOT跳转注意点:

可以使用 boot工程中BOOT_ENABLE_USB_DFU来控制实现boot升级流程,也可以不使用,最终跳转接口jump_to_app

Flash存读接口:

参考prf dongle代码中,对 配对的mac地址的操作,参考代码在200k位置进行配对信息存储

/* 200k start save pair addr two */
FMC_ReadStream(FLCTL, PRF_PAIR_ADDR_FLASH_ADDR0, CMD_DREAD, read_addr0, 6);
FMC_ReadStream(FLCTL, PRF_PAIR_ADDR_FLASH_ADDR1, CMD_DREAD, read_addr1, 6);

FMC_WriteStream(FLCTL, PRF_PAIR_ADDR_FLASH_ADDR0, &prf_state.pair_private_addr[0][0], 6);
FMC_WriteStream(FLCTL, PRF_PAIR_ADDR_FLASH_ADDR1, &prf_state.pair_private_addr[1][0], 6);

5.2 PRF说明

5.2.1 初始化

pan_prf_config_t rx_config =
{
	.work_mode = (prf_mode_t)PRF_MODE_ENHANCE,
	.chip_mode = (prf_chip_mode_sel_t)PRF_CHIP_MODE_SEL_XN297,
	.trx_mode = (prf_trx_mode_t)PRF_RX_MODE,
	.phy = (prf_phy_t)PRF_PHY_2M,
	.crc = (prf_crc_sel_t)PRF_CRC_SEL_CRC16,
	.src = (prf_scramble_sel_t)PRF_SRC_SEL_EN,
	.mode_conf = (prf_mode_conf_sel_t)PRF_BLE_CONF,
	.rx_timeout = 10000,
	.rf_channel = PAIR_PUBLIC_CHANNEL,
	.tx_no_ack = DISABLE,
	.trf_type = (prf_trf_t)PRF_TRF_NORMAL,
	.rx_length = 64,
	.sync_length = 4,
	.crc_include_sync = ENABLE,
	.src_include_sync = ENABLE,
	.sync = PAIR_PUBLIC_ADDR,
	.pid_manual_flag = ENABLE,
	.tx_power = 9,
	.pipe = PRF_PIPE0,
};


void mouse_prf_init(void)
{
	ana_prf_ldo_en();

	panchip_prf_init(&rx_config);

	/* init not init channel, must init channel after init */
	panchip_prf_set_chn(rx_config.rf_channel);

	/* adr match bit match whole absolutely */
	PRI_RF_SetAddrMatchBit(PRI_RF, 0);
	/* disable pid err isr */
	panchip_prf_pid_cfg(&rx_config, 0);
	/* enable len err isr */
	panchip_prf_rx_length_irq_cfg(ENABLE);

	#if PRF_DBG_PIN
	PRI_RF_WRITE_REG_VALUE(PRI_RF, TEST_MUX02, TST_MUX_SELECT_11, 0x14); // tx on
	SYS->P1_MFP |= SYS_MFP_P10_LL_DBG_11;

	PRI_RF_WRITE_REG_VALUE(PRI_RF, TEST_MUX02, TST_MUX_SELECT_09, 0x15); // rx on
	SYS->P0_MFP |= SYS_MFP_P04_LL_DBG_9;

	PRI_RF_WRITE_REG_VALUE(PRI_RF, TEST_MUX02, TST_MUX_SELECT_10, 0x17); // data
	SYS->P0_MFP |= SYS_MFP_P07_LL_DBG_10;

	PRI_RF_WRITE_REG_VALUE(PRI_RF, TEST_MUX03, TST_MUX_SELECT_12, 0x13); // acc match
	SYS->P0_MFP |= SYS_MFP_P05_LL_DBG_12;
	#endif

	mouse_prf_pair_init();

	panchip_prf_trx_start();
}
  1. 全局变量rx_config,部分来源于config文件,部分来源于直接配置,定义好后,panchip_prf_init(&rx_config);会进行除了频点之外的初始化,一定要在之后进行频点设置panchip_prf_set_chn(rx_config.rf_channel);

  2. init后,设置地址全匹配,关闭pid err中断,开启len err中断,rf状态可控,增强型模式下,一定会进行完成r->t/timeout/crc/len err状态,中断内控制好下一次trx start之前进行flash操作、状态控制,不会引起rf死机状态

  3. PRF_DBG_PIN控制lldbg信号,可以抓取rf工作中的时序,但需要注意,开启debug信号时会一定程度影响rf,crc率会变高,关闭后正常

  4. mouse_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

}


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


#### 5.2.2 时间说明

说明比较重要的时间量取参数

![prf_dg_time](images/prf_dg_time.png)

1. timeout debug信号结束到进入timeout中断:9us

2. 设置频点时间:50us

3. trx start调用到debug信号拉取到发送出数据:24us

4. DG端 rx自动转tx发送出时间:26us

5. trx start执行占用时间

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

```c
/* 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使用说明

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

演示说明:

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

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

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

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

对码说明参考演示说明部分的第四点,补充说明鼠标1和鼠标2的区别在于,配对过程数据字段,回复的数据除了各自mac地址,还有额外的数据字段区分对应配对到哪一个pipe,107 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软件过程基本与108一致,其他部分使用也一致

硬件需要注意,101/107系列早期存在USB有问题版本,接入hub并且在hub上的第一个口通常能识别成功但也不稳定,直插线的方式在大部分电脑上都不能成功识别,一定要选用MPC版本之后USB修复后的芯片

void usb_init(void)
{
    usbd_desc_register(0, hid_descriptor);
    usbd_add_interface(0, usbd_hid_init_intf(0, &intf0, standard_keyboard_report, DEF_Intface0_ReportDes_SIZE));
    usbd_add_endpoint(0, &hid_intf0_in_ep);
    usbd_add_interface(0, usbd_hid_init_intf(0, &intf1, keyboard_report, DEF_Intface1_ReportDes_SIZE));
    usbd_add_endpoint(0, &hid_intf1_in_ep);
    usbd_add_endpoint(0, &hid_intf1_out_ep);
    usbd_add_interface(0, usbd_hid_init_intf(0, &intf2, dfu_report, DEF_Intface2_ReportDes_SIZE));
    usbd_add_endpoint(0, &hid_intf2_in_ep);
    usbd_add_endpoint(0, &hid_intf2_out_ep);

    usbd_initialize(0, USB_BASE, usbd_event_handler);
}

6 RAM/Flash资源使用情况

PAN107x:

Flash Size:  38.82k
RAM Size:  10.48 k