CH573 USB Device 怎么分包发送 descriptor

由于我需要传 BOS Descriptor 的内容,Microsoft OS 2.0 descriptor 长达 178 字节,但是我每次只能发送 64字节

我参考了官方示例的 USB 中断处理函数,其中

      else
      {
        if ( chtype & 0x80 )     // 上传
        {
          len = ( SetupReqLen > DevEP0SIZE ) ?
              DevEP0SIZE : SetupReqLen;
          SetupReqLen -= len;
        }
        else
          len = 0;        // 下传
        R8_UEP0_T_LEN = len;
        R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;    // 默认数据包是DATA1
      }

这里会将 len 设置成 64 (DevEp0Size),期望的是 Host 继续发同样的请求,并且 pSetupReqPak->wLength 为 178 - 64,但这并没有发生,我这里是不是做错了,需要怎么分包发送呢?

www.wch.cn/bbs/thread-67066-1.html

你好,可以参考上面的网页例程demo,里面有涉及到分包发送的处理。


在端点0 的in会继续发送吧 直到发完


@xph 好像不行把,Ep0 USB FS 最大packet好像只能 64B


您好,麻烦请帮我看一下这么发送的结果对嘛?Windows 上似乎仍然没法正确获得描述符


image.png


下面这个是USB协议分析仪sniff出来的结果

image.png

// 待发送内容
const uint8_t msOS20Descriptor[] = {
    // Microsoft OS 2.0 descriptor set header (table 10)
    0x0A, 0x00,             // Descriptor size (10 bytes)
    0x00, 0x00,             // MS OS 2.0 descriptor set header
    0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000)
    0xB2, 0x00,      // Size, MS OS 2.0 descriptor set

    // Microsoft OS 2.0 configuration subset header
    0x08, 0x00,             // wLength
    0x01, 0x00,             // wDescriptionTypes
    0x00,                   // bConfigurationValue,     Applies to configuration 1 (indexed from 0 despite configurations normally indexed from 1)
    0x00,                   // Reserved
    0xA8, 0x00, // Size, MS OS 2.0 function subset

    // Microsoft OS 2.0 function subset header
    0x08, 0x00,             // Descriptor size (8 bytes)
    0x02, 0x00,             // MS OS 2.0 function subset header
    0x01,                   // first interface no; msOS20Descriptor[14]
    0x00,                   // Reserved
    0xA0, 0x00, // Size, MS OS 2.0 function subset

    // Microsoft OS 2.0 compatible ID descriptor (table 13)
    0x14, 0x00,                     // wLength
    0x03, 0x00,                   // MS_OS_20_FEATURE_COMPATIBLE_ID
    'W', 'I', 'N', 'U', 'S', 'B', //
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    // interface guids
    0x84, 0x00, // Size of this descriptor
    0x04, 0x00, //Registry property descriptor
    0x07, 0x00, //REG_MULTI_SZ
    //
    0x2A, 0, // Length of the property name

    // Property name with null terminator encoded in UTF-16LE
    'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0,
    'a', 0, 'c', 0, 'e', 0, 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
    // Length of the property value
    0x50, 0,
    //
    '{', 0, '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0, '9', 0, 'C', 0,
    '7', 0, '7', 0, '-', 0, '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0, '9', 0, '3', 0, '3', 0, 'B', 0,
    '-', 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0,
    'B', 0, '}', 0, 0, 0, 0, 0};
    
void USBDevice_EP0_Send_Packet(uint8_t* data, uint16_t len) {
    uint16_t len_left = len;
    uint8_t* pData = data;
    uint16_t send_len;

    while (len_left) {
        if (R8_USB_INT_FG & RB_UIF_TRANSFER) {
            // TX RES 发送 NAK
            R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_NAK | UEP_T_RES_NAK;

            send_len = len_left >= DevEP0SIZE ?
                DevEP0SIZE : len_left;    // 本次传输长度
            memcpy( pEP0_DataBuf, pData, send_len ); /* 加载上传数据 */

            len_left -= send_len;
            pData += send_len;

            R8_UEP0_T_LEN = send_len;

            R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;    // 默认数据包是DATA1

            R8_USB_INT_FG = RB_UIF_TRANSFER;
        }
    }

    while (!(R8_USB_INT_FG & RB_UIF_TRANSFER));
    R8_UEP0_T_LEN = 0;
    R8_UEP0_CTRL ^= RB_UEP_T_TOG;

    R8_USB_INT_FG = RB_UIF_TRANSFER;

}

在中断处理函数里收到 windows 发来要我发这个 descriptor 的包的时候直接调用

USBDevice_EP0_Send_Packet(msOS20Descriptor, 178);



只有登录才能回复,可以选择微信账号登录