Author Topic: CH340B: How to configure internal EEPROM using libusb (Linux)?  (Read 3865 times)

0 Members and 1 Guest are viewing this topic.

Offline vobsTopic starter

  • Newbie
  • Posts: 4
  • Country: de
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
 

Offline vobsTopic starter

  • Newbie
  • Posts: 4
  • Country: de
Re: CH340B: How to configure internal EEPROM using libusb (Linux)?
« Reply #1 on: April 11, 2023, 07:46:16 pm »
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
 
The following users thanked this post: bingo600, Squantor, thinkfat

Offline quinot

  • Newbie
  • Posts: 1
  • Country: fr
    • Thomas' lab notes
Re: CH340B: How to configure internal EEPROM using libusb (Linux)?
« Reply #2 on: January 10, 2025, 06:56:59 pm »
Hello, Were you able to create a Linux programming tool for the CH340B in the end?
 

Offline vobsTopic starter

  • Newbie
  • Posts: 4
  • Country: de
Re: CH340B: How to configure internal EEPROM using libusb (Linux)?
« Reply #3 on: January 16, 2025, 09:43:32 am »
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()".

 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 3826
  • Country: gb
Re: CH340B: How to configure internal EEPROM using libusb (Linux)?
« Reply #4 on: January 16, 2025, 11:57:17 am »
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: [Select]
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)
 

Offline ogogon

  • Newbie
  • Posts: 3
  • Country: ro
Re: CH340B: How to configure internal EEPROM using libusb (Linux)?
« Reply #5 on: November 10, 2025, 01:28:36 am »
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()".
Since you don’t provide the code for your utility, which you certainly have the right to do, I had to write my own, based on your keen observations of life.

My program now transmits six general initialization sequences from your post to the chip, then three sequences to initialize reading, and then performs the reading itself. To my immense amazement, she actually proudly carries a byte 0xFF in her beak.
However, this raises some very serious questions for me.

Where does 0xFF come from in the meaning of VID?
VIDs of the WCH company (Nanjing Qinheng Microelectronics Co., Ltd.) is 1A86 and 1A8A. Regardless of the size of the Indian, the value 0xFF cannot appear in either the high or low byte. Only bytes 0x1A, 0x86 and 0x8A.

Next, I decided to change byte 0x04 in the read request. (From your post it follows that it is this value that specifies the offset in EEPROM that needs to be read.) To my even greater amazement, at any value, the read function still proudly brings 0xFF.
Just like a raven who, in response to any words, yells to "Nevermore!"

Please share your opinion on my observations.

Thanks in advance,
Ogogon.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->