Page MenuHomeFreeBSD

uchcom(4): add support for CH9102 and CH343 uarts
ClosedPublic

Authored by kevlo on Aug 14 2024, 9:08 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Oct 13, 11:05 AM
Unknown Object (File)
Thu, Oct 9, 9:46 PM
Unknown Object (File)
Fri, Sep 26, 3:19 PM
Unknown Object (File)
Fri, Sep 19, 6:54 AM
Unknown Object (File)
Wed, Sep 17, 7:42 AM
Unknown Object (File)
Wed, Sep 17, 3:54 AM
Unknown Object (File)
Sep 16 2025, 9:45 AM
Unknown Object (File)
Sep 16 2025, 8:32 AM

Details

Summary

This patch adds support for CH9102 and CH343 serial adapters.
The WinChipHead CH9102 and CH343 chips support any baud rate up to 6 Mbps.

Test Plan

ugen0.4: <vendor 0x1a86 USB Single Serial> at usbus0
uchcom0 on uhub0
uchcom0: <vendor 0x1a86 USB Single Serial, class 2/0, rev 1.10/4.45, addr 27> on usbus0
uchcom0: CH343 detected

ugen0.4: <vendor 0x1a86 USB2.0-Serial> at usbus0
uchcom0 on uhub0
uchcom0: <vendor 0x1a86 USB2.0-Serial, rev 1.10/2.54, addr 28> on usbus0
uchcom0: CH340 detected

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kevlo requested review of this revision.Aug 14 2024, 9:08 AM
kevlo created this revision.

I can't test the hardware, nor do I have the hardware spec sheet... but this looks good to my eye...

This revision is now accepted and ready to land.Aug 14 2024, 8:56 PM

Remove unused sc_data_iface_no

This revision now requires review to proceed.Aug 15 2024, 2:47 AM

The only thing I would comment is don't forget to update the .Dd field in manual page. :)

Bump a date in .Dd field in man page.

The only thing I would comment is don't forget to update the .Dd field in manual page. :)

I missed that, thanks for spotting!

joerg added inline comments.
sys/dev/usb/serial/uchcom.c
822

Referring to the discussion in

https://github.com/avrdudes/avrdude/discussions/1639

It seems other BSDs only refuse parity and 5/6/7 bit control for a certain (old) revision of CH340. Do you think it would be possible to implement a somewhat more generic functionality here, rather than restricting it to only CH343?

Add support for line modes other than 8-bit/no-parity/1-stop on
CH340/CH341 chips.

sys/dev/usb/serial/uchcom.c
822

The original goal was to support WCH343, but since you asked whether it's
possible to support 5/6/7 data bits, I think it’s feasible.

kevlo marked an inline comment as not done.Aug 19 2024, 7:27 AM
kevlo added inline comments.
sys/dev/usb/serial/uchcom.c
822

The original goal was to support WCH343, but since you asked whether the
CH340/CH341 could support 5/6/7 data bits, I think it’s feasible.
Please try this revised patch, thanks.

sys/dev/usb/serial/uchcom.c
822

Thanks!
I'll try to find a CH340, and give it a try.

I had someone testing the driver, and he told me that the chip is still buffering data.
I made one inline comment where it's a bit suspicious to me about two register write operations that I think got lost now.

sys/dev/usb/serial/uchcom.c
630

Where did those two uchcom_write_reg operations go to in the patched version? I only see a write to UCHCOM_REG_BPS_PRE later on in uchcom_cfg_open(), but only to a default configuration.

kevlo marked an inline comment as not done.

The revised patch increases the buffer size from 4 to 16 bytes, this will avoid overrunning the buffer.

ziaee requested changes to this revision.May 15 2025, 2:16 AM

The hardware section is used to generate the supported hardware page in the release notes. Removing the hardware section would create a dead link there. It does need to be fixed though, I can fix it in another commit if you want.

This revision now requires changes to proceed.May 15 2025, 2:16 AM

The hardware section is used to generate the supported hardware page in the release notes. Removing the hardware section would create a dead link there. It does need to be fixed though, I can fix it in another commit if you want.

All the serial adapters I have tested and know of clearly indicate the chip model, such as https://www.waveshare.com/ch343-usb-uart-board.htm
If you've tested any variant of the uchcom chipset used in a different product model, please help add it, thanks

