CMP EMBEDDED.COM

Login | Register     Welcome Guest ESC Boston  esc india  Call for Abstracts
 




Understanding Universal Serial Bus: Part 2

John Canosa

In the second part of this USB tutorial, John Canosa presents several USB peripheral controllers and investigates issues you must address to implement this new standard. In last month's installment of this two-part series, we looked at the Universal Serial Bus (USB) specification and how it relates to an embedded systems developer designing a USB peripheral. This month we'll look at some of the silicon that's available in the form of USB peripheral cores, microcontrollers, and standalone USB microprocessor peripherals. We'll also examine some of the issues regarding USB bandwidth and data throughput.

USB Peripheral Controllers

Real-world controllers designed for USB peripherals truly run the gamut with regard to performance. At the high end are devices such as the Motorola MPC823, which sports a single issue PowerPC core along with a communications coprocessor that supports USB. For those of you who don't require quite as much horsepower, there are several vendors of 8-bit microprocessors, such as Intel's 82930A and Mitsubishi's M376xx, that have a built-in USB interface. For new designs that integrate systems on a chip, USB cores are available from companies such as NEC and Virtual Chips. And finally, for those of you who are quite happy with your current microprocessor but want to add USB support to your product, there are standalone USB controllers such as the ScanLogic SL11-USB, which you can treat like a sophisticated UART or, more accurately, like a SCSI device controller. Table 1 lists some available controllers for USB peripherals.

Regardless of the approach taken, most of the devices have a similar look and feel when it comes to configuring the USB controller and sending or receiving data. For configuration purposes, a few general control/status registers typically contain such items as interrupt status and enables, a USB address register, and registers to enable and disable the USB ports, send a wake-up signal, and so forth. Typically you'll find one or more general status registers that indicate such things as receipt of a Start of Frame (and the SOF count), and detection of a USB reset condition or suspend state.

For example, Table 2 shows that the SL11 contains five 8-bit registers and two 16-bit registers pertaining to the overall configuration of its USB controller. The control register contains a USB enable bit and a DMA enable bit. The interrupt enable register allows the controller to generate an interrupt when an endpoint data transaction is complete, when DMA transfer has started or ended, when an SOF packet is received, or when a USB reset occurs. The interrupt status register shows the status of the aforementioned interrupt conditions. The USB address register contains the peripheral address that is assigned by the host. A word of caution here: while the SL11 automatically updates this register upon receipt of a SET_ADDRESS request, some USB controllers do not, and the application software must update the address.

The final three USB registers in the SL11 are: the current data set register, which contains the status of the data toggle synchronization status for each endpoint; the SOF register, which contains the 11-bit SOF count that is delivered by the host; and the DMA count register, which contains the number of bytes to be transferred via DMA.

The number of endpoints supported by the various controllers range from four to eight. Each endpoint usually has its own configuration register or registers. These registers contain information such as the endpoint number, direction, type (control, isochronous, bulk, or interrupt), data sequence numbers, and the capability to send a stall or a NAK. In the ScanLogic SL11 example, five registers are associated with each endpoint, as shown in Table 3.

The endpoint control register contains the expected arm, enable, direction, and similar entries. The base address register points to the memory buffer location for reads and writes. The base length register contains the MaxPacketSize information for that particular endpoint. The packet status register contains such information as ACK received, transmission errors, time-outs detected, and overflow conditions.

Data movement between memory and the USB is typically accomplished in one of two ways. Some devices, such as the Intel part, use FIFOs to buffer the data, while others allow the user to set up DMA channels to and from endpoints. Intel's 82930A has four transmit FIFOs and four receive FIFOs. Each FIFO is 16 bytes deep, with the exception of the FIFOs corresponding to Endpoint 1, which have a depth of 256 bytes. FIFOs are the typical transfer mechanism for the 8-bit integrated microprocessor/USB controllers and synthesizable cores, which may not have a DMA controller available in the design.

