打印
[资料分享与下载]

[经验分享]鼠标HID例程简析(中)

[复制链接]
1411|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
HID, ST, USB, AC, se
本帖最后由 FSL_TICS_Jeremy 于 2014-9-17 12:01 编辑

鼠标HID例程简析
    今天紧接《鼠标HID例程简析(上)》一文,继续向大家介绍鼠标HID例程的未完的内容。
Ø  TestApp_Init(void)
TestApp_Init()函数包含USB_Class_HID_Init()函数实现USB接口的初始化, 包括初始化各式USB类结构数据,并且通过其内部的USB_Class_Init()和USB_Device_Init()函数可分别初始化Class driver层中的Common class模块、Framework模块。
*****************************************************************************
* This function starts the Mouse Application
*****************************************************************************/

void TestApp_Init(void)
{
    uint_8   error;

    rpt_buf[3] = 0x00; /* always zero */

    *((uint_32_ptr)rpt_buf) = 0;
    *((uint_32_ptr)null_buf) = 0;
    DisableInterrupts;
    #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H)
     usb_int_dis();
    #endif        

    error = USB_Class_HID_Init(CONTROLLER_ID, USB_App_Callback, NULL,
                            USB_App_Param_Callback);//USB接口初始化
    UNUSED(error);
   
    EnableInterrupts;
    #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H)
     usb_int_en();
    #endif        
}

图1 FSL USB Stack架构

Framework模块:负责处理 USB device 在枚举过程中的控制
端点接到的来自Host的各式请求。
      Commonclass 模块:负责处理所有USB 类都会发生的suspend/resume、reset、stall、SOF。当检测到事件发送时,如USB总线复位、枚举成功、配置变换、数据接收或发生完成等,Common class 模块都会通过传送Callback通知Class specific 模块或者USB Application层。
      Classspecific模块用于处理控制端点外的端点与Host通信的事宜,在这类端点上进行字符发送和接收都受Class specific模块管理,同时Class specific模块还会处理在控制端点上接收到的特定请求,如本例程中的HID类的特定请求:Get_Report、Set_Report 、Get_Idle、 Set_Idle 、Get_Protocol 、Set_Protocol。
USB_Class_HID_Init()函数的函数指针参数:hid_class_callback、vendor_req_callback、param_callback分别对应着处理USB事件,Vendor特定请求,USB类特定请求。
******************************************************************************
*This function initializes the HID Class layer and layers it is dependent on
*****************************************************************************/
uint_8 USB_Class_HID_Init (
    uint_8    controller_ID,                /* [IN] Controller ID */
    USB_CLASS_CALLBACK hid_class_callback,  /* [IN] HID Class Callback */
    USB_REQ_FUNC       vendor_req_callback, /* [IN] Vendor Request Callback */
    USB_CLASS_SPECIFIC_HANDLER_FUNC param_callback
                                        /* [ IN] HID Class requests Callback */
)
{
    uint_8 index,status = USB_OK;
    USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
        USB_Desc_Get_Endpoints(controller_ID);
   
#ifndef COMPOSITE_DEV
    /* Initialize the device layer*/
    status = _usb_device_init(controller_ID, NULL,
        (uint_8)(ep_desc_data->count+1), TRUE);
    if(status == USB_OK)
    {
        /* Initialize the generic class functions */
        status = USB_Class_Init(controller_ID,USB_Class_Hid_Event,
            USB_Other_Requests);

        if(status == USB_OK)
        {
#endif
            g_hid_endpoint_data.count = ep_desc_data->count;

            for(index = 0; index < ep_desc_data->count; index++)
            {
                g_hid_endpoint_data.ep[index].endpoint =
                    ep_desc_data->ep[index].ep_num;
                g_hid_endpoint_data.ep[index].type =
                    ep_desc_data->ep[index].type;
                g_hid_endpoint_data.ep[index].bin_consumer = 0x00;
                g_hid_endpoint_data.ep[index].bin_producer = 0x00;
            }

            /* save the HID class callback pointer */
            g_hid_class_callback = hid_class_callback;

            /* save the vendor request callback pointer */
            g_vendor_req_callback = vendor_req_callback;

            /* Save the callback to ask application for class specific params*/
            g_param_callback = param_callback;
#ifndef COMPOSITE_DEV
        }
    }
#endif
    return status;
}
     USB_Class_Hid_Event()