If you've tested any variant of the uchcom chipset used in a different product model, please help add it, thanks

  • Joy-IT Nano V3 (Arduino) clone
  • Chinese no-name "USB TO TTL" dongle (this is the only text on the PCB at all)

Both using CH340G chips.

All the serial adapters I have tested and know of clearly indicate the chip model

In that case, it should say:

.Sh HARDWARE
The
.Nm
driver supports the following USB to serial adapters:
.Pp
.Bl -bullet -compact
.It
WinChipHead CH9102
.It
WinChipHead CH343
.It
WinChipHead CH341
.It
WinChipHead CH340
.El

Listing specific products instead is less useful, I think.

share/man/man4/uchcom.4
35

USB to serial adapter driver?

Hello world :-)

I have some CH343 CH341 and probably some others / can get others.. how can I help testing? What are test steps to perform? :-)

So far I was able to work with CH343 currently on 14.2-RELEASE AMD64 but only in basic slow UART mode, control lines fail and some transfers fail (i.e. I have one in some ESP32-S3 devkit that I cannot program with esptool) so its unreliable.

FreeBSD hexagon 14.2-RELEASE-p1 FreeBSD 14.2-RELEASE-p1 GENERIC amd64

ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1
umodem0 on uhub8
umodem0: <vendor 0x1a86 USB Single Serial, class 2/0, rev 1.10/4.43, addr 7> on usbus1
umodem0: data interface 1, has no CM over data, has no break

ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (134mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0110
  bDeviceClass = 0x0002  <Communication device>
  bDeviceSubClass = 0x0000
  bDeviceProtocol = 0x0000
  bMaxPacketSize0 = 0x0008
  idVendor = 0x1a86
  idProduct = 0x55d3
  bcdDevice = 0x0443
  iManufacturer = 0x0000  <no string>
  iProduct = 0x0002  <USB Single Serial>
  iSerialNumber = 0x0003  <XXX>
  bNumConfigurations = 0x0001

Hello world :-)

I have some CH343 CH341 and probably some others / can get others.. how can I help testing? What are test steps to perform? :-)

So far I was able to work with CH343 currently on 14.2-RELEASE AMD64 but only in basic slow UART mode, control lines fail and some transfers fail (i.e. I have one in some ESP32-S3 devkit that I cannot program with esptool) so its unreliable.

FreeBSD hexagon 14.2-RELEASE-p1 FreeBSD 14.2-RELEASE-p1 GENERIC amd64

ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1
umodem0 on uhub8
umodem0: <vendor 0x1a86 USB Single Serial, class 2/0, rev 1.10/4.43, addr 7> on usbus1
umodem0: data interface 1, has no CM over data, has no break

umodem(4)? You didn't apply the patch and rebuild uchcom(4) driver.

ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (134mA)

bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0110
bDeviceClass = 0x0002  <Communication device>
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0008
idVendor = 0x1a86
idProduct = 0x55d3
bcdDevice = 0x0443
iManufacturer = 0x0000  <no string>
iProduct = 0x0002  <USB Single Serial>
iSerialNumber = 0x0003  <XXX>
bNumConfigurations = 0x0001

Yup, I provided information "before", now the information "after" and all seems to work fine, the problem is gone, I can flash devkits with CH343 chip, baudrate change seems to work correctly BIG THANK YOU :-)

One note detailed at the bottom - RESET/RTS works, BOOT/DTR does not seem to work.

Two different chips - first is USB2UART, second is ESP32-S3-Touch-LCD-1.28 devkit:

Jun 15 13:47:30 hexagon kernel: ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1
Jun 15 13:47:30 hexagon kernel: uchcom0 on uhub8
Jun 15 13:47:30 hexagon kernel: uchcom0: <vendor 0x1a86 USB Single Serial, class 2/0, rev 1.10/4.43, addr 7> on usbus1
Jun 15 13:47:30 hexagon kernel: uchcom0: CH343 detected
Jun 15 13:47:58 hexagon kernel: ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1 (disconnected)
Jun 15 13:47:58 hexagon kernel: uchcom0: at uhub8, port 1, addr 7 (disconnected)
Jun 15 13:47:58 hexagon kernel: uchcom0: detached


