00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 ,
00238 \endcode
00239
00240 The LED array is then defined, with the associated usage page. The Report
00241 descriptor is formatted in this order to avoid redefining unchanged <i>Global</i>
00242 items, in order to save memory. This time again, the LED status is reported as
00243 a bitmap field. Three LEDs are used here: Num Lock, Caps Lock and Scroll Lock
00244 (IDs 01h to 03h). It is important to note that this is an <b>Output</b> report:
00245 \code
00246
00247 HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
00248 HIDReport_GLOBAL_REPORTSIZE + 1, 1,
00249 HIDReport_GLOBAL_USAGEPAGE + 1, HIDLeds_PAGEID,
00250 HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
00251 HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
00252 HIDReport_LOCAL_USAGEMINIMUM + 1, HIDLeds_NUMLOCK,
00253 HIDReport_LOCAL_USAGEMAXIMUM + 1, HIDLeds_SCROLLLOCK,
00254 HIDReport_OUTPUT + 1, HIDReport_VARIABLE,
00255 \endcode
00256
00257 Since the previous report only contains 3 bits, the data must be padded to a
00258 multiple of one byte. This is done by using constant Output data, as follows:
00259 \code
00260
00261 HIDReport_GLOBAL_REPORTCOUNT + 1, 1,
00262 HIDReport_GLOBAL_REPORTSIZE + 1, 5,
00263 HIDReport_OUTPUT + 1, HIDReport_CONSTANT,
00264 \endcode
00265
00266 The last item, <i>End Collection</i>, is necessary to close the previously opened
00267 <i>Application Collection</i>.
00268 \code
00269 HIDReport_ENDCOLLECTION
00270 };
00271 \endcode
00272
00273 The Input and Output reports defined by this descriptor can be modeled by the
00274 following structures:
00275 \code
00276
00277 typedef struct {
00278
00279
00280 unsigned char bmModifierKeys:8;
00281
00282 unsigned char pressedKeys[HIDDMouseInputReport_MAXKEYPRESSES];
00283
00284 } __attribute__ ((packed)) HIDDMouseInputReport;
00285
00286 typedef struct {
00287
00288 unsigned char numLockStatus:1,
00289 capsLockStatus:1,
00290 scrollLockStatus:1,
00291 padding:5;
00292
00293 } __attribute__ ((packed)) HIDDMouseOutputReport;
00294 \endcode
00295
00296 An instance of each one of the reports is stored in a HIDDMouseDriver
00297 structure, which holds the standard class driver and HID Mouse-specific
00298 data.
00299
00300 \subsection psy_desc Physical Descriptor
00301 A Physical descriptor is useless for a Mouse %device, so none are defined
00302 in this example.
00303
00304 \subsection ep_desc Endpoint Descriptor
00305 Following the Interface and HID-specific descriptors, the two necessary
00306 endpoints are defined.
00307 \code
00308
00309 {
00310 sizeof(USBEndpointDescriptor),
00311 USBGenericDescriptor_ENDPOINT,
00312 USBEndpointDescriptor_ADDRESS(
00313 USBEndpointDescriptor_IN,
00314 HIDDMouseDriverDescriptors_INTERRUPTIN),
00315 USBEndpointDescriptor_INTERRUPT,
00316 sizeof(HIDDMouseInputReport),
00317 HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
00318 },
00319
00320 {
00321 sizeof(USBEndpointDescriptor),
00322 USBGenericDescriptor_ENDPOINT,
00323 USBEndpointDescriptor_ADDRESS(
00324 USBEndpointDescriptor_OUT,
00325 HIDDMouseDriverDescriptors_INTERRUPTOUT),
00326 USBEndpointDescriptor_INTERRUPT,
00327 sizeof(HIDDMouseOutputReport),
00328 HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
00329 }
00330 \endcode
00331
00332 \subsection str_desc String Descriptors
00333 Please refer to \ref usbd_id_str "Usage: USBD VID, PID & Strings".
00334
00335 \section class_spec_req Class-specific requests
00336 A driver request handler should first differentiate between class-specific and
00337 standard requests using the corresponding bits in the <i>bmRequestType</i> field.
00338 In most cases, standard requests can be immediately forwarded to the standard
00339 request handler method; class-specific methods must be decoded and treated by
00340 the custom handler.
00341
00342 \subsection GetDescriptor
00343 Three values have been added by the HID specification for the <b>GET_DESCRIPTOR</b>
00344 request. The high byte of the <i>wValue</i> field contains the type of the
00345 requested descriptor; in addition to the standard types, the <b>HID specification</b>
00346 adds the <b>HID descriptor</b> (21h), the <b>Report descriptor</b>
00347 (22h) and the <b>Physical descriptor</b> (23h) types.
00348
00349 There is no particular action to perform besides sending the descriptor. This
00350 can be done by using the USBD_Write() method, after the requested descriptor has
00351 been identified:
00352 \code
00353 switch (USBGenericRequest_GetRequest(request)) {
00354
00355 case USBGenericRequest_GETDESCRIPTOR:
00356
00357
00358
00359 if (!HIDDMouseDriver_GetDescriptor(
00360 USBGetDescriptorRequest_GetDescriptorType(request),
00361 USBGenericRequest_GetLength(request))) {
00362
00363 USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
00364 request);
00365 }
00366 break;
00367
00368 default:
00369 USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
00370 request);
00371 }
00372 \endcode
00373 A slight complexity of the GET_DESCRIPTOR and SET_DESCRIPTOR requests is that
00374 those are standard requests, but the standard request handler
00375 (USBDDriver_RequestHandler()) must not always be called to treat them (since
00376 they may refer to HID descriptors). The solution is to first identify
00377 GET/SET_DESCRIPTOR requests, treat the HID-specific cases and, finally,
00378 forward any other request to the standard handler.
00379
00380 In this case, a GET_DESCRIPTOR request for the Physical descriptor is first
00381 forwarded to the standard handler, and STALLed there because it is not
00382 recognized. This is done because the %device does not have any Physical
00383 descriptors, and thus, does not need to handle the associated request.
00384
00385 \subsection SetDescriptor
00386 This request is optional and is never issued by most hosts. It is not
00387 implemented in this example.
00388
00389 \subsection GetReport
00390 Since the HID Mouse defines two different reports, the Report Type value
00391 specified by this request (upper byte of the <i>wValue</i> field) must be examined
00392 to decide which report to send. If the type value is 01h, then the Input
00393 report must be returned; if it is 02h, the Output report is requested:
00394 \code
00395 case HIDGenericRequest_GETREPORT:
00396
00397 type = HIDReportRequest_GetReportType(request);
00398 length = USBGenericRequest_GetLength(request);
00399 switch (type) {
00400
00401 case HIDReportRequest_INPUT:
00402
00403
00404 if (length > sizeof(HIDDMouseInputReport)) {
00405
00406 length = sizeof(HIDDMouseInputReport);
00407 }
00408 USBD_Write(0,
00409 &(hiddMouseDriver.inputReport),
00410 length,
00411 0,
00412 0);
00413 break;
00414
00415 case HIDReportRequest_OUTPUT:
00416
00417
00418 if (length > sizeof(HIDDMouseOutputReport)) {
00419
00420 length = sizeof(HIDDMouseOutputReport);
00421 }
00422 USBD_Write(0,
00423 &(hiddMouseDriver.outputReport),
00424 length,
00425 0,
00426 0);
00427 break;
00428
00429 default:
00430 USBD_Stall(0);
00431 }
00432 break;
00433 \endcode
00434
00435 \subsection SetReport
00436 For an HID Mouse, the <b>SET_REPORT</b> command can be sent by the host to
00437 change the state of the LEDs. Normally, the dedicated Interrupt OUT endpoint
00438 will be used for this; but in some cases, using the default Control endpoint
00439 can save some bandwidth on the host side.
00440
00441 Note that the SET_REPORT request can be directed at the Input report of the
00442 Mouse; in this case, it can be safely discarded, according to the HID
00443 specification. Normally, most host drivers only target the Output report. The
00444 Report Type value is stored in the upper byte of the <i>wValue</i> field.
00445
00446 The length of the data phase to follow is stored in the <i>wLength</i> field of the
00447 request. It should be equal to the total length of the Output report. If it is
00448 different, the report status must still be updated with the received data as
00449 best as possible.
00450
00451 When the reception of the new data is completed, some processing must be done
00452 to enable/disable the corresponding LEDs. This is done in the callback
00453 function passed as an argument to USBD_Read():
00454 \code
00455 case HIDGenericRequest_SETREPORT:
00456
00457 type = HIDReportRequest_GetReportType(request);
00458 length = USBGenericRequest_GetLength(request);
00459 switch(type) {
00460
00461 case HIDReportRequest_INPUT:
00462
00463 USBD_Stall(0);
00464 break;
00465
00466 case HIDReportRequest_OUTPUT:
00467
00468 if (length != sizeof(HIDDMouseOutputReport)) {
00469
00470 USBD_Stall(0);
00471 }
00472 else {
00473
00474 USBD_Read(0,
00475 &(hiddMouseDriver.outputReport),
00476 length,
00477 (TransferCallback) HIDDMouseDriver_ReportReceived,
00478 0);
00479 }
00480 break;
00481
00482 default:
00483 USBD_Stall(0);
00484 }
00485 break;
00486 \endcode
00487
00488 \subsection SetIdle
00489 In this case study, the <b>SET_IDLE</b> request is used to set a delay before a key
00490 is repeated. This is common behavior on Mouse devices. Usually, this delay
00491 is set to about 500 ms by the host.
00492
00493 The only action here is to store the new Idle rate. The management of this
00494 setting must be done in the main function, since Interrupt IN reports are sent
00495 from there.
00496
00497 In practice, it is not necessary to perform any action, apart from sending a
00498 zero-length packet to acknowledge it. The main application however has to make
00499 sure that only new reports are sent by the %device.
00500 \code
00501 case HIDGenericRequest_SETIDLE:
00502
00503 hiddMouseDriver.inputReportIdleRate =
00504 HIDIdleRequest_GetIdleRate(request);
00505 USBD_Write(0, 0, 0, 0, 0);
00506 break;
00507 \endcode
00508
00509 \subsection GetIdle
00510 The only necessary operation for this request is to send the previously saved
00511 Idle rate. This is done by calling the USBD_Write() method with the one-byte
00512 variable as its parameter:
00513 \code
00514 case HIDGenericRequest_GETIDLE:
00515
00516 USBD_Write(0, &(hiddMouseDriver.inputReportIdleRate), 1, 0, 0);
00517 break;
00518 \endcode
00519
00520 \subsection get_set_prot GetProtocol, SetProtocol
00521 This HID Mouse example does not support the Boot protocol, so there is no
00522 need to implement the SET_PROTOCOL and GET_PROTOCOL requests. This means they
00523 can be safely STALLed when received.
00524
00525 \section main_app Main Application
00526 Like the mouse example, the main program must perform two different
00527 operations. First, it has to monitor the physical inputs used as keys. In the
00528 example software, the buttons present on the evaluation boards are used to
00529 produce several modifier and alphanumeric keys.
00530
00531 Also, the main program is in charge of sending reports as they are modified,
00532 taking into account the Idle rate specified by the host. Idle rate management
00533 can be carried out by firing/resetting a timer once a new report is sent; if
00534 the timer expires, this means the Input report has not changed since.
00535 According to the HID specification, a single instance of the report must be
00536 sent in this case.
00537
00538 Finally, the HID specification also defines that if too many keys are pressed
00539 at the same time, the %device should report an <i>ErrorRollOver</i> usage value
00540 (01h) in every byte of the key array. This has to be handled by the main
00541 application as well.
00542
00543 */