前言
本篇將以Custom HID達到64 bytes的資料傳輸
1. STM32CubeMX
勾選USB > Device(FS),下面的參數不改
Middleware and Software Packs > 勾選USB_DEVICE
選擇 Custom Human Interface Device Class(HID)
下面的參數這邊先不改,之後直接修改header裡的設定
MX產生出來的Configuration Descriptor在usbd_customhid.c的 USBD_CUSTOM_HID_CfgFSDesc[]
bNumEndpoints:2個(IN和OUT)
CUSTOM_HID_EPIN_SIZE和CUSTOM_HID_EPOUT_SIZE預設2 bytes,後面會改為64 bytes
/* USB CUSTOM_HID device FS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[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: Bytes returned */
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: CUSTOM_HID*/
0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
/******************** Descriptor of CUSTOM_HID *************************/
/* 18 */
0x09, /*bLength: CUSTOM_HID Descriptor size*/
CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
0x22, /*bDescriptorType*/
USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
0x00,
/******************** 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 */
/* 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 */
/* 41 */
};
2. HID Descriptor
usbd_custom_hid_if.c
定義了INPUT及OUTPUT各64 bytes的report,複製到 CUSTOM_HID_ReportDesc_FS[]
/* USER CODE BEGIN 0 */
0x06, 0x00, 0xff, // Usage Page(Undefined )
0x09, 0x01, // USAGE (Undefined)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x40, // REPORT_COUNT (64)
0x09, 0x01, // USAGE (Undefined)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x40, // REPORT_COUNT (64)
0x09, 0x01, // USAGE (Undefined)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x09, 0x01, // USAGE (Undefined)
0xb1, 0x02, // FEATURE (Data,Var,Abs)
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */
usbd_conf.h
USBD_CUSTOM_HID_REPORT_DESC_SIZE 改長度33 bytes
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 33
main.c
在main.c先加入作為資料存取的buffer
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usbd_customhid.h"
/* USER CODE END Includes */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
uint8_t tx_buffer[64];
uint8_t report_buffer[64];
uint8_t flag_rx = 0;
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE END PM */
usbd_custom_hid.c
當主機有資料OUT時會觸發 CUSTOM_HID_OutEvent_FS(),在裡頭加入buffer儲存資料
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{
/* USER CODE BEGIN 6 */
extern uint8_t report_buffer[64];
extern uint8_t flag_rx;
memcpy(report_buffer, hUsbDeviceFS.pClassData, 64);
memset(hUsbDeviceFS.pClassData, 0, 64);
flag_rx = 1;
return (USBD_OK);
/* USER CODE END 6 */
}
usbd_conf.h
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 64
usbd_customhid.h
IN/OUT的endpoint小大皆改為64 bytes
#define CUSTOM_HID_EPIN_SIZE 64U
#define CUSTOM_HID_EPOUT_SIZE 64U
usbd_conf.h
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 64
usbd_customhid.h
應用上加入2個function,MCU再接收到host送出的資料後,隨即再原資料送回host
接下User button(PA0)後送出64 bytes的data(1到64),每次點擊資料內容加1
int main(void)
{
uint8_t j = 0;
while(1)
{
if(flag_rx == 1)
{
flag_rx = 0;
for(int i=0; i<64; i++) tx_buffer[i] = report_buffer[i];
USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, tx_buffer, 64);
memset(report_buffer, 0, 64);
memset(tx_buffer, 0, 64);
}
if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 1)
{
for(int i=0; i<64; i++)
{
tx_buffer[i] = i+1+j;
}
j++;
USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, tx_buffer, 64);
HAL_Delay(300);
}
}
}
3. HID Host軟體
SimpleHIDWrite
填入數值後按下 Set Report送出資料,隨即收到MCU返回的data