Windows.  Viruses.  Notebooks.  Internet.  office.  Utilities.  Drivers

Good book, explains a lot. Useful for those who want to understand how data is transferred over the USB bus.

Introduction 1
Who is this book for: 2
What will you find in book 2
Software requirements 3
Hardware requirements 4
About code 4
Short description chapters 4
Notation 6
Thanks 7
PART I. INTRODUCTION TO USB 9
Chapter 1. What is USB 11
1.1. History of USB 11
1.2. Comparison of USB with other interfaces 14
1.3. USB Basic Concepts 16
1.3.1. General bus architecture 16
1.3.2. Physical and logical bus architecture 16
1.3.3. Components of USB 18
1.3.4. USB device properties 18
1.3.5. Hub properties 19
1.3.6. Host properties 20
1.4. Examples of USB Devices 20
1.4.1. Mouse and keyboard., 21
1.4.2. Monitors 21
1.4.3. USB-to-COM and USB-to-LPT 22 adapters
1.4.4. Scanners 23
1.4.5. Modems 23
1.4.6. Speakers 24
1.4.7. Flash drives 25
1.4.8. Hubs 28
1.4.9. Measuring technology 28
1.4.10. Exotic gadgets 29
1.5. network connection via USB 30
1.5.1. USB to Ethernet converter 31
1.5.2. Direct connection via USB port 31
1.6. Data transfer 31
1.6.1. Communication principles 32
1.6.2. Interrupt mechanism 32
1.6.3. Host adapter interfaces 32
1.6.4. Direct memory access capability 34
1.6.5. Communication modes 34
1.7. Installing and configuring USB devices 35
1.7.1. BIOS settings for USB 38
1.7.2. Troubleshooting 41
1.8. USB Limits 45
1.9. If you buy a computer 46
1.9.1. HS and USB 2.0 are not the same! 46
1.9.2. Motherboard 47
1.9.3. Building 48
1.9.4. USB for “older” computer models 48
1.10. Online resources for this chapter 49
Chapter 2 Hardware USB 51
2.1. Cables and connectors 51
2.1.1. Cable types 52
2.1.2. Cable length 53
2.1.3. Connectors 53
2.2. Physical interface 55
2.2.1. Data encoding 57
2.2.2. Device identification 58
2.3. Nutrition 59
2.3.1. Power Types of USB Devices 59
2.3.2. Energy management 60
2.3.3. Entering the mode low power consumption 61
2.4. Online resources for this chapter 61
PART II. USB INTERNAL ORGANIZATION 63
Chapter 3 Tire Internal Organization 65
3.1. Logical levels of communication 65
3.1.1. Client software level 66
3.1.2. USB system driver level 67
3.1.3. Interface Host Controller Level 68
3.1.4. Peripheral bus level 68
3.1.5. USB logical device level 69
3.1.6. Functional level of the USB device 69
3.2. Layered Data Transfer 69
3.3. Types of data transfers 71
3.4. Synchronization with isochronous transmission 73
3.5. Personnel 77
3.6. Endpoints 78
3.7. Channels 79
3.8. Packages 81
3.8.1. Format of IN, OUT, SETUP, and PING 83 token packets
3.8.2. SOF 83 Packet Format
3.8.3. Data packet format 84
3.8.4. Acknowledgment Packet Format< 84
3.8.5. SPLIT * 84 packet format
3.9. Checksum 85
3.9.1. CRC Calculation Algorithm 86
3.9.2. Software calculation of CRC 87
3.10. Transactions 90
3.10.1. Transaction types 91
3.10.2. Transaction confirmation and flow control 92
3.10.3. Transaction protocols 93
Chapter 4. Internal organization of the device 96
4.1. Requests to USB devices 96
4.1.1. Configuration Pack 96
4.1.2. Standard device queries 99
4.1.3. Device descriptors 105
Chapter 5. Internal organization of the host and hubs 123
5.1. Hubs 123
5.1.1. Interaction of the host controller with the hub 126
5.1.2. Hub descriptor 127
5.1.3. Hub requests 129
5.1.4. Request CLEAR_HUB_FEATURE 130
5.1.5. Request CLEAR PORT_FEATURE 130
5.1.6. Request GET_BUS_STA TE 131
5.1.7. Request GET_HUB_DESCRfPTOR 131
5.1.8. Request GET_HUB_STATUS 131
5.1.9. Request GET_PORT_STA TUS 132
5.1.10. Request SET_HUB_DESCRIPTOR 134
5.1.11. Request SET_HUB_FEATURE 134
5.1.12. SET PORT FEATURE request. 134
5.2. Collaboration devices with different speeds 135
Chapter 6. USB without PC 137
6.1. OTG connectors 138
6.2. Types of OTG devices 138
6.3. OTG Device Descriptor 139
6.4. Online resources for this chapter 140
PART III. PROGRAMMING PRACTICE 141
Chapter 7. USB support in Windows 143
7.1. Model WDM 144
7.2. Interaction with the USB driver 146
Chapter 8 HID Devices * 149
8.1. HID device properties 149
8.2. How to communicate with a HID device 151
8.3. Installing a HID Device 152
8.4. HID Device Identification 152
8.4.1. Identification of boot devices 153
8.4.2. HID device configuration descriptor 153
8.4.3. HID Descriptor 154
8.4.4. Report descriptor 156
8.5. Report descriptor structure 156
8.5.1. Structure of report elements 156
8.5.2. Report item types 157
8.5.3. Descriptor Examples 165
8.6. Requests to the HID device 168
8.6.1. GET_REPORT request. 169
8.6.2. SET_REPORT request 169
8.6.3. GETJDLE request. 170
8.6.4. Request SETJDLE 170
8.6.5. Request GET_PROTOCOL 171
8.6.6. Request SET_PROTOCOL 171
8.7. Tools 171
8.8. Interaction with the HID driver 172
Chapter 9 Introduction to WDM 181
9.1. Driver layers 183
9.2. Symbolic device names 184
9.3. WDM Driver Basic Procedures 189
9.3.1. Procedure DriverEntry 190
9.3.2. AddDevice procedure 192
9.3.3. Unload procedure 194
9.3.4. Driver Operating Procedures 196
9.3.5. Serving IOCTL 203 Requests
9.4. Loading the Driver and Calling Driver Procedures 209
9.4.1. Driver operation procedure 209
9.4.2. Driver Registration 210
9.4.3. Referring to work procedures 217
9.4.4. Storing the driver inside executable file 218
9.5. Driver Creation Tools 220
9.5.1. NuMega Driver Studio 220
9.5.2. Jungo WinDriver 220
9.5.3. Jungo Kernel Driver 220
Chapter 10 USB PnP Specification 221
10.1. General information about the Plug and Play system 221
10.1.1. Plug and Play Tasks and Functions 221
10.1.2. Starting a PnP Procedure 222
10.1.3. PnP Software Components 224
10.2. Plug and Play for USB 225
10.2.1. Configuring USB Devices 226
10.2.2. USB device numbering 226
10.2.3. PnP USB Device IDs 228
10.3. Getting a List of USB Devices 229
10.4. INF file 234
10.4.1. INF file structure 234
10.4.2. Section Version 235
10.4.3. Manufacturer section 237
10.4.4. Destination Dirs Section 239
10.4.5. Model 241 Description Section
10.4.6. Section xxx.AddReg and xxx.DelReg. 242
10.4.7. Section xxx.LogConfig 244
10.4.8. Section xxx.CopyFiles 244
10.4.9. Section Strings 245
10.4.10. Section connections 246
10.4.11. Creating and Testing INF Files 247
10.4.12. Installing Devices Using an INF File 248
10.5. Registry branches for USB 249
Chapter 11 BIOS Features 251
11.1. BIOS service 1AH 251
11.1.1. Function B101H - detecting the presence of PCI BIOS 252
11.1.2. Function В102Н - search for a PCI device by identifiers
device and manufacturer 253
11.1.3. Function B103H - search for a PCI device by class code 254
11.1.4. Function B108H - read configuration register (Byte) 255
11.1.5. Function ВУ9Н - reading configuration register (Word) 256
11.1.6. Function B10AN - read configuration register (DWord) 256
11.1.7. Function В10ВН - write configuration register (Byte) 257
11.1.8. Function B10CH - write configuration register (Word) 257
11.1.9. Function B10DH - Write Configuration Register (DWord) 258
11.2. Usage example 259
PART IV. CREATING USB DEVICES 283
Chapter 12 USB Peripherals 285
12.1. Chips Atmel 286
12.1.1. Microcontrollers with MSC-51 architecture 286
12.1.2. Hub controllers 289
12.1.3. Microprocessor hubs with AVR 289 core
12.1.4. Other Atmel 290 ICs
12.2. Chips Cygnal 291
12.2.1. Microprocessors C8051F320 and C8051F321 291
12.2.2. Other Cygnal 293 ICs
12.3. Chips FTDI 296
12.3.1. Chips FT232AM and FT232BM 297
12.3.2. Chips FT245AM and FT245BM 298
12.3.3. Chip FT2232BM 299
12.3.4. Chip FT8U100AX 300
12.3.5. Debug kits and modules 301
12.3.6. Drivers 302
12.3.7. Additional Utilities 303
12.3.8. Other modules 304
12.4. Chips Intel 304
12.5. Chips Microchip 308
12.6. Motorola 308 ICs
12.7. Philips 309 chips
12.7.1. Microchips USB 310
12.7.2. Hubs 311
12.7.3. Other Philips 313 chips
12.8. Microcircuits Texas Instruments 314
12.9. Chips Trans Dimension 317
12.10. Power Protection ICs 318
12.11. Online resources for this chapter 319
Chapter 13 Atmel AT89C5131 HID Device 322
13.1. Structural diagram of АТ89С5131 322
13.2. USB registers AT89C5131 324
13.2.1. Register USBCON 324
13.2.2. Register USBADDR 326
13.2.3. Register USBINT 327
13.2.4. Register USBIEN 328
13.2.5. UEPNUM register. 329
13.2.6. Register UEPCONX 330
13.2.7. UEPSTAX register. 331
13.2.8. UEPRST register. 334
13.2.9. UEPINT register. 335
13.2.10. Register UEPIEN 336
13.2.11. Register UEPDATX 337
13.2.12. Register UBYCTLX 337
13.2.13. Register UFNUML 338
13.2.14. Register UFNUMH. 338
13.3. Circuitry AT89S5131 338
13.4. Programming tools 339
13.4.1. Compiler 341
13.4.2. Programmer 342
13.5. Program for microprocessor 349
13.5.1. The first version of the program for АТ89С5131 349
13.5.2. Adding String Descriptors 369
13.5.3. Adding Endpoints 374
13.5.4. Creating a HID device 377
13.5.5. Communication with a HID device 381
13.6. Reading reports in Windows 388
13.7. Additional functions Windows XP 396
13.8. Device with multiple reports 397
Chapter 14 Creating an ATMEL AT89C5131 USB Device 402
14.1. Non-HID device 402
14.2. Creating a driver with Driver Studio 405
14.2.1. A few words about the Driver Studio 407 library
14.2.2. Other Driver Studio 411 classes
14.2.3. Creating a Driver Template Using Driver Studio 412
14.2.4. Refinement of the driver template 422
14.2.5. Device Class Base Methods 423
14.2.6. Implementing Data Reading 426
14.2.7. Driver installation 428
14.2.8. Data Reader 429
14.2.9. Reading data from other types of endpoints 438
14.2.10. Clean USB Driver 439
Chapter 15 Using FTDI 457 Chips
15.1. Functional diagram FT232BM 457
15.2. Circuitry FT232BM 460
15.3. Functions D2XX 460
15.4. Transition from COM to USB 465
15.4.1. 465 Converter Circuit Description
15.4.2. Setting the baud rate 467
PART V. HANDBOOK 469
Chapter 16 Windows features 471
16.1. CreateFile and CloseHandle functions: open and close an object.471
16.1.1. Additional information 472
16.1.2. Return value 472
16.1.3. Call example 472
16.2. Read File Function: Read Data 473
16.2.1. Additional information 474
16.2.2. Return value 474
16.2.3. Call example 474
16.3. WriteFile Function: Data Transfer 475
16.3.1. Additional information 476
16.3.2. Return value 476
16.3.3. Call example 476
16.4. ReadFileEx function. APC Read Data 477
16.4.1. Return value 479
16.4.2. Additional information 479
16.4.3. Call example 479
16.5. WriteFileEx Function: APC Data Transfer 480
16.5.1. Return value 481
16.5.2. Call example 481
16.6. Function WaitForSingleObject waiting for a signal
object state 482
16.6.1. Return value 482
16.7. WaitForMultipleObjects function: waiting for a signal
object states 483
16.7.1. Return value 484
16.8. GetOverlappedResult function result of asynchronous operation 484
16.8.1. Return value 485
16.9. DeviceIoControl Function: Direct Driver Control 485
16.9.1. Return value 487
16.10. QueryDosDevice Function: Getting Device Name
by his DOS name 487
16.10.1. Return value 488
16.10.2. Call example 488
16.11: Define Dos Device Function: DOS Device Name Operations 489
16.11.1. Return value 490
16.11.2. Call example 490
Chapter 17 HID API Functions 492
17.1. HidD_Hello Function: Library Check 492
17.2. HidD_GetHidGuid Function: Get GUID 492
17.3. HidD_GetPreparsedData Function: Creating a Device Descriptor 493
17.4. HidD_FreePreparsedData Function: Freeing Device Handle 493
17.5. Function HidD_GetFeature: getting FEATURE report 494
17.6. HidD_SetFeature Function: Sending FEATURE Report 494
17.7. Function HidD_GetNumInputBuffers: getting the number of buffers 495
17.8. Function HidD_SetNumInputBuffers: setting the number of buffers 495
17.9. HidD_GetAttribntes Function: Get Device Attributes 495
17.10. Function HidD_GetMamifactnrerStnng. get manufacturer string 496
17.11. Function HidD_GetProductString. get product line 497
17.12. Function HidD_ Get Serial MumberString. getting a string
serial number 497
17.13. HidD_GetIndexedString function. get row at index 498
17.14. HidDjGetlnputReport function. receiving an INPUT report 498
17.15. Function HidD_SetOutputReport. send OUTPUT report 499
17.16. HidP_GetCaps Function: Get Device Properties 499
17.17. Function HidP_MaxDataListLength: getting report sizes 500
Chapter 18 UCH 502 Host Controller
18.1. 502 Host Controller Control Registers
18.1.1. USB command register (USBCMD) ..504
18.1.2. USB Status Register (USBSTS) 506
18.1.3. Interrupt Control Register (USBINTR) 506
18.1.4. Frame number register (FRNUM) 507
18.1.5. Frame base address register (FLBASEADD) 508
18.1.6. Start of Frame Modifier Register (SOFMOD) 508
18.1.7. Port Status and Control Register (PORTSC) 509
18.2. UCH 510 host controller data structures
18.2.1. Frame List 510
18.2.2. Transmission descriptor i 511
18.2.3. Queue header 514
18.3. UCH 516 Descriptor List Processing
Chapter 19 Tools 518
19.1. Microsoft Visual Studio Tools 518
19.1.1. Depends 518
19.1.2. Error Lookup 518
19.1.3. GuidGen 518
19.2. Microsoft DDK 520 tools
19.2.1. Device Tree 520
19.2.2. DevCon.-521
19.2.3. Chklnf and Genlnf. 526
19.3. CompuWare Corporation 527 Tools
19.3.1. Monitor 527
19.3.2. Symlink 527
19.3.3. EzDriverInstaller 527
19.3.4. WdmSniff 527
19.4. Syslntemals 528 tools
19.4.1. WinObj 528
19.5. USB Forum 531 tools
19.5.1. HID Descriptor Tool 531
19.6. HDD Software Tools 533
19.7. Sourceforge 533 Tools
APPS 535
Appendix 1 Additional Features 537
Appendix 2. Table of language identifiers (LangID) 539
Appendix 3. Table of vendor codes (Vendor ID, Device ID) 543
Appendix 4 CD Description 546
Literature 548
Index 549