In contrast, both the MPC823 and the SL-11 use DMA to transfer data. As an example, the MPC823 uses its communications processor module (CPM) as the USB interface and the DMA controller. Those who are familiar with the other members of Motorola's MPC8xx family or the MC683xx family will recognize the buffer descriptors (BDs) that are used by the DMA engine to move data between memory and the USB transmit and receive buffers. Don't confuse the term "buffer descriptor" with "descriptor" as defined by the USB specification; it's just an unfortunate conflict of terminology.

Each endpoint has one or more buffer descriptors associated with it. Figure 1 shows the format of a transmit buffer descriptor, which would be associated with an endpoint defined as an IN endpoint in the endpoint descriptor. The transmit buffer descriptor consists of a status word, the number of bytes to be transmitted, and a pointer to the region in memory that contains the actual data to be transmitted.

The status word is a bitfield consisting of the following information:

R: Ready
0: Data buffer pointed to by this BD isn't ready for transmission
1: Data buffer is ready for transmission or is currently being transmitted; the CPM clears this bit when transmission is complete
W: Wrap
0: This is not the last BD in the Tx BD table; buffers may be chained so that when the transmission of this buffer is complete, the CPM will automatically move on to the next BD in memory
1: This is the last BD in the BD table
I: Interrupt
0: Do not interrupt after this BD has been serviced
1: Generate an interrupt after this BD has been serviced
L: Last
0: This buffer does not contain the last character of the message
1: This buffer contains the last character of the message
0: Only transmit end of packet (EOP) after last data byte
1: Transmit CRC after the last data byte, then transmit EOP. Unless used for testing, this bit should always be set to one. This field is ignored if the L bit is cleared
PID: Packet ID
0X: Do not append PID to the data
10: Transmit DATA0 PID before sending data
11: Transmit DATA1 PID before sending data
TO: Timeout; written by the CPM if the host failed to acknowledge this packet
UN: Underrun; written by the CPM if an underrun condition is detected during transmission

The typical procedure for setting up a USB transmission by this endpoint would be to prepare the actual data and place it into memory, then write the address of the buffer in the TX_DATA_BUFFER_POINTER, along with the DATA_LENGTH value. Next, all bits of the status register, with the exception of the ready bit should be set to their desired values. Finally, set the ready bit to enable transmission. The next time this particular endpoint is accessed by the host, the data will be transmitted and an interrupt will be generated (if enabled) upon completion of the transmission.
A receive buffer descriptor (Figure 2) contains a status word, the count of the data received (in bytes) and a pointer to the memory buffer containing the data. The status word contains a bitfield with the following structure:

E: Empty
0: The data buffer has been filled by the CPM or data reception has been aborted due to an error
1: The data buffer is empty
W: Wrap
0: Not the last BD in the Rx BD table
1: Last BD in the BD table
I: Interrupt
0: No interrupt is generated when this BD is filled
1: Generate an interrupt when this BD is marked not Empty
L: Last
0: Buffer does not contain the last character of the packet
1: Buffer contains the last character of the packet; either an EOP has been received or an error has been detected
F: First
0: Buffer does not contain the first byte of a packet
1: Buffer contains the first byte of a packet
PID: Packet ID; valid only if the F bit is set
00: Buffer contains a DATA0 packet
01: Buffer contains a DATA1 packet
10: Buffer contains a SETUP packet
NO: Error indicating that a number of bits not divisible by eight was received
AB: Frame aborted; bit stuff error occurred during reception
CR: CRC error; the received CRC bytes are always written to the receive buffer
OV: Overrun; a receiver overrun occurred during reception

Setting up an OUT endpoint (which receives data) buffer descriptor involves allocating memory for the buffer and writing the pointer and size into the appropriate BD fields. Subsequently, the status fields can be filled in and the empty bit set. When the empty bit is read as a zero and/or an interrupt has been generated, the receive buffer data can be examined and acted upon.

As I've mentioned, the previous examples are representative of a typical USB interface. Some of the terminology of the registers and status bits may differ, but they should have similar functionality. The main differences will be in dealing with DMA or FIFOs. In either case, however, the idea is the sameŭset up receive and transmit buffers, and move data between them and the USB controller in the proscribed method, either configuring a DMA operation or writing/reading data to/from the endpoint's FIFO.

