STM32 USB Device HID
前言
USB 的東西,肯定是需要PC 端的軟體配合,尤其是這一種屬於比較客製化的 Custom HID 的東西,雖然HID 是不需要PC端的驅動程式,但還是得要準備自己的上層應用軟體,這個不像一般標準的Virtual COM 可以用超級終端機,這邊針對Device的HID部分較多客戶會有需求希望做成客製化因此該文章會來探討這部分
STM32CubeMX設定
這邊基本上開啟USB後再ST會有選單可以協助弄出客製化設定的HID
其中這一塊是可以針對自己需求新增和配置,可以先使用預設數值再做修正,然後就可以調整clock tree後生成檔案
STM32CubeIDE
這邊主展開專案可以看到主要有幾個c檔,這3個檔案是主要要客製化HID部分會需要確認的檔案可以看下方檔案描述Function
這邊針對Size部分可以再usbd_customhid.h看到CUSTOM_HID_EPIN_SIZE and CUSTOM_HID_EPOUT_SIZEdefinesto 0x40 (64 bytes):這部分主要是因一開始STM32CubeMX設定64
#define CUSTOM_HID_EPIN_SIZE 0x40U
#define CUSTOM_HID_EPOUT_SIZE 0x40U
USB裝置標準描述符會在usbd_custom_hid_if.c 這個file內可以詳細看 Information for Developers | USB-IF:
/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
/* 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 */
};
再來是上報資料給電腦CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE],建議使用 HID descriptor tool工具產生報告符,這裡要注意的是報告描述符大小USBD_CUSTOM_HID_REPORT_DESC_SIZE,一定要與實際產生的報告描述符大小(使用HID descriptor tool可查看)相對應,否則會導致HID設備配置失敗。
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
/* USER CODE BEGIN 0 */
HID_UsagePageVendor(0xa0),
HID_Usage(0xa5),
HID_Collection(0x01),
HID_Usage(0xa6),
/* input */
HID_Usage(0xa7),
HID_LogicalMin(0x00),
HID_LogicalMax(0xFF),
HID_ReportSize(8),
HID_ReportCount(64),
HID_Input(HID_Data | HID_Variable | HID_Absolute),
/* output */
HID_Usage(0xa9),
HID_LogicalMin(0x00),
HID_LogicalMax(0xff),
HID_ReportSize(8),
HID_ReportCount(64),
HID_Output(HID_Data | HID_Variable | HID_Absolute),
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */
};
再來就是定時發送report來更新數據了,USBD_CUSTOM_HID_SendReport,這個函數在usbd_customhid.c中定義
uint8_t USBD_CUSTOM_HID_SendReport (USBD_HandleTypeDef *pdev,
uint8_t *report,
uint16_t len)
{
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData;
if (pdev->dev_state == USBD_STATE_CONFIGURED )
{
if(hhid->state == CUSTOM_HID_IDLE)
{
hhid->state = CUSTOM_HID_BUSY;
USBD_LL_Transmit (pdev,
CUSTOM_HID_EPIN_ADDR,
report,
len);
}
}
return USBD_OK;
}