But it's not enough just to physically connect the device to the computer, you also need to establish data exchange between them. How to choose a port and organize a connection? A few years ago, the standard solution was to use a COM port. By the way, various specialists still install 8, 16, or even 32 COM ports on industrial computers (there is a whole category of different PCI expansion cards for serial ports, controllers, etc.). Thus, if you need to connect several external devices with an RS-232 interface, expensive adapters and exotic expansion boards may be required, which, according to the old tradition, sail to Russia for weeks on steamboats. By the way, the name of an ordinary adapter "DB9m / DB25f adapter" can only cause irritation for a computer store manager.

What is a HID device

Now almost all devices are connected to a computer via a USB interface. Therefore, many new PCs do not have a COM port at all.

USB interface - a typical solution for pairing a new external device with a computer, more precisely, it is a HID interface based on the USB 1.1 protocol.

Although many people think that the HID (Human Interface Device) interface is exclusively for the keyboard, mouse and joystick, it is suitable for many solutions related to interfacing external devices and a computer.

If the user needs to perform low-speed data exchange (up to 64 kbps) and at the same time it is desirable to reduce the time on the tedious development of their own drivers, then HID is quite suitable for them. The output will be simple and quite modern solution based on a standard USB software interface with guaranteed support on all common software platforms.

HID device properties

