USB HID转蓝牙&鼠键宏&指纹解锁

USB-HID-BLER

将有线鼠标键盘游戏手柄等USB HID转换为蓝牙设备,附带鼠键宏和指纹解锁功能。
硬件开源地址前作

主要功能

  • 使用esp32-c3的GPIO模拟USB HOST,识别低速USB HID设备并读取其报告描述符和报告
  • TEANSLATE工作模式: 检测设备类型,尝试对鼠标和键盘的报告描述符进行解析,将其报告翻译成预定义的标准报告并转发
  • PASSTHOUGH工作模式: 对于其他类型设备和解析失败的鼠标键盘,将其报告描述符和报告原样转发
  • 集成电池管理,可使用电池供电、使用USB供电、使用USB为电池供电
  • 鼠键宏: 对于工作在TEANSLATE模式的设备可以定义任意鼠标/键盘宏(施工中)
  • 指纹解锁:集成指纹模块,通过模拟键盘发送密码实现指纹解锁Windows(施工中)
  • 图形化管理软件: 通过蓝牙HID协议无线控制设备状态(施工中)

ESP32-C3固件

开源地址: https://github.com/dnstzzx/usb-hid-bler
固件代码主要由以下几个部分组成:

仅支持低速HID设备,以后可能会考虑用esp32-s3的USB PHY支持全速设备
识别方法:对设备供电后,D-被拉高的为低速设备,D+被拉高的为全速/高速设备

  • 基于乐鑫官方例程的BLE HID Device,用于实现将报告转发到蓝牙主机
  • 解析HID报告描述符并尝试将鼠标键盘设备报告翻译为预定义的标准报告,为便于移植该部分代码已分离到HID-REPORT-TRANSLATER
  • 鼠键宏, 施工中
  • 下位机通讯,施工中

USB软总线

本作品带有两路USB A接口用于接入HID设备,均为通过GPIO进行模拟。实现源自esp32_usb_soft_host,根据原作者的描述存在以下注意事项:

  1. 需要将Menuconfig->compiler options->optimization level设置为O2
  2. 需要将 Component config-> ESP System Setting -> Memory protection关闭

idf.py set-target命令会重置优化级别到Og,需要重新设置

USB Host实现主要位于usb_host.c,大部分代码通过一个周期为1ms的定时器中断执行。定时器中断ISR代码如下:

void IRAM_ATTR usb_process()
{
   
   
#if CONFIG_IDF_TARGET_ESP32C3
	cpu_ll_enable_cycle_count();
#endif	
	for(int k=0;k<NUM_USB;k++)
	{
   
   
		current = &current_usb[k];
		if(current->isValid)
		{
   
   
			setPins(current->DP,current->DM);
			timerCallBack();  
			fsm_Mashine();
		}
	}
}

可见每个定时器周期会对每个USB端口分别执行一次timerCallBack和一次fsm_Mashine。timerCallBack根据上一周期的状态机进行NRZI读写,而fsm_Mashine负责更新状态机。你可能会好奇在ISR中如何进行延时操作(USB低速模式时钟周期为1.5MHz即每传输一位需要等待0.667微秒)。实际上这是通过填充空指令NOP实现的(NOP在Risc-v中被拓展为addi x0, x0, 0 而x0寄存器被硬编码为0,即为一次无意义的加法运算),填充过程如下:

void (*delay_pntA)() =NULL;
#define cpuDelay(x) {
     
     (*delay_pntA)();}

void setDelay(uint8_t ticks)
{
   
   
// opcodes of void test_delay() {__asm__ (" nop"); __asm__ (" nop"); __asm__ (" nop"); ...}
//36 41 00 3d f0 1d f0 00 // one  nop
//36 41 00 3d f0 3d f0 3d f0 3d f0 3d f0 1d f0 00  // five  nops
//36 41 00 3d f0 3d f0 3d f0 3d f0 3d f0 3d f0 1d  f0 00 00 00 //
int    MAX_DELAY_CODE_SIZE = 0x210;
uint8_t*     pntS;
	// it can't execute but can read & write
	if(!delay_pntA)
	{
   
   
		pntS = heap_caps_aligned_alloc(32,MAX_DELAY_CODE_SIZE, MALLOC_CAP_8BIT);
	}
	else
	{
   
   
		pntS = heap_caps_realloc(delay_pntA, MAX_DELAY_CODE_SIZE, MALLOC_CAP_8BIT);
		//~ printf("pntS = %p\n",pntS);
	}
	uint8_t* pnt = (uint8_t*)pntS;
	//put head of delay procedure
	for(int k
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值