Tuesday, May 1, 2012

WinUSB communication with STM32 (Part 4: Software)

Time for some bulk communication. VS project that I added to sources shows steps which are needed for communication. Project uses the Setupapi for device enumeration and obtaining the handle to device. It further uses the winusb to communicate with device.

After obtaining the handle to device and initializing it there can be multiple communication cycles. The communication cycle has the following steps:

  1. reset the communication channel (control EP)
  2. send data (bulk EP)
  3. send end of data message (control EP)
  4. poll status until "READY" or "ERROR" (control EP)
  5. read data size of response (control EP)
  6. read response data (bulk EP).
The source is mostly copied from MSDN with some changes and additions. An improvement to the library would be an object type which would encapsulate all this functionality and expose nice interface to communicate with device. An alternative could be  libusb-win32 or libusbK or other USB libraries. I haven't checked these in detail. If interested check libwdi. There is some information on Windows 8 integrated support for devices like this (no driver needed for WCID devices!).

[Update - WinXP (SP2) and W7 support driver information descriptors; See my next project]

Test application output.

Check project wiki to get build instructions.

This is the forth post in this series (of total 4 posts). See 12, 3.

[Update - I have a new WinUSB device project with STM32F407 without the need for Windows side driver info (.inf and .cat files) ]


  1. which speed data transfer can achieve ?
    is 12mbts/s usb full speed supported?

    1. 12Mb/s data transfer from application to STM32 is not possible although the USB physical layer is 12Mb/s. This is the frequency of switching the bits on the line. But there is not only data you are transferring. You will always have some overhead from transfer control on all communication layers. You can get better data throughput with larger chunks transmitted at once. Overhead per chunk is mostly constant.

  2. What is difference between Low speed and Full speed device driver libraries by Keil for ST32F103 controller?
    I am shifting from Low to full speed. Will that make any difference speed wise?
    Will I get faster communication?

    1. I'm not familiar with Keil library but I believe they kept the USB speed names. Low is 1.5Mbit/s and Full is 12Mbit/s. So yes, you will get faster communication.

    2. Thanks for the information.

  3. I am trying to find out actual USB communication speed. I used below function (from microsoft) and found it's LOW SPEED.
    Is there any way to get a full speed ? Is it a matter of message size I am sending to the controller.

    public string GetUSBDeviceSpeed(IntPtr hDeviceHandle, Byte pDeviceSpeed)

    1. There is no distinction between Low and Full speed in return from WinUsb_QueryDeviceInformation. I presume that is the call used in GetUSBDeviceSpeed function.

      From MSDN: "If InformationType is DEVICE_SPEED, on successful return, Buffer indicates the operating speed of the device. 0x03 indicates high-speed or higher; 0x01 indicates full-speed or lower."

      It might be that your device is already running at Full speed.

    2. Ok. Yes. You are correct. It's already using full speed drivers.
      Actually in current scenario the communication takes place in packets size of 64 Bytes.
      If we try to send a bigger packet then it cuts down and sends it in a chunks of 64 Bytes (max) only.
      Do you think is there any way to change this max packet size limitation and so increasing the ultimate communication speed (if at all it will effect on speed???)? we are using STM32F103ZE..it supports full speed USB 2.0.

      Shall I conclude that there is no way to go beyond current speed?? How much speed do you get in your project?. I mean if you have to write around 2 MB of data (from windows to the hardware) then how much time it'll take???

      I really appreciate your feedback. Your comment are really helping me out.
      Thanks very much...!!

    3. It's the physical packet that is limited to 64Bytes. You don't need to chop your data in 64Byte chunks though. You can send more than that in a single call. But you can't really achieve wire speed specified (12Mbit/s) for transfer of your net data. The problem with bulk mode is small overhead of communicating message tokens, e.g. start, stop and size of your messages on application level. So, bigger the message better the transfer speed. It gets worse when communicating short messages. As you can see in my post above I've achieved cca. 4Mbit/s with quite small buffer (I don't remember the size - see the code). I have improved the application protocol in second iteration and achieved up to 10Mbit/s with 64kByte messages.