Electronic Design

Migrate Your Serial Application To USB The Easy Way

By selecting a microcontroller with a native USB interface and using Windows CDC drivers, you can effectively emulate a legacy serial port.

The once tried and true COM port is missing in action. In its place, most new laptop computers carry a couple of USB ports. In fact, the USB bus was specifically designed to replace most, if not all, of the legacy ports once common to PCs.

Yet with so many USB-capable microcontrollers and interface devices available, the loss of a COM port needn't be a roadblock for embedded designers. Choosing the right tools and software solutions makes the migration path to USB simple.

The Hardware Patch: A strategy that initially might appeal to designers needing a quick fix for an old serial-port-based project is to adopt a sort of patch system. This can be achieved by adding a custom USB-to-UART converter device between the embedded controller's serial interface and the USB connector to the PC (Fig. 1). Such devices, which often come with custom drivers for the various operating systems supported, provide a complete emulation of a standard serial port.

This approach implies the need for a complete redesign of the embedded application board to make room for the new component(s), but it leaves the firmware and PC application unchanged. The added cost of a few dollars can sometimes be justified by removing the serial-port transceiver that's been rendered unnecessary. But then most of the potential benefits of adopting USB are lost.

In fact, while USB would allow much faster data transfers of up to 100 times the typical serial port (12 Mbits/s versus 115 kbits/s), the UART remains in use and constitutes the main bottleneck of the design. Also, the inflexible nature of most custom USB-to-UART interface devices doesn't allow for agile power management, which is a key feature in many embedded designs.