From the point of view of organizing software support for a HID device, everything looks quite attractive: to work under Windows control you can quickly create understandable compact code based on ready-made proven algorithms. In this case, the developer will have plenty of time to implement his own top-level data exchange protocol, since the necessary abstraction level is already organized by the HID protocol (see table). In addition, it is easy for a programmer to debug a written exchange protocol (of course, if there is a working HID device) - due to the relative rigidity of the protocol itself, it is enough to simply develop a program for supporting the device by a computer. Still would! A lot of work has already been done by the creator of the HID device.

Establishing data exchange between a HID device and a computer

To describe the interaction of a HID device with a computer, we will use the term "host". In this case, it means the control device in the general physical architecture communication over the USB protocol. So, all ports in a computer are hosts. You can connect various USB devices to them (flash drives, mice, webcams, cameras, etc.) that do not have a host. The host provides discovery, connection, disconnection, device configuration, as well as statistics collection and power management.

The HID device itself can set the polling frequency, during which the presence of any new data is found out. This means that even at such a low level, the programmer can trust the system, since the polling rate and other communication parameters must be pre-set in the HID device controller program. This is how the HID protocol differs from general description USB 1.1 or USB 2.0, which does not have strict protocol requirements. However, for specific tasks that require a high level of security, it can be quite difficult to get rid of cyclic polls, when almost the same blocks of data are constantly transmitted.

Features of programming HID devices

HID devices have special descriptors. When the host determines that the device belongs to the HID class, it transfers control of it to the appropriate driver. It is assumed that further data exchange is carried out under his leadership.

On Windows, the HidServ system service is responsible for accessing HID devices. More details about the functions of requests to HID devices and other features of working with the HID driver are described in the work by P. V. Agurov “USB interface. The practice of using and programming” (St. Petersburg: BHV-Petersburg, 2005).

Programming HID devices at the "top level"

The hard life of "applied" programmers working on Pascal is facilitated by the proven HID module. PAS, the shell for hid. dll (Hid User Library - as specified in the file properties). The comments to the file say that it is based on the hidsdi.h and hidpi.h modules from Microsoft Corporation. And the HID file itself. PAS is part of the JEDI() package.

To work with a HID device in Delphi environment for win32, the TJvHidDeviceController component is used, which is a convenient global manager for accessing HID devices. And already on its basis, you can get an object instance for working with a specific device.

Main properties and events of the TJvHidDeviceController component

Let's consider the TJvHidDeviceController component in more detail. The OnArrival event fires when a HID device arrives (connects) to the system, access to the device is provided in the handler of this event through an instance of the TJvHidDevice class. The simple event OnDeviceChange reacts to a change in the state of the device, it only signals changes in the system. The OnDeviceData event fires when data arrives from one of the HID devices and passes the following to the handler: HidDev: TJvHidDevice; - the device from which the data was received;

The OnDeviceDataError event notifies of a data transfer error by passing HidDev parameters to the processing procedure: TJvHidDevice; - HID device and Error: DWORD; - error code. The OnDeviceUnplug event notifies you that a device has been removed from the list of devices installed on the system. The types of event handlers on Plug and Unplug are the same (in the source text: TJvHidUnplugEvent = TJvHidPlugEvent). An object of the TJvHidDevice class corresponding to the HID device is passed to the handler.

To sequentially enumerate the HID devices available in the system by calling the Enumerate method, the OnEnumerate event is intended, i.e., in the event handler, the found devices are sequentially transmitted as objects. This event is forcibly triggered by the Enumerate method, which is used to "pass" existing HID devices through the handler, for example, when auditing the state of HID devices initiated by the host (computer).

The OnRemoval event fires when the device is physically removed from the system and has the same TJvHidUnplugEvent handler type as for OnDeviceUnplug. The CountByProductName function returns the number of devices that match the product name specified in the argument, and CountByVendorName returns the number of vendor names specified in the argument.

Main properties and events of the TJvHidDevice class

The TJvHidDevice class is a virtual representation of a single HID device. A new object of this class can be obtained, as already mentioned, from the OnArrival or OnEnumerate event. The functionality of the TJvHidDeviceController and TJvHidDevice classes is partially duplicated, since the first of them integrates a common toolkit for working with a set of HID devices available in the system and a mechanism for accessing one of them. A device can be uniquely identified by its SerialNumber, ProductName, and VendorName properties. You can use the OnData event to get information about the arrival of data using such an object. Data is sent through the WriteFile method (in the strict sense, through a function). WriteFile is a wrapper around the WriteFile (kernel32) system function.

To control the fact that the device is removed, you should assign your own handler to the OnUnplug event. Before starting data exchange with a HID device, you need to make sure that such an exchange is possible using HasReadWriteAccess. This class even has a separate OnDataError event for the occurrence of a data exchange error.

And now let's look at code fragments from a "live" project that implements a test client application for organizing data exchange with a non-standard device - HID-based plastic chip cards. In the struggle for realism, the author took the liberty of not throwing out "extra" technological code bindings from the listings.

The ScanDevices method (Listing 1) is designed to initiate the process of searching the system for the required HID device. Most of the code, with the exception of the call to the Enumerate method, is optional and provides application flexibility, for example, so that you can add the ability to work on a non-HID interface to the same test program. The AddError method prints debugging information to the window while the program is running.

Listing 2 shows the OnEnumerate event handler for finding the required external device. For simplicity, we will assume that the program can work with only one device of the type it needs.

Before considering the further implementation of the project, we should talk a little about the accepted top-level data exchange format, that is, about the structure designed to be an intermediary between the methods of receiving and transmitting data and the specific applied task being solved. The fact is that here the developer is given the opportunity to realize their creative abilities. Or rather, developers, because the process of creating a new protocol is very often two-way, and the first violin is played by the one who finds it more difficult to implement the exchange algorithm. In general, whatever the exchange protocol, it is always nice to make each software entity as visual and self-sufficient as possible, even to the detriment of some generally accepted traditions. For The best decision- one that will be implemented in a short time with minimal reference to software environment and with great potential for further development. Based on these principles, a top-level exchange protocol was created, where the main concept is “command”. Listing 3 shows how much the author loves string data, which saved him more than once when debugging program modules. How wonderful that we even have a String type! All protocol commands are divided into categories (classes), within which there is a command code that uniquely characterizes its purpose. The edParam parameter is used to send data to the device, and the edAnswerData parameter contains the data received from the device. The string type of the described record members allows you to freely and visually manipulate data in the HEX string format. And what is most pleasant, the format of the described record ideologically stands somewhere in the middle between its direct purpose and various forms of its presentation (INI, HEX, XML, etc.)

