打印
[Atmel]

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

[复制链接]
1390|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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中是用户定义的操作:

#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提供的上位机软件,我按键时有反应:




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

2399

主题

6963

帖子

68

粉丝