The Single-Chip Solutions: A better hardware option for migrating from serial to USB is to adopt a single-chip solution, selecting a microcontroller with a native USB interface, and developing a driver, ad hoc, to emulate a serial port (Fig. 2). From the hardware point of view, the single-chip solution appears very interesting:

  • The USB-capable microcontroller is often available for little extra cost, if any, over the general-purpose models.
  • The component count is decreased as the serial-port transceiver is removed and a direct link is made between the low-cost USB connector and the D+/D- pins of the new USB-capable microcontroller.
  • The board redesign cost and effort can be considerably minimized when the pinouts of the general-purpose and USB-capable microcontrollers are designed to be compatible.
  • Further cost reductions are possible by removing the power-supply adapter for those applications that can use the 5-V power supply provided by the USB bus itself.
  • The Software Interfaces: Once we choose the single-chip solution, though, we're confronted with the need to develop new PC drivers for the application, and possibly new firmware. Luckily, software developers have many options at their fingertips to minimize the design effort-offered in the form of reusable application interface classes.

    Probably the most common and best supported class of USB interfaces built into today's PC operating systems is the so-called Human Interface Device, often referred to as the HID class. All PCs need some form of human interface, such as a keyboard or a mouse. The connection for these devices has graduated from the serial or PS/2 ports to USB.

    HID is well supported by all operating systems, because the drivers come already bundled in each copy of the Windows, Linux, and MAC OS. Thus, it's a rather attractive option for designers who want to get small amounts of data to or from their embedded device without many complications.

    Unfortunately, the application programming interface (API) is nothing like the COM port interface. As a result, it becomes more problematic to migrate to an existing design, particularly when there's already complex application software written on the PC.

    Other standard classes of USB interfaces, such as the Printer Class and the Mass Storage Class, could be potential candidates to communicate with embedded devices. They suffer from the same problem, though-the unfamiliar interface and the necessity to develop new PC application software.

    Driver development requires a deep knowledge of the operating system's lower levels. In the case of Windows PCs, this implies familiarity with the Windows Driver Model, often called WDM. If this expertise isn't available-and most embedded control designers are not WDM experts-it may take months to develop just an initial working driver prototype.

    Fortunately, a class of interfaces available inside all of the most recent versions of Windows can come to our rescue. Microsoft originally developed this class, known as the USB Communications Device Class (CDC), to support modem applications. As an example, the full source code of the CDC interface is available for the PIC18F4550 family of flash, USB 8-bit microcontrollers. The CDC interface presents the following desirable characteristics:

  • A relatively small code footprint of 3 kbytes for the firmware library
  • A single-chip solution
  • Data-memory usage of approximately 50 bytes (excluding the data buffer)
  • Maximum throughput speed of about 80 kbytes/s
  • Data flow control handled entirely by the USB protocol (RS-232 XON/XOFF and hardware flow control aren't required).
  • Easy Firmware Migration: In the following scenario, we will assume that the original serial-port code was written in C language, and common C libraries were used to access an integrated UART peripheral. Given these conditions, here's the modifications required for the migration to CDC:

  • At the top of the main C file, replace a few #include commands that are specific to the serial port with the corresponding USB commands.
  • In the main function, add a call to the USB-CDC initialization code.
  • In the main loop, add a call to the USB background task.
  • Verify the application code to allow for cooperative multitasking with the USB background task.
  • Finally, supply the USB-CDC specific libraries to the linker to generate the final executable, and the flash chip will be programmed.

    In practice, this scenario demands that no function invoked by the application contains blocking loops. In other words, it should not be taking 100% of the processor's time, nor prevent the USB background task from executing. In return, all of the USB-specific control functions, interrupts, flags, and buffering mechanisms are taken care of by the CDC-class firmware background task, which keeps the details of the implementation away from the designer's eye. All that's exposed is a small set of functions designed to be very similar to the common serial-port libraries. A partial example list is presented in the table.

    Most readers will immediately recognize these functions and associate them with their common C library equivalents. In fact, puts and gets can be directly replaced with the CDC equivalents putsUSBUSART and getsUSBUSART. Additional implementation-specific functions could be available to support different string styles (null terminated versus fixed-size buffered) and storage types (RAM versus ROM string tables). Listing 1 illustrates the migration of the familiar HelloWorld program presenting its CDC-USB implementation.

    Time to Connect: It's now time to connect the application to a PC and see the Windows Plug and Play technology spring to action. After the initial enumeration phase, which is common to all USB applications (and detailed in the now famous Chapter 9 of the USB 2.0 specifications), a dialog box will pop up on the screen. It will alert the user that a new hardware device has been found and that it will need to be configured for the operating system to use.

    While the CDC drivers are already an integral part of the operating system, a few more pieces of information are still needed to help bind them with the newly "discovered" device. This also creates a port-specific "property page" in the Windows Hardware Manager that will enable the user to uninstall and/or reconfigure the port at a later time. A small plain-text file (with extension ".inf") helps in this phase of the installation, and it needs to be prepared (using a text editor) and supplied when demanded by the plug-and-play wizard. The code is shown in Listing 2.

    The example in Listing 2 can be used as a template and quickly customized. The file format is quite simple, and most Windows programmers will recognize it immediately. For those who don't, it will suffice to say that it consists of sections where the title is contained in squared brackets, each containing one parameter name or more in parameter-value pairs. Of the entire file, the user only will have to customize a few sections, including:

  • The \[Device List\] section, which contains, among other things, the company- and application-unique VID/PID code pair obtained (licensed) from the USB-IF.
  • The \[Strings\] section, which contains various strings and banners that will be used by the operating system in various dialog boxes during the Plug and Play phase and to identify the device in the Hardware Manager.
  • Of VIDs And PIDs: While the contents of the Manufacturer section and Strings section can be tweaked and modified at will by the designer, the VID and PID codes are serious business. The USB-IF has absolute authority (and responsibility) over the assignment of unique 16-bit VID codes to each manufacturer that wants to market and sell USB products. These codes are obtained via a licensing agreement and the payment of a one-time registration fee that, at the time of this writing, is set at $1500.

    Once a VID code is assigned, the licensee has 65,536 (16-bit) PID codes available to uniquely identify an equal number of distinct models of its creation. In other words, this is sort of a "once in a lifetime" event, and it can be easy to amortize the initial VID licensing cost.

    For pure development purposes, it's not necessary to proceed with the whole licensing process, because "development VID/PID pairs" are generally found in the various manufacturers' literature. To further encourage small business outfits, startups, consultants, and other very low-volume productions, some microcontroller manufacturers offer the option to sublicense (at no cost) individual VID/PID pairs.

    We Have COM: If all went well to this point, the Plug and Play mechanism has completed the installation, and a new serial port has appeared in the Hardware Manager. A name was automatically assigned to it, using the next sequential value available (i.e., COM3 will appear, assuming COM2 and COM1 were already installed). The user then can access the port using software that was written to access a real COMx port (e.g. the HyperTerminal program bundled in all distributions of Windows).

    Once connected, there will be no distinction in its functionality, if we ignore the increased communication speed that's an order or two of magnitude higher than the fastest serial port typically available on a PC. Visual Basic or C++ programs will be able to read and write to the new emulated COM port via the standard Windows OpenFile(), ReadFile() and WriteFile() application programming interface (API), with no changes required.

    Now that USB-capable, full-fledged flash microcontrollers are available, these single-chip solutions offer embedded-control designers the lowest cost and maximum flexibility. Through the use of CDC-class libraries, serial port emulation gives engineers the easiest migration path to faster USB communication and freedom from serial-port legacy, while removing the barriers of Windows development. By following these steps, embedded designers can quickly migrate from serial to USB, allowing them to focus 100% on their main area of expertise-the embedded application.

    Recommended Reading:

    1. "USB Specification Revision 2.0," USB Implementers Forum Inc., 2000.
    2. "USB Class Definitions for Communication Devices Version 1.1," USB Implementers Forum Inc., 1999.
    3. Rojvanit, Rawin, "AN956-Migrating Applications to USB from RS-232 UART with Minimal Impact on PC Software," 2004.
    4. Axelson, Jan, USB Complete, 3rd edition, Lakeview Research, 2005, ISBN# 1-931448-02-7.
    5. "PIC18F2455/2550/4455/4550 Data Sheet" (DS39632), Microchip Technology Inc., 2004.
    6. "USB Design Center," www.microchip.com/usb

    Hide comments


    • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

    Plain text

    • No HTML tags allowed.
    • Web page addresses and e-mail addresses turn into links automatically.
    • Lines and paragraphs break automatically.