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

Solution: Multimode Mouse Dongle 4K

重要

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

1 功能概述

此sample为pan108xxb1(32pin芯片、1M Flash)或者pan108xxa1(32pin芯片、512k Flash)配合CH32V30x(高速USB透传芯片)在实体接收器板下的应用

具体支持的feature如下:

  • 2.4G模式(PRF增强型模式)

    1. 跳频:在信号质量不好(连续timeout = 10ms收不到数据)/对码前在8个频点(每个频点RX_FREQ_HOP_MS=10ms)进行跳频

      panchip_prf_rx_timeout(10000); /* rx lost cnt hop 10ms */
      
    2. 对码:上电跳频找到dongle端的频点后,通信互发对端的MAC地址后2字节,之后切换到私有地址进行通信

    3. 数据:数据跟随方案,对鼠标数据进行SPI透传

    4. 性能:配合鼠标端性能

2 环境要求

  • board: pan108xxa1(芯片型号)接收器(带usb)、pan108xxa1(芯片型号)evb开发板(调试使用)

    ​ 需要配合CH32V30x(高速USB透传芯片)

  • uart (option): xxa1串口打印使用P00(TX),P01(RX)

  • 4K鼠标测试工具:05_TOOLS\键鼠专用工具\第三方工具\鼠标测试工具\Polling Rate Tester App_v1.02.00.exe

3 编译和烧录

例程位置:zephyr\samples_panchip\solutions\multimode_mouse_dongle

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

CH32V30x端下载时,需要外部开发IDE:MounRiver_Studio_Setup_V185,下载链接:http://file.mounriver.com/upgrade/MounRiver_Studio_Setup_V185.zip

CH32V30x端源码工程: 05_TOOLS\键鼠专用工具\第三方工具\高速USB芯片配合工具\CH32_CODE\EXAM\USB\USBHS\DEVICE\CompatibilityHID\CompatibilityHID.wvproj

4 演示说明

芯片全擦除后,分别烧录PAN1080x芯片代码及CH32V30x芯片代码

4.1 初始对码

  1. 初始对码时,初始鼠标板(全擦除后烧录)先上电,鼠标端快速闪动时插入接收器,鼠标由快闪变为呼吸灯

  2. 之后鼠标未强制对码时,接收器可以一直保持,鼠标端重新上电可以与接收器通信

4.2 强制对码

鼠标端进入强制对码时,需要重新插拔接收器,鼠标端快速闪动时插入接收器,鼠标由快闪变为呼吸灯

4.3 DeviceTool使用

配合上位机工具键鼠专用工具\PAN108x工具\MouseDeviceTool可以进行产线USB信息测试及单载波测试,具体操作可以参考工具内说明文档

默认界面支持自定义消息开发,可以配合高速鼠标端 发送最长64B数据到鼠标端,并在下一包鼠标数据内带回可解析数据,回复固定9B,其余补充0xff

  • 需要先配合待通信鼠标端点击发送0a 43 01消息使鼠标端进入连续发送不休眠状态,后续才能在鼠标不移动状态下连续发送数据,

  • 根据协议文档传输数据时最长 可发送最长64B数据,0a 40为预留自定义消息头部

  • 恢复鼠标正常会休眠状态发送0a 43 00

  • 消息收发demo如下图,可以自定义通过历史发送消息封装成固定消息格式

DeviceTool_DG

自定义消息界面

显示界面可以切换到USB设置测试功能界面

5 开发说明

5.1 架构说明

multimode_mouse_dongle_4k基于zephyr架构,使用中断方式进行跳频对码,