Device Side Software

On the surface, design of a USB peripheral's software seems simple. You must have the descriptors defined, stored in memory, and ready for transmission. Once the device is configured, it's a matter of feeding or emptying FIFOs or keeping the DMA controller ready for the next USB transaction. Of course, the design isn't always as simple as it seems.

A USB device-side application consists of four parts: USB communications handling, USB control command parsing and execution, application data transmission and reception, and error handling.

Communications and Application-Specific Data Transmission

One key area to understand regarding USB is the data buffering system. Buffering requirements are different for each type of transaction. Interrupt transactions are guaranteed to occur at intervals of 1ms, or an integer multiple thereof, and the amount of data transmitted is limited to 64 bytes. A buffer or FIFO size equal to the amount of one data packet will be sufficient. Once the data is transmitted from the FIFO, the software has a little under a millisecond (at least) to refill it. For most microprocessors, this shouldn't be a problem. As a precaution, the software should program the USB controller to send a NAK if the FIFO does not have a complete packet to transmit.

Isochronous endpoints can be a little more complicated. For example, let's say the device in question is a set of stereo speakers that want to drive their D/A converters at a 44.1KHz rate. How big should the input FIFO be? In this case, we have a 1KHz USB frame rate and a 44.1KHz sample rate. The 44.1KHz isn't an integral multiple of 1KHz, so the number of bytes transmitted per frame will vary. We must also consider the buffer latency-isochronous data sinks can't start consuming data received in a frame until the SOF of the next frame is received. From this restriction alone we see that the buffer size must be greater than maximum packet size expected. A quick calculation can give us a rough idea of the buffer size required.

We could transmit 44 samples (at four bytes per sample) per frame (every tenth frame will contain 45 samples to get to 44.1 KHz, but we will ignore that for now). Because we know that we cannot consume any data until the next SOF, after the first frame there will be 44 x 4 = 176 bytes in the FIFO. Once the next SOF arrives, we can start consuming data at our desired rate of 44.1K samples per second, which is equal to 176.4KBps. However, during that time we will also be filling the FIFO with the next USB frame's data at a 1.5MBps rate. This situation is shown in Figure 3. The isochronous filling of the FIFO can be described with the following equation:

F = 1.5E6 * T 0 < T < 1.7333ms
= 0 T > 1.7333ms
where F is the number of bytes added to the FIFO and T = t ŭ nT, with t = time (in seconds), T = the USB frame rate (1ms), and n = 0,1,2,3ŭ
The number 1.7333ms simply comes from the time it takes to write 176 bytes (44 samples) to the FIFO over the USB. Notice that we are ignoring any packet overhead and assuming that the isochronous transfer starts at the very beginning of the frame, which is the worst case.

At the same time the filling of the FIFO is occurring, we are pulling data from it through the other port. The rate we are emptying the FIFO is simply:
E = 0 t < 1ms
E = 176,400 * (t ŭ 1ms) t > 1ms

Therefore, the total number of bytes in the FIFO is:
B = B + F , E
where B is the number of bytes in the FIFO. With the FIFO initially empty (B = 0), after the first millisecond we can confirm that we have 176 bytes in the FIFO. The maximum number of bytes in the FIFO will occur during the second frame, because the second set of samples is being transmitted over the USB while the device has just started removing data from the first transaction. In this case, the maximum works out to be 332 bytes, a little under twice the packet size. Therefore, the buffer should be at least two times the amount of data that will be transmitted per frame. One word of caution: don't forget that every tenth frame has an extra four bytes associated with it.

The USB specification suggests that bulk transfers normally require a buffer the size of a transmitted packet (64 bytes maximum for bulk transfers). This is true for devices that are happy with transmitting data only once per frame for a total 64KBps transfer rate. For devices that need to transmit large amounts of error-free data, such as a scanner or digital camera, that transfer rate is too slow. If an application running on the host requests a large amount of data, multiple bulk transactions involving the same endpoint could occur in a single frame. In fact, devices such as scanners rely on multiple transactions during a frameŭit's the only way to get close to their desired transfer rates of around 1MBps.