USB_Class_Hid_Event对应着处理各式USB事件,如USB 总线复位、枚举成功、配置变换、数据接收或发生完成。
***************************************************************************
[url=home.php?mod=space&uid=139335]@name[/url]  USB_Class_Hid_Event
  The funtion initializes the HID endpoints when Enumeration complete event is
  received
***************************************************************************/
void USB_Class_Hid_Event (
    uint_8 controller_ID,   /* [IN] Controller ID */
    uint_8 event,           /* [IN] Event Type */
    void* val               /* [IN] Pointer to configuration Value */
)
{
    uint_8 index;

    if(event == USB_APP_ENUM_COMPLETE)
    {
        uint_8 index_num = 0;
        uint_8 count = 0,ep_count = 0;
        USB_ENDPOINTS *ep_desc_data;  
        
#ifdef COMPOSITE_DEV
        DEV_ARCHITECTURE_STRUCT_PTR dev_arc_ptr;
        CLASS_ARC_STRUCT_PTR dev_class_ptr;   
        dev_arc_ptr = (DEV_ARCHITECTURE_STRUCT *)USB_Desc_Get_Class_Architecture(controller_ID);   
        for(count = 0; count < dev_arc_ptr->cl_count; count++)
        {
            dev_class_ptr = (CLASS_ARC_STRUCT_PTR)dev_arc_ptr->value[count];
            /* Initializes sub_classes */
            ep_count = dev_class_ptr->value[0];
            if(dev_class_ptr->class_type == 0x03/*HID_CC*/)
                break;
            index_num +=dev_class_ptr->value[0];
        }
        /* get the endpoints from the descriptor module */
        ep_desc_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID);
#else
        /* get the endpoints from the descriptor module */
        ep_desc_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID);
                                       
                ep_count = ep_desc_data->count;
#endif
                /* deinitialize all endpoints in case they were initialized */
                for(count=index_num;count<ep_count+index_num;count++)
                {   
                        USB_EP_STRUCT_PTR ep_struct_ptr=
                                (USB_EP_STRUCT_PTR) (&ep_desc_data->ep[count]);
                        (void)_usb_device_deinit_endpoint(&controller_ID,
                                ep_struct_ptr->ep_num, ep_struct_ptr->direction);  
                }

        /* intialize all non control endpoints */
        for(count=index_num;count<ep_count+index_num;count++)
        {
            USB_EP_STRUCT_PTR ep_struct=
                (USB_EP_STRUCT_PTR)&ep_desc_data->ep[count];

            (void)_usb_device_init_endpoint(&controller_ID, ep_struct->ep_num,
                            ep_struct->size, ep_struct->direction, ep_struct->type,
                            TRUE);

            /* register callback service for the endpoint */
            (void)_usb_device_register_service(controller_ID,
                                  (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                                                             USB_Service_Hid);


            /* set the EndPoint Status as Idle in the device layer */
            (void)_usb_device_set_status(&controller_ID,
                (uint_8)(USB_STATUS_ENDPOINT | ep_struct->ep_num |
                (ep_struct->direction << USB_COMPONENT_DIRECTION_SHIFT)),
                USB_STATUS_IDLE);
        }

    }
    else if((event == USB_APP_BUS_RESET) || (event == USB_APP_CONFIG_CHANGED))
    {
        /* clear producer and consumer on reset */
        for(index = 0; index < g_hid_endpoint_data.count; index++)
        {
            g_hid_endpoint_data.ep[index].bin_consumer = 0x00;
            g_hid_endpoint_data.ep[index].bin_producer = 0x00;
            g_hid_endpoint_data.ep[index].queue_num    = 0x00;
        }
    }

    if(g_hid_class_callback != NULL)
    {
        /* notify the application of the event */
        g_hid_class_callback(controller_ID, event, val);
    }

}
     USB_Other_Requests()
