[Atmel] 用SAM-BA或JLINK跑ATSAM4E16的程序(19) USB HID GENERIC

[复制链接]
 楼主| ddllxxrr 发表于 2015-11-28 20:51 | 显示全部楼层 |阅读模式
HID 是Single Interface Device 信号接口设备。
USB HID类是比较大的一个类,HID类设备属于人机交互操作的设备。用于控制计算机操作的一些方面,如USB鼠标,USB键盘,USB游戏操纵杆,USB触摸板,USB轨迹球、电话拨号设备、VCR遥控等等设备。另外,使用HID设备的一个好处就是,操作系统自带了HID类的驱动程序,而用户无需去开发很麻烦的驱动程序,只要直接使用API调用即可完成通信。所以很多简单的USB设备,喜欢枚举成HID设备,这样就可以不用安装驱动而直接使用。


本程是一个通用的HID例子,在开发板上按键盘可以在计算机那边显示。

在ui.c中是用户定义的操作:

  1. #include <asf.h>
  2. #include "ui.h"

  3. /** HID report buffer */
  4. static uint8_t ui_hid_report[UDI_HID_REPORT_OUT_SIZE];

  5. void ui_init(void)
  6. {
  7.         /* Initialize LEDs */
  8.         LED_Off(LED0);
  9.         LED_Off(LED1);
  10. }

  11. void ui_powerdown(void)
  12. {
  13.         LED_Off(LED0);
  14.         LED_Off(LED1);
  15. }


  16. void ui_wakeup_enable(void)
  17. {
  18. }

  19. void ui_wakeup_disable(void)
  20. {
  21. }

  22. void ui_wakeup(void)
  23. {
  24.         LED_On(LED0);
  25. }

  26. void ui_process(uint16_t framenumber)
  27. {
  28.         bool b_btn_state;
  29.         static bool btn0_last_state = false;
  30.         static bool btn1_last_state = false;
  31.         static uint8_t cpt_sof = 0;

  32.         if ((framenumber % 1000) == 0) {
  33.                 LED_On(LED1);
  34.         }
  35.         if ((framenumber % 1000) == 500) {
  36.                 LED_Off(LED1);
  37.         }
  38.         /* Scan process running each 40ms */
  39.         cpt_sof++;
  40.         if (cpt_sof < 40) {
  41.                 return;
  42.         }
  43.         cpt_sof = 0;

  44.         /* Scan push buttons 1 and 2 */
  45.         b_btn_state = !ioport_get_pin_level(GPIO_PUSH_BUTTON_1);
  46.         if (b_btn_state != btn0_last_state) {
  47.                 ui_hid_report[0]=b_btn_state;
  48.                 udi_hid_generic_send_report_in(ui_hid_report);
  49.                 btn0_last_state = b_btn_state;
  50.         }
  51.         b_btn_state = !ioport_get_pin_level(GPIO_PUSH_BUTTON_2);
  52.         if (b_btn_state != btn1_last_state) {
  53.                 ui_hid_report[0]=b_btn_state;
  54.                 udi_hid_generic_send_report_in(ui_hid_report);
  55.                 btn1_last_state = b_btn_state;
  56.         }
  57. }

  58. void ui_led_change(uint8_t *report)
  59. {
  60.         if (report[0]=='1') {
  61.                 /* A led must be on */
  62.                 switch(report[1]) {
  63.                         case '1':
  64.                         LED_On(LED2);
  65.                         break;
  66.                 }
  67.         } else {
  68.                 /* A led must be off */
  69.                 switch(report[1]) {
  70.                         case '1':
  71.                         LED_Off(LED2);
  72.                         break;
  73.                 }
  74.         }
  75. }

  76. /**
  77. * \defgroup UI User Interface
  78. *
  79. * Human interface on SAM4E-EK:
  80. * - Led 0 (D2) is on when USB is wakeup
  81. * - Led 1 (D3) blinks when USB host has checked and enabled HID generic interface
  82. * - Led 2 (D4) is linked on HID events LED1
  83. * - Event buttons are linked to push button 1 (BP2) and push button 2 (BP3)
  84. *
  85. */
