I am using multiple channels on the CP2130. When I try to write data to one channel of the CP2130 and then switch the another channel, the data seems to get corrupted. What is wrong?
Answer
As part of the SPI protocol, the interface requires a chip select (CS) signal to enable each channel. The CP2130 supports up to 10 CS lines so that the host can communicate with multiple devices. In order to communicate with a specific device, the channel has to be initialized and then set to the activate state during the data transfer phase to enable the data interface. From the host perspective, enabling and sending data is accomplished via the application writing to the CP2130 host side libraries, which communicate to the USB stack. After the CP2130 GPIO has been initialized for the CS function, the typical host sequence of events to transmit data is shown in the pseudo code below:
Set_GPIO_Chip_Select(channel to set active)
CP2130_TransferWrite(data to be transferred and the number of bytes)
Set_GPIO_Chip_Select(channel to set inactive)
The CP2130_TransferWrite API call is a non-blocking function and will return when the data has been written to the USB stack. There is no handshaking when using this API and no indication when either the data has been written by the USB or the data has been written over the SPI bus to the device. As a result, there are several unknowns when operating in this mode:
1) The CP2130 uses bulk transfers to communicate the data. These transfers provide the ability to send large amounts of data, but are subject to latency due to USB loading and host scheduling.
2) Unpredictable host latency can cause transfers to take longer than expected.
Depending on the timing of the system and how much data is to be transferred, this sequence will perform with no errors. However, if multiple channels are being used and a subsequent data transfer is initiated prior to the other transfer completing, there may be data loss and a write timeout on the following transfer.
There are two other transfer types defined in AN792 called: CP213x_TransferReadSync and CP213x_TransferWriteRead. Both of these functions are blocking functions and won't return until the data has been completely transferred and the requested number of bytes have been read back from the device. Using these functions provide implicit handshaking and will alleviate the need to estimate timing as required by the CP2130_TransferWrite API call.
Can I implement a slider using the TouchXpress CPT devices?
Answer
The TouchXpress CPT112S device provides the capability to implement capacitive sense sliders (linear only). Up to 12 slider segments are supported using the CPT112S. If Wake on Prox is going to be supported, then the CPT112S can support 11 slider segments. Please check updated devices and revisions for additional slider support.
The length of the slider is dependent on the layout of the pads. In order to implement the slider functionality, be sure to provide enough sensitivity and overlap between the pads in order for the slider algorithm to determine valid transition points along the slider. Please see AN447 for a detailed description of the pad layout requirements. Application notes can be found on the Silicon Labs website (www.silabs.com/interface-appnotes).
Is there a way in Linux to fix the /dev/ttyUSBx assignment for a specific CP210x? When I have more than one plugged into a system, the /dev/ttyUSBx assignments get shuffled and this breaks scripts that I have written.
Answer
For starters, we need to understand that population of the /dev file system (devfs) in Linux is performed by the device manager. While there are many distributions of Linux covering mainframes to small embedded devices and everything in between, the most commonly used distributions, such as Debian, Ubuntu, Mint, Red Hat, Fedora, CentOS, Gentoo, and Arch all make use of the udev device manager.
One of udev's design goals is to dynamically create and remove /dev nodes as needed, a capability that is naturally a requirement for supporting plug-and-play device configuration. During boot time enumeration and any time a capable device is plugged in or removed, udev generates events, and these events can trigger the processing of rules.
The robust rules system in udev is one of its most powerful features. For example, a server with multiple network cards might be used to provide multiple streaming video feeds. If the server is brought down to replace a failed network adapter, the newly installed adapter might not be assigned the same network interface (e.g. eth1) on reboot, thus breaking a working firewall or port forwarding configuration. A properly written udev rule can fix this.
So, if a udev rule can be written to fix network interface assignments for different Ethernet cards in a server, it can certainly be used to assign a specific device node to a CP210x USB-to-serial bridge. In fact, the procedure is very similar to what is done with network interface cards.
First, we need to see which USB devices are plugged in with the lsusb command:
Notice, however, that there's not enough information here for us to determine which CP210x is which. We need a way to further query each CP210x, but, before we do that, we need to actually see which device nodes udev has already assigned. That's easy enough. We just need to list the contents of /dev and specifically look for ttyUSB nodes because this is the default name for USB-to-serial devices:
Finding more specific information about one of these CP210x bridges will take a bit of effort. We might need to scour the output of dmesg or one of the logs generated by various agents running under the Linux kernel to find more detailed information. Using lsusb in verbose mode is probably the most direct option, but the amount of data output, especially in a system with multiple USB devices, can be overwhelming. So, instead, we'll actually use one of udev's own administration tools to find what we need:
With this information handy, writing a specific udev rule to rename/renumber this particular CP210x bridge device is a simple matter. First, we need to edit (if it already exists) or create the file /etc/udev/rules.d/99-usb-serial.rules. Note that some on Linux distributions udev rules might reside in /etc/udev/rules (note the missing ".d"), so adjust the path accordingly. We'll then add the following line (make sure it is entered as a single line) to give the CP210x with the serial number attribute "00492F60" the device name ttySLAB0 each time it is plugged in:
Linux savvy readers might see this and say "Hey! You're not renaming ttyUSB0, you're only creating a symbolic link to it named ttySLAB0." Alas, this is correct. Current versions of the Linux kernel do not allow device nodes to be renamed and will output an error message like this...
...if the renaming option is used. This isn't ideal for purists who want to enforce fixed numbering of all CP210x bridges connected to a system and retain the customary ttyUSB device naming. It does, however, accomplish the desired goal of permitting scripts or other code written to communicate with a particular serial device connected to a CP210x to always access that device with the same name.
Interface Knowledge Base
What is the proper method to set the chip select (CS) lines and read/write data to the CP2130?
Slider implementation using the TouchXpress devices
Fixed tty device assignments in Linux using udev