In USB Complete, Jan Axelson once again reveals the programming secrets for a popular interface. The topic this time is the new Universal Serial Bus (USB), which was designed from the ground up to provide a single, easy-to-use interface for multiple peripherals. But this ease of use has come at the cost of greater complexity for the developers who design USB peripherals and write the program code that communicates with them.
Axelson takes the pain out of designing for USB by showing how to write applications that communicate with USB devices using Visual Basic (or any programming language that can call Win32 API functions). There's no need to write low-level device drivers; you can use the drivers included with Windows 98/2000.
Unlike other books that only rehash specifications and manufacturers' marketing materials, this book has original examples, hands-on guidance, and practical tips that developers can put to use right away. USB Complete is an independent guide that isn't obligated to promote one manufacturer's products.
This book will help you decide whether or not USB is the right choice for a peripheral. You'll find tips on selecting the controller chip that matches your design's needs and enables you to get your peripheral up and running quickly. An example project shows how to develop a custom USB peripheral from start to finish, including device firmware and application programming.
As in her previous best-selling Serial Port Complete and Parallel Port Complete, Axelson's simple, direct style and attention to detail help make a complex topic understandable.
|Publisher:||Lakeview Research, LLC|
|Edition description:||BK&CD ROM|
|Product dimensions:||7.02(w) x 8.91(h) x 0.90(d)|
About the Author
Jan Axelson is the author of Parallel Port Complete, Serial Port Complete, The Microcontroller Idea Book, and Making Printed Circuit Boards. Bill Machrone of PC Magazine has described Jan's writing as "a model of clarity and conciseness."
Read an Excerpt
The Host's Duties...The host PC is in charge of the bus. The host has to know what devices are on the bus and the capabilities of each. The host must also do its best to ensure that all devices on the bus can send and receive data as needed. A bus may have many devices, each with different requirements, and all wanting to transfer data at the same time. The host's job is not trivial!
Fortunately, the host controller's hardware and the USB support in Windows do much of the work of managing the bus. Each USB device attached to the host must have a device driver, which is a software component that enables applications to communicate with the device. Some peripherals can use device drivers included with Windows, while others require custom drivers. Other system-level software components manage communications between the device driver and the host controller.
Applications don't have to worry about the details of USB communications. All they have to do is send and receive data using standard operating-system functions that are accessible from just about all programming languages.
These are tasks that the host performs with little or no support required from applications:
Detect DevicesOn power-up, the hubs make the host aware of all attached USB devices. In a process called enumeration, the host assigns an address and requests additional information from each device. After power-up, whenever a device is removed or attached, the host learns of the event and enumerates any newly attached device and removes any detached device from the devices available to applications.
Manage Data FlowThe host manages the flow of data on the bus. Multiple peripherals may want to transfer data at the same time. The host controller handles this by dividing the data path into 1-millisecond frames and giving each transmission a portion of each frame.
Transfers that must occur at specific rate are guaranteed to have the amount of time they need in each frame. During enumeration, a device's driver requests the bandwidth it will need for transfers that must have guaranteed timing. If the bandwidth isn't available, the host doesn't allow communications with the device. The driver can then request a smaller portion of the bandwidth, or wait until the requested bandwidth is available. Transfers that have no guaranteed rate use the remaining portion of the frames, and may have to wait.
Error CheckingThe host also has error-checking duties. It adds error-checking bits to the data it sends. When a device receives data, it can perform calculations on the data and compare the results with the received error-checking bits. If the results don't match, the device doesn't acknowledge receiving the data and the host knows that it should retransmit. (USB also supports one transfer type that doesn't allow re-transmitting, in the interest of maintaining a constant transfer rate.) In a similar way, the host may error-check the data it receives from devices.
The host may receive other error indicators that indicate that a device can't send or receive data. The host can then inform the device's driver of the problem, and the driver can notify the application so it can take appropriate action.
Provide PowerIn addition to its two signal wires, a USB cable has +5V and ground wires. Some peripherals can draw all of their power from these lines. The host provides power to all devices on power-up or attachment, and works with the devices to conserve power when possible. Each full-power, bus-powered device can draw up to 500 milliamperes. The ports on some battery-powered PCs and hubs support only low-power devices, which are limited to 100 milliamperes. A device may have its own power supply, using bus power only during the initial communications with the host.
Exchange Data with PeripheralsAll of the above tasks support the host's main job, which is to exchange data with peripherals. In some cases, a device driver requests the host to poll a peripheral continuously at a requested rate, while in others the host communicates only when an application or other software component requests it. The device driver reports any problems to the appropriate application.
The Peripheral's DutiesIn many ways, the peripheral's, or device's, duties are a mirror image of the host's. When the host initiates communications, the peripheral must respond. However, the peripheral also has duties that are unique.
A device can't begin USB communications on its own. Instead, it must wait and respond to a communication from the host. (An exception is the remote wakeup feature, which enables a device to request a communication from the host.)
The USB controller in the device handles many of the USB's duties automatically. The amount of support required in the device's program code varies with the chip.
Detect Communications Directed to the ChipEach device monitors the device address in each communication on the bus. If the address doesn't match the device's stored address, the device knows it should ignore the communication. If the address does match, the device stores the data in its receive buffer and generates an interrupt to signal that data has arrived. In almost all chips, this is automatic; it's built into the hardware. The device's program code doesn't have to take action or make decisions until the chip has detected a communication containing its address.
Respond to Standard RequestsOn power-up, or when the device attaches to a powered system, the device must respond to the requests made by the host in the enumeration process.
All USB devices must respond to the eleven standard request codes that query the capabilities and status of the device and select a configuration. On receiving a request, the device places the information to send in response in its transmit buffer. In some cases, such as setting an address or configuration, the device takes other action in addition to responding with information.
The device doesn't have to carry out every request, however; it just has to respond to the request in an understandable way. For example, when the host requests to use a configuration that the device doesn't support, the device responds with an indicator that the request is unsupported.
Error CheckLike the host, the device adds error-checking bits to the data it sends. On receiving data that includes error-checking bits, the device does the error-checking calculations and (with some exceptions) may request a retransmit if it detects an error. These functions built into the hardware and don't need to be programmed. When appropriate, the device also detects the acknowledgements that the host sends in reply to data it has received.
Manage PowerIf the device isn't bus-powered, it must have its own power supply. When there is no bus activity, the device must enter its low-power Suspend state, while continuing to monitor the bus, exiting the Suspend state when bus activity resumes.
When the host enters a low-power state, such as Windows 98's Standby state, all communications on the bus cease, including the timing markers the host normally sends each millisecond. When the devices that connect to the bus detect the absence of bus activity for three milliseconds, they must enter the Suspend state and limit the current they draw from the bus. A host may also request to suspend communications with a specific device. When bus activity resumes, the device must exit its Suspend state.
Devices that don't support the remote-wakeup feature can consume no more than 500 microamperes from the bus in the Suspend state. With the remote-wakeup feature available and enabled by the host, the limit is 2.5 milliamperes. These are average values over a 1 second; the peak current can be greater.
Exchange Data with the HostAll of the above tasks support the main job of the device's USB port, which is to exchange data with the host. After the device is configured, it must respond to requests to send and receive data. The host may poll the device at regular intervals or only when an application requests to communicate with it. The device's configuration, the host's device driver, and the applications that use the device together determine what type of requests the host makes and how often it makes them.
For most transfer types, the device must respond to each poll by sending an acknowledge code (ACK) that indicates that it received the data, or a negative acknowledge (NAK) to indicate that it's too busy to handle the data. The device's hardware sends the appropriate response automatically. Some transfers don't use acknowledgements and the host just assumes that the device has received all transmitted data.
The controller chip's hardware handles the details of formatting the data for the bus. This includes adding error-checking bits to data to transmit, checking for errors in received data, and sending and receiving the individual bits on the bus.
Of course, the device must also do anything else it's responsible for. For example, a mouse must always be ready to detect movement and mouse clicks, a data-acquisition unit has to read the data from its sensors, and a printer must translate received data into images on paper....
Table of Contents
- 1: A Fresh Start
- 2: Is USB Right for My Project?
- 3: Inside USB Transfers
- 4: A Transfer Type for Every Purpose
- 5: Enumeration: How the Host Learns about Devices
- 6: Control Transfers: Structured Requests for Critical Data
- 7: Chip Choices
- 8: Inside a USB Controller: the Cypress CY7C63001
- 9: Writing Firmware: the Cypress CY7C63001
- 10: How the Host Communicates
- 11: How Windows Selects a Driver
- 12: Human Interface Devices: Firmware Basics
- 13: Human Interface Devices: Reports
- 14: Human Interface Devices: Host Applications
- 15: Device Testing
- 16: Hubs: the Link between Devices and the Host
- 17: Managing Power
- 18: The Electrical Interface
- 19: Signals and Encoding
- Appendix A: Resources
- Appendix B: Cypress CY7C63001 Registers
- 2: Is USB Right for My Project?