架构中应用层主要包含

  • 2种中断

    • PRF中断

      RF中断内为提高效率,不适用效率低的接口,直接进行寄存器操作效率最高,4K速率速率通信时,不建议很长的ACK(0~2比较合适),偶尔长包上报不影响使用和速率

    • TIMER0中断(调试使用,测试35B数据1s上报逻辑)通过宏CONFIG_PRF_PACKET_RATE_TEST开启

  • 重要接口说明

    • 对码接口

      void prf_pair_start(void)
      
    • SPI透传接口(透传至高速USBCH32V30x

      __ramfunc void spi_transfer(uint8_t *data, uint32_t data_len)
      

5.2 线程说明

4K方案暂未使用,按需同步1K方案

线程定义方式如下

/**
 * @brief Statically define and initialize a thread.
 *
 * The thread may be scheduled for immediate execution or a delayed start.
 *
 * Thread options are architecture-specific, and can include K_ESSENTIAL,
 * K_FP_REGS, and K_SSE_REGS. Multiple options may be specified by separating
 * them using "|" (the logical OR operator).
 *
 * The ID of the thread can be accessed using:
 *
 * @code extern const k_tid_t <name>; @endcode
 *
 * @param name Name of the thread.
 * @param stack_size Stack size in bytes.
 * @param entry Thread entry function.
 * @param p1 1st entry point parameter.
 * @param p2 2nd entry point parameter.
 * @param p3 3rd entry point parameter.
 * @param prio Thread priority.
 * @param options Thread options.
 * @param delay Scheduling delay (in milliseconds), zero for no delay.
 *
 *
 * @internal It has been observed that the x86 compiler by default aligns
 * these _static_thread_data structures to 32-byte boundaries, thereby
 * wasting space. To work around this, force a 4-byte alignment.
 *
 */
#define K_THREAD_DEFINE(name, stack_size,                                \
			entry, p1, p2, p3,                               \
			prio, options, delay)                            \
	K_THREAD_STACK_DEFINE(_k_thread_stack_##name, stack_size);	 \
	struct k_thread _k_thread_obj_##name;				 \
	STRUCT_SECTION_ITERABLE(_static_thread_data, _k_thread_data_##name) = \
		Z_THREAD_INITIALIZER(&_k_thread_obj_##name,		 \
				    _k_thread_stack_##name, stack_size,  \
				entry, p1, p2, p3, prio, options, delay, \
				NULL, name);				 	 \
	const k_tid_t name = (k_tid_t)&_k_thread_obj_##name

根据线程定义,定义了如下几个线程

5.2.1 PRF线程

2.4G主线程,接收数据,判断数据seq并为USB准备数据

#define PRF_THREAD_PRIORITY             2
#define PRF_THREAD_STACKSIZE            1024

K_THREAD_DEFINE(prf, PRF_THREAD_STACKSIZE, thread_prf, NULL, NULL, NULL,
		PRF_THREAD_PRIORITY, 0, 0);

5.2.2 USB线程

USB线程,USB插入PC时进入,获取组包并且上报

#define USB_THREAD_PRIORITY                     1
#define USB_THREAD_STACKSIZE            		1024

K_THREAD_DEFINE(usb, USB_THREAD_STACKSIZE, thread_usb, NULL, NULL, NULL,
		USB_THREAD_PRIORITY, 0, 0);

5.3 RF中断说明

接收器为PRF RX端,增强型模式会在RX后自动转入TX, 需要注意配置timeout时间控制跳频逻辑,RX中断内SPI发送数据

5.4 主要数据结构说明

5.4.1 枚举状态

5.4.1.1 配对状态、地址类型
enum prf_pair_stat_t {
	prf_pair_default,
	prf_pair_start,
	prf_pair_comm,
	prf_pair_end,
};

enum pair_addr_type_t {
	prf_pair_public,
	prf_pair_private,
};

5.4.2 全局结构

5.4.2.1 packet格式结构体

10B数据SPI透传至 CH32V30x即可,CH32V30x端会进行buffer缓存并上传USB端

5.4.2.2 配对信息结构体
struct pair_ctrl_t {
	enum prf_pair_stat_t prf_pair_stat;
	bool prf_pair_timeout;
	bool paired_flag;
	uint8_t pair_own_addr[2];
	uint8_t pair_peer_addr[2];
	uint8_t pair_cnt;
	bool pair_saved_flag;
	enum pair_addr_type_t pair_addr_type;
};

5.5 主要逻辑

参考4K鼠标文档,接收端主要逻辑为跳频收包SPI透传

6 补充说明

4Kdongle端不能(USBP02 P03用来做SPI功能)也没有必要同时具有USB功能,可以对相关USB,EMI内容进行移除或者变更

相关RF,USB代码可以进行裁剪移除

7 RAM/Flash资源使用情况

Memory region         Used Size  Region Size  %age Used
FLASH:       58644 B       152 KB     37.68%
SRAM:        32616 B        50 KB     63.70%