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;
}

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart