当前位置:首页 > 单片机 > 单片机
[导读]usb_prop.c文件可以说是一个蛮重要的文件,因为USB的许多处理函数都在这里定义。在无论是在USB的建立阶段、数据阶段还是状态阶段的一些处理都在这个文件,USB标准函数请求的函数也在这个文件里。usb_prop.c一开始就是

usb_prop.c文件可以说是一个蛮重要的文件,因为USB的许多处理函数都在这里定义。在无论是在USB的建立阶段、数据阶段还是状态阶段的一些处理都在这个文件,USB标准函数请求的函数也在这个文件里。

usb_prop.c一开始就是一连串的结构体,如下:

DEVICE Device_Table =

{

EP_NUM, //被使用的端点数

1 //可以使用的端点数

};


DEVICE_PROP Device_Property =//注册一些CustomHID函数

{

CustomHID_init,//CustomHID的初始化函数

CustomHID_Reset,//CustomHID的复位函数

CustomHID_Status_In,//CustomHID状态输入函数

CustomHID_Status_Out,//CustomHID状态输出函数

CustomHID_Data_Setup,//CustomHID的处理有数据阶段的特殊类请求函数

CustomHID_NoData_Setup,//CustomHID的处理没有数据阶段特殊类请求函数

CustomHID_Get_Interface_Setting,//CustomHID获取接口及备用接口设置(是否可用)

CustomHID_GetDeviceDescriptor,//CustomHID获取设备描述符

CustomHID_GetConfigDescriptor,//CustomHID获取配置描述符

CustomHID_GetStringDescriptor,//CustomHID获取字符串描述符

0,//当前库未使用

0x40 /*MAX PACKET SIZE*/ //最大的包长度为64字节

};


/*注册USB标准请求的实现函数*/

USER_STANDARD_REQUESTS User_Standard_Requests =

{

CustomHID_GetConfiguration,//获取配置请求

CustomHID_SetConfiguration,//设置配置请求

CustomHID_GetInterface,//获取接口请求

CustomHID_SetInterface,//设置接口请求

CustomHID_GetStatus,//获取状态请求

CustomHID_ClearFeature,//清除属性请求

CustomHID_SetEndPointFeature,//设置端点属性请求

CustomHID_SetDeviceFeature,//设置设备属性请求

CustomHID_SetDeviceAddress//设置设备地址请求

};


/*注册设备描述符信息*/

ONE_DESCRIPTOR Device_Descriptor =

{

(uint8_t*)CustomHID_DeviceDescriptor, //注册设备描述符数组

CUSTOMHID_SIZ_DEVICE_DESC //设备描述符的长度

};


/*注册设备描述符信息*/

ONE_DESCRIPTOR Config_Descriptor =

{

(uint8_t*)CustomHID_ConfigDescriptor, //注册配置描述符数组

CUSTOMHID_SIZ_CONFIG_DESC //配置描述符的长度

};


/*注册报告描述符信息*/

ONE_DESCRIPTOR CustomHID_Report_Descriptor =

{

(uint8_t *)CustomHID_ReportDescriptor, //注册报告描述符数组

CUSTOMHID_SIZ_REPORT_DESC //报告描述符的长度

};


/*注册HID描述符信息*/

ONE_DESCRIPTOR CustomHID_Descriptor =

{

(uint8_t*)CustomHID_ConfigDescriptor + CUSTOMHID_OFF_HID_DESC, //注册HID描述符数组

CUSTOMHID_SIZ_HID_DESC //HID数组的长度

};


/*注册字符串描述符,包括语言ID、厂商、产品、序列号描述符*/

ONE_DESCRIPTOR String_Descriptor[4] =

{

{(uint8_t*)CustomHID_StringLangID, CUSTOMHID_SIZ_STRING_LANGID},//注册语言字符串描述符数组

{(uint8_t*)CustomHID_StringVendor, CUSTOMHID_SIZ_STRING_VENDOR},//注册厂商字符串描述符数组

{(uint8_t*)CustomHID_StringProduct, CUSTOMHID_SIZ_STRING_PRODUCT},//注册产品字符串描述符数组

{(uint8_t*)CustomHID_StringSerial, CUSTOMHID_SIZ_STRING_SERIAL}//注册序列号字符串描述符数组

};


应该看了很明白,这一系列的结构体就是注册一些处理函数。我们一个个分析。

先来说下 DEVICE Device_Table这个结构体,DEVICE这个结构体类型在usb_core.h中定义:

typedef struct _DEVICE

{

uint8_t Total_Endpoint; /*被使用的端点数*/

uint8_t Total_Configuration;/*还可以用的端点数*/

}

DEVICE;


这个结构体类型很简单,在结构体中定义了已经被使用的端点和没有被使用的端点,把他们两个放在一起方便查询和管理。




接下去的说说DEVICE_PROP

Device_Property 这个类型的结构体。这个结构体的前10个元素都是函数指针类型的,把一些常用的函数放在这里,而函数定义都在该结构体之后定义,有没有觉得像是语文中的关键句,把整个文件的概要全部浓缩在这个结构体中了,只要看这个结构体就可以把整个文件做什么了解个七七八八了。这样的结构使用起来也非常方便,比如说我想要使用CustomHID_init函数,只要写Device_Property.CustomHID_init不就可以了。我们必须学会这种方法。