Command execution, i.e. sending data to the device, is implemented using sending data packets with a length of 8 bytes (Listing 4). This length is not the only decision, this choice is dictated by the requirements of the upper layer protocol and may be different in each specific case. This is what is called a matter of taste. The weird IsUSBMode flag in the ExecuteCommand method (Listing 5 in PC Disk World) is left as a reminder that instead of working with USB, we may need to use a COM port or some other interface. At the beginning of the sent data group, a sync sequence of an arbitrarily chosen format (for example, 3E3E3E2B) is transmitted to the device, informing the device that it has completely legal data at the input. Let me remind you that in this case we are talking not so much about HID, but about a specific top-level protocol, ideologically divorced from hardware and designed to solve specific applied problems.

In the GetDataExecutor handler of the data received from the device (package of 8 bytes), a specially created OnNewInputData event was used to transfer the initially processed data for further processing, indicating their old and new values ​​(Listing 6 on the "PC-Disk World"). Thus, the events of raw data arrival and an indication of further processing are decoupled, allowing some specific warning algorithm to be added at an early stage for erroneous, repeated, or unnecessary input information.

The examples of working with a HID device presented here illustrate the general idea of ​​the article - the relative simplicity of programming non-standard HID devices using Delphi tools.

Introduction
Who is this book for?
What will you find in the book
Software Requirements
Hardware Requirements
About the code
Brief description of the chapters
Notation
Thanks
Feedback
Part I. Understanding USB
Chapter 1 USB specification
1.1. What is USB and why is it needed
1.1.1. General USB architecture
1.1.2. USB physical and logical architecture
1.1.3. USB components
1.1.4. USB device properties
1.1.5. Communication principles
1.1.6. Interrupt mechanism
1.1.7. Communication modes
1.1.8. Logical levels of communication
1.1.8.1. Client software level
1.1.8.2. USB system driver level
1.1.8.3. Interface Host Controller Layer
1.1.8.4. USB peripheral bus level
1.1.8.5. USB logical device level
1.1.8.6. Functional level of the USB device
1.1.9. Data transfer by levels
1.1.10. Types of data transfers
1.1.11. Personnel
1.1.12. Endpoints
1.1.13. Channels
1.1.14. Packages
1.1.14.1. Format of IN, OUT, SETUP, and PING token packets
1.1.14.2. SOF packet format
1.1.14.3. Data Packet Format
1.1.14.4. Acknowledgment Packet Format
1.1.14.5. SPLIT Packet Format
1.1.15. Check sum
1.1.15.1. CRC Calculation Algorithm
1.1.15.2. Software CRC Calculation
1.1.16. Transactions
1.1.16.1. Transaction types
1.1.16.2. Transaction confirmation and flow control
1.1.16.3. Transaction protocols
1.2. Requests to USB devices
1.2.1. Configuration package
1.2.2. Standard requests to USB devices
1.2.2.1. Getting the GET_STATUS state
1.2.2.2. Resetting the CLEAR_FEATURE property
1.2.2.3. SET_FEATURE Property Resolution
1.2.2.4. Setting the address on the SET_ADDRESS bus
1.2.2.5. Getting a GET_DESCRIPTOR handle
1.2.2.6. Passing a SET_DESCRIPTOR Descriptor
1.2.2.7. Get configuration code GET_CONFIGURATION
1.2.2.8. Setting the SET_CONFIGURATION configuration code
1.2.2.9. Getting the interface configuration code GET_INTERFACE
1.2.2.10. Setting the SET_INTERFACE interface setup code
1.2.2.11. Setting the SYNC_FRAME sync frame number
1.2.2.12. Handling standard requests
1.2.3. Device handle
1.2.3.1. Device handle
1.2.3.2. Qualifying device descriptor
1.2.3.3. Configuration Descriptor
1.2.3.4. Interface descriptor
1.2.3.5. Endpoint handle
1.2.3.6. Line handle
1.2.3.7. Specific descriptors
1.2.3.8. Descriptor Obtaining Order
1.3. Plug and Play (PnP) system
1.3.1. Configuring USB Devices
1.3.2. USB device numbering
1.3.3. PnP USB IDs
1.3.4. Symbolic device names
1.4. WDM Model
Chapter 2 Microcontroller C Programming
2.1. General information about the C language for microcontrollers
2.2. Using Standard Libraries
2.3. Programming for AT89C5131
2.3.1. Initialization file
2.3.2. Descriptor Structures
2.3.3. Project Structure
Chapter 3 Tools
3.1. programmers
3.1.1. Flip programmer
3.1.2. Programmer ER-Tronik
3.2. Driver Creation Tools
3.2.1. NuMega Driver Studio
3.2.2. Jungo WinDriver
3.2.3. Jungo KernelDriver
3.3. Microsoft Visual Studio Tools
3.3.1. Depends (Dependency Walker)
3.3.2. Error Lookup
3.3.3. GuidGen
3.4. Microsoft DDK tools
3.4.1. device tree
3.4.2. devcon
3.4.2.1. classes key
3.4.2.2. driverfiles key
3.4.2.3. hwids key
3.4.2.4. key rescan
3.4.2.5. stack key
3.4.2.6. status key
3.4.3. Chklnf and Genlnf
3.5. CompuWare Corporation Tools
3.5.1. Monitor
3.5.2. SymLink
3.5.3. EzDriverInstaller
3.5.4. WdmSniff
3.6. SysInternals Tools
3.6.1. WinObj
3.7. USB Forum Tools
3.7.1. HID Descriptor Tool
3.8. USB Command Verifier
3.9. HDD Software Tools
3.10. Sourceforge Tools
3.11. Bus Hound monitoring software
Chapter 4 Understanding Win32 Functions in .NET
4.1. General information
4.2. Importing Win32 Functions
4.3. structures
4.3.1. StructLayout attribute
4.3.2. MarshalAs attribute
4.4. Direct access to data
4.5. Handling Windows Messages
4.6. General information about WMI
4.7. Online resources for this chapter
Part II. USB classes
Chapter 5
5.1. USB/RS-232 Interface Conversion Methods
5.2. General information about the RS-232 interface
5.2.1. Exchange lines
5.2.1.1. Transmitted data (BA/TxD/TD)
5.2.1.2. Received data (BB/RxD/RD)
5.2.1.3. Transfer Request (CA/RTS)
5.2.1.4. Transfer Ready (CB/CTS)
5.2.1.5. DCE Ready (CC/DSR)
5.2.1.6. DTE Ready (CD/DTR)
5.2.1.7. Call indicator (CE/RI)
5.2.1.8. Carrier Detect (CF/DCD)
5.2.1.9. Ready to Receive (CJ)
5.3. CDC specification
5.3.1. Standard descriptors
5.3.2. Function Descriptors
5.3.2.1. Header Function Descriptor
5.3.2.2. Command Mode Descriptor
5.3.2.3. Abstract Device Descriptor
5.3.2.4. Grouping descriptor
5.3.3. Special requests
5.3.3.1. SET_LINE_CODING request
5.3.3.2. GET_LINE_CODING request
5.3.3.3. SET_CONTROL_LINE_STATE query
5.3.3.4. SEND_BREAK request
5.3.4. Notifications
5.3.4.1. RING^DETECT notification
5.3.4.2. SERIAL_STATE notification
5.4. CDC support on Windows
5.4.1. Overview of Windows features for working with serial ports
5.4.1.1. Basic Port Operations
5.4.1.2. Port setting functions
5.4.1.3. Custom port setting
5.4.1.4. Getting the status of modem lines
5.4.1.5. Working with CDC on the platform. NET
5.4.2. Matching Windows features and USB requests
Chapter 6 HID class
6.1. HID device specification
6.2. How to communicate with a HID device
6.3. Installing the HID device driver
6.4. HID Device Identification
6.4.1. Identification of boot devices
6.4.2. HID device configuration descriptor
6.4.3. HID descriptor
6.4.4. Report descriptor
6.5. Report descriptor structure
6.5.1. Report elements
6.5.1.1. Short Type Elements
6.5.1.2. Long type elements
6.5.2. Report item types
6.5.2.1. Essential elements
6.5.2.2. Global elements
6.5.2.3. Local elements
6.5.3. Descriptor Examples
6.6. Requests to an HID device
6.6.1. GET_REPORT request
6.6.2. SET_REPORT request
6.6.3. GET_IDLE request
6.6.4. SET_IDLE request
6.6.5. GET_PROTOCOL request
6.6.6. SET_PROTOCOL request
6.7. Tools
6.8. Drivers for HID Devices in Windows
Chapter 7 Other USB Classes
Part III. USB Programming Practice
Chapter 8. Creating a USB device based on AT89C5131
8.1. General information about AT89C5131
8.2. Structural diagram of AT89S5131
8.3. USB registers AT89C5131
8.3.1. USBCON register
8.3.2. Register USBADDR
8.3.3. USBINT register
8.3.4. USBIEN register
8.3.5. UEPNUM register
8.3.6. UEPCONX register
8.3.7. UEPSTAX register
8.3.8. Register UEPRST
8.3.9. UEPINT register
8.3.10. Register UEPIEN
8.3.11. UEPDATX register
8.3.12. Register UBYCTLX
8.3.13. UFNUML register
8.3.14. Register UFNUMH
8.4. Circuitry AT89S5131
8.5. Basic design for AT89C5131
8.5.1. The first version of the program for АТ89С5131
8.5.2. Adding string descriptors
8.5.3. Adding Endpoints
8.6. Program download
Chapter 9 Implementing the CDC Class
9.1. CDC Implementation
9.2. Device handles
9.2.1. Endpoint initialization
9.2.2. Processing CDC Requests
9.2.3. RS port and CDC line configuration
9.2.4. Receiving and transmitting data
9.3. Driver installation
9.4. Programming data exchange with a CDC device in Delphi
9.5. Programming an exchange with a CDC device in C#
9.5.1. Using the MSCOMM Component
9.5.2. Using Win32 Functions
9.6. CDC issues
Chapter 10 Implementing the HID Class
10.1. Implementation of HID on AT89C5131
10.2. Transferring multiple bytes
10.3. Feature reports
10.4. Sending data from the host (SET_REPORT)
10.5. HID device installation
10.6. Communication with HID device
10.6.1. Getting the name of a HID device
10.6.2. Getting device attributes and reading reports
10.6.3. Data transfer from host to HID device
10.7. HID Device Examples
10.7.1. Implementation of the mouse device
10.7.2. Implementation of the "keyboard" device
10.8. Using the HID Protocol
10.8.1. Data interpretation
10.8.2. Collections
10.8.3. Arrays and Buttons
10.9. HID device with multiple reports
Chapter 11 Special Features Windows
11.1. Setup API Functions
11.1.1. Enumerating USB Devices
11.1.2. Getting the status of a USB device
11.2. Enumerating USB Devices with WMI
11.3. Windows XP special features
11.3.1. HidD_GetInputReport - read HID reports
11.3.2. Getting Raw Input Data
11.4. DirectX Features
11.5. Dialog for adding new equipment
11.6. Working with Symbolic Device Names
11.7. Safe ejection of flash drives
11.8. Device addition and removal detection
11.9. Internet resources
Chapter 12 Driver Development
12.1. WDM Driver Basic Procedures
12.1.1. Procedure DriverEntry
12.1.2. Procedure AddDevice
12.1.3. Procedure Unload
12.1.4. Driver Operating Procedures
12.1.4.1. Packet header
12.1.4.2. I/O Stack Cells
12.4.1.3. Driver Operating Procedures
12.1.5. Serving IOCTL Requests
12.2. Loading the Driver and Calling the Driver Procedures
12.2.1. Driver procedure
12.2.2. Driver registration
12.2.2.1. Registering with SCM
12.2.2.2. Driver settings in the registry
12.2.3. Referring to work procedures
12.2.4. Storing the driver inside the executable file
12.3. Creating a driver with Driver Studio
12.3.1. A few words about the Driver Studio library
12.3.1.1. KDriver class
12.3.1.2. KDevice class
12.3.1.3. Klrp class
12.3.1.4. KRegistryKey class
12.3.1.5. KLowerDevice class
12.3.1.6. USB classes
12.3.2. Other Driver Studio classes
12.3.3. Creating a Driver Template Using Driver Studio
12.3.3.1. Step 1. Set the name and path of the project
12.3.3.2. Step 2: Choosing a Driver Architecture
12.3.3.3. Step 3. Tire selection
12.3.3.4. Step 4 - Define a set of endpoints
12.3.3.5. Step 5. Specifying the class and file name
12.3.3.6. Step 6Choosing Driver Features
12.3.3.7. Step 7. Choosing how to process requests
12.3.3.8. Step 8: Create Persistent Driver Settings
12.3.3.9. Step 9 Driver Properties
12.3.3.10. Step 10. Specifying the IOCTL Codes
12.3.3.11. Step 11 Advanced Settings
12.3.4. Refinement of the driver template
12.3.5. Device Class Base Methods
12.3.6. Implementation of data reading
12.3.7. Driver installation
12.3.8. Data reader
12.3.9. Reading data from other types of endpoints
12.3.10. "Clean" USB device driver
Part IV. Directory
Chapter 13. INF File Format
13.1. INF file structure
13.1.1. Version section
13.1.2. Manufacturer section
13.1.3. DestinationDirs Section
13.1.3.1. DefaultDescDir key
13.1.3.2. file-list-section keys
13.1.3.3. dirid key
13.1.3.4. subdir key
13.1.4. Model description section
13.1.5. Section xxx. AddRegw xxx. DelReg
13.1.6. Section xxx. logconfig
13.1.7. Section xxx. CopyFiles
13.1.8. Section Strings
13.1.9. Section links
13.2. Creating and Testing INF Files
13.3. Installing Devices Using an INF File
13.4. Registry branches for USB
Chapter 14 Basic Windows Functions
14.1. CreateFile and CloseHandle Functions: Opening and Closing an Object
14.1.1. additional information
14.1.2. Return value
14.1.3. Call example
14.2. ReadFile function: reading data
14.2.1. additional information
14.2.2. Return value
14.2.3. Call example
14.3. Write File Function: Data Transfer
14.3.1. additional information
14.3.2. Return value
14.3.3. Call example
14.4. ReadFileEx function. APC data reading
14.4.1. Return value
14.4.2. additional information
14.4.3. Call example
14.5. WriteFiieEx Function: APC Data Transfer
14.5.1. Return value
14.5.2. Call example
14.6. WaitForSingieObject function waiting for the signaled state of an object
14.6.1. Return value
14.7. WaitForMultipleObjects function: waiting for the signaled state of objects
14.7.1. Return value
14.8. GetOverlapped Result function: the result of an asynchronous operation
14.8.1. Return value
14.9. DeviceloControl function: direct driver control
14.9.1. Return value
14.10. Cancel/o function: aborting an operation
14.10.1. Return value
14.11. Query Dos Device function, getting the device name from its DOS name
14.11.1. Return value
14.11.2. Call example
14.12. Define Dos Device function: operations with DOS device name
14.12.1. Return value
14.12.2. Call example
Chapter 15 Windows Structures and Functions for Serial Ports
15.1. COMMCONFIG port settings structure
15.2. Port Properties Structure COMMPROP
15.3. Structure of COMMTIMEOUTS timeouts
15.4. COMSTAT port status structure
15.5. DCB Structure
15.6. BuildCommDCB Function: Build a DCB Structure from a String
15.6.1. additional information
15.6.2. Return value
15.6.3. Call example
15.7. BuildCommDCBAndTimeouts Function: Build DCB Structure and Timeouts from String
15.8. SetCommBreak and ClearCommBreak Functions: Output Control
15.8.1. Return value
15.9. ClearCommError Function: Getting and Clearing Port Errors
15.9.1. Return value
15.10. EscapeCommFunction: port control
15.10.1. Return value
15.11. GetCommMask and SetCommMask functions: event call mask
15.11.1. Return value
15.12. WaitCommEvent function waiting for a COM port event
15.12.1. Return value
15.12.2. additional information
15.12.3. Call example
15.13. GetCommConfig and SetCommConfig Functions: Configuring Port Settings
15.13.1. Return value
15.13.2. Call example
15.14. CommConfigDialog Function: Port Configuration Dialog
15.14.1. Return value
15.14.2. additional information
15.14.3. Call example
15.15. GetCommProperties function: read port properties
15.15.1. Return value
15.15.2. Call example
15.16. GetCommState and SetCommState Functions: Port State
15.16.1. Return value
15.16.2. Call example
15.17. GetCommTimeouts and SetComniTimeouts Functions: Port Timeouts
15.17.1. Return value
15.17.2. Call example
15.18. PurgeComm Function: Flush Port Buffers
15.18.1. Return value
15.18.2. Call example
15.19. SetupComm function: configuring buffer sizes
15.19.1. Return value
15.20. GetDefaultCommConfig and SetDefaitltCommConfig Functions: Default Port Settings
15.20.1. Return value
15.21. TransmitCommChar function. broadcast special characters
15.21.1. Return value
15.22. GetCommModemStatus function: modem status
15.22.1. Return value
15.22.2. Call example
15.23. EnumPorts Function: Enumerating Ports
15.23.1. additional information
15.23.2. Return value
15.23.3. Call example
Chapter 16. Windows Setup API Structures and Functions
16.1. Setup function DiGetCiassDevs: device enumeration
16.1.1. Return value
16.2. SetupDiDestroyDevicelnfoList function freeing the device description block
16.2.1. Return value
16.3. SetupDiEnumDevicenterfaces Function: Device Information
16.3.1. Return value
16.4. SetupDiGetDevicelnterfaceDetaii function: detailed device information
16.5. SetupDiEnumDevicelInfo Function: Device Information
16.6. SetupDiGetDeviceRegistryProperty Function: Getting Plug and Play Device Properties
16.7. CM_Get_DevNode_Status function: device status
16.8. CM_Request_Device_Eject function safe device ejection
Chapter 17 Windows HID API Structures and Functions
17.1. HidD_Hello Function: Library Check
17.2. HidD_JetHidGuid Function: Getting a GUID
17.3. HidD_GetPreparsedData Function: Create Device Handle
17.4. HidD_EreePreparsedData Function: Release Device Handle
17.5. HidD_Get Feature function: getting a Feature report
17.6. HidD_SetFeature Function: Passing a Feature Report
17.7. Function HidD_GetNumlnputBuffers: getting the number of buffers
17.8. Function HidD_SetNumlnputBuffers: Set the number of buffers
17.9. HidD_GetAttributes Function: Getting Device Attributes
17.10. Function HidD_GetManufacturerString. get manufacturer string
17.11. HidD_GetProductString function getting a product string
17.12. Function HidD_GetSerialNumberString. getting serial number string
17.13. HidD_GetIndexedString function. get row by index
17.14. Function HidD_Jetlnput Report receiving an Input report
17.15. Function HidD_SetOutputReport. sending an output report
17.16. HidP_GetCaps Function: Getting Device Properties
17.17. HidP_MaxDataListLength function: getting report sizes
17.18. HidD_FIushQueue Function: Flushing Buffers
17.19. HidP_GetLinkColiectionNodes Function: Collection Tree
17.20. Functions HidP_GetScaledUsageValue and HidP_SetScaledUsage Value: Get and set converted values
17.21. Function HidF_MaxUsageListLength: buffer size for keycodes
17.22. Function HidP_UsageListDifference: difference between arrays
Applications
Appendix 1. Additional Features
Appendix 2. Compiling examples in other versions of Delphi
Appendix 3. Table of language identifiers (LangID)
Appendix 4. Table of vendor codes (Vendor ID, Device ID)
Appendix 5. How to Create a Device Manager Shortcut
Annex 6. Frequently Asked Questions
Appendix 7 CD Description
Literature
Subject index

