STM32 USB Host 同时连接多个设备样例(如鼠标和键盘)--原创
STM32 USB Host 同时连接多个设备样例(如鼠标和键盘)
在网上搜了很多都是USB Host单独连接鼠标或键盘的样例, 而当前很多无线鼠标键盘都是并到一个USB口上的, 也就是同一个USB有两个interface. 而官方提供的USB Host库中只会对一个Interface进行处理, 要么键盘要么鼠标, 所以为了能够同时使用键盘和鼠标要对USB Host库进行修改才行.
具体修改如下:
首先使用CubeMX创建了一个带USB HID类功能的工程, 创建步骤很简单网上有很多文档不在这里讨论.
接着进入正题, 修改USB Host库文件.
- usbh_def.h
修改USBH_ClassTypeDef, 使当前Class支持多接口:
/* USB Host Class structure */
typedef struct
{const char *Name;uint8_t ClassCode;USBH_StatusTypeDef(*Init)(struct _USBH_HandleTypeDef *phost);USBH_StatusTypeDef(*DeInit)(struct _USBH_HandleTypeDef *phost);USBH_StatusTypeDef(*Requests)(struct _USBH_HandleTypeDef *phost);USBH_StatusTypeDef(*BgndProcess)(struct _USBH_HandleTypeDef *phost);USBH_StatusTypeDef(*SOFProcess)(struct _USBH_HandleTypeDef *phost);
/* [ */void *pData[USBH_MAX_NUM_INTERFACES]; /* HID interfaces Handle */uint8_t InterfaceNum; /* interface 数量 */__IO uint8_t CurrInterface; /* 当前interface */
/* ] */
} USBH_ClassTypeDef;
修改HID_HandleTypeDef, 记录interface的协议类型:
/* Structure for HID process */
typedef struct _HID_Process
{uint8_t OutPipe;uint8_t InPipe;HID_StateTypeDef state;uint8_t OutEp;uint8_t InEp;HID_CtlStateTypeDef ctl_state;FIFO_TypeDef fifo;uint8_t *pData;uint16_t length;uint8_t ep_addr;uint16_t poll;uint32_t timer;uint8_t DataReady;HID_DescTypeDef HID_Desc;USBH_StatusTypeDef(* Init)(USBH_HandleTypeDef *phost);
/* [ */uint8_t Protocol; /* 协议类型: HID_KEYBRD_BOOT_CODE / HID_MOUSE_BOOT_CODE */
/* ] */
} HID_HandleTypeDef;
- usbh_hid.c
修改USBH_HID_InterfaceInit函数, 在初始化的时候判断当前枚举了几个HID接口, 如果有多个接口, 则创建多个HID_HandleTypeDef:
static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost)
{USBH_StatusTypeDef status = USBH_OK;HID_HandleTypeDef *HID_Handle;uint8_t max_ep;uint8_t num = 0U;/* [ */uint8_t boot = HID_KEYBRD_BOOT_CODE;uint8_t interface_num = 0;uint8_t interface;for (interface_num = 0; interface_num < phost->device.CfgDesc.bNumInterfaces; interface_num++){interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, boot);/* ] */if ((interface == 0xFFU) || (interface >= USBH_MAX_NUM_INTERFACES)) /* No Valid Interface */{USBH_DbgLog("Cannot Find the interface for %s class.", phost->pActiveClass->Name);status = USBH_FAIL;break;}status = USBH_SelectInterface(phost, interface);if (status != USBH_OK){return USBH_FAIL;}/* [ */phost->pActiveClass->pData[interface_num] = (HID_HandleTypeDef *)USBH_malloc(sizeof(HID_HandleTypeDef));phost->pActiveClass->InterfaceNumber++;phost->pActiveClass->CurrInterface = interface_num;HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData[interface_num];/* ] */if (HID_Handle == NULL){USBH_DbgLog("Cannot allocate memory for HID Handle");return USBH_FAIL;}/* Initialize hid handler */USBH_memset(HID_Handle, 0, sizeof(HID_HandleTypeDef));HID_Handle->state = HID_ERROR;/*Decode Bootclass Protocol: Mouse or Keyboard*/HID_Handle->Protocol = phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol;....../* 配置完成 [ */if (boot == HID_KEYBRD_BOOT_CODE)boot = HID_MOUSE_BOOT_CODE;elseboot = HID_KEYBRD_BOOT_CODE;/* ] */}return status;
}
修改USBH_HID_Process, 在POLL空闲时如果10次连续空闲未收到有效数据则切换接口, 使下次执行Process的时候切换到另一个接口:
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
{USBH_StatusTypeDef status = USBH_OK;HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData[phost->pActiveClass->CurrInterface];uint32_t XferSize;/* [ */uint8_t interface;uint8_t protocol;static __IO uint16_t num = 0;/* ] */switch (HID_Handle->state){...case HID_POLL:if (USBH_LL_GetURBState(phost, HID_Handle->InPipe) == USBH_URB_DONE){XferSize = USBH_LL_GetLastXferSize(phost, HID_Handle->InPipe);if ((HID_Handle->DataReady == 0U) && (XferSize != 0U)){USBH_HID_FifoWrite(&HID_Handle->fifo, HID_Handle->pData, HID_Handle->length);HID_Handle->DataReady = 1U;USBH_HID_EventCallback(phost);#if (USBH_USE_OS == 1U)phost->os_msg = (uint32_t)USBH_URB_EVENT;
#if (osCMSIS < 0x20000U)(void)osMessagePut(phost->os_event, phost->os_msg, 0U);
#else(void)osMessageQueuePut(phost->os_event, &phost->os_msg, 0U, NULL);
#endif
#endif/* 如果检测到有效数据, 则清除空闲计数 [ */num = 0;/* ] */}}else{/* 如果空闲计数达到10次, 则切换到其他interface [ */num++;if (num > 10){if (phost->pActiveClass->InterfaceNumber > 1){if (phost->pActiveClass->CurrInterface == 0)phost->pActiveClass->CurrInterface = 1;elsephost->pActiveClass->CurrInterface = 0;protocol = ((HID_HandleTypeDef *)phost->pActiveClass->pData[phost->pActiveClass->CurrInterface])->Protocol;interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, protocol);USBH_SelectInterface(phost, interface);}num = 0;}/* ] *//* IN Endpoint Stalled */if (USBH_LL_GetURBState(phost, HID_Handle->InPipe) == USBH_URB_STALL){/* Issue Clear Feature on interrupt IN endpoint */if (USBH_ClrFeature(phost, HID_Handle->ep_addr) == USBH_OK){/* Change state to issue next IN token */HID_Handle->state = HID_GET_DATA;}}}break;...}
}
另外其他涉及到"phost->pActiveClass->pData"的地方全部改为"phost->pActiveClass->pData[phost->pActiveClass->CurrInterface]", 因为pData已经不再是一个结构体指针而是一个结构体指针数组, 主要涉及的文件包括:
usbh_hid.c, usbh_hid_keybs.c, usbh_hid_mouse.c
3. 修改键盘和鼠标的驱动
最后就是按照键盘鼠标的协议定义相应的回调函数, 因为不同的无线鼠标键盘有不同的协议, 在此不做描述. 主要涉及的文件包括:
usb_host.c, usbh_hid_keybs.c, usbh_hid_mouse.c
做好驱动以后就可以同时使用键盘和鼠标了, 此方法也可适用于USB连接其他多设备场景, 只要USB初始化的时候能够检测到相应的设备.
测试视频:
STM32 USB Host同时连接鼠标和键盘演示视频
转载请注明出处.
STM32 USB Host 同时连接多个设备样例(如鼠标和键盘)--原创相关推荐
- 为什么USB最多只能连接127个设备?
** 为什么USB最多只能连接127个设备?** 一台USB主机可以同时支持多达128个地址. 作为默认地址,地址0仅在设备枚举期间临时 使用,不能分配给任何设备.因此,一个 USB主机可以同时支持多 ...
- Android + kernel USB host 如何判断插入的设备是高速还是低速的设备
d+ d- 0 0 PC 0 1 错误设备 1 0 非标准充电器 1 1 ...
- linux读写usb host,LINUX下USB1.1设备学习小记(3)_host与device
各位还记得"任何传输都是由host发起的"这句话么~ 在usb设备插入pc中到拔出usb设备,都是由host进行询问的 一个usb鼠标的工作流程可以表达如下: usb鼠标插入pc中 ...
- 实现连接池技术的样例
1. 在tomcat的安装文件夹下conf文件夹下的context.xml文件加入例如以下代码: <Resource name="jdbc/course" auth=&quo ...
- STM32 USB高速USB端口加持4G联网
本文由RT-Thread论坛用户@fhqmcu原创发布:https://club.rt-thread.org/ask/article/8fc0968257c2ca01.html 1.前言 关于STM3 ...
- 首创STM32 USB主机驱动4G rndis设备
1.4G模块使用技术现状与难题 4G模块支持的对外通信接口有串口和USB接口,串口一般使用AT指令的方式,这个在MCU类产品上面使用的很多,USB接口主用于在连接APU应用处理器上面,由LINUX操作 ...
- STM32 USB无法连接电脑
一.说明 在调试 STM32 USB device MSC 功能时,使用官方提供的库和示例项目,电脑可以正确识别设备,也可以正常操作.但是将 USB 部分的代码移植到自己的工程后,发现电脑无法正确识别 ...
- Android USB Host开发之manager.getDeviceList()获取不到设备列表
同样遇到这样的问题,我的Android设备是原道N12C,官方的4.0.3系统,遇到这个问题,后来找了半天找到的,现在汇总一下吧: 1.创建 android.hardware.usb.host.xml ...
- STM32之独立版USB(Host)驱动+MSC+Fatfs移植
源:STM32之独立版USB(Host)驱动+MSC+Fatfs移植 STM32之USB驱动库详解(架构+文件+函数+使用说明+示例程序)
最新文章
- LOJ6435 PKUSC2018 星际穿越
- php变量定义的位置,php变量一般放在哪个位置
- java流处理为什么快_“任何情况下,都不可以堕胎”是道德普遍主义的观点。
- JNI中参数的传递与操作
- XShell常用快捷键
- 当下的互联网时代,“急功近利”不是坏事
- JSON-B和Yasson详解
- 淡定的写代码,淡定的人生
- 12c emcc Algorithm negotiation fail
- Calendar中add()和roll()函数的用法
- 二分图最大权匹配【KM算法 BFS优化下的真正的O(N3)的KM算法】【KM算法模板】
- 开源配置管理中心apollo使用方法
- android截图方法,安卓手机的截图方法
- 周鸿祎的“花房上市”执念
- Ubuntu18.04 配置nvidia 460驱动、cuda10.1和cudnn7.6.5
- div的水平排列、垂直排列
- 微信自定义分享卡片链接的解决方案(可自定义标题 描述 缩列图)
- Going out on a limb:Joint Extraction of Entity Mentions and Relations without Dependency Trees【论文笔记】
- 【动手学深度学习PyTorch版】6 权重衰退
- lumia flash android,Lumia830吃上棉花糖!WP手机刷安卓7.1详细教程