Jun 15 13:48:09 hexagon kernel: ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1
Jun 15 13:48:09 hexagon kernel: uchcom0 on uhub8
Jun 15 13:48:09 hexagon kernel: uchcom0: <vendor 0x1a86 USB Single Serial, class 2/0, rev 1.10/4.45, addr 8> on usbus1
Jun 15 13:48:09 hexagon kernel: uchcom0: CH343 detected
Jun 15 14:02:01 hexagon kernel: ugen1.8: <vendor 0x1a86 USB Single Serial> at usbus1 (disconnected)
Jun 15 14:02:01 hexagon kernel: uchcom0: at uhub8, port 1, addr 8 (disconnected)
Jun 15 14:02:01 hexagon kernel: uchcom0: detached
% uname -a
FreeBSD hexagon 14.2-RELEASE-p3 FreeBSD 14.2-RELEASE-p3 #0 releng/14.2-n269524-1eb03b059e56-dirty: Sun Jun 15 04:00:07 CEST 2025     root@hexagon:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64


% esptool.py chip_id
esptool.py v4.8.1
Serial port /dev/cuaU0
Connecting.....................
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: 3c:84:27:e7:fc:50
Uploading stub...
Running stub...
Stub running...
Warning: ESP32-S3 has no Chip ID. Reading MAC instead.
MAC: XXXX
Hard resetting via RTS pin...


% esptool.py write_flash 0 factory.bin
esptool.py v4.8.1
Serial port /dev/cuaU0
Connecting..........
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: XXXX
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash will be erased from 0x00000000 to 0x0005dfff...
Compressed 384400 bytes to 190094...
Wrote 384400 bytes (190094 compressed) at 0x00000000 in 16.7 seconds (effective 183.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...



% esptool.py write_flash 0 S3-Touch-LCD-1.28-MPY.bin
esptool.py v4.8.1
Serial port /dev/cuaU0
Connecting........................
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: XXXX
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00182fff...
Compressed 1583792 bytes to 1050433...
Wrote 1583792 bytes (1050433 compressed) at 0x00000000 in 92.0 seconds (effective 137.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...



% cu -l /dev/cuaU0 -s 115200
Connected
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3810,len:0xf8c
load:0x403c9700,len:0xb3c
load:0x403cc700,len:0x2dc8
entry 0x403c989c
Performing initial setup
MicroPython 5b4a2baff on
>>> help
<function>
>>>
gc              os              bdev
>>> os.
remove          __dict__        VfsFat          VfsLfs2
chdir           dupterm         dupterm_notify  getcwd
ilistdir        listdir         mkdir           mount
rename          rmdir           stat            statvfs
sync            umount          uname           unlink
urandom
>>> bdev.
find            BOOT            RUNNING         TYPE_APP
TYPE_DATA       get_next_update                 info
ioctl           mark_app_valid_cancel_rollback  readblocks
set_boot        writeblocks
>>> ~
[EOT]



% cu -l /dev/cuaU0 -s 9600
Connected
j()n-=L~.
Traceback (most recent call last):
  File "<stdin>", line 1
SyntaxError: invalid syntax
>>> ~
[EOT]

hexagon% cu -l /dev/cuaU0 -s 1000000
Connected
!#f
   f~
[EOT]

One note: RTS is used to control RESET signal onboard, DTR is used to control BOOT signal onboard (boot mode select). Reset works but DTR does not seem to work therefore board cannot be programmed without manual interaction with buttons (problematic for automation and I have over 50 boards for automated testing). Did you notice that behavior on your ESP32-C6 Kev? This is another problem but would be also great to fix one day :-) Schematics is here: https://files.waveshare.com/wiki/ESP32-S3-Touch-LCD-1.28/ESP32-S3-Touch-LCD-1.28-Sch.pdf.

Yup, I provided information "before", now the information "after" and all seems to work fine, the problem is gone, I can flash devkits with CH343 chip, baudrate change seems to work correctly BIG THANK YOU :-)

One note detailed at the bottom - RESET/RTS works, BOOT/DTR does not seem to work.

[snip]

Thanks for testing! I know where the problem lies. Please test the revised patch, thanks again.

AMAZING! Big Thank You Kev!! I will be able to verify on Monday :-)

BIG THANK YOU KEV!! Both UART baudrate and RTS/DTR seems to be fixed now! I can fully flash the devkit with esptool without manual intervention :-)