Picture 1

The USB interface is becoming increasingly popular as an interface for connecting peripherals to PCs and modern computers often do not have the usual RS-232 interface. The popularity of USB is due to many reasons, here are the main ones:

  • high exchange rate, high noise immunity
  • data flow control, integrity control and error correction
  • possibility of branching through hubs and connections a large number devices.
  • bus power supply
  • bus versatility - the ability to connect diverse devices (keyboard, printer, modem)
  • automatic system identification and configuration, Plug and Play

However, there are (often unreasonable) factors holding back mass USB usage developers of microcontroller devices:

  • the need to program drivers for Windows
  • relatively low prevalence of microcontrollers with built-in USB interface
  • Lesson 2: Create a USB 2.0 Compliant HID Joystick Device.

This series of articles is intended to show that it is quite easy to overcome these difficulties and everyone can "upgrade" their device from the usual RS-232 to USB or create a new device with a USB interface.

As a microcontroller in the examples, a microcontroller manufactured by Microchip will be considered. PIC18F4550 with USB 2.0 interface (supports Low Speed ​​and Full Speed).

Lesson 1. USB without Windows programming, virtual COM port

One of the tasks that arise when developing USB devices is the transition from the RS-232 interface to USB, and if an "old" device is being modified or the device must be compatible with existing protocols and PC software, then it is desirable to get rid of any software modification. software on the computer. One solution to this problem is to use the USB interface as a virtual COM port. The use of this method eliminates the need to modify the computer software, because. The USB connection is seen by the personal computer as an additional COM port. Another important advantage is that standard Windows drivers are used and there is no need to create any custom driver.

