1 USB HID 是什麼
USB 是即插即用使用差動信號的裝置介面,是以 端點 ( Endpoint ),做為傳輸裝置的輸出入端,透過不同的端點 ( Endpoint ) 和模式,來進行與裝置的溝通,USB HID 就是使用 USB 傳輸模式中的中斷傳輸 ( Interrupt ) 的端點傳輸和可以部份使用 控制傳輸 ( Control ) ,且若是符合USB 標準,都無需再撰寫 USB 裝置的驅動程式。
AT32F405 內含 USB 高速傳輸,可以透過一些簡單的修改,讓使用者更容易使用。
1.1 傳輸方塊圖
USB 傳輸方塊圖,如『圖1.1.1』( 註1 )
『圖1.1.1』( 註1 )
2 使用 AT32F405 的優缺點總結
『圖2.2』
『圖2.3』
『圖2.4』
之後就可以直接使用 Bus hound,或是 Artery_UsbHid_Demo.exe ( 註2 ) 來傳輸 HID data 了。
若是不想用 info 來解決,還可以將 custom_hid project 加上 mouse or Keyboard HID device,變成一個 Composite 裝置,就可以直接使用 window USB driver ,而不需要經過 info file 設定或是直接原廠的 GUI app
3 如何新增 HID
用 Mouse +客制HID 為例,可以使用 mouse project 再加上 custom_hid 的相關設定,或是使用 custom_hid project 再加上 HID mouse 的相關設定。
但是一開始要修改的地方,就是 class 層的程式,要將 custom_hid & mouse 的strcture 各別規劃成一個 typedef
typedef struct
{
uint8_t g_rxhid_buff[USBD_CUSTOM_OUT_MAXPACKET_SIZE];
uint8_t g_txhid_buff[USBD_CUSTOM_IN_MAXPACKET_SIZE];
uint32_t hid_protocol;
uint32_t hid_set_idle;
uint32_t alt_setting;
uint8_t hid_set_report[64];
uint8_t hid_get_report[64];
uint8_t hid_state;
uint8_t send_state;
}custom_hid_type;
typedef struct
{
uint32_t hid_protocol;
uint32_t hid_set_idle;
uint32_t alt_setting;
uint8_t hid_set_report[64];
uint8_t mouse_buffer[4];
uint8_t hid_state;
__IO uint8_t hid_suspend_flag;
uint8_t send_state;
}mouse_type;
typedef struct
{
custom_hid_type custom_hid;
mouse_type mouse;
uint8_t interface_number;
__IO uint8_t hid_suspend_flag;
}composite_hid_type;
再將先前各別定義的 typedef 再放在 Composite 的type 內,來做為整體的架構,再來就是要將 descriptor table => g_usbd_hs_configuration 將要新增的 custom hid 放在 Mouse 宣告的後面,當然 interface number 和 End point 的宣告不能重疊,不然會出現問題。
ALIGNED_HEAD static uint8_t g_usbd_hs_configuration[USBD_CUSHID_CONFIG_DESC_SIZE] ALIGNED_TAIL =
{
…
/* mouse */
USB_DEVICE_CFG_DESC_LEN, /* bLength: configuration descriptor size */
USB_DEVICE_IF_DESC_LEN, /* bLength: interface descriptor size */
USB_DESCIPTOR_TYPE_INTERFACE, /* bDescriptorType: interface descriptor type */
MOUSE_INTERFACE_NUMBER, /* bInterfaceNumber: number of interface */
0x00, /* bAlternateSetting: alternate set */
0x01, /* bNumEndpoints: number of endpoints */
USB_CLASS_CODE_HID, /* bInterfaceClass: class code hid */
0x01, /* bInterfaceSubClass: subclass code */
0x02, /* bInterfaceProtocol: protocol code */
0x00, /* iInterface: index of string descriptor */
0x09, /* bLength: size of HID descriptor in bytes */
HID_CLASS_DESC_HID, /* bDescriptorType: HID descriptor type */
LBYTE(MOUSE_BCD_NUM),
HBYTE(MOUSE_BCD_NUM), /* bcdHID: HID class specification release number */
0x00, /* bCountryCode: hardware target conutry */
0x01, /* bNumDescriptors: number of HID class descriptor to follow */
HID_CLASS_DESC_REPORT, /* bDescriptorType: report descriptor type */
LBYTE(sizeof(g_usbd_mouse_report)),
HBYTE(sizeof(g_usbd_mouse_report)), /* wDescriptorLength: total length of reprot descriptor */
…
/*custom hid*/
USB_DEVICE_IF_DESC_LEN, /* bLength: interface descriptor size */
USB_DESCIPTOR_TYPE_INTERFACE, /* bDescriptorType: interface descriptor type */
HID_INTERFACE_NUMBER, /* bInterfaceNumber: number of interface */
0x00, /* bAlternateSetting: alternate set */
0x02, /* bNumEndpoints: number of endpoints */
USB_CLASS_CODE_HID, /* bInterfaceClass: class code hid */
0x00, /* bInterfaceSubClass: subclass code */
0x00, /* bInterfaceProtocol: protocol code */
0x00, /* iInterface: index of string descriptor */
…
}
再將先前定義好的custom hid class 放在class_init_handler 內
…
static usb_sts_type class_init_handler(void *udev)
{
usb_sts_type status = USB_OK;
usbd_core_type *pudev = (usbd_core_type *)udev;
composite_hid_type *pcshid = (composite_hid_type *)pudev->class_handler->pdata;
/* open mouse in endpoint */
usbd_ept_open(pudev, USBD_MOUSE_IN_EPT, EPT_INT_TYPE, USBD_MOUSE_IN_MAXPACKET_SIZE);
pcshid->mouse.send_state = 0;
/* open custom hid in endpoint */
usbd_ept_open(pudev, USBD_CUSTOM_HID_IN_EPT, EPT_INT_TYPE, USBD_CUSTOM_IN_MAXPACKET_SIZE);
/* open custom hid out endpoint */
usbd_ept_open(pudev, USBD_CUSTOM_HID_OUT_EPT, EPT_INT_TYPE, USBD_CUSTOM_OUT_MAXPACKET_SIZE);
pcshid->custom_hid.send_state = 0;
/* set out endpoint to receive status */
usbd_ept_recv(pudev, USBD_CUSTOM_HID_OUT_EPT, pcshid->custom_hid.g_rxhid_buff, USBD_CUSTOM_OUT_MAXPACKET_SIZE);
return status;
}
再修改 class_clear_handler , class_setup_handler ,class_ept0_tx_handler,class_ept0_rx_handler,class_in_handler,class_out_handler,xxx_class_send_report,class_setup_handler_xxx之後,再將這樣 composite_hid_class_handler基本的框架就好了,之後就要看 AP 層的功能是否要改寫,或是不使用,並且一步一步的驗證程式了。
4 參考資料
註1 : 作者: USB ORG ( Compaq ,Hewlett-Packard ,Intel ,Lucent,Microsoft,NEC,Philips );出處 : https://www.usb.org/document-library/usb-20-specification
註2 : 作者: Artery 原廠;Artery_UsbHid_Demo_V1xxx.zip => USBHID Demo
出處 :https://www.arterytek.com/cn/support/index.jsp?index=2
評論