USB_Other_Requests()函数用于处理Host发送来的HID类特定请求和Vendor特定请求,如,Get_Report、Set_Report 、Get_Idle、 Set_Idle 、Get_Protocol 、Set_Protocol。
******************************************************************************
* Handles HID Class requests and forwards vendor specific request to the
* application
*****************************************************************************/
#ifndef COMPOSITE_DEV
static uint_8 USB_Other_Requests
#else
uint_8 USB_HID_Other_Requests
#endif
(
    uint_8 controller_ID,               /* [IN] Controller ID */
    USB_SETUP_STRUCT * setup_packet,    /*[IN] Setup packet received */
    uint_8_ptr *data,                   /* [OUT] Data to be send back */
    USB_PACKET_SIZE *size               /* [OUT] Size to be returned*/
)
{
    uint_8 index;
    uint_8 status = USBERR_INVALID_REQ_TYPE;
    uint_8 rpt_buf[REPORT_SIZE];/* buffer to send in case of get report req */
    *((uint_32_ptr)rpt_buf) = 0;

    if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) ==
        USB_REQUEST_CLASS_CLASS)
    {
        /* class request so handle it here */
        /* index == 0 for get/set idle, index == 1 for get/set protocol */
        index = (uint_8)((setup_packet->request - 2) &
            USB_HID_REQUEST_TYPE_MASK);

        status = USB_OK;
        /* point to the data which comes after the setup packet */
        *data = ((uint_8*)setup_packet) + USB_SETUP_PKT_SIZE;
        *size = 0;
        /* handle the class request */
        switch(setup_packet->request)
        {
            case USB_HID_GET_REPORT_REQUEST :
                /*set the data pointer to the buffer to send */
                *data = &rpt_buf[0];
                if(*size > REPORT_SIZE) *size = REPORT_SIZE;
                break;

            case USB_HID_SET_REPORT_REQUEST :
                for(index = 0; index < REPORT_SIZE; index++)
                {   /* copy the data sent by host in the buffer */
                  rpt_buf[index] = *(*data + index);
                }
                break;

            case USB_HID_GET_IDLE_REQUEST :
                /* point to the current idle rate */
                *data = &g_class_request_params[index];
                *size = CLASS_REQ_DATA_SIZE;
                break;

            case USB_HID_SET_IDLE_REQUEST :
                /* set the idle rate sent by the host */
                g_class_request_params[index] =(uint_8)((setup_packet->value
                    & MSB_MASK) >> HIGH_BYTE_SHIFT);
                break;

            case USB_HID_GET_PROTOCOL_REQUEST :
                /* point to the current protocol code
                            0 = Boot Protocol
                            1 = Report Protocol*/
                *data = &g_class_request_params[index];
                *size = CLASS_REQ_DATA_SIZE;
                break;

            case USB_HID_SET_PROTOCOL_REQUEST :
                /* set the protocol sent by the host
                             0 = Boot Protocol
                             1 = Report Protocol*/
                g_class_request_params[index] = (uint_8)(setup_packet->value);
                break;
            default :
                break;
        }

        if(g_param_callback != NULL)
        {
            /*
               handle callback if the application has supplied it
               set the size of the transfer from the setup packet
            */
            *size = (USB_PACKET_SIZE)setup_packet->length;

            /* notify the application of the class request.
               give control to the application */
            status = g_param_callback(setup_packet->request,/* request type */
                setup_packet->value,
                setup_packet->index, /* Application needs to know which Interface is being communicated with */
                data,/* pointer to the data */
                size);/* size of the transfer */
        }

    }
    else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) ==
        USB_REQUEST_CLASS_VENDOR)
    {
        /* vendor specific request  */
        if(g_vendor_req_callback != NULL)
        {
            status = g_vendor_req_callback(controller_ID, setup_packet,data,
                size);
        }
    }
    return status;
}
文档下载:
鼠标HID例程(中).pdf (380.4 KB)
参考文献:






相关帖子

沙发
FSL_TICS_Jeremy|  楼主 | 2014-9-17 12:00 | 只看该作者

如有什么错误或者不足,欢迎网友指正,请在后面跟帖!

使用特权

评论回复
板凳
茫茫大士| | 2014-9-18 19:41 | 只看该作者
好东西谢谢分享

使用特权

评论回复
地板
deliciouscook| | 2015-1-25 19:45 | 只看该作者
谢楼主分享

使用特权

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

本版积分规则

113

主题

2865

帖子

38

粉丝