AT32F405 USB 深入淺出 (1) HID 傳輸

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 的優缺點總結

若是使用 USB device 的 custom_hid project,來進行測試,直接使用 Bus Hound 會發現直接下中斷的時候,會直接變成 Invalid command,因為是客制的 HID 需要指定 driver 或是撰寫 inf 檔,或是先下載 Artery_UsbHid_Demo_V1.0.2.zip 再執行 Artery_UsbHid_Demo.exe 按下 Communication view 就會安裝好了



『圖2.1』



『圖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

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

評論