Electronics > Projects, Designs, and Technical Stuff
CH340B: How to configure internal EEPROM using libusb (Linux)?
(1/1)
vobs:
Dear all,
I'd like to write configuration data, like serial number, product id etc., into the internal EEPROM of a CH340B USB-to-RS232 converter. Unfortunately I don't find any information about the USB interface and the related vendor or control transfers of this device. The data sheet contains the EEPROM's byte addresses, but gives not hints about EEPROM access.
There is an open source project available on github, called tools-ch340b-configuration. But this relies on some undocumented features of the device's proprietary vendor specific windows driver.
I'd like to write a small command line configuration tool running under Linux and using libusb.
Any information about CH340B EEPROM access using libusb would be appreciated!
Regards,
Volker
vobs:
Dear all,
in the meantime I managed to eavesdrop on the communication between my mother's outdated Windows PC (Vista) running CH340B EEPROM config software "tools-ch340b-configuration" (available from github) and CH340B using Hantek 4032L and Sigrok's USB protocol decoder.
My findings:
1. Initialization sequence of USB setup/control/vendor transmissions while the PC config software was started:
SETUP out: [ 40 A1 9C C3 8A D9 00 00 ][ ] : ACK
SETUP out: [ 40 9A 2C 0F 07 00 00 00 ][ ] : ACK
SETUP out: [ 40 A4 DF 00 00 00 00 00 ][ ] : ACK
SETUP out: [ 40 A4 9F 00 00 00 00 00 ][ ] : ACK
SETUP out: [ 40 9A 12 13 80 D9 00 00 ][ ] : ACK
SETUP out: [ 40 9A 2C 0F EB 00 00 00 ][ ] : ACK
2. Initialization sequence, sent before reading EEPROM data:
SETUP out: [ 40 A1 9C C3 E8 D9 00 00 ][ ] : ACK
SETUP out: [ 40 A4 DF 00 00 00 00 00 ][ ] : ACK
SETUP out: [ 40 A4 9F 00 00 00 00 00 ][ ] : ACK
3. Reading one Byte (0xFF) @ EEPROM address 0x04 (Vendor-ID low byte):
SETUP in: [ C0 54 00 04 01 A0 01 00 ][ FF ]
4. In Initialization sequence, sent before writing EEPROM data:
SETUP out: [ 40 A1 9C C3 E8 D9 00 00 ][ ] : ACK
SETUP out: [ 40 A4 DF 00 00 00 00 00 ][ ] : ACK
SETUP out: [ 40 A4 9F 00 00 00 00 00 ][ ] : ACK
5. Writing a byte (0xFF) to EEPROM address 0x04:
SETUP out: [ 40 54 FF 04 01 A0 00 00 ][ ] : ACK
SETUP out: [ 40 5E 0A 00 00 00 00 00 ][ ] : ACK
The 2nd transfer seems to activate a kind of delay as the request byte 0x5E is named CH341A_DELAY_MS in some sources.
The above data bytes can be used as parameters for libusb function libusb_control_transfer()
1st byte: bmRequestType,
2nd byte: bRequest
3rd byte: wValue low byte
4th byte: wValue high byte
5th byte: wIndex low byte
6th byte: wIndex high byte
7th byte: wLength low byte
8th byte: wLength high byte
Regards,
Volker
quinot:
Hello, Were you able to create a Linux programming tool for the CH340B in the end?
vobs:
Yes, and it works quite well -- for me.
Unfortunately I lack the time for writing "foolprove" code and a user's manual, so I hesitate to share the software.
Also the program is a very simple and quite uncomfortable command line tool that might do a lot of damage...
But in my posting above you find all information required for read or write access to the ch340b eeprom by using function "libusb_control_transfer()".
voltsandjolts:
This would be a good fit for a small python script which would be nicely cross-platform.
It could be something based on this completely untested never run scribbling of mine:
--- Code: ---try:
import usb.core,usb.util
except ImportError as e:
print("The pyusb module needs to be installed.\n"
"At command prompt type:\npy -m pip install pyusb\n"
"Also, the libusb library needs to be on the system path")
CH340B_VID = 0x1a86
CH340B_PID = 0x7523
VENDOR_CTRL_IN = 0xC0 #USB control transfer types
VENDOR_CTRL_OUT = 0x40
mydev = usb.core.find(idVendor=CH340B_VID, idProduct=CH340B_PID)
if mydev is None:
raise ValueError('Device not found')
mydev.set_configuration()
# ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, payload)
# where payload=byte[] for OUT transfer, or num bytes to read for IN transfer
#4. In Initialization sequence, sent before writing EEPROM data:
#SETUP out: [ 40 A1 9C C3 E8 D9 00 00 ][ ] : ACK
mydev.ctrl_transfer(VENDOR_CTRL_OUT, 0xA1, 0xc39c, 0xd9e8, None)
#SETUP out: [ 40 A4 DF 00 00 00 00 00 ][ ] : ACK
mydev.ctrl_transfer(VENDOR_CTRL_OUT, 0xA4, 0x00df, 0x0000, None)
#SETUP out: [ 40 A4 9F 00 00 00 00 00 ][ ] : ACK
mydev.ctrl_transfer(VENDOR_CTRL_OUT, 0xA4, 0x009f, 0x0000, None)
usb.util.dispose_resources(mydev)
--- End code ---
Navigation
[0] Message Index
Go to full version