硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1607|回复: 7
收起左侧

[有问必答] USBH CDC通讯,如何修改通讯波特率?

[复制链接]

1

主题

57

回帖

60

积分

初级会员

积分
60
发表于 2024-5-29 09:39:14 | 显示全部楼层 |阅读模式
硬件:STM37F407 + CH340
软件:CubeMX,MDK
已经实现USBH接口通过CH340和外部串口通讯,波特率19200。
目前无法修改通讯波特率,GetLineCoding()和SetLineCoding()返回都是USBH_BUSY,怎么解决?
开发过程,参考了如下帖子:
https://blog.csdn.net/gyzw_mx/article/details/103619301
https://blog.csdn.net/qizhi321123/article/details/126622434

回复

使用道具 举报

25

主题

232

回帖

307

积分

高级会员

积分
307
QQ
发表于 2024-5-29 15:16:46 | 显示全部楼层
找到一个参考,根据这个驱动源码来看,是要USB给CH340发配置消息,改变波特率
创建驱动CH340的USB HOST 设备_stm32作为host连接ch340-CSDN博客
CH340_LINUX.png

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-5-30 08:45:09 | 显示全部楼层
RL-USB有个驱动PL2303的例子,也可以参考

[C] 纯文本查看 复制代码
/*------------------------------------------------------------------------------
 * MDK Middleware - Component ::USB:Host:Custom Class
 * Copyright (c) 2004-2020 Arm Limited (or its affiliates). All rights reserved.
 *------------------------------------------------------------------------------
 * Name:    USBH_PL2303.c
 * Purpose: USB Host (USBH) - Custom Class - Prolific PL2303 USB to serial
 *          RS232 adapter driver
 * Rev.:    V6.3.2
 *----------------------------------------------------------------------------*/
/*
 * USBH_PL2303.c is a Prolific PL2303 USB to serial RS232 adapter driver
 * for USB Host stack implemented as USB Host Custom Class driver.
 * Prolific PL2303 USB to serial RS232 adapter is similar to the CDC device
 * but using vendor specific class device with interface containing
 * 1 Bulk IN, 1 Bulk OUT and 1 Interrupt IN Endpoints.
 * This implementation supports only one instance.
 *
 * The template implements 4 callback functions called by the USB Host core
 * when device is connected or disconnected, these are:
 *   USBH_CustomClass_Configure
 *   USBH_CustomClass_Unconfigure
 *   USBH_CustomClass_Initialize
 *   USBH_CustomClass_Uninitialize
 * 
 * First to enable USB Host Controller (if not already enabled) call:
 *   USBH_Initialize (ctrl_num);
 */
 
#include <stdio.h>
#include <stdint.h>
#include "rl_usb.h"
 
// Interface class, subclass and protocol of the device that is supported
#define CUSTOM_CLASS_IF_CLASS           USB_DEVICE_CLASS_VENDOR_SPECIFIC
#define CUSTOM_CLASS_IF_SUBCLASS        0
#define CUSTOM_CLASS_IF_PROTOCOL        0
 
extern
uint8_t    USBH_CC_Device;
uint8_t    USBH_CC_Device = 0U;         // Device used for USB transfers
extern 
USBH_PIPE_HANDLE USBH_CC_PipeHandle[8];
USBH_PIPE_HANDLE USBH_CC_PipeHandle[8]; // Pipe Handles
 
 
/************************** Class Driver Functions ****************************/
 