Consider a digital camera that uses 64-byte packets. Table 5-6 of the USB specification indicates the theoretical maximum throughput is 1.216MBps for 64-byte packets.1 This calculation is theoretical; it assumes no other activity on the bus and that the data is such that no bit stuffing is required-hardly a likely scenario. John Garney's "An Analysis of Throughput Characteristics of Universal Serial Bus" has a more realistic set of calculations regarding USB bandwidth.2

However, our intent is to determine the amount of buffering required on the device side. The key is to determine how much time we have between transactions to fill up a 64-byte FIFO. If we assume back-to-back transactions, the time between the last data byte of the previous transaction being transferred and the requirement for the first data byte of the current transaction to be ready is easily calculated:

16-bit CRC of previous
2-bit EOP time
8-bit ACK handshake sync pattern
8-bit ACK packet
2-bit EOP time
8-bit IN token sync pattern
24-bits IN token packet
2 EOP times
8-bit DATA packet sync pattern
+ 8-bit DATA token
__________________________
88-bit times or 7.3ms
(We are ignoring any turnaround and cable delay times)

Note that this calculation assumes an interrupt would be generated immediately after transmission of the last data byte of the previous packet. In reality, the interrupt is most likely generated after receiving the handshake packet, which is the true indication that the transaction is complete.

Just for reference, to get the total transaction time to send an entire 64-byte packet, add 64*8 bit times to the overhead calculated above, and you'll get 50ms. In either case, it's not a lot of time to be handling an interrupt and then filling up a buffer. If the buffer isn't ready for the next transaction, a NAK must be sent. If this is a common occurrence, our throughput can be severely affected. If we are using 64-byte data packets, sending one NAK between every data transmission will cut our throughput by almost 10%.

When trying to achieve maximum performance, the buffer or FIFO used should obviously be at least twice the size of the data packets. Another solution is to have multiple buffers, so that one may be filled while the other is being transmitted. In fact, having two separate buffers maps nicely into the DATA0 and DATA1 synchronization scheme of USB. One buffer could be defined as the DATA0 buffer and the other would be the DATA1 buffer.

Most controllers allow the user to set up a buffer while another is being transmitted. The ScanLogic SL11, for example, has two buffers. Switching between the buffers is a matter of changing a bit setting in the current data set register. The Intel 82930A is similar in that it lets the user identify two distinct data sets within a single transmit FIFO. The controller will automatically select which data set to transmit, depending on the state of the FIFO. While reading from the proper transmit FIFO data set is automatic, writing to the proper data set is not and must be monitored by the software.

The Motorola MPC823 is a little more sophisticated, allowing the use of many buffers. The software designer could arrange these buffers in a circular queue, with an interrupt generated when each of the buffers is available to be filled. This arrangement could allow the processor to fill up the buffers at a more leisurely rate at the expense of making it more difficult to keep track of which buffer is transmitting DATA0 or DATA1 packets.

Interrupt Service Routines

The preceding discussion on buffering makes it clear that for high performance devices the ISRs of a USB controller must be quick. To reiterate, all USB controller interfaces present a similar software interface, so a discussion of interrupt service routines can look at a specific processor and still be relevant to other devices. In this case, we'll look at the Intel 82930A in a hypothetical scanner application.

In talking about the ISRs, we need to differentiate between two types. The first type is an interrupt that requires the software to initiate a data transfer, while the second is an interrupt signifying that a packet transmission is complete. If the amount of data required to be transmitted is large, such as a scanned image or a digital camera image file, multiple instances of the second type of interrupt will occur for every one of the first type.

We will assume that the USB controller has been configured and that we will be using Endpoint 1 (which has a 256-byte FIFO) in the bulk transfer mode with a maximum data size of 64 bytes. We will also assume that the host application has issued a scan command on some other pipe and that it is waiting for data. In this case, the application has registered an IRP with the USB system software, which is sending out IN packets to our bulk endpoint. While our device is scanning and processing the scanned data, we have set the endpoint to reply with NAKs whenever it is contacted. We achieve this by clearing the TX_OE bit in the endpoint control register (EPCON1). To minimize memory usage, our scanned data will be stored in a circular queue of 64-byte buffers. This way we can perform any image processing on the data in chunks, without requiring storage for both the entire scanned image and the processed image.

