Silabs CP2104 USB UART modules

Posted at 2015-04-27.

There are several Silabs CP21xx based modules available from Chinese shops. I think these work far better than Prolific based modules and far cheaper than FTDI. CP2104 seems to be the nicest one around.

Cnewtec board

CP2104 USB module back and front
CP2104 USB module

I bought a bag of these. They are practically cheap enough to leave in projects or bag with prewired cables for certain devices. A five-pin cable is included (separate pins).

There are pins on board for DTR, 5V (via resistor from USB), 3.3 V (chip contains a regulator), TxD/RxD, and ground. There are also holes labeled RI, DCD, DSR, RTS, CTS, SPD, RST, SPD/ and IO0-IO3. Most names match EIA-232 signals. SPD and SPD/ Seem to connect to Suspend and Suspend. It looks like DTR has a series cap.

According to the datasheet, TxD should indeed transmit and RxD receive data as it should be. Sometimes the pins are labeled backwards probably to indicate what they should be connected to. This may even lead to broken parts as some chips can't handle their transmit pins being pulled up/down by other circuits. Tracing the board, it seems these are taken to pins with matching labels. Looking at the TxD pin with a scope should confirm this.

Some projets (microcontrollers) would also be happier with 3V3 signals and many modules use 5V signals. On CP2104, connection to the Vio pin (5) determines the voltage. The connection is not quite visible on the boards, but Vdd seems very temptingly close. Only 5V connection to the chip seems to be going to the Regin pin. Measuring the pin and TxD or handshake signals should confirm this.

Update: These seem to work well as Propeller programmer/interface.

Linux driver

usb 2-1.2: new full-speed USB device number 10 using ehci-pci
usb 2-1.2: New USB device found, idVendor=10c4, idProduct=ea60
usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 2-1.2: Product: CP2104 USB to UART Bridge Controller
usb 2-1.2: Manufacturer: Silicon Labs
usb 2-1.2: SerialNumber: 00BE674B
usbcore: registered new interface driver usbserial
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver cp210x
usbserial: USB Serial support registered for cp210x
cp210x 2-1.2:1.0: cp210x converter detected
usb 2-1.2: reset full-speed USB device number 10 using ehci-pci
usb 2-1.2: cp210x converter now attached to ttyUSB0

Works out of the box on Debian Jessie (amd64), and probably every other GPOS out there. It's easy enough to use udev rules to set device name and permissions if you like.

Connecting with picocom does send a low pulse to DTR. Disconnecting sends a high pulse to DTR. So, the actual DTR seems to idle high and go low on connect and there is indeed a series cap. Sending data does cause TxD to pulse down from 3.3 V (or so) and probing RxD seems to generate noise characters in the tty. Sending a break (^A^\ in picocom) will be a distinct blip.

I poked around with pyserial as well. Getter functions show changes when pulling down pins, as they should. Setters toggle pins (or pulse DTR).

% ipython3 
Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
Type "copyright", "credits" or "license" for more information.

IPython 2.3.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import serial
In [2]: s = serial.Serial('/dev/ttyUSB0')
In [3]: # Listen to noise
Out[3]: b'\xff'

In [13]: s.getDSR()
Out[13]: False

In [14]: s.getDSR() # Data Set Ready
Out[14]: True

In [16]: s.getDSR()
Out[16]: False

In [18]: s.getRI() # Ring indicator
Out[18]: True

In [19]: s.getRI()
Out[19]: False

In [22]: s.getCD() # DCD is Data Carrier Detect
Out[22]: True

In [23]: s.getCD()
Out[23]: False

In [31]: s.setRTS(True)

In [32]: s.setRTS(False)

In [28]: s.setDTR(True)

In [29]: s.setDTR(False)

In [68]: s.write(b'asdfasdfasdfasdf')
Out[68]: 16

Looking around Linux 3.16 cp210x.c, it says 2104 should try to clock to requested rates. Feeding 31250 to the formulas gives an exact 31250 back, so it looks like this thing could actually talk MIDI. (See datasheet section 6.1.)

There seem to have been some efforts to get GPIO support in, but I don't think anyone has made it in clearly. This kind of mixed device is a bit odd, of course.