% esptool.py erase_flash
esptool.py v4.8.1
Serial port /dev/cuaU0
Connecting....
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: XXX
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 38.4s
Hard resetting via RTS pin...


hexagon% cu -l /dev/cuaU0 -s 115200
Connected
er: 0xffffffff
invalid heBuild:Mar 27 2021
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
(..)


% esptool.py  write_flash 0 MicroPython-bin/S3-Touch-LCD-1.28-MPY.bin
esptool.py v4.8.1
Serial port /dev/cuaU0
Connecting.........
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: XXX
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00182fff...
Compressed 1583792 bytes to 1050433...
Wrote 1583792 bytes (1050433 compressed) at 0x00000000 in 91.9 seconds (effective 137.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...


% cu -l /dev/cuaU0 -s 115200
Connected
more information.
>>> D mBuild:Mar 27 2021
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3810,len:0xf8c
load:0x403c9700,len:0xb3c
load:0x403cc700,len:0x2dc8
entry 0x403c989c
Performing initial setup
MicroPython 5b4a2baff on
>>> help()
Welcome to MicroPython on the ESP32!

For online docs please visit http://docs.micropython.org/

For access to the hardware use the 'machine' module:

import machine
pin12 = machine.Pin(12, machine.Pin.OUT)
pin12.value(1)
pin13 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP)
print(pin13.value())
i2c = machine.I2C(scl=machine.Pin(21), sda=machine.Pin(22))
i2c.scan()
i2c.writeto(addr, b'1234')
i2c.readfrom(addr, 4)

Basic WiFi configuration:

import network
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
sta_if.scan()                             # Scan for available access points
sta_if.connect("<AP_name>", "<password>") # Connect to an AP
sta_if.isconnected()                      # Check for successful connection

Control commands:
  CTRL-A        -- on a blank line, enter raw REPL mode
  CTRL-B        -- on a blank line, enter normal REPL mode
  CTRL-C        -- interrupt a running program
  CTRL-D        -- on a blank line, do a soft reset of the board
  CTRL-E        -- on a blank line, enter paste mode

For further help on a specific object, type help(obj)
For a list of available modules, type help('modules')
>>> ~
[EOT]



% esptool.py erase_flash
esptool.py v4.8.1
Serial port /dev/cuaU0
Connecting.........
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: XXX
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 38.2s
Hard resetting via RTS pin...


% cu -l /dev/cuaU0 -s 115200
Connected
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
(..)


% esptool.py  write_flash 0 factory-bin/factory.bin
esptool.py v4.8.1
Serial port /dev/cuaU0
Connecting.........
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: XXX
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash will be erased from 0x00000000 to 0x0005dfff...
Compressed 384400 bytes to 190094...
Wrote 384400 bytes (190094 compressed) at 0x00000000 in 16.7 seconds (effective 183.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...


% cu -l /dev/cuaU0 -s 115200
Connected
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x44c
load:0x403c9700,len:0xbe4
load:0x403cc700,len:0x2a68
entry 0x403c98d4

PSRAM is correctly initialized
DEV_Module_Init OK
GPIO Init successful!
Debug : Set image Rotate 0
drawing...

QMI8658Register_WhoAmI = 255
QMI8658Register_WhoAmI = 255
QMI8658Register_WhoAmI = 255
QMI8658Register_WhoAmI = 255
QMI8658Register_WhoAmI = 255
QMI8658Register_WhoAmI = 5
QMI8658_init slave = 107
nQMI8658Register_WhoAmI = 5 124
QMI8658Register_Ctrl1 = 96
QMI8658Register_Ctrl2 = 35
QMI8658Register_Ctrl1 = 67
QMI8658Register_Ctrl1 = 0
QMI8658Register_Ctrl1 = 0
QMI8658Register_Ctrl1 = 0
QMI8658Register_Ctrl1 = 3
QMI8658_init

Is there any chance this driver will land into next 14.2-RELEASE-p4? That would come really handy for some existing setups :-)

This revision was not accepted when it landed; it landed in state Needs Review.Jun 25 2025, 1:36 AM
This revision was automatically updated to reflect the committed changes.

Would it be possible to backport this fix to releng/14.2 branch so it lands into next 14.2-p6 update please? I need to rebuild after update while this fix is important and unblocks working with various embedded systems :-) Is it already in 14.3?