HID based USB↔Serial converter

Found on Chinese multimeters.

HOITEK HE2325U - a HID based USB Serial Converter (RS232, COM port)

Pin connections from data sheet

P01 18P1
n.c.3 16P3
Data+ (?)514TxD
Uss (0 V)613USB D+
Upp (0 V)712USB D–
Ureg8 11Ucc (5 V)
Data– (?)910n.c.

This 18-lead SMD IC has following properties:

This implementation as a HID has the following advantages and disadvantages: This chip has been seen for the PC interface of hand and desk multimeters. Especially for devices by Chinese company UNI-Trend. The chip was also seen at PeakTech device interfaces.

Update (unknown chip name)

Another unknown IC has the same HID protocol and interface, but has changed USB vendor ID and product ID, changed strings and is Full-Speed. Its data rate should be 64 kByte/s.

A clone can be made using new microcontrollers PIC16F1454. Advantages compared to CDC (Communication Device Class) would be a silent Windows installation and functioning in Windows 98/Me. (CDC is not supported by Win98/Me.)

This chip has a silicon bug! It works only after USB Reset signaling. Windows itself does emit USB Reset signaling (Single-Ended-Zero for 50 ms) on every enumeration (i.e. plug-in). Linux doesn't do so (enumerates faster). Therefore, this IC appears inoperable in Linux. You have to put the chip into Suspend beforehand. (The USB Wwakeup is done by USB Reset signaling.)

Ralf Burger had revealed and solved this problem, and documented. Thank him.


USB Descriptors

Device Bus Speed:     Low
 …updated…            Full

Device Descriptor:
 bcdUSB:            0x0100
 bDeviceClass:        0x00
 bDeviceSubClass:     0x00
 bDeviceProtocol:     0x00
 bMaxPacketSize0:     0x08 (8)
 idVendor:          0x04FA (Dallas Semiconductor)
  …updated…         0x1A86 (QinHeng Electronics)
 idProduct:         0x2490 (DS1490F - iButton)
  …updated…         0xE008
 bcdDevice:         0x0000
  …updated…         0x1100
 iManufacturer:       0x01 "Hoitek Semiconductor"
  …updated…                "WCH.CN \1"
 iProduct:            0x02 "USB to Serial"
 iSerialNumber:       0x00
 bNumConfigurations:  0x01

Configuration Descriptor:
wTotalLength:       0x0029
bNumInterfaces:       0x01
bConfigurationValue:  0x01
iConfiguration:       0x04 "Sample HID"
bmAttributes:         0x80 (Bus Powered )
MaxPower:             0x32 (100 mA)

Interface Descriptor:
bInterfaceNumber:     0x00
bAlternateSetting:    0x00
bNumEndpoints:        0x02
bInterfaceClass:      0x03 (HID)
bInterfaceSubClass:   0x00
bInterfaceProtocol:   0x00
iInterface:           0x00

HID Descriptor:
bcdHID:             0x0100
bCountryCode:         0x00
bNumDescriptors:      0x01
bDescriptorType:      0x22 (Report)
wDescriptorLength:  0x0025 (37 Bytes)

Endpoint Descriptor:
 bEndpointAddress:    0x81 (EP1IN)
 Transfer Type:  Interrupt
 wMaxPacketSize:    0x0008 (8 Bytes)
 bInterval:           0x0A (10 ms)

Endpoint Descriptor:
 bEndpointAddress:    0x02 (EP2OUT)
 Transfer Type:  Interrupt
 wMaxPacketSize:    0x0008 (8 Bytes)
 bInterval:           0x0A (10 ms)

Searching for possible communication using Win32 API, as much as possible information had to be collected beforehand.

The accompanying software for the multimeters does not meet the requirements. In particular, it is not possible to select out of several USB-serial converters.

This typical-Chinese bashly colorful bloatware full of translation errors is not for me. Moreover, without source code you cannot adopt it for your needs. Not to mention Linux and MacOS application …

Using „USB View“ (usbview.exe) I had read-out the Descriptors. The Vendor ID 0x04FA seems to be leaved from Dallas Semiconducter. Maybe Hoitek is a subsidiary, a Joint Venture, or the (expensive, about 2500 US$) Vendor ID is taken over.