DEVICE_PROP这个结构体类型还是在usb_core.h中定义:

typedef struct _DEVICE_PROP

{

void (*Init)(void); /*初始化设备*/

void (*Reset)(void); /*复位该设备*/


/*在控制传输中分三个过程:1.建立过程,2、可选的数据过程,3、状态过程*/

/* Device dependent process after the status stage */

void (*Process_Status_IN)(void);/*状态过程中,处理IN令牌包*/

void (*Process_Status_OUT)(void);/*状态过程中,处理OUT令牌包*/


/*在建立阶段的过程中,会有很多特殊类请求的数据阶段stage */

/*所有在数据阶段的特殊类请求都在Class_Data_Setup()函数中处理

Class_Data_Setup() 会响应去检查所有的特殊类请求,同时根据请求填充ENDPOINT_INFO结构信息

如果IN令牌包是期望的令牌包,则wLength和wOffset两个域会分别被填充成要发送的总字节数和要开始传输的位置

如果OUT令牌包是期盼的令牌包,则rLength和rOffser将会分别被填充成要接收的总字节数和要接收数据的缓冲区起始地址

如果请求有效,Class_Data_Setup返回SUCCESS,否则返回UNSUPPORT


注意:

因为GET_CONFIGURATION和GET_INTERFACE两个请求跟个别的类联系密切,所以他们会在该函数中检查和处理*/

RESULT (*Class_Data_Setup)(uint8_t RequestNo);


/*在建立过程中,会有很多特殊类请求的无数据阶段*/

/*所有的没有数据阶段的特殊请求都在Class_NoData_Setup这个函数中处理

Class_NoData_Setup()

会响应去检查所有特殊类请求,并且执行请求

注意:

因为SET_CONFIGURATION和SET_INTERFACE这两个请求跟个别的类联系密切,他们都会在该函数中被检查和处理*/

RESULT (*Class_NoData_Setup)(uint8_t RequestNo);


/*Class_Get_Interface_Setting()

这个函数时在usb_core.c文件中被调用来测试应用程序是否支持被选中的接口和备用接口

这个函数时由用户写的。如果应用程序支持接口和备用接口,则必须返回"SUCCESS",否则,返回"UNSUPPORT"*/


RESULT (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);


uint8_t* (*GetDeviceDescriptor)(uint16_t Length);

uint8_t* (*GetConfigDescriptor)(uint16_t Length);

uint8_t* (*GetStringDescriptor)(uint16_t Length);


/* 这个字段不是用于当前库版本。它是只保持兼容以前的版本*/

void* RxEP_buffer;

uint8_t MaxPacketSize;


}DEVICE_PROP;





接下去是USER_STANDARD_REQUESTS User_Standard_Requests这个结构体,在这个结构体中主要注册了USB标准请求的实现函数,当然这些函数也实在该结构体后面定义的。跟上面的DEVICE_PROP

Device_Property结构体类似,就不多讲了。

USER_STANDARD_REQUESTS 结构体也是在usb_core.h中定义:

typedef struct _USER_STANDARD_REQUESTS

{

void (*User_GetConfiguration)(void); /*获取配置*/

void (*User_SetConfiguration)(void); /*设置配置*/

void (*User_GetInterface)(void); /*获取接口*/

void (*User_SetInterface)(void); /*设置接口*/

void (*User_GetStatus)(void); /*获取状态*/

void (*User_ClearFeature)(void); /*清除特性*/

void (*User_SetEndPointFeature)(void); /*设置端点特性*/

void (*User_SetDeviceFeature)(void); /*设置设备特性*/

void (*User_SetDeviceAddress)(void); /*设置设备地址*/

}

USER_STANDARD_REQUESTS;



像ONE_DESCRIPTOR Device_Descriptor、ONE_DESCRIPTOR Config_Descriptor、ONE_DESCRIPTOR CustomHID_Report_Descriptor、ONE_DESCRIPTOR CustomHID_Descriptor、ONE_DESCRIPTOR String_Descriptor[4]这些结构体都不仔细讲了。贴出各个结构体的定义,依旧在usb_core.h中:

typedef struct OneDescriptor

{

uint8_t *Descriptor;

uint16_t Descriptor_Size;

}

ONE_DESCRIPTOR, *PONE_DESCRIPTOR;



接下去上面各个结构体注册的函数贴出来:

/*******************************************************************************

* Function Name : CustomHID_init.

* Description : CustomHID Mouse init routine.初始化

* Input : None.

* Output : None.

* Return : None.

*******************************************************************************/

void CustomHID_init(void)

{


/* Update the serial number string descriptor with the data from the unique

ID*/

Get_SerialNum();//获取序列号


pInformation->Current_Configuration = 0;

/* Connect the device */

PowerOn();//上电


/* Perform basic device initialization operations */

USB_SIL_Init();//执行基本的初始化操作,比如说设备IP和端点0的初始化


bDeviceState =

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