今天紧接《鼠标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 functi on 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) u***_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) u***_int_en(); #endif }
[color=rgb(51, 102, 153) !important]复制代码
USB_Class_HID_Init()
本人在《FSL USB Stack简介》一文中,已向大家介绍过USB Stack 架构中各层的组成和相互之间的关系,如图1所示。
图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 = _u***_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; }
[color=rgb(51, 102, 153) !important]复制代码
USB_Class_Hid_Event()
USB_Class_Hid_Event对应着处理各式USB事件,如USB 总线复位、枚举成功、配置变换、数据接收或发生完成。
*************************************************************************** @name 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 { USB_EP_STRUCT_PTR ep_struct_ptr= (USB_EP_STRUCT_PTR) (&ep_desc_data->ep[count]); (void)_u***_device_deinit_endpoint(&controller_ID, ep_struct_ptr->ep_num, ep_struct_ptr->direction); } /* intialize all non control endpoints */ for(count=index_num;count { USB_EP_STRUCT_PTR ep_struct= (USB_EP_STRUCT_PTR)&ep_desc_data->ep[count]; (void)_u***_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)_u***_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)_u***_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); } }
[color=rgb(51, 102, 153) !important]复制代码
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; }
[color=rgb(51, 102, 153) !important]复制代码
参考文献:
[size=19.0909080505371px]完整文档下载:
0