HID 是Single Interface Device 信号接口设备。
USB HID类是比较大的一个类,HID类设备属于人机交互操作的设备。用于控制计算机操作的一些方面,如USB鼠标,USB键盘,USB游戏操纵杆,USB触摸板,USB轨迹球、电话拨号设备、VCR遥控等等设备。另外,使用HID设备的一个好处就是,操作系统自带了HID类的驱动程序,而用户无需去开发很麻烦的驱动程序,只要直接使用API调用即可完成通信。所以很多简单的USB设备,喜欢枚举成HID设备,这样就可以不用安装驱动而直接使用。
本程是一个通用的HID例子,在开发板上按键盘可以在计算机那边显示。
在ui.c中是用户定义的操作:
- #include <asf.h>
- #include "ui.h"
- /** HID report buffer */
- static uint8_t ui_hid_report[UDI_HID_REPORT_OUT_SIZE];
- void ui_init(void)
- {
- /* Initialize LEDs */
- LED_Off(LED0);
- LED_Off(LED1);
- }
- void ui_powerdown(void)
- {
- LED_Off(LED0);
- LED_Off(LED1);
- }
- void ui_wakeup_enable(void)
- {
- }
- void ui_wakeup_disable(void)
- {
- }
- void ui_wakeup(void)
- {
- LED_On(LED0);
- }
- void ui_process(uint16_t framenumber)
- {
- bool b_btn_state;
- static bool btn0_last_state = false;
- static bool btn1_last_state = false;
- static uint8_t cpt_sof = 0;
- if ((framenumber % 1000) == 0) {
- LED_On(LED1);
- }
- if ((framenumber % 1000) == 500) {
- LED_Off(LED1);
- }
- /* Scan process running each 40ms */
- cpt_sof++;
- if (cpt_sof < 40) {
- return;
- }
- cpt_sof = 0;
- /* Scan push buttons 1 and 2 */
- b_btn_state = !ioport_get_pin_level(GPIO_PUSH_BUTTON_1);
- if (b_btn_state != btn0_last_state) {
- ui_hid_report[0]=b_btn_state;
- udi_hid_generic_send_report_in(ui_hid_report);
- btn0_last_state = b_btn_state;
- }
- b_btn_state = !ioport_get_pin_level(GPIO_PUSH_BUTTON_2);
- if (b_btn_state != btn1_last_state) {
- ui_hid_report[0]=b_btn_state;
- udi_hid_generic_send_report_in(ui_hid_report);
- btn1_last_state = b_btn_state;
- }
- }
- void ui_led_change(uint8_t *report)
- {
- if (report[0]=='1') {
- /* A led must be on */
- switch(report[1]) {
- case '1':
- LED_On(LED2);
- break;
- }
- } else {
- /* A led must be off */
- switch(report[1]) {
- case '1':
- LED_Off(LED2);
- break;
- }
- }
- }
- /**
- * \defgroup UI User Interface
- *
- * Human interface on SAM4E-EK:
- * - Led 0 (D2) is on when USB is wakeup
- * - Led 1 (D3) blinks when USB host has checked and enabled HID generic interface
- * - Led 2 (D4) is linked on HID events LED1
- * - Event buttons are linked to push button 1 (BP2) and push button 2 (BP3)
- *
- */
在config_usb.h中定义参数:
- #ifndef _CONF_USB_H_
- #define _CONF_USB_H_
- #include "compiler.h"
- /**
- * USB Device Configuration
- * @{
- */
- //! Device definition (mandatory)
- #define USB_DEVICE_VENDOR_ID USB_VID_ATMEL
- #define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_ASF_HIDGENERIC
- #define USB_DEVICE_MAJOR_VERSION 1
- #define USB_DEVICE_MINOR_VERSION 0
- #define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA)
- #define USB_DEVICE_ATTR \
- (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
- // (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
- // (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
- // (USB_CONFIG_ATTR_SELF_POWERED)
- // (USB_CONFIG_ATTR_BUS_POWERED)
- //! USB Device string definitions (Optional)
- #define USB_DEVICE_MANUFACTURE_NAME "ATMEL ASF"
- #define USB_DEVICE_PRODUCT_NAME "HID Generic"
- // #define USB_DEVICE_SERIAL_NAME "12...EF"
- /**
- * Device speeds support
- * @{
- */
- //! To define a Low speed device
- //#define USB_DEVICE_LOW_SPEED
- //! To authorize the High speed
- #if (UC3A3||UC3A4)
- //#define USB_DEVICE_HS_SUPPORT
- #elif (SAM3XA||SAM3U)
- //#define USB_DEVICE_HS_SUPPORT
- #endif
- //@}
- /**
- * USB Device Callbacks definitions (Optional)
- * @{
- */
- #define UDC_VBUS_EVENT(b_vbus_high)
- #define UDC_SOF_EVENT() main_sof_action()
- #define UDC_SUSPEND_EVENT() main_suspend_action()
- #define UDC_RESUME_EVENT() main_resume_action()
- //! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature
- #define UDC_REMOTEWAKEUP_ENABLE() main_remotewakeup_enable()
- #define UDC_REMOTEWAKEUP_DISABLE() main_remotewakeup_disable()
- //! When a extra string descriptor must be supported
- //! other than manufacturer, product and serial string
- // #define UDC_GET_EXTRA_STRING()
- //@}
- //@}
- /**
- * USB Interface Configuration
- * @{
- */
- /**
- * Configuration of HID Generic interface
- * @{
- */
- //! Interface callback definition
- #define UDI_HID_GENERIC_ENABLE_EXT() main_generic_enable()
- #define UDI_HID_GENERIC_DISABLE_EXT() main_generic_disable()
- #define UDI_HID_GENERIC_REPORT_OUT(ptr) ui_led_change(ptr)
- #define UDI_HID_GENERIC_SET_FEATURE(report) main_hid_set_feature(report)
- //! Sizes of I/O reports
- #define UDI_HID_REPORT_IN_SIZE 8
- #define UDI_HID_REPORT_OUT_SIZE 8
- #define UDI_HID_REPORT_FEATURE_SIZE 4
- //! Sizes of I/O endpoints
- #define UDI_HID_GENERIC_EP_SIZE 8
描述符在udi_hid_generic.h说明:
- #ifndef _UDI_HID_GENERIC_H_
- #define _UDI_HID_GENERIC_H_
- #include "conf_usb.h"
- #include "usb_protocol.h"
- #include "usb_protocol_hid.h"
- #include "udc_desc.h"
- #include "udi.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * \addtogroup udi_hid_generic_group_udc
- * @{
- */
- //! Global structure which contains standard UDI API for UDC
- extern UDC_DESC_STORAGE udi_api_t udi_api_hid_generic;
- //@}
- /**
- * \ingroup udi_hid_generic_group
- * \defgroup udi_hid_generic_group_desc USB interface descriptors
- *
- * The following structures provide predefined USB interface descriptors.
- * It must be used to define the final USB descriptors.
- */
- //@{
- //! Interface descriptor structure for HID generic
- typedef struct {
- usb_iface_desc_t iface;
- usb_hid_descriptor_t hid;
- usb_ep_desc_t ep_in;
- usb_ep_desc_t ep_out;
- } udi_hid_generic_desc_t;
- //! Report descriptor for HID generic
- typedef struct {
- uint8_t array[53];
- } udi_hid_generic_report_desc_t;
- //! By default no string associated to this interface
- #ifndef UDI_HID_GENERIC_STRING_ID
- #define UDI_HID_GENERIC_STRING_ID 0
- #endif
- //! Content of HID generic interface descriptor for all speed
- #define UDI_HID_GENERIC_DESC {\
- .iface.bLength = sizeof(usb_iface_desc_t),\
- .iface.bDescriptorType = USB_DT_INTERFACE,\
- .iface.bInterfaceNumber = UDI_HID_GENERIC_IFACE_NUMBER,\
- .iface.bAlternateSetting = 0,\
- .iface.bNumEndpoints = 2,\
- .iface.bInterfaceClass = HID_CLASS,\
- .iface.bInterfaceSubClass = HID_SUB_CLASS_NOBOOT,\
- .iface.bInterfaceProtocol = HID_PROTOCOL_GENERIC,\
- .iface.iInterface = UDI_HID_GENERIC_STRING_ID,\
- .hid.bLength = sizeof(usb_hid_descriptor_t),\
- .hid.bDescriptorType = USB_DT_HID,\
- .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\
- .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\
- .hid.bNumDescriptors = USB_HID_NUM_DESC,\
- .hid.bRDescriptorType = USB_DT_HID_REPORT,\
- .hid.wDescriptorLength = LE16(sizeof(udi_hid_generic_report_desc_t)),\
- .ep_in.bLength = sizeof(usb_ep_desc_t),\
- .ep_in.bDescriptorType = USB_DT_ENDPOINT,\
- .ep_in.bEndpointAddress = UDI_HID_GENERIC_EP_IN,\
- .ep_in.bmAttributes = USB_EP_TYPE_INTERRUPT,\
- .ep_in.wMaxPacketSize = LE16(UDI_HID_GENERIC_EP_SIZE),\
- .ep_in.bInterval = 4,\
- .ep_out.bLength = sizeof(usb_ep_desc_t),\
- .ep_out.bDescriptorType = USB_DT_ENDPOINT,\
- .ep_out.bEndpointAddress = UDI_HID_GENERIC_EP_OUT,\
- .ep_out.bmAttributes = USB_EP_TYPE_INTERRUPT,\
- .ep_out.wMaxPacketSize = LE16(UDI_HID_GENERIC_EP_SIZE),\
- .ep_out.bInterval = 4,\
- }
- //@}
- /**
- * \ingroup udi_hid_group
- * \defgroup udi_hid_generic_group USB Device Interface (UDI) for Human Interface Device (HID) Generic Class
- *
- * Common APIs used by high level application to use this USB class.
- *
- * See \ref udi_hid_generic_quickstart.
- * @{
- */
- /**
- * \brief Routine used to send a report to USB Host
- *
- * \param data Pointer on the report to send (size = UDI_HID_REPORT_IN_SIZE)
- *
- * \return \c 1 if function was successfully done, otherwise \c 0.
- */
- bool udi_hid_generic_send_report_in(uint8_t *data);
- //@}
- #ifdef __cplusplus
- }
而定议端点数及缓冲大小在udi_hid_generic_conf.h:
- #ifndef _UDI_HID_GENERIC_CONF_H_
- #define _UDI_HID_GENERIC_CONF_H_
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * \addtogroup udi_hid_generic_group_single_desc
- * @{
- */
- //! Control endpoint size
- #ifdef USB_DEVICE_HS_SUPPORT
- # define USB_DEVICE_EP_CTRL_SIZE 64
- #else
- # define USB_DEVICE_EP_CTRL_SIZE 8
- #endif
- //! Endpoint number used by HID generic interface
- #define UDI_HID_GENERIC_EP_OUT (2 | USB_EP_DIR_OUT)
- #define UDI_HID_GENERIC_EP_IN (1 | USB_EP_DIR_IN)
- //! Interface number
- #define UDI_HID_GENERIC_IFACE_NUMBER 0
- /**
- * \name UDD Configuration
- */
- //@{
- //! 2 endpoints used by HID generic standard interface
- #undef USB_DEVICE_MAX_EP // undefine this definition in header file
- #define USB_DEVICE_MAX_EP 2
- //@}
- //@}
- #ifdef __cplusplus
- }
- #endif
- #include "udi_hid_generic.h"
- #endif // _UDI_HID_GENERIC_CONF_H_
而其它的统统交给HID USB 模块处理。
该程序的运行结果如下:
当我插上USB线是,多了一个设备:
打开Atmel提供的上位机软件,我按键时有反应:
|