/// \brief Analyze device configuration and configure resources
/// \param[in]     device               index of USB Device.
/// \param[in]     ptr_dev_desc         pointer to device descriptor.
/// \param[in]     ptr_cfg_desc         pointer to configuration descriptor.
/// \return                             index of configured custom class device instance or configuration failed :
///                                       - value <= 127 : index of configured custom class device instance
///                                       - value 255 :    configuration failed
uint8_t USBH_CustomClass_Configure (uint8_t device, const USB_DEVICE_DESCRIPTOR *ptr_dev_desc, const USB_CONFIGURATION_DESCRIPTOR *ptr_cfg_desc) {
  USB_INTERFACE_DESCRIPTOR *ptr_if_desc;
  USB_ENDPOINT_DESCRIPTOR  *ptr_ep_desc;
  USBH_PIPE_HANDLE          pipe_hndl;
  uint8_t                   num, i;
 
  USBH_CC_Device = device;              // Store device
  for (i = 0U; i < 8U; i++) {           // Clear all pipe handles
    USBH_CC_PipeHandle[i] = 0U;
  }
  ptr_if_desc = (USB_INTERFACE_DESCRIPTOR *)((uint32_t)ptr_cfg_desc + ptr_cfg_desc->bLength);
  num = ptr_if_desc->bNumEndpoints;     // Number of endpoints
 
  // Supported device: - Prolific PL2303 (VID = 0x067B, PID = 0x2303)
  if ((ptr_dev_desc->idVendor != 0x067BU) || (ptr_dev_desc->idProduct != 0x2303U)) {
    return 255U;
  }
 
  switch (ptr_if_desc->bInterfaceClass) {
    case CUSTOM_CLASS_IF_CLASS:                 // Interface class
      switch (ptr_if_desc->bInterfaceSubClass) {
        case CUSTOM_CLASS_IF_SUBCLASS:          // Interface subclass
          switch (ptr_if_desc->bInterfaceProtocol) {
            case CUSTOM_CLASS_IF_PROTOCOL:      // Interface protocol
              // Create Pipes
              ptr_ep_desc = (USB_ENDPOINT_DESCRIPTOR *)((uint32_t)ptr_if_desc + ptr_if_desc->bLength);
              i           = 0U;
              while (num-- != 0U) {
                pipe_hndl = USBH_PipeCreate (device, ptr_ep_desc->bEndpointAddress, ptr_ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK, ptr_ep_desc->wMaxPacketSize & 0x7FFU, ptr_ep_desc->bInterval);
                if (pipe_hndl == 0U) {
                  // If creation of pipe has failed delete previously created pipes
                  for (i = 0U; i < 8U; i++) {
                    if (USBH_CC_PipeHandle[i] != 0U) {
                      (void)USBH_PipeDelete (USBH_CC_PipeHandle[i]);
                      USBH_CC_PipeHandle[i] = 0U;
                    }
                  }
                  return 255U;
                }
                USBH_CC_PipeHandle[i++] = pipe_hndl;
                ptr_ep_desc++;
              }
              return 0U;                // Device connected and configured
                                        // Only single instance supported
                                        // so it's instance index is 0
            default:
              break;
          }
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
 
  return 255U;                          // Device not handled
}
 
/// \brief De-configure resources
/// \param[in]     instance             index of custom class device instance.
/// \return                             status code that indicates the execution status of the function as defined with usbStatus.
usbStatus USBH_CustomClass_Unconfigure (uint8_t instance) {
  uint8_t i;
 
  (void)instance;                       // Only single instance is supported
 
  USBH_CC_Device = 0U;
 
  for (i = 0U; i < 8U; i++) {
    if (USBH_CC_PipeHandle[i] != 0U) {
      (void)USBH_PipeDelete (USBH_CC_PipeHandle[i]);
      USBH_CC_PipeHandle[i] = 0U;
    }
  }
 
  return usbOK;
}
 
/// \brief Initialize Custom Class Device instance
/// \param[in]     instance             index of custom class device instance.
/// \return                             status code that indicates the execution status of the function as defined with usbStatus.
usbStatus USBH_CustomClass_Initialize (uint8_t instance) {
  USB_SETUP_PACKET setup_packet;
  uint32_t         br;
  uint8_t          buf[8];
 
  (void)instance;                       // Only single instance is supported
 
  // Custom PL2303 initialization
  setup_packet.bmRequestType.Dir      = USB_REQUEST_DEVICE_TO_HOST;
  setup_packet.bmRequestType.Type     = USB_REQUEST_VENDOR;
  setup_packet.bmRequestType.Recipient= USB_REQUEST_TO_DEVICE;
  setup_packet.bRequest               = 1U;
  setup_packet.wValue                 = U16_LE(0x8484U);
  setup_packet.wIndex                 = U16_LE(0U);
  setup_packet.wLength                = U16_LE(1U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf,  1U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.bmRequestType.Dir      = USB_REQUEST_HOST_TO_DEVICE;
  setup_packet.wValue                 = U16_LE(0x0404U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf,  1U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.bmRequestType.Dir      = USB_REQUEST_DEVICE_TO_HOST;
  setup_packet.wValue                 = U16_LE(0x8484U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf,  1U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.wValue                 = U16_LE(0x8383U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf,  1U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.wValue                 = U16_LE(0x8484U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf,  1U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.bmRequestType.Dir      = USB_REQUEST_HOST_TO_DEVICE;
  setup_packet.wValue                 = U16_LE(0x0404U);
  setup_packet.wIndex                 = U16_LE(1U);
  setup_packet.wLength                = U16_LE(0U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, NULL, 0U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.bmRequestType.Dir      = USB_REQUEST_DEVICE_TO_HOST;
  setup_packet.wValue                 = U16_LE(0x8484U);
  setup_packet.wIndex                 = U16_LE(0U);
  setup_packet.wLength                = U16_LE(1U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf,  1U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.wValue                 = U16_LE(0x8383U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf,  1U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.bmRequestType.Dir      = USB_REQUEST_HOST_TO_DEVICE;
  setup_packet.wValue                 = U16_LE(0U);
  setup_packet.wIndex                 = U16_LE(1U);
  setup_packet.wLength                = U16_LE(0U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, NULL, 0U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.wValue                 = U16_LE(1U);
  setup_packet.wIndex                 = U16_LE(0U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, NULL, 0U) != usbOK) { return usbClassErrorCustom; }
 
  setup_packet.wValue                 = U16_LE(2U);
  setup_packet.wIndex                 = U16_LE(0x44U);
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, NULL, 0U) != usbOK) { return usbClassErrorCustom; }
 
  // Initial CDC SetLineCoding request: Set 9600 baud, 8 data bits, 1 stop bit, no parity
  setup_packet.bmRequestType.Dir      = USB_REQUEST_HOST_TO_DEVICE;
  setup_packet.bmRequestType.Type     = USB_REQUEST_CLASS;
  setup_packet.bmRequestType.Recipient= USB_REQUEST_TO_INTERFACE;
  setup_packet.bRequest               = 0x20U;
  setup_packet.wValue                 = U16_LE(0U);
  setup_packet.wIndex                 = U16_LE(0U);
  setup_packet.wLength                = U16_LE(7U);
  br                                  = U32_LE(9600U);  // Data terminal rate in bits per second = 9600 baud
  buf[0]                              = (uint8_t)( br        & 0xFFU);
  buf[1]                              = (uint8_t)((br >>  8) & 0xFFU);
  buf[2]                              = (uint8_t)((br >> 16) & 0xFFU);
  buf[3]                              = (uint8_t)((br >> 24) & 0xFFU);
  buf[4]                              = 0U;            // Number of stop bits = 1
  buf[5]                              = 0U;            // Parity bit type = None
  buf[6]                              = 8U;            // Number of data bits = 8
  if (USBH_ControlTransfer (USBH_CC_Device, &setup_packet, buf, 7U) != usbOK) { return usbClassErrorCustom; }
 
  return usbOK;
}
 
/// \brief De-initialize Custom Class Device instance
/// \param[in]     instance             index of custom class device instance.
/// \return                             status code that indicates the execution status of the function as defined with usbStatus.
usbStatus USBH_CustomClass_Uninitialize (uint8_t instance) {
 
  (void)instance;                       // Only single instance is supported
 
  return usbOK;
}
回复

使用道具 举报

1

主题

57

回帖

60

积分

初级会员

积分
60
 楼主| 发表于 2024-5-30 11:23:47 | 显示全部楼层
yono 发表于 2024-5-29 15:16
找到一个参考,根据这个驱动源码来看,是要USB给CH340发配置消息,改变波特率
创建驱动CH340的USB HOST 设 ...

非常感谢!有进展我在后面续帖
回复

使用道具 举报

1

主题

57

回帖

60

积分

初级会员

积分
60
 楼主| 发表于 2024-5-30 11:26:25 | 显示全部楼层
eric2013 发表于 2024-5-30 08:45
RL-USB有个驱动PL2303的例子,也可以参考

[mw_shl_code=c,true]/*------------------------------------ ...

感谢硬汉回复!不太会用RL_USB。手上有V7开发板,但是没用来开发过USBH应用。
USBH CDC的例程比较少
回复

使用道具 举报

1

主题

6

回帖

9

积分

新手上路

积分
9
发表于 2024-12-20 11:38:50 | 显示全部楼层
eric2013 发表于 2024-5-30 08:45
RL-USB有个驱动PL2303的例子,也可以参考

[mw_shl_code=c,true]/*------------------------------------ ...

大佬请问一下,例程上的这个东西我咋没看见定义啊,用的h723
74496132d9ed97e988afe1dff8c8df8.png
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-12-21 09:03:52 | 显示全部楼层
Hc_IpxZerg 发表于 2024-12-20 11:38
大佬请问一下,例程上的这个东西我咋没看见定义啊,用的h723

这个是CMSIS Driver UART的驱动文件
回复

使用道具 举报

1

主题

3

回帖

6

积分

新手上路

积分
6
发表于 2025-1-24 11:34:28 | 显示全部楼层
我可以要下你的例程吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 06:27 , Processed in 0.045850 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表