Once the buffer queue is full and ready for transmission, our application generates an interrupt that indicates that fact. The ISR then takes over. The first step is to verify that the FIFO is ready to accept data; if not, we need to notify the calling task and return from the interrupt. If there is room available, we can write to the FIFO and take the following steps:

Write 64 bytes to the FIFO
Check the overflow bit (OVF) in the transmit FIFO flag (TXFLG1) register. If it's set, we have an error condition and should set the STL_TX bit in EPCON1. This setting will cause the handshake to a STALL condition and notify the host of a problem. If there was no overflow, we simply write the byte count to the TXCNT1 register
Next, we should increment our read pointer in the buffer queue. We should not mark the buffer we just wrote as available yet, as there may be an error in the transmission and the data may need to be resent
Because there is much more data to transmit, we'd like to set up the second data set in the FIFO before we enable transmission. First, check the FIFO index flags to make sure the second data set is available; if it is not, there is an error (we made sure the FIFO was empty before we started). If there is room, we write the next 64 bytes and the bytecount and increment the pointer in our circular queue
Now that we have both data sets in the FIFO, we can enable the transmission by setting the TX_OE bit in EPCON1 and returning from our ISR
Note that with the 82930A, we have no control over the data sequence number (DATA0, DATA1). The data sequence number is based on the data set from the FIFO that the transmitter is using. Once the serial interface unit (SIU) completes transmission (successfully or unsuccessfully), an interrupt is generated. The ISR for this interrupt should perform the following tasks:
Because the transmit interrupt can be triggered by any endpoint, we first verify that Endpoint 1 caused the interrupt; if not, we pass on to the appropriate endpoint ISR
Read and clear the status from TXSTAT1 and clear the interrupt bits
If the ACK bit is set, the transmission completed without errors. We can advance the FIFO read marker (which starts transmission of the next data set), fill the FIFO with the next buffer from the queue, advance the queue pointer, and mark the buffer whose data we just transmitted as available
If the ACK is not set, then an error occurred. If the error was not a FIFO underrun (URF = 0), then it was a USB error and we need to retransmit the data. We accomplish this by setting the REV_RP bit in TXCON1. This setting tells the SIU to retransmit the data that is still in the original data set of the FIFO without incrementing the USB sequence number
If there was a FIFO underrun, there is a serious problem and we should notify the host
Many of the above interrupts will occur during the transmission of the file, so the key is to keep the buffers ready so that the ISRs will have data to move into the FIFO. Remember, this example is specific to the Intel part, but the general principles will be the same no matter what USB controller is used.

USB Control Command Handling

When a device receives a SETUP transaction on the control endpoint (Endpoint 0), the application should be aware that an 8-byte command is following it. This command could be a request for data, a command with data associated with it, or a dataless command. It's the responsibility of the device software to parse the command, perform the required task, and generate a status response as shown in Figure 4. Of course, if the command is one that required the device to respond with data, such as a GET_DESCRIPTOR command, the flowchart in Figure 4 would not end with a zero length data packet, but with a packet containing at least a portion of the requested data. Error Handling
Not to sound paranoid, but potential sources of errors lurk everywhere. From noisy electronics to unsupported commands to application errors, a USB device should be able to handle errors with aplomb. The STALL handshake turns out to be a useful error handling tool. For example, if the host sends a SET_CONFIGURATION command with an invalid configuration number, the device should return a STALL. Another example would be if a device determines that there is a device error such as a paper jam, the device could return a STALL on the next USB transaction in which it participates. The host would then send the CLEAR_FEATURE - ENDPOINT STALL command and inquire as to the nature of the error. Because no true interrupts are defined for USB, this method would provide the host with the most immediate notification of an error. flexibly complex

Those who have done the null modem/gender changer/ 9-pin-to-25-pin adapter/RS-232 dance will appreciate what USB will do for serial communications. The plug-and-play aspects of USB make it extremely attractive to the average consumer and a godsend to those who have struggled through the alternatives.