The USB specification describes a class of communication devices (Communication Device Class - CDC), which defines a set of connection modes for telecommunication (modems, terminals, telephones) and network devices (Ethernet adapters and hubs, ADSL modems), including serial port emulation.

Let's take as an example a device that transmits voltage data from a potentiometer and temperature from a TC77 digital sensor via RS-232, and also receives commands to turn on / off two LEDs (for simplicity, we implement this example on the PICDEM™ FS USB DEMONSTRATION BOARD board, but you can assemble a simpler circuit - see below).

The PICDEM FS-USB debug board is designed for developing and demonstrating devices based on the PIC18F4550 microcontroller with a USB2.0 bus. The board has a PIC18F4550 controller in a TQFP44 package, which has the following features:

  • Maximum operating frequency - 48 MHz (12 MIPS);
  • 32 KB Flash program memory (Enhanced Flash technology);
  • 2 KB of data memory (of which 1 KB of dual-port RAM);
  • 256 bytes EEPROM data memory;
  • FS USB2.0 interface supporting 12Mbps speed with built-in transceiver and voltage regulator.

The board has:

  • Quartz 20 MHz;
  • RS-232 interface to demonstrate the possibility of moving from USART to USB;
  • Connector for in-circuit programming and debugging
  • Voltage stabilizer with the ability to switch to USB bus power;
  • PICtail™ expansion connector;
  • Temperature sensor TC77 connected via I2C;
  • Variable resistor connected to the ADC input;
  • LEDs, buttons.

This device has a PC program for controlling the device and displaying voltage and temperature values. So, we can connect the device to RS-232, select the COM port available in the system and set the exchange rate with our device, the number of data bits, the number of stop bits, as well as the parameters of parity bits and flow control in accordance with the microcontroller program (for we need to know the initialization parameters of our controller)


Rice. 2

Let's start connecting our device to USB.

Microchip Technology Inc. Offers a ready-made application example AN956, which implements USB CDC support for the PIC18F2550, PIC18F2455, PIC18F4455, PIC18F4550 microcontroller. The program is built on a modular basis, which allows easy modernization and integration into finished projects.

After the initial initialization of the controller, the program can communicate with the PC via the USB interface through several ready-made functions:

Let's modify our program to send and receive data via USB.

Fragment of the program for preparing and transmitting data:

Data reception:

if(getsUSBUSART(input_buffer,1)) ( switch (input_buffer) ( case "1" : mLED_3_On(); break; case "2" : mLED_3_Off(); break; case "3" : mLED_4_On(); break; case " 4" : mLED_4_Off(); break; default: break; ) )

After connecting the device to USB, the system will recognize the new device


Rice. 3