Using “USB Monitor Professional” I had read-out the HID Report descriptor. But its content isn't useful very much.
{0x06,0xA0,0xFF,	//G Usage Page: 65440 (Unknown)
 0x09,0x01,		//L Usage: 1 (Unknown)
  0xA1,0x02,		//M Collection
  0x09,0x01,		//L  Usage: 1 (Unknown)
  0x15,0x00,		//G  Logical Minimum: 0
  0x26,0xFF,0x00,	//G  Logical Maximum: 255
  0x75,0x08,		//G  Report Size: 8 bits
  0x95,0x08,		//G  Report Count: 8 elements
  0x81,0x02,		//M  Input: 2 (Data,Variable,Absolute, …)
  0x09,0x02,		//L  Usage: 2 (Unknown)
  0x75,0x08,		//G  Report Size: 8 bits … superfluous here!
  0x95,0x08,		//G  Report Count: 8 elements … superfluous here!
  0x91,0x02,		//M  Output: 2 (Data,Variable,Absolute, …)
  0x09,0x03,		//L  Usage: 3 (Unknown)
  0x75,0x08,		//G  Report Size: 8 bits … superfluous here!
  0x95,0x05,		//G  Report Count: 5 elements
  0xB1,0x02,		//M  Feature: 2 (Data,Variable,Absolute, …)
 0xC0};			//M End Collection

The Windows API function HidD_GetCaps() shows this:


So it's obviously that the following assignments apply: Report IDs are not used at all, which helps preserving bandwidth.

Feature Report (6 bytes)

#pragma pack(1)
typedef struct {
 char ReportID;	//not used: 0
 long BaudRate;	//little endian
 char unknown;	//always equals 3 *
#pragma pack
* for 8 data bits, no parity, 1 stop bit

Spying the HidD_SetFeature() function (using SoftICE debugger) I could guess the meaning of the bytes of the Feature Reports.

The Chinese software sends 10 instead of 6 Bytes. The extra bytes (zeroes only) are ignored by the HID driver without notice.

The secret with the unknown byte couldn't be revealed until now. I guess: data word length, 0 = 5 bit, 1 = 6 bit, 2 = 7 bit, 3 = 8 bit.

Furthermore, I guess the HE2325U chip doesn't handle parity generation nor parity error handling, so “no parity” is the only option.

Input Report (9 bytes)

typedef struct {
 BYTE ReportID;	//not used: 0
 BYTE DataLen:3;//Bit 2:0, see below
 BYTE Data[7];	//0..7 data bytes

For some reason I couldn't spy the Input Report!!

Normally these reports go through Win32 function ReadFile(). So I wrote a small emulation program and got the bits and bytes.

The direction selection of the 4-bit parallel port is done either using some bits in the Feature Report, or — more probably — there is no such selection: Open Collector outputs with built-in or external Pull-Up.

The length of Input and Output Reports using 8 bytes tends to a good usage of USB bandwidth.

A library he2325u.dll for access


Preliminary implementation!
Last change 02/11: Parameter for asynchronous access o.

Download, Browse

Mit diesem Wissen gestaltet sich der Zugriff auf solche HID-basierten USB-Seriell-Umsetzer recht einfach.

Im Beispiel wird dem Problem etwas Aufmerksamkeit geschenkt, dem Benutzer unterscheidbare und an USB-Buchsen gebundene „Nummern“ anzubieten.
Einfach „erster gefundener Adapter“, „zweiter gefundener Adapter“ usw. ist auf Dauer konfus, weil man nie weiß, welcher gerade wo ist.

Der angezeigte Name ist dann beispielsweise "USB1", "USB2" usw. (nicht diese Monster aus SetupDiGetDeviceInterfaceDetail()!)
Die Zuordnung wird in der Registrierung gespeichert und von der DLL automatisch verwaltet. (Dummerweise hakelt die derzeitige Implementierung unter Vistas UAC.)

Die 4-Bit-Parallelport-Bits werden vorläufig ignoriert.

Analyze measurement instrument's data

This is off-topic here, but documented for UT60, UT61, UT70, UT71, UT81, UT233, UT325, UT803, and UT804. That documentation also applies to the Voltcraft devices VC-820, VC-920, VC-940, VC-960, and VC-1008.