The types of devices that will use USB include telephones, modems, keyboards, mice, 4x and 6x CD-ROM drives, joysticks, tape and floppy drives, scanners, digital cameras, and printers. USB's 12Mbps data rate will also accommodate a whole new generation of peripherals, including MPEG-2 video-based products, data gloves, and digitizers. Because computer/telephony/consumer integration is expected to be a big growth area for PCs, you can expect to see Integrated Services Digital Network (ISDN), ADSL, and digital PBXs, as well as a generation of products yet to be thought of.

As with most things electronic, with flexibility comes complexity, and USB was designed to be a very flexible bus. The software aspects of USB should not be underestimated, both on the device and host sides. On the device side, cost and time-to-market pressures combine to create some very software-intensive designs. These pressures, along with the USB specification, also place some demanding requirements on the device software, including code size, speed, and buffer size. Only a thorough knowledge of USB will allow a designer to deliver a product that meets all of those requirements.

While initial forecasts predicted that by early 1997 USB would be standard for all PCs shipped, that prediction has slipped a bit. As I mentioned before, Microsoft has been a bit late in releasing its new driver model and the associated class drivers and minidrivers. The current estimates are that USB will be ubiquitous in 1998. This slippage has merely prolonged the inevitable, but it does reinforce what most of us involved in embedded systems design have known for a while-software is critical.

John Canosa is a principal member of the technical staff at Questra Consulting, where he is responsible for designing and developing hardware and software for embedded designs.

References
1. Universal Serial Bus Specification, Rev. 1.0. Hillsboro, OR: USBIF, 1996.
2. www.intel.com/embedded: Garney, John, "An Analysis of Throughput Characteristics of Universal Serial Bus," Media and Interconnect Technology, Intel Architecture Labs. other sources
Anderson, Don. USB System Architecture. Reading, MA: Addison-Wesley, 1996.
Intel 82930A Universal Serial Bus Microcontroller User's Manual. Santa Clara, CA: Intel Corp., 1996.
Motorola MPC823 Specification. Austin, TX: Motorola Semiconductor Products Sector, 1997 (http://www. mot.com/SPS/ADC/pps/prod/eppc/mpc823.html). ScanLogic SL11 USB Controller Technical Reference. Bedford, MA: ScanLogic Corporation.
www.mindshare.com: USB Training Courses, Mindshare Inc. (719) 488-8990.
www.usb.org: The USB Implemen-ter's Forum Home Page. Source of information about the USB, including the specification and pointers to USB products, controllers, cores, and so on.

table1.
Manufacturer Device
USB Cores
CMD
Future
Technology Devices
LSI Logic
Sand Microelectronics
Technical Data Freeway
Vautomation Inc.
USB0676
EMCU USB ASIC
USB Function Core
USB Synthesizable Cores
Synthesizable USB Function Core
USB Synthesizable Cores
Peripheral Microcontrollers
8/16-Bit
Atmel
Cypress
Intel
Mitsubishi
Motorola
NEC
AT43351
CY7C63XX
82930AX
M37690 (Also available as ASIC core)
68HC05
PD789806Y
32-Bit
Motorola MPC823
Standalone Microprocessor Peripherals
Lucent
NetChip
ScanLogic
Thesys
USS620
NET2888
SL-11
TH6503

table 2. SL11 registers.

Register Name Address (Hex)
Control Register
Interrupt Enable Register
USB Address Register
Interrupt Status Register
Current Data Set Register
SOF Low Byte Register
SOF High Byte Register
DMA Total Count Low Register
DMA Total Count High Register
0x05
0x06
0x07
0x0D
0x0E
0x15
0x16
0x35
0x36

table 3 Endpoints and addresses.

Endpoint n Register Set Address
Endpoint n Control Register
Endpoint n Base Address
Endpoint n Base Length
Endpoint n Packet Status
Endpoint n Transfer Count
xx
xx+1
xx+2
xx+3
xx+4

Embedded.com Career Center
Ready to take that job and shove it?
SEARCH JOBS

Browse all jobs

SPONSOR
RECENT JOB POSTINGS




 :