...
Some constants are available to customize the class. These constants are located in the USB device configuration file, usbd_cfg.h
. shows Table - HID Class Configuration Constants shows their description.
Excerpt | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
The HID class uses an internal task to manage periodic input reports. The task priority and stack size shown in are Table - HID Internal Task’s Configuration Constants are defined in the application configuration file,
|
Class Instance Configuration
Before starting the communication phase, your application needs to initialize and configure the class to suit its needs. summarizes Table - HID Class Initialization API Summary summarizes the initialization functions provided by the HID class. For more details about the functions parameters, refer to the HID API Reference.
Anchor | ||||
---|---|---|---|---|
|
Panel | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
|
You need to call these functions in the order shown below to successfully initialize the HID class:
...
Finally, once the HID class instance has been created, you must add it to a specific configuration.
Listing - HID Class Initialization Example illustrates the use of the previous functions for initializing the HID class.
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||||
---|---|---|---|---|
| ||||
static USBD_HID_CALLBACK App_USBD_HID_Callback = { (3)
App_USBD_HID_GetFeatureReport,
App_USBD_HID_SetFeatureReport,
App_USBD_HID_GetProtocol,
App_USBD_HID_SetProtocol,
App_USBD_HID_ReportSet
};
CPU_BOOLEAN App_USBD_HID_Init (CPU_INT08U dev_nbr,
CPU_INT08U cfg_hs,
CPU_INT08U cfg_fs)
{
USBD_ERR err;
CPU_INT08U class_nbr;
USBD_HID_Init(&err); (1)
if (err != USBD_ERR_NONE) {
/* Handle the error. */
}
class_nbr = USBD_HID_Add( USBD_HID_SUBCLASS_BOOT, (2)
USBD_HID_PROTOCOL_MOUSE,
USBD_HID_COUNTRY_CODE_NOT_SUPPORTED,
&App_USBD_HID_ReportDesc[0],
sizeof(App_USBD_HID_ReportDesc),
(CPU_INT08U *)0,
0u,
2u,
2u,
DEF_YES,
&App_USBD_HID_Callback, (3)
&err);
if (err != USBD_ERR_NONE) {
/* Handle the error. */
}
if (cfg_hs != USBD_CFG_NBR_NONE) {
USBD_HID_CfgAdd(class_nbr, dev_nbr, cfg_hs, &err); (4)
if (err != USBD_ERR_NONE) {
/* Handle the error. */
}
}
if (cfg_fs != USBD_CFG_NBR_NONE) {
USBD_HID_CfgAdd(class_nbr, dev_nbr, cfg_fs, &err); (5)
if (err != USBD_ERR_NONE) {
/* Handle the error. */
}
}
} |
Panel | ||
---|---|---|
| ||
(1) Initialize HID internal structures, variables and OS layer. (2) Create a new HID class instance. In this example, the subclass is “Boot”, the protocol is “Mouse” and the country code is unknown. A table, (3) There are 5 application callbacks for class-specific requests processing. There is one callback for each of the following requests: (4) Check if the high-speed configuration is active and proceed to add the HID instance previously created to this configuration. (5) Check if the full-speed configuration is active and proceed to add the HID instance to this configuration. |
Listing - HID Class Initialization Example also illustrates an example of multiple configurations. The functions USBD_HID_Add()
and USBD_HID_CfgAdd()
allow you to create multiple configurations and multiple instances architecture. Refer to for to Table - Constants and Functions Related to the Concept of Multiple Class Instances for more details about multiple class instances.
Listing - Mouse Report Descriptor Example presents an example of table declaration defining a Report descriptor corresponding to a mouse. The example matches the mouse report descriptor viewed by the host HID parser in Figure - Report Descriptor Content from a Host HID Parser View. The mouse report represents an Input report. Refer to the Report section for more details about the Report descriptor format. The items inside a collection are intentionally indented for code clarity.
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||||
---|---|---|---|---|
| ||||
static CPU_INT08U App_USBD_HID_ReportDesc[] = { (1) (2)
USBD_HID_GLOBAL_USAGE_PAGE + 1, USBD_HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS,
USBD_HID_LOCAL_USAGE + 1, USBD_HID_CA_MOUSE, (3)
USBD_HID_MAIN_COLLECTION + 1, USBD_HID_COLLECTION_APPLICATION, (4)
USBD_HID_LOCAL_USAGE + 1, USBD_HID_CP_POINTER, (5)
USBD_HID_MAIN_COLLECTION + 1, USBD_HID_COLLECTION_PHYSICAL, (6)
USBD_HID_GLOBAL_USAGE_PAGE + 1, USBD_HID_USAGE_PAGE_BUTTON, (7)
USBD_HID_LOCAL_USAGE_MIN + 1, 0x01,
USBD_HID_LOCAL_USAGE_MAX + 1, 0x03,
USBD_HID_GLOBAL_LOG_MIN + 1, 0x00,
USBD_HID_GLOBAL_LOG_MAX + 1, 0x01,
USBD_HID_GLOBAL_REPORT_COUNT + 1, 0x03,
USBD_HID_GLOBAL_REPORT_SIZE + 1, 0x01,
USBD_HID_MAIN_INPUT + 1, USBD_HID_MAIN_DATA |
USBD_HID_MAIN_VARIABLE |
USBD_HID_MAIN_ABSOLUTE,
USBD_HID_GLOBAL_REPORT_COUNT + 1, 0x01, (8)
USBD_HID_GLOBAL_REPORT_SIZE + 1, 0x0D,
USBD_HID_MAIN_INPUT + 1, USBD_HID_MAIN_CONSTANT,
(9)
USBD_HID_GLOBAL_USAGE_PAGE + 1, USBD_HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS,
USBD_HID_LOCAL_USAGE + 1, USBD_HID_DV_X,
USBD_HID_LOCAL_USAGE + 1, USBD_HID_DV_Y,
USBD_HID_GLOBAL_LOG_MIN + 1, 0x81,
USBD_HID_GLOBAL_LOG_MAX + 1, 0x7F,
USBD_HID_GLOBAL_REPORT_SIZE + 1, 0x08,
USBD_HID_GLOBAL_REPORT_COUNT + 1, 0x02,
USBD_HID_MAIN_INPUT + 1, USBD_HID_MAIN_DATA |
USBD_HID_MAIN_VARIABLE |
USBD_HID_MAIN_RELATIVE,
USBD_HID_MAIN_ENDCOLLECTION, (10)
USBD_HID_MAIN_ENDCOLLECTION (11)
}; |
Panel |
---|
(1) The table representing a mouse Report descriptor is initialized in such way that each line corresponds to a short item. The latter is formed from a 1-byte prefix and a 1-byte data. Refer to “Device Class Definition for Human Interface Devices (HID) Version 1.11”, sections 5.3 and 6.2.2.2 for more details about short items format. This table content corresponds to the mouse Report descriptor content viewed by a host HID parser in Figure - Report Descriptor Content from a Host HID Parser View. (2) The Generic Desktop Usage Page is used. (3) Within the Generic Desktop Usage Page, the usage tag suggests that the group of controls is for controlling a mouse. A mouse collection typically consists of two axes (X and Y) and one, two, or three buttons. (4) The mouse collection is started. (5) Within the mouse collection, a usage tag suggests more specifically that the mouse controls belong to the pointer collection. A pointer collection is a collection of axes that generates a value to direct, indicate, or point user intentions to an application. (6) The pointer collection is started. (7) The Buttons Usage Page defines an Input item composed of three 1-bit fields. Each 1-bit field represents the mouse’s button 1, 2 and 3 respectively and can return a value of 0 or 1. (8) The Input Item for the Buttons Usage Page is padded with 13 other bits. (9) Another Generic Desktop Usage Page is indicated for describing the mouse position with the axes X and Y. The Input item is composed of two 8-bit fields whose value can be between -127 and 127. (10) The pointer collection is closed. (11) The mouse collection is closed. |
Class Instance Communication
The HID class offers the following functions to communicate with the host. For more details about the functions parameters, refer to the HID API Reference.
Anchor | ||||
---|---|---|---|---|
|
Panel | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
|
Synchronous Communication
Synchronous communication means that the transfer is blocking. Upon function call, the applications blocks until the transfer completion with or without an error. A timeout can be specified to avoid waiting forever.
presents Listing - Synchronous Bulk Read and Write Example presents a read and write example to receive data from the host using the interrupt OUT endpoint and to send data to the host using the interrupt IN endpoint.
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||||
---|---|---|---|---|
| ||||
CPU_INT08U rx_buf[2];
CPU_INT08U tx_buf[2];
USBD_ERR err;
(void)USBD_HID_Rd( class_nbr, (1)
(void *)&rx_buf[0], (2)
2u,
0u, (3)
&err);
if (err != USBD_ERR_NONE) {
/* $$$$ Handle the error. */
}
(void)USBD_HID_Wr( class_nbr, (1)
(void *)&tx_buf[0], (4)
2u,
0u, (3)
&err);
if (err != USBD_ERR_NONE) {
/* $$$$ Handle the error. */
} |
Panel | ||
---|---|---|
| ||
(1) The class instance number created from (2) The application must ensure that the buffer provided to the function is large enough to accommodate all the data. Otherwise, synchronization issues might happen. Internally, the read operation is done either with the control endpoint or with the interrupt endpoint depending on the control read flag set when calling (3) In order to avoid an infinite blocking situation, a timeout expressed in milliseconds can be specified. A value of ‘0’ makes the application task wait forever. (4) The application provides the initialized transmit buffer. |
Asynchronous Communication
Asynchronous communication means that the transfer is non-blocking. Upon function call, the application passes the transfer information to the device stack and does not block. Other application processing can be done while the transfer is in progress over the USB bus. Once the transfer is completed, a callback is called by the device stack to inform the application about the transfer completion.
Listing - Asynchronous Bulk Read and Write Example shows an example of an asynchronous read and write.
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||||
---|---|---|---|---|
| ||||
void App_USBD_HID_Comm (CPU_INT08U class_nbr)
{
CPU_INT08U rx_buf[2];
CPU_INT08U tx_buf[2];
USBD_ERR err;
USBD_HID_RdAsync( class_nbr, (1)
(void *)&rx_buf[0], (2)
2u,
App_USBD_HID_RxCmpl, (3)
(void *) 0u, (4)
&err);
if (err != USBD_ERR_NONE) {
/* Handle the error. */
}
USBD_HID_WrAsync( class_nbr, (1)
(void *)&tx_buf[0], (5)
2u,
App_USBD_HID_TxCmpl, (3)
(void *) 0u, (4)
&err);
if (err != USBD_ERR_NONE) {
/* $$$$ Handle the error. */
}
}
static void App_USBD_HID_RxCmpl (CPU_INT08U class_nbr, (3)
void *p_buf,
CPU_INT32U buf_len,
CPU_INT32U xfer_len,
void *p_callback_arg,
USBD_ERR err)
{
(void)class_nbr;
(void)p_buf;
(void)buf_len;
(void)xfer_len;
(void)p_callback_arg; (4)
if (err == USBD_ERR_NONE) {
/* $$$$ Do some processing. */
} else {
/* $$$$ Handle the error. */
}
}
static void App_USBD_HID_TxCmpl (CPU_INT08U class_nbr, (3)
void *p_buf,
CPU_INT32U buf_len,
CPU_INT32U xfer_len,
void *p_callback_arg,
USBD_ERR err)
{
(void)class_nbr;
(void)p_buf;
(void)buf_len;
(void)xfer_len;
(void)p_callback_arg; (4)
if (err == USBD_ERR_NONE) {
/* $$$$ Do some processing. */
} else {
/* $$$$ Handle the error. */
}
} |
Panel | ||
---|---|---|
| ||
(1) The class instance number serves internally for the HID class to route the transfer to the proper interrupt OUT or IN endpoint. (2) The application must ensure that the buffer provided to the function is large enough to accommodate all the data. Otherwise, synchronization issues might happen. Internally, the read operation is done either with the control endpoint or with the interrupt endpoint depending on the control read flag set when calling (3) The application provides a callback passed as a parameter. Upon completion of the transfer, the device stack calls this callback so that the application can finalize the transfer by analyzing the transfer result. For instance, upon read operation completion, the application may do a certain processing with the received data. Upon write completion, the application may indicate if the write was successful and how many bytes were sent. (4) An argument associated to the callback can be also passed. Then in the callback context, some private information can be retrieved. (5) The application provides the initialized transmit buffer. |