在config_usb.h中定义参数:


  1. #ifndef _CONF_USB_H_
  2. #define _CONF_USB_H_

  3. #include "compiler.h"

  4. /**
  5. * USB Device Configuration
  6. * @{
  7. */

  8. //! Device definition (mandatory)
  9. #define  USB_DEVICE_VENDOR_ID             USB_VID_ATMEL
  10. #define  USB_DEVICE_PRODUCT_ID            USB_PID_ATMEL_ASF_HIDGENERIC
  11. #define  USB_DEVICE_MAJOR_VERSION         1
  12. #define  USB_DEVICE_MINOR_VERSION         0
  13. #define  USB_DEVICE_POWER                 100 // Consumption on Vbus line (mA)
  14. #define  USB_DEVICE_ATTR                  \
  15.         (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
  16. //        (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
  17. //        (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
  18. //        (USB_CONFIG_ATTR_SELF_POWERED)
  19. //        (USB_CONFIG_ATTR_BUS_POWERED)

  20. //! USB Device string definitions (Optional)
  21. #define  USB_DEVICE_MANUFACTURE_NAME      "ATMEL ASF"
  22. #define  USB_DEVICE_PRODUCT_NAME          "HID Generic"
  23. // #define  USB_DEVICE_SERIAL_NAME           "12...EF"

  24. /**
  25. * Device speeds support
  26. * @{
  27. */
  28. //! To define a Low speed device
  29. //#define  USB_DEVICE_LOW_SPEED

  30. //! To authorize the High speed
  31. #if (UC3A3||UC3A4)
  32. //#define  USB_DEVICE_HS_SUPPORT
  33. #elif (SAM3XA||SAM3U)
  34. //#define  USB_DEVICE_HS_SUPPORT
  35. #endif
  36. //@}

  37. /**
  38. * USB Device Callbacks definitions (Optional)
  39. * @{
  40. */
  41. #define  UDC_VBUS_EVENT(b_vbus_high)
  42. #define  UDC_SOF_EVENT()                  main_sof_action()
  43. #define  UDC_SUSPEND_EVENT()              main_suspend_action()
  44. #define  UDC_RESUME_EVENT()               main_resume_action()
  45. //! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature
  46. #define  UDC_REMOTEWAKEUP_ENABLE()        main_remotewakeup_enable()
  47. #define  UDC_REMOTEWAKEUP_DISABLE()       main_remotewakeup_disable()
  48. //! When a extra string descriptor must be supported
  49. //! other than manufacturer, product and serial string
  50. // #define  UDC_GET_EXTRA_STRING()
  51. //@}

  52. //@}


  53. /**
  54. * USB Interface Configuration
  55. * @{
  56. */
  57. /**
  58. * Configuration of HID Generic interface
  59. * @{
  60. */
  61. //! Interface callback definition
  62. #define  UDI_HID_GENERIC_ENABLE_EXT()        main_generic_enable()
  63. #define  UDI_HID_GENERIC_DISABLE_EXT()       main_generic_disable()
  64. #define  UDI_HID_GENERIC_REPORT_OUT(ptr)     ui_led_change(ptr)
  65. #define  UDI_HID_GENERIC_SET_FEATURE(report) main_hid_set_feature(report)

  66. //! Sizes of I/O reports
  67. #define  UDI_HID_REPORT_IN_SIZE             8
  68. #define  UDI_HID_REPORT_OUT_SIZE            8
  69. #define  UDI_HID_REPORT_FEATURE_SIZE        4

  70. //! Sizes of I/O endpoints
  71. #define  UDI_HID_GENERIC_EP_SIZE            8


描述符在udi_hid_generic.h说明:


  1. #ifndef _UDI_HID_GENERIC_H_
  2. #define _UDI_HID_GENERIC_H_

  3. #include "conf_usb.h"
  4. #include "usb_protocol.h"
  5. #include "usb_protocol_hid.h"
  6. #include "udc_desc.h"
  7. #include "udi.h"

  8. #ifdef __cplusplus
  9. extern "C" {
  10. #endif

  11. /**
  12. * \addtogroup udi_hid_generic_group_udc
  13. * @{
  14. */
  15. //! Global structure which contains standard UDI API for UDC
  16. extern UDC_DESC_STORAGE udi_api_t udi_api_hid_generic;
  17. //@}

  18. /**
  19. * \ingroup udi_hid_generic_group
  20. * \defgroup udi_hid_generic_group_desc USB interface descriptors
  21. *
  22. * The following structures provide predefined USB interface descriptors.
  23. * It must be used to define the final USB descriptors.
  24. */
  25. //@{

  26. //! Interface descriptor structure for HID generic
  27. typedef struct {
  28.         usb_iface_desc_t iface;
  29.         usb_hid_descriptor_t hid;
  30.         usb_ep_desc_t ep_in;
  31.         usb_ep_desc_t ep_out;
  32. } udi_hid_generic_desc_t;

  33. //! Report descriptor for HID generic
  34. typedef struct {
  35.         uint8_t array[53];
  36. } udi_hid_generic_report_desc_t;


  37. //! By default no string associated to this interface
  38. #ifndef UDI_HID_GENERIC_STRING_ID
  39. #define UDI_HID_GENERIC_STRING_ID 0
  40. #endif



  41. //! Content of HID generic interface descriptor for all speed
  42. #define UDI_HID_GENERIC_DESC    {\
  43.    .iface.bLength             = sizeof(usb_iface_desc_t),\
  44.    .iface.bDescriptorType     = USB_DT_INTERFACE,\
  45.    .iface.bInterfaceNumber    = UDI_HID_GENERIC_IFACE_NUMBER,\
  46.    .iface.bAlternateSetting   = 0,\
  47.    .iface.bNumEndpoints       = 2,\
  48.    .iface.bInterfaceClass     = HID_CLASS,\
  49.    .iface.bInterfaceSubClass  = HID_SUB_CLASS_NOBOOT,\
  50.    .iface.bInterfaceProtocol  = HID_PROTOCOL_GENERIC,\
  51.    .iface.iInterface          = UDI_HID_GENERIC_STRING_ID,\
  52.    .hid.bLength               = sizeof(usb_hid_descriptor_t),\
  53.    .hid.bDescriptorType       = USB_DT_HID,\
  54.    .hid.bcdHID                = LE16(USB_HID_BDC_V1_11),\
  55.    .hid.bCountryCode          = USB_HID_NO_COUNTRY_CODE,\
  56.    .hid.bNumDescriptors       = USB_HID_NUM_DESC,\
  57.    .hid.bRDescriptorType      = USB_DT_HID_REPORT,\
  58.    .hid.wDescriptorLength     = LE16(sizeof(udi_hid_generic_report_desc_t)),\
  59.    .ep_in.bLength             = sizeof(usb_ep_desc_t),\
  60.    .ep_in.bDescriptorType     = USB_DT_ENDPOINT,\
  61.    .ep_in.bEndpointAddress    = UDI_HID_GENERIC_EP_IN,\
  62.    .ep_in.bmAttributes        = USB_EP_TYPE_INTERRUPT,\
  63.    .ep_in.wMaxPacketSize      = LE16(UDI_HID_GENERIC_EP_SIZE),\
  64.    .ep_in.bInterval           = 4,\
  65.    .ep_out.bLength            = sizeof(usb_ep_desc_t),\
  66.    .ep_out.bDescriptorType    = USB_DT_ENDPOINT,\
  67.    .ep_out.bEndpointAddress   = UDI_HID_GENERIC_EP_OUT,\
  68.    .ep_out.bmAttributes       = USB_EP_TYPE_INTERRUPT,\
  69.    .ep_out.wMaxPacketSize     = LE16(UDI_HID_GENERIC_EP_SIZE),\
  70.    .ep_out.bInterval          = 4,\
  71.    }
  72. //@}


  73. /**
  74. * \ingroup udi_hid_group
  75. * \defgroup udi_hid_generic_group USB Device Interface (UDI) for Human Interface Device (HID) Generic Class
  76. *
  77. * Common APIs used by high level application to use this USB class.
  78. *
  79. * See \ref udi_hid_generic_quickstart.
  80. * @{
  81. */

  82. /**
  83. * \brief Routine used to send a report to USB Host
  84. *
  85. * \param data     Pointer on the report to send (size = UDI_HID_REPORT_IN_SIZE)
  86. *
  87. * \return \c 1 if function was successfully done, otherwise \c 0.
  88. */
  89. bool udi_hid_generic_send_report_in(uint8_t *data);

  90. //@}


  91. #ifdef __cplusplus
  92. }
