I2C-SPI mode

$ lsusb
Bus 002 Device 003: ID 1a86:5512 QinHeng Electronics CH341 in EPP/MEM/I2C mode, EPP/I2C adapter
$ dmesg
[ 1739.299811] usb 2-1.2: new full-speed USB device number 3 using ehci-pci
[ 1739.385559] usb 2-1.2: New USB device found, idVendor=1a86, idProduct=5512
[ 1739.385565] usb 2-1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0

UART mode

$ lsusb
Bus 002 Device 004: ID 1a86:5523 QinHeng Electronics CH341 in serial mode, usb to serial port converter
$ dmesg
[ 1982.227595] usb 2-1.2: new full-speed USB device number 5 using ehci-pci
[ 1982.313544] usb 2-1.2: New USB device found, idVendor=1a86, idProduct=5523
[ 1982.313550] usb 2-1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 1982.314088] ch341 2-1.2:1.0: ch341-uart converter detected
[ 1982.315989] usb 2-1.2: ch341-uart converter now attached to ttyUSB0

SPI flasher mode

Flashrom has now some support for flash SPI chips

Chinese software

There is some chinese winbrol software to toggle the GPIOs, even though none of the datasheets documents those GPIOs.

BSD driver

Nice quote from the BSD driver:

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.7 2008/10/22 10:35:50 haad Exp $");

 * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.

GPIO mode

I recently found another linux kernel driver "i2c-ch341-usb" available at which exposes all the 8 GPIOs in sysfs, and on the Electrodragon board, I successfully tested 6 of them in output mode (D0, D1, D2, D3, D4, D5) while I could not put D6-D7 in output mode. You have to edit "i2c-ch341-usb.c" and put the following config:

struct ch341_pin_config ch341_board_config[CH341_GPIO_NUM_PINS] =
    // pin  GPIO mode           GPIO name   hwirq
    {   15, CH341_PIN_MODE_OUT , "gpio0"    , 0 }, // used as output
    {   16, CH341_PIN_MODE_OUT , "gpio1"    , 0 }, // used as output
    {   17, CH341_PIN_MODE_OUT , "gpio2"    , 0 }, // used as output
    {   18, CH341_PIN_MODE_OUT , "gpio3"    , 0 }, // used as output
    {   19, CH341_PIN_MODE_OUT , "gpio4"    , 1 }, // used as output with hardware IRQ
    {   20, CH341_PIN_MODE_OUT , "gpio5"    , 0 }, // used as ouput
    {   21, CH341_PIN_MODE_IN  , "gpio6"    , 0 }, // used as input
    {   22, CH341_PIN_MODE_IN  , "gpio7"    , 0 }  // used as input

Then do a "make; sudo make install; sudo modprobe i2c-ch341-usb", then you should have those entries "gpio0, gpio1, gpio2, gpio3, gpio4, gpio5" in /sys/class/gpio.

If you want to test them, put a LED with the short leg on GND, and the long leg on D0 for example, and toggle the LED with:

$ cd /sys/class/gpio/gpio0
$ while true; do echo 1 > value; sleep 1; echo 0 > value; sleep 1; done

Now I need to make some benchmark speed tests to see how fast I can go.

With a simple shell script:

$ cat 
while ((x--)); do
    echo 0 > /sys/class/gpio/gpio1/value
    echo 1 > /sys/class/gpio/gpio1/value

You can run:

$ time sudo ./ 
real    0m45.511s
user    0m12.428s
sys    0m7.143s

Which makes a speed of approx 2.2KHz:

$ python
Python 2.7.14 (default, Dec  6 2017, 16:31:20) 
[GCC 5.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 100000.0/45.5

K2000 demo with 6 GPIOs

You can run the following simple script to blink 6 LEDs in a loop:

for i in 0 1 2 3 4 5; do
        echo 0 > /sys/class/gpio/gpio$i/value

while true; do
  for i in 0 1 2 3 4 5 4 3 2 1; do
        echo 1 > /sys/class/gpio/gpio$i/value
        sleep 0.2
        echo 0 > /sys/class/gpio/gpio$i/value

Save it under "", make it executable with "chmod +x", and then call it with sudo (standard user does not have permissions to access /sys/class/gpio entries):

$ chmod +x
$ sudo ./

It should give you this:


Ch341a programmer

You can find on Aliexpress or Ebay those cheap ch341a programmers (2USD to 5USD).


Thanks to the OneTransistor blog post and its schematics, I could find that 3 exposed pins on the yellow header (MOSI, CS, CLK) can be used as GPIOs, but in 5V (not 3.3V!):


The CS pin is also connected to a LED next to the USB connector, and you can make it blink by using /sys/class/gpio/gpio0.

You can mod the board to put it in 3.3v, see the discussion on the EEVBlog forum:

The hack looks like this:


Electrodragon board

Electrodragon is now selling a much cheaper board (2.50 USD) based on the same CH341 chip, with all the pins exposed as well, with 5V/3.3V switcher, and UART/SPI switcher:


WARNING: Electrodragon just made a labelling mistake on some of their boards:

From: Chow He <>
Date: Wed, 22 Feb 2017 11:42:35 +0800
Subject: Electrodragon Board Bug Notice

Dear customer,

Our current board has a bug, Very sorry for such troubles.

This will inflence usage but not serious not usable, please pay attention
when you use it.

The board is: CH341 USB Convert Flash Board, USB, TTL, IIC, SPI, etc

The error is on board silk print "VCC TXD RXD GND" in which VCC and GND
should be reversed, so it should be "GND TXD RXD VCC". Please notice.

Thank you.

Kind regards,

Electrodragon Team
Twitter <> | Facebook
<> | Google+

CJMCU-CH341 board

CJMCU is also selling a ch341a breakout board similar to the Electrodragon, with a 3.3v/5v pad to be soldered on the back on the board.


You can get it on Aliexpress for around 3EUR.

It has a mini-usb connector, which is considered by many to be stronger then a micro-usb, but the cable is also becoming more rare.