The magic "CH341A USB to I2C/IIC/SPI/UART/TTL/ISP/GPIO adapter, EPP/MEM parallel port converter!"
2018-08-21[ ch341a usb linux driver kernel ]
A long time ago I saw this in hackaday, after investigation over it on internet, I decided to get one from aliexpress ($9).
This dongle should provide:
- SPI/ISP [Front (4)]
- I²C [Front (6)]
- UART-TTL [Front (3, 7, 8)]
- GPIO [Front (3, 4), Back (1)]
The main CI is the CH341A.
In [Back (2)] we have a 3.3V regulator.
The switch in [Front (1)] will change the USB PID value.
- For I²C and SPI:
idVendor=1a86, idProduct=5512, bcdDevice= 3.04
- For UART:
idVendor=1a86, idProduct=5523, bcdDevice= 3.04
Making the USB driver to select the correct kernel module to deal with it.
It's also possible to change the output voltage with the voltage selection switches [Front (2, 5)].
I'm pretty happy with the hardware, the selection keys makes everything easy to configure and dealing between all the modes sounds pretty possible. It would be better to have all modes at the same time, but that is not possible and does not sound as a terrible thing right now for me. Besides that, the 3.3V regulator can provide up to 1A, and that sounds pretty good also.
The serial interface mode works without any problem as a normal ch341a serial interface (some Arduinos does use it).
The big question is the other modes, like I²C, GPIO and SPI. But the great and beautiful community has already the modules for all functionalities.
- For I²C: allanbian1017/i2c-ch341-usb
- For I²C + GPIO: gschorcht/i2c-ch341-usb
- For SPI + GPIO: gschorcht/spi-ch341-usb
- I did corrections in all repositories, you can check my forks or the PRs in each one.
How to compile, load and remove a module
First things first:
- To load something that you compiled
- Compile with
make
- Load with
sudo insmod module_name.ko
- Unload with
sudo rmmod module_name
- Compile with
- To load a kernel module
- Load with
sudo modprobe module
- Unload with
sudo rmmod module
- Load with
That's what you need to know, for anything else you can use Google.
GPIO and I²C
All GPIOs are provided with sysfs
, I would personally prefer something like libiio or providing /dev/*
devices (Like in: I²C or SPI).
(The GPIO in both SPI and I²C are D* Pins in [Back (1)] and CS* in [Front (4)]).
Ok, to check the I²C, you need to make sure that your i2c-dev module is loaded, you can search it in /lib/modules
with find . | grep i2c-dev
and load it with sudo modprobe i2c-dev
, this will allow the modules to show the I²C devices under /dev
.
The gschorcht/i2c-ch341-usb driver will returns in dmesg
:
[314374.047570] usb 1-1.1.1: new full-speed USB device number 109 using xhci_hcd
[314374.138693] usb 1-1.1.1: New USB device found, idVendor=1a86, idProduct=5512, bcdDevice= 3.04
[314374.138702] usb 1-1.1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[314374.148039] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: output gpio0 gpio=0 irq=0
[314374.148049] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: output gpio1 gpio=1 irq=1
[314374.148055] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: output gpio2 gpio=2 irq=2
[314374.148061] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: output gpio3 gpio=3 irq=3
[314374.148068] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: input gpio4 gpio=4 irq=4 (hwirq)
[314374.148074] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: input gpio5 gpio=5 irq=5
[314374.148080] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: input gpio6 gpio=6 irq=6
[314374.148086] i2c-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: input gpio7 gpio=7 irq=7
[314374.148349] i2c-ch341-usb 1-1.1.1:1.0: ch341_i2c_probe: created i2c device /dev/i2c-8
[314374.148354] i2c-ch341-usb 1-1.1.1:1.0: ch341_i2c_set_speed: Change i2c bus speed to 100 kbps
[314374.149365] i2c-ch341-usb 1-1.1.1:1.0: ch341_usb_probe: connected
Showing our 8 pins plus the i2c-8
device running at 100khz.
I was able to do a simple test with i2cdetect 8
. (You can get it from i2c-tools).
You can download my i2cdetect test raw .logicdata or a csv.
I did a simple test with while true; do echo 1 > /sys/class/gpio/gpio0/value; echo 0 > /sys/class/gpio/gpio0/value; done
, and the example gpio_output.c
file, both were able to toggle the GPIO at average 10khz.
You can download my gpio test raw .logicdata or a csv.
SPI
For the spi device, you need also to load the device module called spidev, sudo modprove spidev
. Now with the driver loaded, you should just compile and load the spi module.
[315818.960403] usb 1-1.1.1: USB disconnect, device number 117
[315819.771286] usbcore: registered new interface driver spi-ch341-usb
[315824.287292] usb 1-1.1.1: new full-speed USB device number 118 using xhci_hcd
[315824.381352] usb 1-1.1.1: New USB device found, idVendor=1a86, idProduct=5512, bcdDevice= 3.04
[315824.381358] usb 1-1.1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[315824.391008] spi-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: output cs0 SPI slave with cs=0
[315824.391013] spi-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: output cs1 SPI slave with cs=1
[315824.391016] spi-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: output cs2 SPI slave with cs=2
[315824.391020] spi-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: input gpio4 gpio=0 irq=0 (hwirq)
[315824.391023] spi-ch341-usb 1-1.1.1:1.0: ch341_cfg_probe: input gpio5 gpio=1 irq=1
[315824.391028] spi-ch341-usb 1-1.1.1:1.0: ch341_spi_probe: SPI master connected to SPI bus 0
[315824.391307] spi-ch341-usb 1-1.1.1:1.0: ch341_spi_probe: SPI device /dev/spidev0.0 created
[315824.391645] spi-ch341-usb 1-1.1.1:1.0: ch341_spi_probe: SPI device /dev/spidev0.1 created
[315824.391981] spi-ch341-usb 1-1.1.1:1.0: ch341_spi_probe: SPI device /dev/spidev0.2 created
[315824.392423] spi-ch341-usb 1-1.1.1:1.0: ch341_usb_probe: connected
The SPI was running with 1.5MHz, the tests was done with python-spidev.
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
to_send = []
for i in range(30):
to_send += [i]
spi.xfer(to_send)
More than 30 bytes will give:
Traceback (most recent call last):
File "test.py", line 7, in <module>
spi.xfer(to_send)
TimeoutError: [Errno 110] Connection timed out
I'm not sure why.
You can download my spi test raw .logicdata or a csv.
Final
Yes, I give a positive vote in this device, everything appears to be working with the correct kernel modules. I don't have time right now to test with real devices/sensors, but everything shows that will work, I'll try to update this subject in the future.