And installs new equipment


Rice. 4

We select the installation from the specified location and specify the path for the location of the mcpusb.inf file from the set of source codes for the program to AN956. After that, a new device is installed in the system.


Rice. 5

So, the new device is ready to go. The system has a new virtual COM port.


Rice. 6

Now in our program we can select the appeared virtual COM port to communicate with the device...


Rice. 7

... and see that the device really began to work through the COM port that appeared in the system via a USB connection.

It should be noted that USB provides data control and correction, so such concepts as flow rate, parity bits and flow control become abstract concepts, and in our case they can be chosen by anyone, the only informational parameter is the virtual COM port number.

PICDEM CDC window


Rice. 8

When using PIC18Fxx5x microcontrollers with a built-in USB 2.0 module, the virtual COM port can provide a data transfer rate of up to 80Kbytes per second (640Kbps), which significantly exceeds the possible transfer rate via RS-232, while, as we can see, there is no need to modify software for a computer it took!

Sample programs, documentation and diagram used in lesson 1.

  1. Download PICDEM CDC + Delphi sources
  2. Download Delphi component for working with COM port
  3. AN956+ original source codes
  4. File user_uart.c (all changes to the original program from AN956 were made only in this file. To run the example for lesson 1, you need to copy this file to the C:\MCHFFSUSB\fw\Cdc\user\ directory, replace the user.c file in the project with user_uart .c, compile the project and flash the microcontroller)
  5. Simplified diagram of a USB device


Rice. 9

Note: The original circuitry of the PICDEM FS USB board uses automatic detection of the board's power source (external or USB). Therefore, when using a simplified scheme, you must comment out the #define USE_USB_BUSSENSE_IO line in the usbcfg.h file

Lesson 2: Creating a USB 2.0 Compliant HID Joystick Device

The most common USB devices are Human Interface Devices (HID). Typical representatives of this class are USB keyboards, mice, joysticks, monitor settings panels, barcode readers, card readers, etc. The advantages of HID devices are:

  • ease of implementation;
  • compact code;
  • Windows support (no additional drivers needed).

The Microchip website has an example implementation of a HID mouse. Consider the implementation of the simplest game controller based on this example. We will be using the PICDEM FS-USB demo board (DM163025) for this project. The PICDEM FS-USB debug board has one variable resistor and 2 buttons, so the joystick under development will have a minimum of controls (2 buttons and, for example, a throttle).

First of all, we need to rewrite the device descriptor for the created joystick. To simplify the task, you can use the HID Descriptor Tool program, which can be downloaded from the site www.usb.org

Included with the program are examples of configurations of some HID devices, which you can adjust for your task or create your own HID device.


Rice. 10

So, in our case, several types of data will be used - this is a simulation of the control - Simulation Controls, and specifically this is the throttle (pedal) (Throttle) and control buttons (Button). In order for the operating system to "know" how to handle these data types, it is necessary to describe the maximum and minimum values ​​and the size of the data. In our case, "gas" is one 8-bit value (report_size = 8, report_count = 1), and the state of the buttons is defined as a field of one-bit values. The example uses only 2 buttons, but it is necessary to align the field to a byte value (report_size = 1, report_count = 8). In total, the microcontroller, when requesting data from the computer, must transmit 2 bytes - the gas level and the state of the buttons in accordance with the generated device descriptor (for a detailed description of possible descriptors, see the specification for HID devices www.usb.org). The created description of the device descriptor can be saved in different formats, including as a header file.h

Additionally, you need to adjust the size of the received device descriptor in the description of the HID Class-Specific Descriptor and change the size of the data transmitted through the endpoint in the endpoint descriptor (in our case, we transfer 2 bytes, so the size is HID_INT_IN_EP_SIZE=2).

These changes are enough for Windows to recognize the connected device as a joystick. Now we can adjust the string data so that the device has the name we want (eg "PIC18F4550 Joystick"). In order to assign a name to the device in Russian, you must specify a string descriptor in UNICODE encoding. This is where the description of the joystick ends and we need to prepare the data for transfer to the PC.

ReadPOT(); // start potentiometer voltage measurement buffer = ADRESH; // handle button states if(sw2==0) buffer |= 0x01; buffer &= ~0x01; if(sw3==0) buffer |= 0x02; buffer &= ~0x02; // data transfer Emulate_Joystick();

After compiling the project and programming the microcontroller, you can connect the device to the USB port. The board is defined as a HID gaming device, installed into the system and ready to go.


Rice. eleven

Through the control panel in Windows we can open the available gaming devices, select our joystick, calibrate it and test the functionality.


Rice. 12

When changing the device configuration - adding controls or buttons, it is necessary not only to change the description of the device descriptor, but also to transmit data strictly in accordance with the created descriptor. Thus, by changing the maximum number of buttons from 2 to 8 in the description of the USAGE_MAXIMUM (BUTTON 2) device descriptor, we get a joystick with 8 buttons.


Rice. 13

When the descriptor becomes more complicated, we can get a more complete implementation of the joystick, while you need to remember to change the following parameters: the size of the descriptor, the size of the endpoint, and you need to send as much information data as declared in the descriptor.


Rice. 14

Sample programs, documentation and diagram used in lesson 2.

  1. The original source codes for the implementation of the HID mouse.
  2. HID joystick implementation source codes.

Lesson 3

Any USB device can have multiple configurations, and each configuration has multiple interfaces. This USB property allows the device being created to be recognized by the computer as multiple USB devices with different interfaces. A mouse, for example, may have a built-in card reader and interact with the computer as two independent devices.

Device descriptor structure:


Rice. 15

Based on the standard example of a mouse and the created joystick, we will create a composite USB device that will be defined by the computer as two independent HID devices.

1. Create a descriptor.

Change the structure of the descriptor (file usbdsc.h)

The device will have 2 interfaces, each with one endpoint.

#define CFG01 rom struct \(USB_CFG_DSC cd01;\USB_INTF_DSC i00a00;\USB_HID_DSC hid_i00a00;\USB_EP_DSC ep01i_i00a00;\USB_INTF_DSC i01a00;\USB_HID_DSC hid_i01a00;\USB_EP_DSC ep0 2i_i01a00; \ ) cfg01
  1. In accordance with the changed structure, you need to change the descriptor in the usbdsc.c file.
  2. In the usbcfg.h file, define interface identifiers, endpoints used, report descriptor sizes.
  3. In the hid.c file, you need to initialize additional endpoints (in the HIDInitEP function) and change the HID request processing function (USBCheckHIDRequest function).
  4. Each of the devices, mouse and joystick, each must transmit data to its own endpoint. Therefore, we need to add functions for transferring data to specific endpoints and checking that the desired endpoint is free (add functions similar to mHIDTxIsBusy and HIDTxReport in the hid.c file).

Then the data transfer for the mouse will look like

After compiling the project, flashing the controller and connecting the device to USB, a new composite device will be detected by the computer and a mouse and joystick will be added.


Rice. 16


Rice. 17

Composite HID Device Source Codes.

Comment. Don't forget to change the PID when creating a new device, or delete a previous device with the same PID from the system.

Lesson 4

Microchip Technology Inc. releases inexpensive developer programmer PICkit2, which is primarily used for programming Flash controllers. A distinctive feature of this programmer is the availability of full documentation and firmware source codes for the microcontroller, and a shell program for the computer. PICkit2 is powered by USB, generates adjustable programming and power voltages, and also has 3 input-output lines for connecting to a programmable device. To be able to update the firmware of the programmer in PICkit2, a bootloader program has been implemented.


Rice. 18

CDC device based on PICkit2

