好的,以下是基于STM32键盘工程中添加自定义HID描述符的代码及其详细解析:
首先,在工程中需要添加一个自定义的HID描述符,我们可以通过定义一个结构体来实现:
```c
typedef struct
{
uint8_t bLength; // 描述符长度
uint8_t bDescriptorType; // 描述符类型
uint16_t bcdHID; // HID协议版本
uint8_t bCountryCode; // 国家码
uint8_t bNumDescriptors; // HID描述符个数
uint8_t bDescriptorType1; // 报告描述符类型
uint16_t wItemLength; // 报告描述符长度
} HID_DescTypeDef;
```
其中,bLength表示描述符长度,bDescriptorType表示描述符类型,bcdHID表示HID协议版本,bCountryCode表示国家码,bNumDescriptors表示HID描述符个数,bDescriptorType1表示报告描述符类型,wItemLength表示报告描述符长度。
接下来,在工程中添加一个HID描述符:
```c
#define HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESC 0x22
#define HID_DESCRIPTOR_SIZE 0x09
__ALIGN_BEGIN static uint8_t CustomHID_Desc[HID_DESCRIPTOR_SIZE] __ALIGN_END =
{
HID_DESCRIPTOR_SIZE, // bLength
HID_DESCRIPTOR_TYPE, // bDescriptorType
0x11, 0x01, // bcdHID
0x00, // bCountryCode
0x01, // bNumDescriptors
HID_REPORT_DESC, // bDescriptorType1
0x22, 0x00 // wItemLength
};
```
其中,HID_DESCRIPTOR_TYPE表示HID描述符类型,HID_REPORT_DESC表示报告描述符类型,HID_DESCRIPTOR_SIZE表示描述符长度。
最后,在USB初始化函数中,添加自定义HID描述符:
```c
USBD_CUSTOM_HID_HandleTypeDef hUsbDeviceFS;
/* USB CUSTOM_HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: configuration descriptor set total length */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xC0, /* bmAttributes: bus powered */
0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */
/************** Descriptor of CUSTOM HID interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0x00, /* iInterface: Index of string descriptor */
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
0x11, 0x01, /* bcdHID: HID Class Spec release number */
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
HID_REPORT_DESC, /* bDescriptorType */
HID_DESCRIPTOR_SIZE, /* wItemLength: Total length of Report descriptor */
/* 27 */
/******************** Descriptor of Custom HID endpoints **************************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */
0x00,
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval (10 ms) */
/* 34 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
0x00,
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval (10 ms) */
/* 41 */
} ;
/* USB CUSTOM_HID device Configuration Descriptor */
static uint8_t *USBD_CUSTOM_HID_GetCfgDesc(uint16_t *length)
{
*length = sizeof(USBD_CUSTOM_HID_CfgDesc);
return USBD_CUSTOM_HID_CfgDesc;
}
/* USB CUSTOM_HID device HS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END =
{
/* 18 */
0x09, /* bLength: CUSTOM_HID Descriptor size */
CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
0x11, 0x01, /* bcdHID: HID Class Spec release number */
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
HID_REPORT_DESC, /* bDescriptorType */
HID_DESCRIPTOR_SIZE, /* wItemLength: Total length of Report descriptor */
/* 25 */
};
/* USB CUSTOM_HID device HS Configuration Descriptor */
static uint8_t *USBD_CUSTOM_HID_GetDesc(uint16_t *length)
{
*length = sizeof(USBD_CUSTOM_HID_Desc);
return USBD_CUSTOM_HID_Desc;
}
/* USB CUSTOM_HID device core functions */
USBD_ClassTypeDef USBD_CUSTOM_HID =
{
USBD_CUSTOM_HID_Init,
USBD_CUSTOM_HID_DeInit,
USBD_CUSTOM_HID_Setup,
NULL, /* EP0_TxSent */
USBD_CUSTOM_HID_EP0_RxReady,
USBD_CUSTOM_HID_DataIn,
USBD_CUSTOM_HID_DataOut,
NULL, /* SOF */
NULL,
NULL,
USBD_CUSTOM_HID_GetHSCfgDesc,
USBD_CUSTOM_HID_GetCfgDesc,
USBD_CUSTOM_HID_GetDesc,
NULL,
NULL,
NULL,
NULL,
USBD_CUSTOM_HID_SOF,
NULL,
};
```
其中,USBD_CUSTOM_HID_CfgDesc为自定义HID配置描述符,USBD_CUSTOM_HID_Desc为自定义HID描述符,USBD_CUSTOM_HID为自定义HID设备的核心函数。在USBD_CUSTOM_HID_Init函数中,需要设置自定义HID描述符:
```c
hUsbDeviceFS.pDesc = USBD_CUSTOM_HID_Desc;
hUsbDeviceFS.pClass = &USBD_CUSTOM_HID;
hUsbDeviceFS.pConfDesc = USBD_CUSTOM_HID_CfgDesc;
hUsbDeviceFS.langID = 0x409;
hUsbDeviceFS.idVendor = 0x0483;
hUsbDeviceFS.idProduct = 0x5711;
hUsbDeviceFS.bcdDevice = 0x0200;
hUsbDeviceFS.Malfunction_Callback = NULL;
hUsbDeviceFS.Microphone_Callback = NULL;
hUsbDeviceFS.Keyboard_Callback = NULL;
hUsbDeviceFS.Mouse_Callback = NULL;
hUsbDeviceFS.Vendor_Callback = NULL;
hUsbDeviceFS.power = 250;
USBD_CUSTOM_HID_RegisterInterface(&hUsbDeviceFS, USBD_CUSTOM_HID_REPORT_IN_FS, USBD_CUSTOM_HID_REPORT_OUT_FS);
```
以上就是基于STM32键盘工程中添加自定义HID描述符的代码及其详细解析。