USB Component  Version 6.17.0
MDK Middleware for USB Device and Host Communication
HID: Human Interface Class

Implement application specific behaviour of a Human Interface Device (HID) Class USB Device. More...

Content

 User API
 User API reference of the Human Interface Device Class.
 
 Configuration
 Configuration of the USB Device HID Class in µVision.
 

Description

Implement application specific behaviour of a Human Interface Device (HID) Class USB Device.

The HID class in the USB Component is used for data exchange. It implements a vendor defined HID class with Usage Page ID=0xFF00.

Refer to:

The USB Component allows multiple instances of the HID class. This feature is used to create USB Composite Devices. Each HID class instance has a separate files and interface functions:

This documentation uses n as a placeholder for the instance number 0 - 3. Most applications only require one instance of a HID class. For the first HID class instance the instance number is 0:

Descriptor Requirements The following descriptors are required in an USB HID Device:

The necessary descriptors are automatically generated by the USB Middleware Component. The report descriptor is built based on the settings in the USBD_Config_HID_x.h file. The number of reports and their maximum size are specified in this file. The page USB Descriptors provides more information on the topic.

Software Structure

The handling for the HID class endpoint events is implemented in USBD_HIDn_Thread which is started by USBD_Initialize. Each instance of a HID class runs an instance of USBD_HIDn_Thread which calls the data exchange functions USBD_HIDn_GetReport and USBD_HIDn_SetReport.

USBD_HID_GetReportTrigger may be called from any user thread to send asynchronous data reports to the USB Host. USBD_HID_GetReportTrigger cannot be called from interrupt service routines (ISR) as it may wait for previous data to be sent.

The HID class uses a CMSIS-RTOS osTimer set to a 4ms interval to handle polling reports. The polling timing is defined with Endpoint Descriptor. For more information refer to "Set_Idle Request" in Device Class Definition HID specification which is provided by USB Implementers Forum (USB-IF).

msc_inline_mscgraph_6

Implementation

To create an USB Device with a HID class:

User Code Templates
There are two user code templates available that help to add support for an HID device:

  1. USBD_User_HID.c contains all the callback functions that need to be implemented by the user.
  2. USBD_User_HID_Mouse.c is a code template for the application specific functionality of a USB HID Device acting as a mouse pointer input device.

User Code Template USBD_User_HID.c

The following source code can be used to implement the application specific behavior of an USB HID Device.

/*------------------------------------------------------------------------------
* MDK Middleware - Component ::USB:Device:HID
* Copyright (c) 2004-2020 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: USBD_User_HID_n.c
* Purpose: USB Device Human Interface Device class (HID) User module
* Rev.: V6.2.4
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include "rl_usb.h"
// Called during USBD_Initialize to initialize the USB HID class instance.
void USBD_HIDn_Initialize (void) {
// Add code for initialization
}
// Called during USBD_Uninitialize to de-initialize the USB HID class instance.
// Add code for de-initialization
}
// \brief Prepare HID Report data to send.
// \param[in] rtype report type:
// - HID_REPORT_INPUT = input report requested
// - HID_REPORT_FEATURE = feature report requested
// \param[in] req request type:
// - USBD_HID_REQ_EP_CTRL = control endpoint request
// - USBD_HID_REQ_PERIOD_UPDATE = idle period expiration request
// - USBD_HID_REQ_EP_INT = previously sent report on interrupt endpoint request
// \param[in] rid report ID (0 if only one report exists).
// \param[out] buf buffer containing report data to send.
// \return number of report data bytes prepared to send or invalid report requested.
// - value >= 0: number of report data bytes prepared to send
// - value = -1: invalid report requested
int32_t USBD_HIDn_GetReport (uint8_t rtype, uint8_t req, uint8_t rid, uint8_t *buf) {
(void)buf;
switch (rtype) {
case HID_REPORT_INPUT:
switch (rid) {
case 0:
switch (req) {
case USBD_HID_REQ_EP_CTRL: // Explicit USB Host request via Control OUT Endpoint
case USBD_HID_REQ_PERIOD_UPDATE: // Periodic USB Host request via Interrupt OUT Endpoint
// Update buffer for report data, example:
// buf[0] = 0; // Data Value = 0
// buf[1] = 5; // Data Value = 5
// return 2; // Data Size = 2 bytes
break;
case USBD_HID_REQ_EP_INT: // Called after USBD_HID_GetReportTrigger to signal
// data obtained.
break;
default:
break;
}
break;
default:
break;
}
break;
case HID_REPORT_FEATURE:
break;
default:
break;
}
return 0;
}
// \brief Process received HID Report data.
// \param[in] rtype report type:
// - HID_REPORT_OUTPUT = output report received
// - HID_REPORT_FEATURE = feature report received
// \param[in] req request type:
// - USBD_HID_REQ_EP_CTRL = report received on control endpoint
// - USBD_HID_REQ_EP_INT = report received on interrupt endpoint
// \param[in] rid report ID (0 if only one report exists).
// \param[in] buf buffer that receives report data.
// \param[in] len length of received report data.
// \return true received report data processed.
// \return false received report data not processed or request not supported.
bool USBD_HIDn_SetReport (uint8_t rtype, uint8_t req, uint8_t rid, const uint8_t *buf, int32_t len) {
(void)req;
(void)rid;
(void)buf;
(void)len;
switch (rtype) {
case HID_REPORT_OUTPUT:
/*
buf: Received Data
len: Received Data Length
*/
break;
case HID_REPORT_FEATURE:
break;
default:
break;
}
return true;
}

