Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Probe wch.cn WCH-Link (2a86:8011) support #1395

Closed
eugene-bright opened this issue May 25, 2022 · 12 comments · Fixed by #1399
Closed

Probe wch.cn WCH-Link (2a86:8011) support #1395

eugene-bright opened this issue May 25, 2022 · 12 comments · Fixed by #1399

Comments

@eugene-bright
Copy link
Contributor

I gave a try to a cheap QYF2 CMSIS DAPLink.

pyOCD can't find the debugger.

$ lsusb | grep WCH-Link
Bus 003 Device 068: ID 2a86:8011 wch.cn WCH-Link

$ pyocd list
No available debug probes are connected

$ pyocd --version
0.33.1

It looks to be ordinary DAP-CMSIS with exotic VID and PID.
I can successfully access the chip with it using openocd this way:

$ openocd -c "adapter driver cmsis-dap; cmsis_dap_vid_pid 0x2a86 0x8011"  -f target/stm32g0x.cfg`
@eugene-bright
Copy link
Contributor Author

Here is also another Chinese adapter based on CH549F MCU.
It would be nice to add these VID/PID (0x1a86 0x8011) too.

@eugene-bright
Copy link
Contributor Author

Related issues:
#1121
probe-rs/probe-rs#995

@eugene-bright
Copy link
Contributor Author

It looks like 0x1a86 0x8011 is already covered and 0x2a86 0x8011 is not.

@elfmimi
Copy link

elfmimi commented May 29, 2022

pyOCD is not relying on VID:PID to detect probes. pyOCD is relying on product string and also interface string when needed.

The problem with WCH-Link is that it is not fully compliant to USB standard. It fails to report properly to get-string-descriptor requests in some condition.

The workaround introduced in #1122 seems only effective with MacOS .

@elfmimi
Copy link

elfmimi commented May 29, 2022

Assuming you are using Linux environment, you may try the following.

Edit this line of pyocd/probe/pydapaccess/interface/hidapi_backend.py to

if ("CMSIS-DAP" not in product_name and "WCH-Link" not in product_name):

and use it with specifying backend like this.
PYOCD_USB_BACKEND=hidapiusb python3 -mpyocd list

You may also need to uninstall hid and install hidapi.
pip3 uninstall hid
pip3 install hidapi==0.7.99.post14
sudo apt install libhidapi-hidraw0

@flit
Copy link
Member

flit commented May 29, 2022

Hi all! Thanks @elfmimi for helping out! 😄

There have actually been some changes related to this on develop, specifically commit a926e94 which adds matching by VID/PID pair. It was, I think, to match a probe with no device name string or at least a non-standard string. There was already a small list of ID pairs used for printing more helpful permissions errors on Linux (if we know the device is CMSIS-DAP rather than a random USB device like a keyboard). So it wasn't a big change. This also works with all of the USB backends.

Certainly there's an argument that matching by device name is more reliable/maintainable than matching by VID/PID pair.
Perhaps both should be supported?

@eugene-bright I'll leave it up to you to decide. … More suggestions back on the PR #1399 so they are co-located with the code review…

@flit
Copy link
Member

flit commented May 30, 2022

@eugene-bright Would you mind running lsusb -v -d 2a86:8011 and copying the output? (You're on Linux, right?) I'd like to see if "CMSIS-DAP" appears in any other USB strings.

Pyocd should find "CMSIS-DAP" if it's in the interface name string, as it is for the 1a86:8011 version of the WCH-Link (see the related issues you linked above). It would be nice to know if the same is true for this 2a86:8011 variant.

Unfortunately, hidapi does not provide access to the USB interface name strings. But if you're on Linux, the pyusb backend should be used by default, and that can access interface names.


Back story (partially copied from #1399)…

The WCH-Link variant in this issue has a USB VID of 0x2a86. The one references in the links above has a VID of 0x1a86.

The most recent USB-IF VID owners list shows that 0x1a86 is registered to Nanjing Qinheng Microelectronics Co., Ltd., aka WCH-IC. While 0x2a86 is registered to Kitrin AG.

So either someone made a stupid typo in the code? Or something more nefarious is going on. 🤨 Is this 0x2a86 variant a clone of the real WCH-Link?

@eugene-bright
Copy link
Contributor Author

Here it is

$ lsusb -v -d 2a86:8011

Bus 003 Device 118: ID 2a86:8011 wch.cn WCH-Link
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0         8
  idVendor           0x2a86 
  idProduct          0x8011 
  bcdDevice            1.00
  iManufacturer           1 wch.cn
  iProduct                2 WCH-Link
  iSerial                 3 0001A0000001
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x006b
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass       2 Abstract (modem)
      bFunctionProtocol       1 AT-commands (v.25ter)
      iFunction               4 QYF CMSIS-DAP
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      0 
      iInterface              4 QYF CMSIS-DAP
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x01
          call management
        bDataInterface          1
      CDC ACM:
        bmCapabilities       0x02
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              5 (error)
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              6 QYF CMSIS-DAP
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      33
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)

@eugene-bright
Copy link
Contributor Author

Tip for myself

iInterface              5 (error)

In python this is equivalent to the

usb.util.get_string(interface.device, interface.iInterface)

and raises usb.core.USBError.
It's currently non-properly nandled in the code.

@eugene-bright
Copy link
Contributor Author

The MCU chip marking of my 0x2a86 is erased. It may be an unauthorized clone

@flit
Copy link
Member

flit commented May 30, 2022

Thanks! All very interesting. 😄

So it does indeed have "CMSIS-DAP" in the interface name. But the CDC control interface also has the name "QYF CMSIS-DAP". I wonder if that could be causing trouble? Like pyocd sees a "CMSIS-DAP" interface, but it has the wrong endpoints.

Btw, do you have udev configured to allow access to the device? Presumably so, since your PR worked, but should asked. (And we might want to update the included udev rules.) hidapi might have worked around this; I've not used hidapi on Linux so I'm not sure exactly how it behaves with regards to permissions.

@flit
Copy link
Member

flit commented Jun 12, 2022

The main issue is fixed in #1399 for the hidapi USB backend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants