The USB Differential

Embedded systems often need to communicate with other systems of some kind. In the past, RS232 was a popular choice for communication with other computers (PCs or other embedded systems like smart sensors). The hardware was cheap and plentiful. A lot of CPUs had built-in support for doing the serial conversion and if not, it was easy to bit bang an RS232 port at logic levels completely in software. A little extra hardware for level conversion and you were good to go.

But the sun is setting on serial ports. The motherboard I just installed has a serial port, but no connector for it. Most of the motherboards I looked at didn’t have one at all. I haven’t seen a laptop with a serial port in a long time.

There are a few reasons for this, and a few solutions. The first is that you can find USB to serial adapters that are robust and will work in nearly all cases that you would use a serial port. You can also find PCI cards that provide serial ports. So even though I have my motherboard serial port disabled (I was too lazy to mount the connector in my case), it didn’t matter because I have 2 PCI-based ports, and 9 (that’s right… 9) USB serial ports, most of which come from an Edgeport USB 8 port adapter (these show up on eBay regularly).

This is fine for you and me. But if you are delivering a piece of hardware to end users, it might be too much to expect them to have a slew of serial ports on their modern computer. The predominant choice now is USB. However, most people choose to essentially build in a USB to RS232 cab ***a***le – often in the form of the chips these cables use instead of an actual cable. There are many modules that offer this function, and they allow your embedded system to stay the same. I’ve used cheap no-name adapters from eBay and in production quantities I’ve used this little module.

If you are really worried about preserving your investment in RS232, you can even get a DB9 connector that has the cable built in.

However, these are halfway measures. Some CPUs are including USB support these days. And I am always surprised that more people are not bit banging USB. If you look around, some people are using the term “bit bang” to mean using a USB interface chip to provide discrete I/O. That’s not what I mean here. What I mean is using software in a microprocessor to convert a few general-purpose I/O pins into a USB port.

It isn’t as trivial as bit banging USB, but it can be done. Click here for one example. Click here for another.

One of the challenges to USB (and many other modern protocols) is that they are differential. I’ll talk more about that next time. In a bit banged RS232 implementation, the inputs and outputs are single ended (and often inverted):

for (bitcount=0;bitcount<7;bitcount++)
   SETBIT(PORTC,SERIAL_OUT_BIT, (byte & (1<<bitcount))?0:1);

With a differe ***a***ntial input (or output), two pins have to be in the opposite state which make it more complicated. For example:

   for (bitcount=0;bitcount<7;bitcount++)
       int state=(byte & (1<<bitcount))?0:1;
       SETBITS(PORTC, OUT_BIT_A, state, OUT_BIT_B, state?0:1);

I’ll talk next time about why differential encoding is a good thing. The extra processing does put more demand on the processor though. In addition, USB requires things like bit stuffing and timing for NRZI decoding. This article has a good overview of the issues encountered by a developer building a software USB stack.

I miss the days when I could count on serial ports that didn’t require me to mess with getting vendor IDs and worrying about driver support. But those days are nearly gone and we have to learn to move on to the new technologies.