Using all these features, based on the PICkit2 programmer, it is possible to create and debug your own USB device with the ability to roll back to its programmer functions at any time. With the help of the bootloader that is flashed into the programmer, other programs can be flashed into the PICkit2, for example, the virtual COM port support program. To do this, we take the example of CDC, rename the project and do the following

  1. in the main.c file, we change the address of the firmware location (the PICkit2 bootloader transfers control to the user program to the address 0x002000.
    #pragma code _RESET_INTERRUPT_VECTOR = 0x002000
  2. in the io_cfg.h file, we remove everything about port D (you can set the LED to blink on PORTC0).

    Since PICKIT2 is always powered by USB, we set

    #define usb_bus_sense 1 // device is always plugged in #define self_power 0 // device is powered from USB

  3. in the usbcfg.h file we put comments on 2 lines
    //#define USE_SELF_POWER_SENSE_IO //#define USE_USB_BUS_SENSE_IO
  4. In the user.c file, we output the data we need to USB
  5. include the linker file pickit2.lkr

After that, you can compile the project and load the new firmware through the PICkit2 shell.

After reprogramming the PICkit2, the computer detects the appearance of a new COM port, and through the hyperterminal we can see that the PICkit2 is sending data through the virtual COM port.

The source code for this example is available at link.

Based on this example, and using the external pins of the PICkit2 programmer, you can receive data from external devices and transfer it to a computer via USB. Thus, using PICkit2, you can output data to COG LCD indicators, I2C readers, SPI and 1-wire devices, such as temperature sensors, etc. devices.

Radio HID keyboard based on PICkit2


Rice. 19

Let's consider one more example of "inappropriate" use of the PICkit2 programmer - a keyboard emulator with an air interface. Such a device can be used, for example, for presentations - for flipping through slides away from the computer.

To implement such a device, we need:

  • PICkit2
  • PICkit2 demo board (DV164120)
  • radio receiver (rfRXD0420) and radio transmitter (rfPIC12F675) from rfPICkit.

We connect the radio receiver to the demo board. The microcontroller on the board will receive data from the receiver, process them and, when one of the two buttons on the remote control is pressed, will set the log.1 level on one of the 2 outputs connected to PICkit2.

PICkit2 will perform the following functions:

  • when connected to a computer via USB, it is defined as a HID keyboard
  • generate a +5V supply voltage for a demo board with a receiver
  • interrogate 2 external outputs of the receiver controller and, if available, a log. 1 send codes for pressing the PageUp or PageDown buttons to the computer.

Two virtual COM ports (FTDI2232 chip emulation) based on PICKit2

This example is only for learning how USB works. Review the FTDI driver license requirement before use!

The example shows how to make 2 virtual COM ports based on a microcontroller with a USB port. First you need to install drivers for the FTDI2232 chip. Then, to boot into PICkit2, you need to select the firmware update item in the PICkit2 shell and point to the TestVCP2.hex file from archive. After reprogramming PICkit2, you will have 2 independent serial COM ports in your system.

Example taken from website http://forum.microchip.com/tm.aspx?m=261649

To reverse restore PICkit2 as a programmer, you need to disconnect PICkit2 from USB and, while pressing the button, reconnect the USB cable, and then choose to load the standard firmware of the programmer.

All examples above are based on MCHFFSUSB Framework v1.3. With the advent of PIC24 and PIC32 controllers with USB OTG, Microchip has released a new version of the stack - USB stack v. 2.x.

In the new version of USB stack v. 2.3, in addition to the USB device stacks that implement the functionality of a USB client, the USB Embedded host that implements the host functionality, a USB dual role stack that implements the functions of both the host and the client has also been obtained; and USB OTG supporting Host Role Negotiation Protocol (HNP), Session Request Protocol (SRP), and fully compliant with the USB OTG specification. Implemented in the application examples:

  • Embedded Host
    • Printer Class host - support for ESC/POS, PostScript® and PCL5 printers
    • CDC Class host - support for ACM devices (abstract control model)
    • HID Keyboard
  • device
    • HID bootloader - added support for PIC32MX460F512L and PIC18F14K50 families
    • HID keyboard, mouse
    • MSD internal flash demo - using internal flash to store files
    • MSD + HID composite example - MSD and HID composite device example
    • CDC - COM port emulation
    • PIC32MX460F512L family support for all PC demo projects
    • The HID, MCHPUSB, and WinUSB examples now support the Microsoft Plug-and-Play (PnP) feature for auto-detection.
  • Documentation
    • a complete description of all APIs is located in the folder "\Microchip\Help"

Microchip provides free drivers for the most popular USB classes:

  1. User interface (HID). This exchange mode is used in almost all keyboards, mice and other input / output devices.
  2. Communication Device (CDC). This mode is the easiest to switch from serial RS-232 to USB. On WinXP/2K computers, a virtual COM port is created and emulated when a microcontroller is connected. Programs that work with COM1.. 4 ports will work without changes with a virtual port, but at a higher speed (about 1 Mbps)
  3. Mass Storage Devices (MSDs). These are devices that work as storage media - flash drives, SD / MMC cards, disks, etc.
  4. Printer class devices. This mode is designed for use with USB printers, which allows the end device on a PIC microcontroller with a USB module to output the necessary information directly to the USB printer.
  5. Microchip resident bootloader. The simplest mode, which is used only for updating the microcontroller software via USB. From the PC side, a small program is installed, an analogue of the driver
  6. Own driver (Custom). The most complete use of USB2.0 resources for advanced users: the ability to select bus operation modes (isochronous, interrupt, surround, control), high transfer speed. Requires deep bus knowledge and Windows software development skills

Bootloader with USB Flash Drive

Updating the firmware from a regular flash drive.

To update the firmware of a microcontroller with a USB-OTG module (PIC24 or PIC32), it is not necessary to use special software. The presence of the Host mode allows you to connect ordinary USB-data drives (Flash Drive) to the microcontroller. An example has been posted on the Microchip website ( beta version) that allows you to update the microcontroller software from a connected USB drive.

To run the example, you need to load the bootloader firmware into a PIC32 USB Board or Explorer 16 (with a PIC32 USB PIM processor module and a PICtail Plus USB Daughter Board installed). If power is applied to the board while the button is pressed, the controller will enter the firmware update mode. If you now connect a Flash drive with a recorded firmware update file, the microcontroller reads this file and overwrites it in its program memory.

Development boards and development tools for USB

PICkit2 debugger programmer (order number PG164120)

The presence of a bootloader allows you to upload your software to master the skills of working with USB


Rice. 20

PICDEM FS-USB Development Board (order number DM163025)

Designed for development and demonstration of devices based on the PIC18F4550 microcontroller with USB2.0 bus. The board has a PIC18F4550 controller in a TQFP44 package.


Rice. 21

Low Pin Count USB Development Kit (order number DM164127)

The Low Pin Count USB Development Kit provides an easy way to evaluate the microcontroller capabilities of the Microchip PIC18F14K50 and PIC18F13K50 20-pin USB microcontrollers. The kit includes everything you need to get started with USB controllers (software, example source files, documentation).


Rice. 22

PIC18F87J50 Full Speed ​​USB PIC18F87J50 FS USB Demo Board (order number MA180021)

The PIC18F87J50 FS USB Demo Board is used to debug Full Speed ​​USB 2.0 microcontrollers of the PIC18F87J50 family. In addition to autonomous operation, the board can also be used as a processor module for the PIC18 Explorer Board.


Rice. 23

PIC24 Starter Kit (order number DM240011)

The PIC24F Starter Kit contains everything you need to get started with the high performance PIC24F family of controllers. This inexpensive kit contains an integrated in-circuit debugger and programmer, a USB PIC24F controller (Host and Device functions can be implemented on the board), a tri-color LED, a capacitive touch panel and an OLED graphic display. The demo program through the graphical menu allows you to write data to an external USB Flash Drive, configure the touch panel and run graphics tasks.


Rice. 24

PIC32 USB Board (order number DM320003)

Allows you to master the USB-OTG module in PIC32 controllers


Rice. 25

Development board "Explorer 16 Development Board" (order number DM240001)

This is a low cost debugging tool for getting started with the high performance PIC24 16-bit microcontroller families and dsPIC33F digital signal processing controllers.


Rice. 26

Daughter board "USB PICtali Plus" (order number AC164131)

Together with USB processor plug-in modules, it allows you to develop and debug USB devices Host, Device, USB-OTG.


Rice. 27

Ilya Afanasiev,
Company

If you notice an error, select a piece of text and press Ctrl + Enter
SHARE: