CH32V307枚举USB为WINUSB并且免驱

先说结论:

1、只要能枚举成功为bulk设备,那么就能在设备管理器里面,手动更新驱动程序,强制选择为WINUSB设备即可!不一定要识别为Winusb设备,Win10通用。

2、要识别为Win USB设备,需要枚举时增加一些描述符,windows才能自动安装驱动,而无需强制选择。有2个版本增加描述符方法,这里讲1.0版本,下面重点讲讲单片机MCU如何自动识别为WinUSB

A,定义描述符,具体看这里:使用微软系统描述符1.0制作免驱动自定义USB设备

/* 下面是WINUSB所需的描述符 https://blog.csdn.net/weixin_46753805/article/details/116200729
 *
 * 会索引0xEE处的OS字符串描述符,确认设备是否支持WCID,若回复内容为MSFT100则说明该设备支持WCID,后续才会继续获取兼容ID特征描述等;
       获取兼容ID特征描述符,回复兼容信息为WinUSB设备;
       获取兼容ID后,系统会根据兼容ID的情况请求属性描述符,对于WinUSB设备需要注册设备接口GUID;
 *
 *
 *
 */

// 当系统正确并获取到此字符串前,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\usbflags\[VID+PID+BCD_RELEASE_NUMBER]的位置创建一个键值为osvc字节的REG_BINARY的2字节密钥。

// "MSFT100" : index : 0xEE : langId : 0x0000
const uint8_t OS_StringDescritpor[ ] =
{ 0x12,  0x03,  'M',  0,  'S',  0,  'F',  0,  'T',  0,  '1',  0,  '0',  0,  '0',  0,  BMS_VENDORCODE,  0 };

// 会在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB的位置存储该设备的兼容ID.如VID_04D8&PID_FA2E
// "WINUSB\0\0" : wIndex : 0x0004
const uint8_t WINUSB_ExtendedCompatId_Descritpor[ ] =
{
  // WCID descriptor = 16byte
  0x28, 0x00, 0x00, 0x00,                         // dwLength
  0x00, 0x01,                                     // bcdVersion
  0x04, 0x00,                                     // wIndex=4用于获取设备的兼容ID,在windows领域内使用index=5用于获取固件自己定义的设备interface guid
  0x01,                                           // bCount
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // Reserved[7]

  // WCID function descriptor
  0x00,                                           // bFirstInterfaceNumber
  0x01,                                           // RESERVED ( 0x01 )
  'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,       // compactiableID[8]
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompactiableID[8]
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00              // Reserved[6]
};

// 在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vidxxx&&Pidxxx\LUSBW1\Device Parameters
// L"DeviceInterfaceGUID" : wIndex = 0x0005
// L"{12345678-1234-1234-1234-123456789ABC}"(可以换自己的GUID)
const uint8_t WINUSB_ExtendedProperty_InterfaceGUID_Descritpor[ ] =
{
  // WCID property descriptor = 10 byte
  0x8E, 0x00, 0x00, 0x00,     // dwTotalSize = Header + All sections
  0x00, 0x01,                 // bcdVersion
  0x05, 0x00,                 // wIndex=5用于获取固件自己定义的设备interface guid.
  0x01, 0x00,                 // wCount

  0x84, 0x00, 0x00, 0x00,     // dwSize -- this section

  0x01, 0x00, 0x00, 0x00,     // dwPropertyDataType

  0x28, 0x00,                 // wPropertyNameLength

  'D', 0x00, 'e', 0x00,       // bProperytName : WCHAR : L"DeviceInterfaceGUID"
  'v', 0x00, 'i', 0x00,       // bProperytName : WCHAR
  'c', 0x00, 'e', 0x00,       // bProperytName : WCHAR
  'I', 0x00, 'n', 0x00,       // bProperytName : WCHAR
  't', 0x00, 'e', 0x00,       // bProperytName : WCHAR
  'r', 0x00, 'f', 0x00,       // bProperytName : WCHAR
  'a', 0x00, 'c', 0x00,       // bProperytName : WCHAR
  'e', 0x00, 'G', 0x00,       // bProperytName : WCHAR
  'U', 0x00, 'I', 0x00,       // bProperytName : WCHAR
  'D', 0x00, 0x00, 0x00,      // bProperytName : WCHAR

  0x4E, 0x00, 0x00, 0x00,     // dwPropertyDataLength : 78 Bytes = 0x0000004E

  '{', 0x00, '1', 0x00,       // bPropertyData : WCHAR : L"{12345678-1234-1234-1234-123456789ABC}"
  '2', 0x00, '3', 0x00,       // bPropertyData
  '4', 0x00, '5', 0x00,       // bPropertyData
  '6', 0x00, '7', 0x00,       // bPropertyData
  '8', 0x00, '-', 0x00,       // bPropertyData
  '1', 0x00, '2', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '-', 0x00, '1', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '4', 0x00, '-', 0x00,       // bPropertyData
  '1', 0x00, '2', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '-', 0x00, '1', 0x00,       // bPropertyData
  '2', 0x00, '3', 0x00,       // bPropertyData
  '4', 0x00, '5', 0x00,       // bPropertyData
  '6', 0x00, '7', 0x00,       // bPropertyData
  '8', 0x00, '9', 0x00,       // bPropertyData
  'A', 0x00, 'B', 0x00,       // bPropertyData
  'C', 0x00, '}', 0x00,       // bPropertyData
  0x00, 0x00                  // bPropertyData
};


现在的问题就是怎么在单片机端,把这些描述符给他上报上去。


B、在获取字符串那里增加index = 0xee分支,把OS_StringDescritpor上报上去

C、在非标准setup那里把0xC0+VENDORCODE,以及0xC1+VENDORCODE 分别上报WINUSB_ExtendedCompatId_Descritpor以及

WINUSB_ExtendedProperty_InterfaceGUID_Descritpor

Windows在每个流程会最少请求2次,第一次先请求前面0x10个字节,然后知道要传0x28和0x8E,第二次才请求实际长的数据


D、如果包长大于端点0的64字节,那么第二个包要到token_in分支进行传输!否则主机获取不到0x8E个字节就会报xact error错误!


完整的传输截图如下:

LYJ博客

难点在ep0分包传输,以及在正确的位置上报描述符!


LYJ博客


E、要Windows每次发出0xC1请求,需要把这个Device Parameters节点删除,否则会认为有数据而不会发0xC1请求!0xC0会每次发,只要0xEE上报有数据的话。


LYJ博客

本文为3YL原创,转载无需联系,但请注明来自labisart.com。

原创文章不易,如果觉得有帮助,可打赏或点击右侧广告支持:

查看打赏记录

发表评论请遵守党国法律!后台审核后方可显示!
  • 最新评论
  • 总共0条评论
  • Blog v1.1© 2024 labisart.com 版权所有 | 联系:labartwork@163.com