⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hid-mouse.dir

📁 本代bootloader通过usb下载代码首先存放在sdram中
💻 DIR
📖 第 1 页 / 共 2 页
字号:

 The Input and Output reports defined by this descriptor can be modeled by the
 following structures:
\code
// HID Input Report
typedef struct {

  // State of modifier keys.
  unsigned char bmModifierKeys:8;
  // Key codes of pressed keys.
  unsigned char pressedKeys[HIDDMouseInputReport_MAXKEYPRESSES];

} __attribute__ ((packed)) HIDDMouseInputReport; // GCC
// HID Output Report
typedef struct {

  unsigned char numLockStatus:1, // State of the num. lock LED.
    capsLockStatus:1,   // State of the caps lock LED.
    scrollLockStatus:1, // State of the scroll lock LED.
    padding:5;          // Padding bits.

} __attribute__ ((packed)) HIDDMouseOutputReport; // GCC
\endcode

 An instance of each one of the reports is stored in a HIDDMouseDriver
 structure, which holds the standard class driver and HID Mouse-specific
 data.

 !!Physical Descriptor
 A Physical descriptor is useless for a Mouse %device, so none are defined
 in this example.

 !!Endpoint Descriptor
 Following the Interface and HID-specific descriptors, the two necessary
 endpoints are defined.
\code
// Interrupt IN endpoint descriptor
{
    sizeof(USBEndpointDescriptor),
    USBGenericDescriptor_ENDPOINT,
    USBEndpointDescriptor_ADDRESS(
        USBEndpointDescriptor_IN,
        HIDDMouseDriverDescriptors_INTERRUPTIN),
    USBEndpointDescriptor_INTERRUPT,
    sizeof(HIDDMouseInputReport),
    HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
},
// Interrupt OUT endpoint descriptor
{
    sizeof(USBEndpointDescriptor),
    USBGenericDescriptor_ENDPOINT,
    USBEndpointDescriptor_ADDRESS(
        USBEndpointDescriptor_OUT,
        HIDDMouseDriverDescriptors_INTERRUPTOUT),
    USBEndpointDescriptor_INTERRUPT,
    sizeof(HIDDMouseOutputReport),
    HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
}
\endcode

 !!String Descriptors
 Please refer to "Usage: USBD VID, PID & Strings".

 !!!Class-specific requests
 A driver request handler should first differentiate between class-specific and
 standard requests using the corresponding bits in the }bmRequestType} field.
 In most cases, standard requests can be immediately forwarded to the standard
 request handler method; class-specific methods must be decoded and treated by
 the custom handler.

 !!GetDescriptor
 Three values have been added by the HID specification for the #GET_DESCRIPTOR#
 request. The high byte of the }wValue} field contains the type of the
 requested descriptor; in addition to the standard types, the #HID
 specification# adds the #HID descriptor# (21h), the #Report descriptor#
 (22h) and the #Physical descriptor# (23h) types.

 There is no particular action to perform besides sending the descriptor. This
 can be done by using the USBD_Write method, after the requested descriptor has
 been identified:
\code
switch (USBGenericRequest_GetRequest(request)) {

  case USBGenericRequest_GETDESCRIPTOR:
    // Check if this is a HID descriptor,
    // otherwise forward it to
    // the standard driver
    if (!HIDDMouseDriver_GetDescriptor(
        USBGetDescriptorRequest_GetDescriptorType(request),
        USBGenericRequest_GetLength(request))) {

      USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
                              request);
    }
    break;

  default:
    USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
                                  request);
}
\endcode
 A slight complexity of the GET_DESCRIPTOR and SET_DESCRIPTOR requests is that
 those are standard requests, but the standard request handler
 (USBDDriver_RequestHandler) must not always be called to treat them (since
 they may refer to HID descriptors). The solution is to first identify
 GET/SET_DESCRIPTOR requests, treat the HID-specific cases and, finally,
 forward any other request to the standard handler.

 In this case, a GET_DESCRIPTOR request for the Physical descriptor is first
 forwarded to the standard handler, and STALLed there because it is not
 recognized. This is done because the %device does not have any Physical
 descriptors, and thus, does not need to handle the associated request.

 !!SetDescriptor
 This request is optional and is never issued by most hosts. It is not
 implemented in this example.

 !!GetReport
 Since the HID Mouse defines two different reports, the Report Type value
 specified by this request (upper byte of the }wValue} field) must be examined
 to decide which report to send. If the type value is 01h, then the Input
 report must be returned; if it is 02h, the Output report is requested:
\code
case HIDGenericRequest_GETREPORT:
//-------------------------------
  type = HIDReportRequest_GetReportType(request);
  length = USBGenericRequest_GetLength(request);
  switch (type) {

      case HIDReportRequest_INPUT:

        // Adjust size and send report
        if (length > sizeof(HIDDMouseInputReport)) {

          length = sizeof(HIDDMouseInputReport);
        }
        USBD_Write(0, // Endpoint #0
           &(hiddMouseDriver.inputReport),
           length,
           0, // No callback
           0);
        break;

      case HIDReportRequest_OUTPUT:

        // Adjust size and send report
        if (length > sizeof(HIDDMouseOutputReport)) {

          length = sizeof(HIDDMouseOutputReport);
        }
        USBD_Write(0, // Endpoint #0
           &(hiddMouseDriver.outputReport),
           length,
           0, // No callback
           0);
        break;

      default:
        USBD_Stall(0);
  }
break;
\endcode

 !!SetReport
 For an HID Mouse, the #SET_REPORT# command can be sent by the host to
 change the state of the LEDs. Normally, the dedicated Interrupt OUT endpoint
 will be used for this; but in some cases, using the default Control endpoint
 can save some bandwidth on the host side.

 Note that the SET_REPORT request can be directed at the Input report of the
 Mouse; in this case, it can be safely discarded, according to the HID
 specification. Normally, most host drivers only target the Output report. The
 Report Type value is stored in the upper byte of the }wValue} field.

 The length of the data phase to follow is stored in the }wLength} field of the
 request. It should be equal to the total length of the Output report. If it is
 different, the report status must still be updated with the received data as
 best as possible.

 When the reception of the new data is completed, some processing must be done
 to enable/disable the corresponding LEDs. This is done in the callback
 function passed as an argument to USBD_Read:
\code
case HIDGenericRequest_SETREPORT:
//-------------------------------
  type = HIDReportRequest_GetReportType(request);
  length = USBGenericRequest_GetLength(request);
  switch(type) {

    case HIDReportRequest_INPUT:
      // SET_REPORT requests on input reports are ignored
      USBD_Stall(0);
      break;

    case HIDReportRequest_OUTPUT:
      // Check report length
      if (length != sizeof(HIDDMouseOutputReport)) {

        USBD_Stall(0);
      }
      else {
      
        USBD_Read(0, // Endpoint #0
          &(hiddMouseDriver.outputReport),
          length,
          (TransferCallback) HIDDMouseDriver_ReportReceived,
          0); // No argument to the callback function
      }
      break;

    default:
      USBD_Stall(0);
  }
break;
\endcode

 !!SetIdle
 In this case study, the #SET_IDLE# request is used to set a delay before a key
 is repeated. This is common behavior on Mouse devices. Usually, this delay
 is set to about 500 ms by the host.

 The only action here is to store the new Idle rate. The management of this
 setting must be done in the main function, since Interrupt IN reports are sent
 from there.

 In practice, it is not necessary to perform any action, apart from sending a
 zero-length packet to acknowledge it. The main application however has to make
 sure that only new reports are sent by the %device.
\code
case HIDGenericRequest_SETIDLE:
//-----------------------------
  hiddMouseDriver.inputReportIdleRate =
           HIDIdleRequest_GetIdleRate(request);
  USBD_Write(0, 0, 0, 0, 0);
break;
\endcode

 !!GetIdle
 The only necessary operation for this request is to send the previously saved
 Idle rate. This is done by calling the USBD_Write method with the one-byte
 variable as its parameter:
\code
case HIDGenericRequest_GETIDLE:
//-----------------------------
  USBD_Write(0, &(hiddMouseDriver.inputReportIdleRate), 1, 0, 0);
break;
\endcode

 !!GetProtocol, SetProtocol
 This HID Mouse example does not support the Boot protocol, so there is no
 need to implement the SET_PROTOCOL and GET_PROTOCOL requests. This means they
 can be safely STALLed when received.

 !!!Main Application
 Like the mouse example, the main program must perform two different
 operations. First, it has to monitor the physical inputs used as keys. In the
 example software, the buttons present on the evaluation boards are used to
 produce several modifier and alphanumeric keys.

 Also, the main program is in charge of sending reports as they are modified,
 taking into account the Idle rate specified by the host. Idle rate management
 can be carried out by firing/resetting a timer once a new report is sent; if
 the timer expires, this means the Input report has not changed since.
 According to the HID specification, a single instance of the report must be
 sent in this case.

 Finally, the HID specification also defines that if too many keys are pressed
 at the same time, the %device should report an }ErrorRollOver} usage value
 (01h) in every byte of the key array. This has to be handled by the main
 application as well.

*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -