打印
[STM32H5]

【NUCLEO- H563ZI 测评】USBX 之 CDC+HID

[复制链接]
1783|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
USB, CD, dc, HID, NUC

1、STM32H5有一个全速度USB2.0和一个USB Type-C/USB power-delivery。基于Type-C支持正反插、速度更快、供电更强大等优点目前很多电子产品很多都是使用USB Type-C接口,STM32H5直接支持USB Type-C可以给我们在使用中带来更多的便利。
NUCLEO-H563ZI上USB口的硬件接口电路如下:D+1/D-1和D+2/D-2用于传输USB 2.0数据。


STM32Cube_FW_H5_V1.1.0开发包里面提供了使用Azure RTOS USBX 协议栈提供的USB demo,好久没有用ST的新产品了,都换成了USBX了吗。这和我之前熟悉的ST自己提供的USB device和host 协议栈不太一样,也是第一次接触USBX ,先了解学习下。



下面测试的是HID和CDC的复合设备的例子。
程序中使用的RTOS 是ThreadX,总共创建了4个任务用于初始化USB驱动和启动USB、CDC接收数据、CDC发送数据、HID传输数据。

1)USB读取功能,用于从USB VCP接收数据,然后发送到STlink的虚拟串口上
VOID usbx_cdc_acm_read_thread_entry(ULONG thread_input)
{
  ULONG actual_length;
  ULONG senddataflag = 0;
  UX_SLAVE_DEVICE *device;

  UX_PARAMETER_NOT_USED(thread_input);

  device = &_ux_system_slave->ux_system_slave_device;

  while (1)
  {
    /* Check if device is configured */
    if ((device->ux_slave_device_state == UX_DEVICE_CONFIGURED) && (cdc_acm != UX_NULL))
    {

#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE

      /* Set transmission_status to UX_FALSE for the first time */
      cdc_acm -> ux_slave_class_cdc_acm_transmission_status = UX_FALSE;

#endif /* UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE */

      /* Read the received data in blocking mode */
      ux_device_class_cdc_acm_read(cdc_acm, (UCHAR *)UserRxBufferFS, 64,
                                   &actual_length);
      if (actual_length != 0)
      {
        /* Send the data via UART */
        if (HAL_UART_Transmit_DMA(uart_handler, (uint8_t *)UserRxBufferFS, actual_length) != HAL_OK)
        {
          Error_Handler();
        }

        /* Wait until the requested flag TX_NEW_TRANSMITTED_DATA is received */
        if (tx_event_flags_get(&EventFlag, TX_NEW_TRANSMITTED_DATA, TX_OR_CLEAR,
                               &senddataflag, TX_WAIT_FOREVER) != TX_SUCCESS)
        {
          Error_Handler();
        }
      }
      else
      {
        /* Sleep thread for 10ms if no data received */
        tx_thread_sleep(MS_TO_TICK(10));
      }
    }
    else
    {
      /* Sleep thread for 10ms */
      tx_thread_sleep(MS_TO_TICK(10));
    }
  }
}
2)USB写数据功能。用于将从STlink 虚拟串口接收到的数据发送出去
VOID usbx_cdc_acm_write_thread_entry(ULONG thread_input)
{
  ULONG receivedataflag = 0;
  ULONG actual_length, buffptr, buffsize;

  UX_PARAMETER_NOT_USED(thread_input);

  while (1)
  {
    /* Wait until the requested flag RX_NEW_RECEIVED_DATA is received */
    if (tx_event_flags_get(&EventFlag, RX_NEW_RECEIVED_DATA, TX_OR_CLEAR,
                           &receivedataflag, TX_WAIT_FOREVER) != TX_SUCCESS)
    {
      Error_Handler();
    }

#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE

    /* Set transmission_status to UX_FALSE for the first time */
    cdc_acm -> ux_slave_class_cdc_acm_transmission_status = UX_FALSE;

#endif

    /* Check if there is a new data to send */
    if (UserTxBufPtrOut != UserTxBufPtrIn)
    {
      /* Check buffer overflow and Rollback */
      if (UserTxBufPtrOut > UserTxBufPtrIn)
      {
        buffsize = APP_RX_DATA_SIZE - UserTxBufPtrOut;
      }
      else
      {
        /* Calculate data size */
        buffsize = UserTxBufPtrIn - UserTxBufPtrOut;
      }

      /* Copy UserTxBufPtrOut in buffptr */
      buffptr = UserTxBufPtrOut;

      /* Send data over the class cdc_acm_write */
      if (ux_device_class_cdc_acm_write(cdc_acm, (UCHAR *)(&UserTxBufferFS[buffptr]),
                                        buffsize, &actual_length) == UX_SUCCESS)
      {
        /* Increment the UserTxBufPtrOut pointer */
        UserTxBufPtrOut += buffsize;

        /* Rollback UserTxBufPtrOut if it equal to APP_TX_DATA_SIZE */
        if (UserTxBufPtrOut == APP_TX_DATA_SIZE)
        {
          UserTxBufPtrOut = 0;
        }
      }
    }
  }
}
测试效果:打开2个串口助手,一个用于打开STlink的VCP 一个打开USB CDC 。这样2个串口就可以聊天了。



3)HID 功能用于将用户按下开发板上的按键之后发送到PC上,鼠标就会移动一下
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));
    }
  }
}
本来想测试下STM32H5的CDC的速度的,但是发现USBX和之前熟悉的ST的USB协议栈有很多不一样的地方,在动手修改之前还要先熟悉USBX,所有此次的测试就是简单的了解下数据传输的各个任务。STM32H5没有F1/F4/F7那种ST USB协议栈了吗?






使用特权

评论回复
评论
xu@xupt 2023-9-17 08:15 回复TA
很不错的资源,学习一下 
沙发
MessageRing| | 2023-8-23 21:33 | 只看该作者
ThreadX跟FreeRTOS哪个更好用啊

使用特权

评论回复
板凳
gumenggumeng| | 2023-9-1 15:49 | 只看该作者
是直接用的官方给的例程嘛?想实现usbx custom hid与PC端的通信,看了半天头大,可以交流下嘛

使用特权

评论回复
地板
Stahan| | 2023-9-2 21:40 | 只看该作者
USBX是升级的usb协议吗?

使用特权

评论回复
5
香水城| | 2023-9-17 16:26 | 只看该作者

使用特权

评论回复
6
Bowclad| | 2023-9-17 21:26 | 只看该作者
Stahan 发表于 2023-9-2 21:40
USBX是升级的usb协议吗?

USBX 是一种高性能的 USB 主机、设备和移动 (OTG) 嵌入式堆栈

使用特权

评论回复
7
lulugl| | 2024-4-16 21:15 | 只看该作者
可以讲讲stm32cubeMAX如何配置的吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

45

帖子

3

粉丝