STM32F4_USB远程唤醒避坑指南

STM32F4 USB远程唤醒避坑指南

本篇文章是以STM32F411CEU6为例,使用USB远程唤醒功能去唤醒PC做的一个测试例程,以下是个人成功唤醒PC的一个方法。

1、配置描述符的bmAttributres字节必须配置远程唤醒功能

因为USB host会根据此D5:远程唤醒位来判断设备是否支持远程唤醒,若设备支持远程唤醒,那么PC进入休眠前会发送Set_Feature请求告诉USB device启用远程唤醒功能,此时device知道主机可以支持远程唤醒功能。当device发送唤醒序列唤醒host后,host会发送Clear_Feature清除此位来禁用远程唤醒功能。

在这里插入图片描述

2、远程唤醒流程参考

可以参考这两个网站,说的比较详细:

USB设备的休眠挂起及远程唤醒 - USB中文网 (usbzh.com)

USB设备远程唤醒RemoteWakeUp - USB中文网 (usbzh.com)

需要注意的是,当device向电脑端发送完唤醒序列后,电脑端被唤醒后会去读取device的设备HID端点数据,如果没有数据,此时电脑会重新进入休眠,会出现唤醒序列正确但是唤不醒电脑的现象。

所以,当device发送完唤醒序列后,必须还得发送HID report数据才能够成功唤醒电脑端,我这里是唤醒后去打开joystick设备,以此能在发送唤醒序列后再发送HID report数据成功唤醒PC。

3、code例程参考

例程中我是用了一个按键去触发唤醒序列实现的,代码如下:

/* 按键中断函数 */
void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0) != RESET) {
#ifdef KEY_REMOTE_WAEUP_ENABLE
		usb_drv_remote_wakeup();
#endif

        EXTI_IRQn_Handler(EXTI_Line0);

    	EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

/* 唤醒函数 */
void usb_drv_remote_wakeup(void)
{
    usb_remote_wakeup_active_action();
    usb_drv_device_resume_ind();
}

static void usb_remote_wakeup_active_action(void)
{
	if (USB_OTG_dev.dev.DevRemoteWakeup)
	{
		if (USB_OTG_dev.cfg.low_power)
		{
			/* Reset SLEEPDEEP and SLEEPONEXIT bits */
			SCB->SCR &=
				(uint32_t) ~
				((uint32_t) (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));

             /* device休眠后唤醒需要重新初始化时钟 */
			SystemInit();

            /* 重新打开USB clock */
			USB_OTG_UngateClock(&USB_OTG_dev);
		}

		USB_OTG_ActiveRemoteWakeup(&USB_OTG_dev);		//启用唤醒序列,1~15ms均可
		USB_OTG_dev.dev.device_status = USB_OTG_dev.dev.device_old_status;		//此处必须调用
		usb_context.remote_wakeup = true;				//唤醒标志位
		APP_LOG_I("> USB Device woke up.\n");
	}
}

void usb_drv_device_resume_ind(void)
{
    usb_context.usbIsReady = true;

    usb_drv_periph_enable();			//此处打开hid report外设,如果没打开就无法在唤醒后report data,则无法唤醒PC
}

sb_drv_periph_enable(); //此处打开hid report外设,如果没打开就无法在唤醒后report data,则无法唤醒PC
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值