目录
现在市面上的键盘大多支持“远程唤醒”功能。在使用个人电脑PC的场景中,USB键鼠(包括键鼠的2.4G模式,无线接收头也是被电脑识别为USB设备)的“远程唤醒”指键盘可以通过USB的Resume信号来唤醒电脑,“唤醒电脑”成功的最直观体现为显示器屏幕被点亮。
当键鼠设备的USB键鼠上传键值的功能正常,但就是无法令休眠的PC“点亮屏幕”时:
①先判断USB口的电源是否异常。
有Power-Z工具的话就很直观,在PC休眠期间也能检测到二三十mA上下的电流,那是有保持供电的。
也可以用多款鼠标做对比测试,如果都无法唤醒电脑,大概是PC休眠期间把USB口给断了,需要在电脑系统中做相关配置。
②结合日志/IO信号,去判断MCU是否识别到PC休眠,又是否发出了RESUME信号。
——是否识别到PC休眠?
WCH的三模键鼠demo中,用USBHS_DevSleepStatus这一变量,来记录键鼠是否应该休眠。
USBHS_DevSleepStatus的bit0置1,表示MCU收到USB_SET_FEATURE命令。
在USB的setup包解析中可以找到。WIN系统会在电脑休眠的前一刻下发USB_SET_FEATURE命令,允许键鼠设备发起远程唤醒;而MAC电脑在枚举到设备支持远程唤醒后,即下发USB_SET_FEATURE命令。
USBHS_DevSleepStatus的bit1置1,表示MCU收到SUSPEND信号。
在USB中断标志RB_UIF_SUSPEND或是USBHS_UDIF_SUSPEND(分别对应全速/高速USB)上下,可以找到。
当USBHS_DevSleepStatus为0x03时,键鼠判断电脑已休眠,键鼠自身应该关闭灯光等耗电外设功能,降低功耗。
电脑休眠期间,键鼠不允许发出USB报文,否则USB-CV(USB指令认证)测试无法通过。
——是否发出了RESUME信号?
WCH的三模键鼠demo中,封装了USB_Wake_Up()函数和USBHS_Send_Resume()函数,用于在全速/高速USB下,产生RESUME信号。
一般放在键鼠被唤醒后执行。在这两个函数一开头,加个打印日志/IO电平翻转,监控一下有没有跑到。
也可以用示波器抓到D+D-脚上产生一个持续20ms的USB-K状态电平保持信号。USB的其他信号都是高频变化的差分信号,示波器中很好区别是否有这一段信号。
USB设备需要发发出K状态1~15ms(MCU通过上述resume接口函数发出),USB主机检测到后会补足到≥20ms。

如果到目前为止一切正常,示波器抓到的USB-RESUME波形也正常,还是无法点亮电脑屏幕呢?
应用需求是什么样的?
比如说,希望只敲一下键盘上的任意键,电脑就能显示屏保界面,那么有一种情况:电脑系统可以接收到USB-RESUME的唤醒信号,电脑也有后续发出USB的SOF帧起始信号、CLEAR_FEATURE命令等正常流程,但是由于键鼠没有做后续响应,电脑认为没必要执行包括点亮屏幕的后续操作。也就是说,在RESUME信号后,键鼠需要再发至少一包键鼠报文,电脑才会点亮屏幕。
“只敲一下键盘上的任意键”
——如果需要发出表示键盘/鼠标功能的报文,
从MCU的休眠唤醒角度上讲,MCU的sleep等级的休眠,被IO唤醒后无需复位MCU,IO唤醒后MCU正常工作需要2~3ms左右的时间,那么MCU可以缓存下数包键鼠键值,在PC下发CLEAR_FEATURE命令并恢复IN令牌包后依次上传。
但是如果是在键盘shutdown等级的休眠即最低功耗的深度睡眠的场景下,MCU被IO唤醒后立即复位了,该键值无法被记录下来,无法上传该键值,这样只能“再敲一下键盘”来点亮屏幕。
再敲一下键盘才能点亮屏幕的键盘,在市面上是存在的。有抓过罗x品牌的一款有线键盘,在唤醒休眠的PC时,仅发出RESUME信号,而不发出键盘键值,PC屏幕未被点亮;再敲一下键盘则可点亮屏幕。
——如果需要发出其他类型的报文(比如说音量加减,它用的是是HID的多媒体报文),
根据我抓到了3款不同型号的WIN笔记本电脑来看,音量加减的报文可以上传,但是没办法令电脑亮屏显示屏保,音量加减也没有实际完成。一定要发出一包键鼠的键值,哪怕是全0的表示键盘“全抬起”的报文。
如果接受USB-CV认证流程中,在紧接着WAKEUP唤醒条目后的“CLEAR FEATURE命令后禁止唤醒”条目,概率性不通过的情况,那么可以发“全抬起”报文来令电脑亮屏。
比如说,应用要求需要单独按下键盘的FN键,也可以唤醒电脑点亮屏幕,那么可以在键盘唤醒电脑时刻,按下FN后发送“全抬起”报文;再比如说,直接操作音量滚轮无法唤醒电脑,可以在滚轮键值发出前,先发出键盘“全抬起”报文。