而定议端点数及缓冲大小在udi_hid_generic_conf.h:

  1. #ifndef _UDI_HID_GENERIC_CONF_H_
  2. #define _UDI_HID_GENERIC_CONF_H_

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif

  6. /**
  7. * \addtogroup udi_hid_generic_group_single_desc
  8. * @{
  9. */

  10. //! Control endpoint size
  11. #ifdef USB_DEVICE_HS_SUPPORT
  12. #  define  USB_DEVICE_EP_CTRL_SIZE       64
  13. #else
  14. #  define  USB_DEVICE_EP_CTRL_SIZE       8
  15. #endif

  16. //! Endpoint number used by HID generic interface
  17. #define  UDI_HID_GENERIC_EP_OUT   (2 | USB_EP_DIR_OUT)
  18. #define  UDI_HID_GENERIC_EP_IN    (1 | USB_EP_DIR_IN)

  19. //! Interface number
  20. #define  UDI_HID_GENERIC_IFACE_NUMBER     0


  21. /**
  22. * \name UDD Configuration
  23. */
  24. //@{
  25. //! 2 endpoints used by HID generic standard interface
  26. #undef USB_DEVICE_MAX_EP   // undefine this definition in header file
  27. #define  USB_DEVICE_MAX_EP    2
  28. //@}

  29. //@}

  30. #ifdef __cplusplus
  31. }
  32. #endif

  33. #include "udi_hid_generic.h"

  34. #endif // _UDI_HID_GENERIC_CONF_H_

而其它的统统交给HID USB 模块处理。

该程序的运行结果如下:

当我插上USB线是,多了一个设备:



打开Atmel提供的上位机软件,我按键时有反应:




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2403

主题

6994

帖子

68

粉丝
快速回复 在线客服 返回列表 返回顶部