【STM32H5开发板】USBX协议HID设备测试
本帖最后由 bigbat 于 2023-5-25 23:28 编辑<p>H563ZI的板子上有完整的USB Type-C接口,接口通过TCPP01-M12保护USB Type-C,在USB拔插时容易出现过流、过压等电气情况,芯片可以避免故障。板子上还有USBLC6-2SC6用作ESD保护用来防护静电,其实就是一颗TVS集成芯片。作为USB接口的设计参考非常的赞。</p>
<p>本次测试主要是测试板子作为HID设备,具体的就是用来模拟标准的鼠标。这个例子比较容易实现,主要是模拟鼠标不需要写windows驱动程序。</p>
<p>首先,打开cube进行设置,</p>
<p> 设置USBPD,这个设置是用来管理USB Type-C充电管理地,有了这个设备就可以知道USB设备的电源状态,以及设备的供电管理。以前的USB没有这个设置USB设备的探测比较麻烦,也不能管理是否需要主机供电或设备是否为有源设备等。</p>
<p>接下来是USBX的设置</p>
<p>USBX设置中内置了很多的协议,例如:虚拟串口,虚拟网口,还有可以向Android设备一样的RNDIS终端等等协议。不过貌似该板子只能使用CDC-ACM(虚拟串口)和DUF,本次设置没有选用更高级的内置协议。HID协议是通过ux_device_descriptors.c描述符定义地,</p>
<pre>
<code class="language-cpp">__ALIGN_BEGIN uint8_t USBD_HID_MOUSE_ReportDesc[]
__ALIGN_END =
{
/* USER CODE BEGIN USBD_HID_MOUSE_ReportDesc */
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
0x09, 0x02, /* Usage (Mouse) */
0xA1, 0x01, /* Collection (Application) */
0x09, 0x01, /* Usage (Pointer) */
0xA1, 0x00, /* Collection (Physical) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 0x01, /* Usage Minimum (0x01) */
0x29, 0x03, /* Usage Maximum (0x03) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x95, 0x03, /* Report Count (3) */
0x75, 0x01, /* Report Size (1) */
0x81, 0x02, /* Input (Data,Var,Abs) */
0x95, 0x01, /* Report Count (1) */
0x75, 0x05, /* Report Size (5) */
0x81, 0x01, /* Input (Const,Array,Abs) */
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
0x09, 0x38, /* Usage (Wheel) */
0x15, 0x81, /* Logical Minimum (-127) */
0x25, 0x7F, /* Logical Maximum (127) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x03, /* Report Count (3) */
0x81, 0x06, /* Input (Data,Var,Rel) */
0xC0, /* End Collection */
0x09, 0x3C, /* Usage (Motion Wakeup) */
0x05, 0xFF, /* Usage Page (Reserved 0xFF) */
0x09, 0x01, /* Usage (0x01) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x02, /* Report Count (2) */
0xB1, 0x22, /* Feature (Data,Var,Abs,NoWrp) */
0x75, 0x06, /* Report Size (6) */
0x95, 0x01, /* Report Count (1) */
0xB1, 0x01, /* Feature (Const,Array,Abs,NoWrp) */
/* USER CODE END USBD_HID_MOUSE_ReportDesc */
0xC0 /* End Collection */
};
#endif /* USBD_HID_MOUSE_ACTIVATED == 1U */</code></pre>
<p> 如果想模拟其它类型的设备修改这个描述符表就可以了。</p>
<pre>
<code class="language-cpp">/* USER CODE END Private_defines */
#define USBD_VID 1155
#define USBD_PID 22288
#define USBD_LANGID_STRING 1033
#define USBD_MANUFACTURER_STRING "STMicroelectronics"
#define USBD_PRODUCT_STRING "STM32 HID Mouse Device"
#define USBD_SERIAL_NUMBER "HID001"
#define USB_DESC_TYPE_INTERFACE 0x04U
#define USB_DESC_TYPE_ENDPOINT 0x05U
#define USB_DESC_TYPE_CONFIGURATION 0x02U
#define USB_DESC_TYPE_IAD 0x0BU
#define USBD_EP_TYPE_CTRL 0x00U
#define USBD_EP_TYPE_ISOC 0x01U
#define USBD_EP_TYPE_BULK 0x02U
#define USBD_EP_TYPE_INTR 0x03U
#define USBD_FULL_SPEED 0x00U
#define USBD_HIGH_SPEED 0x01U
#define USB_BCDUSB 0x0200U
#define LANGUAGE_ID_MAX_LENGTH 2U
#define USBD_IDX_MFC_STR 0x01U
#define USBD_IDX_PRODUCT_STR 0x02U
#define USBD_IDX_SERIAL_STR 0x03U
#define USBD_MAX_EP0_SIZE 64U
#define USBD_DEVICE_QUALIFIER_DESC_SIZE 0x0AU
#define USBD_STRING_FRAMEWORK_MAX_LENGTH 256U
/* Device HID Mouse */
#define USBD_HID_MOUSE_EPIN_ADDR 0x81U
#define USBD_HID_MOUSE_EPIN_FS_MPS 4U
#define USBD_HID_MOUSE_EPIN_HS_MPS 4U
#define USBD_HID_MOUSE_EPIN_FS_BINTERVAL 5U
#define USBD_HID_MOUSE_EPIN_HS_BINTERVAL 5U
#ifndef USBD_CONFIG_STR_DESC_IDX
#define USBD_CONFIG_STR_DESC_IDX 0U
#endif /* USBD_CONFIG_STR_DESC_IDX */
#ifndef USBD_CONFIG_BMATTRIBUTES
#define USBD_CONFIG_BMATTRIBUTES 0xC0U
#endif /* USBD_CONFIG_BMATTRIBUTES */
/* Private macro -----------------------------------------------------------*/
/* USER CODE BEGIN Private_macro */</code></pre>
<p>修改设备名称,直接修改这个第二阶段自举设备描述信息就可以。 程序启动后就可以看到电脑主机多了一个STM32 HID类型鼠标。</p>
<p> 这时只要按下蓝色的按钮,就可以发现电脑的鼠标移动了一段距离。</p>
<pre>
<code class="language-cpp">/**
* <a href="home.php?mod=space&uid=159083" target="_blank">@brief </a> Function implementing usbx_hid_thread_entry.
* @paramthread_input: Not used
* @retval none
*/
VOID usbx_hid_thread_entry(ULONG thread_input)
{
UX_SLAVE_DEVICE *device;
UX_SLAVE_CLASS_HID_EVENT hid_event;
UX_PARAMETER_NOT_USED(thread_input);
device = &_ux_system_slave->ux_system_slave_device;
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
while (1)
{
/* Check if the device state already configured */
if ((device->ux_slave_device_state == UX_DEVICE_CONFIGURED) && (hid_mouse != UX_NULL))
{
/* sleep for 10ms */
tx_thread_sleep(MS_TO_TICK(10));
/* Check if user button is pressed */
if (User_Button_State != 0U)
{
/* Get the new position */
GetPointerData(&hid_event);
/* Send an event to the hid */
ux_device_class_hid_event_set(hid_mouse, &hid_event);
/* Reset User Button state */
User_Button_State = 0U;
}
}
else
{
/* Sleep thread for 10ms */
tx_thread_sleep(MS_TO_TICK(10));
}
}
}
/**
* @briefGetPointerData
* Gets Pointer Data.
* @paramhid_event: Pointer to structure of the hid event.
* @retval None
*/
static VOID GetPointerData(UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
static int8_t counter = 0;
static int8_t x = 0, y = 0;
/* Reset counter */
if (counter == 16)
{
counter = 0;
}
/* Update pointer position x and y */
if ((counter >= 0) && (counter < 4))
{
y = 0;
x = CURSOR_STEP;
}
else if ((counter >= 4) && (counter < 8))
{
x = 0;
y = CURSOR_STEP;
}
else if ((counter >= 8) && (counter < 12))
{
y = 0;
x = -CURSOR_STEP;
}
else
{
x = 0;
y = -CURSOR_STEP;
}
/* Increment counter */
counter++;
/* Mouse event. Length is fixed to 3 */
hid_event->ux_device_class_hid_event_length = 3;
/* Set X position. */
hid_event->ux_device_class_hid_event_buffer = x;
/* Set Y position. */
hid_event->ux_device_class_hid_event_buffer = y;
hid_event->ux_device_class_hid_event_buffer = 0;
}
/* USER CODE END 1 */</code></pre>
<p>这个程序中的usbx_hid_thread_entry线程中的ux_device_class_hid_event_set函数就是发送数据地,修改鼠标的步长就可以用该函数发送。</p>
<pre>
<code class="language-cpp">/* Send an event to the hid */
ux_device_class_hid_event_set(hid_mouse, &hid_event);</code></pre>
<p>后记:</p>
<p>开始这个实验前,我是想单独的模拟HID设备不使用USBPD来着,参考了STM32H503的程序,无奈中间出现了很多问题,后来不得不使用了这个参考样例,看来USBPD对于USB Type-C设备的电源管理很重要。电路不同可能设备无法设别。</p>
<p> </p>
<p>虚拟串口,虚拟网口还是很常用的功能</p>
可以分享一下您的源代码学习一下吗?我最近在学习H503的鼠标 lugl4313820 发表于 2024-4-17 23:49
可以分享一下您的源代码学习一下吗?我最近在学习H503的鼠标
<p>你参考一下,STM32H5的例程,我也是参考这个例程编写的</p>
<p> </p>
bigbat 发表于 2024-4-18 09:15
你参考一下,STM32H5的例程,我也是参考这个例程编写的
<p>感谢感谢,我按大佬您的指点,我再试试。</p>
页:
[1]