User Code Template USBD_User_HID_Mouse.c

The following source code can be used to implement the application specific behavior of an USB HID Mouse Device.

/*------------------------------------------------------------------------------
* MDK Middleware - Component ::USB:Device:HID
* Copyright (c) 2004-2020 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: USBD_User_HID_Mouse_n.c
* Purpose: USB Device Human Interface Device class (HID) User module
* Rev.: V6.3.4
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include "rl_usb.h"
// User Provided HID Report Descriptor
// for standard mouse (size of this descriptor is 52 bytes)
extern
const uint8_t usbd_hidn_report_descriptor[];
const uint8_t usbd_hidn_report_descriptor[] = {
HID_UsagePage(HID_USAGE_PAGE_GENERIC),
HID_Usage(HID_USAGE_GENERIC_MOUSE),
HID_Collection(HID_Application),
HID_Usage(HID_USAGE_GENERIC_POINTER),
HID_Collection(HID_Physical),
HID_UsagePage(HID_USAGE_PAGE_BUTTON),
HID_UsageMin(1),
HID_UsageMax(3),
HID_LogicalMin(0),
HID_LogicalMax(1),
HID_ReportCount(3),
HID_ReportSize(1),
HID_Input(HID_Variable),
HID_ReportCount(1),
HID_ReportSize(5),
HID_Input(HID_Constant),
HID_UsagePage(HID_USAGE_PAGE_GENERIC),
HID_Usage(HID_USAGE_GENERIC_X),
HID_Usage(HID_USAGE_GENERIC_Y),
HID_Usage(HID_USAGE_GENERIC_WHEEL),
HID_LogicalMin((uint8_t)(-127)),
HID_LogicalMax(127),
HID_ReportSize(8),
HID_ReportCount(3),
HID_Input(HID_Variable | HID_Relative),
HID_EndCollection,
HID_EndCollection,
};
// Called during USBD_Initialize to initialize the USB HID class instance.
void USBD_HIDn_Initialize (void) {
// Add code for initialization
}
// Called during USBD_Uninitialize to de-initialize the USB HID class instance.
// Add code for de-initialization
}
// \brief Prepare HID Report data to send.
// \param[in] rtype report type:
// - HID_REPORT_INPUT = input report requested
// - HID_REPORT_FEATURE = feature report requested
// \param[in] req request type:
// - USBD_HID_REQ_EP_CTRL = control endpoint request
// - USBD_HID_REQ_PERIOD_UPDATE = idle period expiration request
// - USBD_HID_REQ_EP_INT = previously sent report on interrupt endpoint request
// \param[in] rid report ID (0 if only one report exists).
// \param[out] buf buffer containing report data to send.
// \return number of report data bytes prepared to send or invalid report requested.
// - value >= 0: number of report data bytes prepared to send
// - value = -1: invalid report requested
int32_t USBD_HIDn_GetReport (uint8_t rtype, uint8_t req, uint8_t rid, uint8_t *buf) {
(void)buf;
switch (rtype) {
case HID_REPORT_INPUT:
switch (rid) {
case 0:
switch (req) {
case USBD_HID_REQ_EP_CTRL: // Explicit USB Host request via Control OUT Endpoint
case USBD_HID_REQ_PERIOD_UPDATE: // Periodic USB Host request via Interrupt OUT Endpoint
// Update buffer for report data, example:
// buf[0] = 0; // Data Value = 0
// buf[1] = 5; // Data Value = 5
// return (2); // Data Size = 2 bytes
break;
case USBD_HID_REQ_EP_INT: // Called after USBD_HID_GetReportTrigger to signal
// data obtained.
break;
default:
break;
}
break;
default:
break;
}
break;
case HID_REPORT_FEATURE:
break;
default:
break;
}
return (0);
}
// \brief Process received HID Report data.
// \param[in] rtype report type:
// - HID_REPORT_OUTPUT = output report received
// - HID_REPORT_FEATURE = feature report received
// \param[in] req request type:
// - USBD_HID_REQ_EP_CTRL = report received on control endpoint
// - USBD_HID_REQ_EP_INT = report received on interrupt endpoint
// \param[in] rid report ID (0 if only one report exists).
// \param[in] buf buffer that receives report data.
// \param[in] len length of received report data.
// \return true received report data processed.
// \return false received report data not processed or request not supported.
bool USBD_HIDn_SetReport (uint8_t rtype, uint8_t req, uint8_t rid, const uint8_t *buf, int32_t len) {
(void)req;
(void)rid;
(void)buf;
(void)len;
switch (rtype) {
case HID_REPORT_OUTPUT:
/*
buf: Received Data
len: Received Data Length
*/
break;
case HID_REPORT_FEATURE:
break;
default:
break;
}
return true;
}