深入解析STM32_USB-FS-Device_Lib库
说明:这个是我学习STM32USB编程时的总结,其中的部分内容是英文文档直接复制过来的,不影响我的阅读,并且我有时也觉得不能准确表达原文的意思,所以我就没有翻译。声明:该文档只供学习之用,任何用于其他目的的行为,需征得本人
同意。
董鸿勇2009.12.15donghongyong@live.cnQQ:262559202
图1展示了一个典型的USB应用与USB-FS-Devicelibrary的关系图。我们可以看出图中由3个层构成分别是:外围硬件(hardware)、STM32_USB-FS_Device_Lib和用户层(Userapplication)。我们从下到上来分析:
图1典型的USB应用与USB-FS-Devicelibray的关系图1.外围硬件(hardware)就是我们的购买的芯片STM32F10XX和开发板2STM32_USB-FS_Device_Lib
就是ST提供给我们的TheUSB-FS-Devicelibrary固件库,它由STM32_USBFS_Device_Driver和ApplicationInterfacelayer两个部分组成。其中STM32_USB-FS_Device_Driver这层管理USB的硬件设备和USB标准协议的直接交互,它又由LowLayer和MediumLayer两个层组成;ApplicationInterfacelayer-HighLayer这层又叫Highayer层,它在固件库核和应用提供给用户一个完整的接口。图2是我给出的STM32_USB-FS-Device_Lib_V3.1.0结构图,下面我们将对这个整个结
构的运行机理分析,然后结构逐层给出具体含义。和其他的接口一样,当受到USB的中断后,进入stm32f10x_it.c中的USB_LP_CAN1_RX0_IRQHandler()和USB_HP_CAN1_TX_IRQHandler()中断服务子程序。其中优先级高的由USB_HP_CAN1_TX_IRQHandler处理,优先级低的由USB_LP_CAN1_RX0_IRQHandler处
理。对于USB_HP_CAN1_TX_IRQHandler函数,它直接调用usb_int(.h,.c)中的CTR_HP(),然后根据发送和接受数据,它调用usb_endp(.c)中的EPX_IN_Calback()或EPX_OUT_Calback()函数。对于EPX_IN_Calback和EPX_OUT_Calback()这14个函数(X=1,
2...7)它们在usb_conf(.h)中通过#defineEPX_IN_CalbackNOP_Proces#defineEP_OUT_CalbackP_Proces的形式,来由用户决定是否提供具体的实现并调用。而将它们和CTR_HP联系在一起的操作,在usb_istr(.h,.c)中以下面的形式给出:
void(pEpInt_IN[7])(void)={EP1_I_Calback,...EP7_IN_Calback,};void(pEpInt_OUT[7])(void)={
EP1_OT_Calback,...EP7_OUT_Calback,};对于SB_HP_CAN1_TX_IRQHandler函数,它直接调用usb_istr(.h,.c)中的USB_Istr(),USB_Istr()根据具体的请求决定是调用usb_istr(.h,.c)中下面函数
voidCTR_Calback(void);voidDOV_alback(void);voidER_Calback(void);voidWKUP_Calback(void);voidSP_Calback(void);
voidREST_Calback(void);voidSOF_Calback(void);voidESF_Calback(void);还是调用usb_int(.h,.c)中的voidCTR_LP(void)。对于上面的这个函数是否给出定义,是由用户在usb_conf(.h)中,通过下面的宏决定的
/#defineCTR_CALBACK//#defineDOV//#defineER_CALBACK//#defineWKUP//#defineSP_CALBACK/
/#defineREST/#defineSOF_CALBACK/#defineESFL/如果调用了CTR_LP()函数,CTR_LP()函数中如果不是端点0的请求,则和CTR_LP一样的顺序处理;如果是端点0,它调用usb_core(.h,.c)中的
uint8_tSetup0_Proces(void);
uint8_tPost0_Proces(void);uint8_tOut0_Proces(void);uInt8_tIn0_Proces(void);如果是标准的请求,便调用usb_core(.h,.c)中的下面的函数
RESULTStandard_SetEndPointFeature(void);RESULTStandard_SetDeviceFature(void);uint8_tStandard_GetConfiguration(uint16_tLength);RESULTStandard_SetConfiguration(void);
uint8_tStandard_GetInterface(uint16_tLength);RESULTStandard_SetInterface(void);Uint8_tStandard_GetDescriptorDat(uint16_t...);uint8_tStandard_GetStaus(uint16_tLength);
RESULTStandard_ClearFeature(void);voidSetDeviceAddres(uint8_t);这些函数,又调用USER_STANDARD_REQUEST结构指定的中,用户在usb_prop(.h,.c)中定义的函数。如果不是标准请求,则调用EVICE_PROP结构指定的中,用户在usb_prop(.h,.c)
中定义的函数其他一些函数。
图2STM32_USB-FS-Device_Lib_V3.1.0结构图
下面是上面各个模块的解释,基本都是来自STM32的官网UM0424用户手册翻译。2.1STM32_USB-FS_Device_Driver-LowLayer对于USB-FS_Device来说LowLayer就是USB-FSperipheralinterface,它由Table1中模块
组成。Table1.USB-FS_Devicepripheralinterfacemodules
2.1.1usb_reg(.h,.c)usb_regs模块实现了硬件抽象层,它提供了一个存取USB-FS_Device外围设备寄存器的函数集合。这个集合包括Commonregisterfunctions、Endpointregisterfunctions、Bufferdescriptiontablefunctions和Double-bufferdendpointsfunctions四个函数级。
注意:这些函数集合可以用宏的形式和函数的形式调用:–宏形式:_NameofFunction(parmetr1,.)–函数形式:ameofFunction(parmetr1,.)2.1.1.1Comonregisterfunctions:这些函数可以用来设置和获得USB-FS_Device外围普通寄存器的值;其寄存器可以是CNTR、ISTR、FNR、DADR、BTALE。
able2.Comonregisterfunctions
2.1.1.2Endpointregisterfunctions:所有和端点寄存器(Endpointregister)相关的操作都可以用SetENDPOINTandGetENDPOINT函数来完成。而且,还有一些继承自它们的函数可以在特定的域(field)提供一个直接而快速的操作。a)Endpointset/getvalue
SetNDPOINTOOO:voidSetENDPOINT(uint8_tbEpNum,int16_twRegValue)bEpum=Endpointumber,wRegValue=ValuetowriteGetNDPOINTGOGOGO:uint16_tGetENDPOINT(uint8_tbEpNum)
FileDescritionusb_reg(.h,.c)硬件抽象层Hardwareabstractionlayerusb_int.c正确传输中断服务线程Correctransferinteruptserviceroutineusb_mem(.h,.c)数据传输管理Dattransfermanagement(from/topacketmemoryare)
RegisterfunctionCNTRvoidSetCNTR(uint16_twValue)uint16_tGetT(void)ISTRvoidSetISTR(uint16_twValue)uint16_tGetIST(void)
FNRuint16_tetFNR(void)DADvoidSetDAD(uint16_twValue)uint16_tGetR(void)BTABLEvoidSetBTABLE(uint16_twValue)uint16_tGetTLE(void)
bEpNum=Endpointumberreturnvalue:thendpointregistervalueb)EdpointTYPEfieldUSB_EPnR寄存器分布
其中EP_TYPE根据SB_EPnR中的位置和端点类型编码给出下面的宏定义:#define_BULK(0x0000)/EndpointBULK#defineEP_CONTROL(0x0200)/EndpointCONTROL#define_ISCHNUS(0x0400)/ndpointISCHRNOUS#defineEP_INTERPT(0x0600)/EndpointINTEUPT
端点类型编码
SetEPType:voidSetEPType(uint8_tbEpNum,uint16_twtype)bEpNum=Endpointnumber,wtype=Endpointype(valuefromtheabovedefine’s)GetEPTypeGGG:uint16_tGetEPType(uint8_tbEpNum)bEpNum=Endpointnumberreturnvalue:avluefromtheabovedefine’s
c)EndpointSTAUSfield其中STA_TX/TA_RX根据SB_EPnR中的位置和端点类型编码给出下面的宏定义:#defineEP_DIS(0x0000)/EndpointTXDISabled#define_TX_STAL(0x0010)/ndpointTALed#defineEP_NK(0x0020)/EndpointTXNKed#define_TX_VALID(0x0030)/ndpointVALID
#defineEP_R_DIS(0x0000)/EndpointRXDISabled#defineX_STAL(0x1000)/ndpointTALed#defineEP_R_NK(0x2000)/EndpointRXNKed#defineX_VALID(0x3000)/ndpointVALID
接收状态编码
EP_TYPE[1:0]描述0BULK:批量端点01CONTROL:控制端点10IS:同步端点1
INTERUPT:中断端点
STA_RX[1:0]描述0DISABLED:端点忽略所有的接收请求。01TL:端点以STAL分组响应所有的接收请求。10NAK:端点以NAK分组响应所有的接收请求。
发送状态编码
SetEPTxStatus:voidSetEPTxStaus(uint8_tbEpNum,uint16_twStae)etRxStats:voidetRxStaus(uint8_tum,uint16_ttae)bEpNum=Endpointnumber,wStae=avluefromtheabovedefine’sGetEPTxStatusGGG:uint16_tGetPTxStaus(uint8_tbEpNum)GetRxStatsGGG:uint16_tetERxStaus(uint8_tum)bEpNum=endpointnumber
returnvalue:avluefromtheabovedefine’sd)EndpointKINDKKKfieldSetP_KINDKKK:voidSetEP_KIND(uint8_tbEpNum)ClearEP_KIKKK:voidClearEP_I(uint8_tbEpum)
bEpNum=endpointumberSet_Staus_OtOOO:voidSet_Staus_Out(int8_tbEpNum)Clear_Staus_OtOOO:voidClear_Staus_ut(int8_tbEpum)bEpNum=endpointumber注意:在usb_regs.h中#define_Set_Staus_Out(bEpNum)_SetEP_KIND(bEpNum)
#define_Clear_Staus_ut(bEpum)_ClearEP_I(bEpum)SetEPDoubleBuf:voidSetEPDoubleBuf(uint8_tbEpNum)ClearPoubleuf:voidClearEPoubleBuf(uint8_tbEpum)bEpNum=endpointumber注意:在usb_regs.h中#define_SetEPDoubleBuf(bEpNum)_SetEP_KIND(bEpNum)
#define_ClearEPoubleuf(bEpum)_ClearEP_I(bEpum)e)CorrectTransferRx/TxfieldslearEP_CR_X:voidClearEP_CTR_X(uint8_tbEpNum)ClearP_T_T:voidlearEP_T_T(uint8_tbEpum)bEpNum=endpointumberf)DataToggleRx/Txfields
TogleDOG_XOGOGOG:voidTogleDTOG_RX(uint8_tbEpNum)ogleTOG_OGOGOG:voidTogleT_T(uint8_tbEpum)bEpNum=endpointumberg)Adresfield端点地址SetEPAdres:voidSetEPAdres(uint8_tbEpNum,int8_tbAdr)
bEpNum=endpointumberbAdr=adrestobestGetEPAdresGGG:uint8_tGetEPAdres(uint8_tbEpNum)bEpNum=endpointumber
1VALID:端点可用于接收。STA_RX[1:0]描述0DISABLED:端点忽略所有的发送请求。01STL:端点以STAL分组响应所有的发送请求。
10NAK:端点以NK分组响应所有的发送请求。1VLID:端点可用于发送。
2.1.1.3Buferdescriptiontablefunctions这些函数用来设置和获得端点接受和发送缓冲区的地址和大小。a)Tx/RxbuferaddresfieldsSetEPTxAdr:voidSetEPTxAdr(uint8_tbEpNum,int16_twAdr);SetPRxdr:voidSetEPRxdr(uint8_tbEpum,int16_tdr);
bEpNum=endpointumberwAdr=adrestobest(expresdasPMAbuferadres)GetEPTxAdrGGG:uint16_tGetEPTxAdr(uint8_tbEpNum);GetPRxdrGGG:uint16_tetEPRxdr(uint8_tbEpum);bEpNum=endpointumber
returnvalue:adresvalue(xpresdasPMAbuferadres)b)Tx/RxbfercounterfieldsSetEPTxCount:voidSetEPTxCount(uint8_tbEpNum,int16_twCount);SetPRxount:voidSetEPRxount(uint8_tbEpum,int16_tount);bEpNum=endpointumber
wCount=countertobestGetEPTxCountGGG:uint16_tGetEPTxCount(uint8_tbEpNum);GetPRxountGGG:uint16_tetEPRxount(uint8_tbEpum);bEpNum=endpointumberreturnvalue:countervalue
2.1.1.4Double-buferdendpointsfunctions在批量和同步传输中,为了获得大数据传输吞吐量,double-buferd模式必须被编程。在这个操作模式,一些端点寄存器的域和缓冲区描述表单元与单缓冲区模式有不同的含义。为了更加容易的使用这个模式,一些函数被设计出来。SetEPDoubleBuf():一个工作在批量模式的端点可以通过设置EP-KIND位来将其设置成双
缓冲模式,SetEPDoubleBuff()这个函数及可以完成这样的任务。FreUserBufer:在double-bufferd模式,该端点变成单向端点,并且那个不使用方向(接收和发送)的的缓冲区被用做使用方向的第二个缓冲区。地址和计数器必须被用不同的方式处理。Rx和Tx地址和计数器单元变成Buffer0andBuffer1单元。并且,在库中直接提供这样操作功能的函数。在批量传输中,USB模块填充一个缓冲区的同时,另一个缓冲区为应用程序服务。应用
程序必须在下一个批量传输需要下一个缓冲区前处理完数据。这个服务于用户应用程序必须被及时的释放。FreeUserBuffer就是提供用来释放应用程序使用了的缓冲区的。FreserBufer:voidFreUserBuffer(uint8_tbEpNum,uint8_tbDir);bEpNum=endpointnumbera)Doubleuferaddresse
这些函数用来在doublebufferd模式下,获得和设置缓冲区描述表中缓冲区的地址值。SetEPDblBufAdr:voidSetEPDblBuffAddr(uint8_tbEpNum,uint16_twBuf0Addr,uint16_twBuf1Addr);SetEPDbluf0Adr:voidSetEPDblBuf0Addr(uint8_tbEpNum,uint16_twBuf0Addr);
SetEPDbluf1Adr:voidSetEPDblBuf1Addr(uint8_tbEpNum,uint16_twBuf1Addr);bEpNum=endpointnumberwBuf0Addr,wBuf1Addr=bufferaddress(expresdasPMAbufferaddress)GetEPDblBuf0AdrGGG:uint16_tGetEPDblBuf0Addr(uint8_tbEpNum);Getlf1rGGG:uint16_tetbluf1Addr(uint8_tum);
bEpNum=endpointnumberreturnvalue:bufferaddressb)Doubleufercounters这些函数用来在doublebufferd模式下,获得和设置缓冲区描述表中缓冲区的计数器值。SetEPDblBufCount:voidSetEPDblBufCount(uint8_tbEpNum,uint8_tbDir,uint16_twCount);
SetPbluf0ount:voidSetEPbluf0ount(uint8_tbEpum,uint8_tbir,uint16_tount);SetEPDblBuf1Count:voidSetEPDblBuf1Count(uint8_tbEpNum,uint8_tbDir,uint16_twCount);bEpNum=endpointumberbDir=endpointdirectionwCount=bufercounter
GetEPDblBuf0CountGGG:uint16_tGetEPDblBuf0Count(uint8_tbEpNum);GetPbluf1ountGGG:uint16_tetEPbluf1ount(uint8_tbEpum);bEpNum=endpointumberreturnvalue:bufercounterc)DoubleuferSTAUSThesimpleanddoublebuffermodesusethesamefunctionstomanagethe
EndpointSTAUSexceptfortheSTALstausfordoublebuffermode.Thisfunctionalityismanagedbythefunction:单缓冲区和双缓冲区模式使用相同的函数去管理端点STAUS,除了STAL状态。这个功能是被下面的函数管理。SetDouBleufEPStal:voidSetDouBleufEPStal(uint8_tbEpNum,int8_tbDir)
bEpNum=endpointumberbDir=endpointdirection2.1.2usb_int(.h,.c)s_it模块处理正确传输中断服务程序;它提供了USB协议事件与这个库的连接。STM32F10xxxUSB-FS_Device外围设备提供两个正确传输处理函数:
●低优先级中断Low-priorityinterupt:.被CTR_LP()函数管理,用于控制模式、中断模式和批量模式(单缓冲区)。●高优先级中断High-priorityinterupt:被CTR_HP()函数管理,用于快速传输模式,像同步模式和批量模式(双缓冲区)。2.1.3usb_mem(.h,.c)usb_mem模块负责拷贝数据从用户内存区(usermmoryare)到USB模块内存区(packet
memoryare)(PMA)或者从USB模块内存区(packetmemoryare)(PMA)到用户内存区(usermmoryare)。它提供两个不同的函数:voidUserToPMABuferCopy(uint8_tpbUsrBuf,int16_twPMABufAdr,uint16_twNBytes);voidPMAToUseruferopy(uint8_tpbsruf,int16_tPufdr,uint16_tytes);
2.2STM32_USB-FS_Device_Driver-mediumLayerTable2.USB-FS-Device_Drivermediumlayerodules
2.2.1usb_init(.h,.c)usb_init模块设置在整个库中用到的usb初始化函数和全局变量。/函数voidUSB_Init(void);/变量uint8_tEPindex;/Thenumberofcurrentendpoint,itwilbeusedtospecifyanendpoint/
/uit8_tDevice_no;//Thenumberofcurrentdevice,itisanindextotheDevice_Table/DEVICE_INFOOOODevice_Info;I_IOOOOpInformation;/PointstotheDEVICE_INFOstructureofcurrentdevice//Thepurposeofthisregisteristospeeduptheexecution/DEVICE_PROPOOOpProperty;/PointstotheDEVICE_PROPstructureofcurrentdevice//Thepurposeofthisregisteristospeeduptheexecution/
USER_STANDARD_REQUSQQQpUser_Standar_Request;uint16_taveState;/TemporarysavethestaeofRx&Txstaus.//WhenevertheRxorTxstaeischanged,itsvalueisaved//inthisvariblefirstandwilbesetotheEPRBorEPRA//atheendofinteruptproces/uint16_twInterupt_Mask;
2.2.2usb_core(.h,.c)usb_core模块是这个库的“核”,它实现了USB2.0规范第9章中描述的所有函数。模块中的一些子程序处理控制断点(ENDP0)的USB标准请求,提供必须的代码去完成setup枚举阶段的顺序请求。Astaemachine被实现,为了去处理setup传输不同阶段的请求。USB核模块也用User_Standar_Request结构,在标准的请求和用户实现之间,实现一
个动态的接口。当需要的时候,USB核分发一些类的特定请求和一些总线事件给用户程序。这些处理程序在Device_Property中指定。这些被和用到的数据结构和函数,在下面的文章中详细的描述:1.DevicetablestructureThecorekeepsdevicelvelinformationintheDevice_Tablestructure.Device_Table
isofthetype:DEVICE.核将设备级(devicelvel)信息保存在Device_Table结构体中。Device_Table是DEVICE类型。
Fileescriptionusb_init(.h,.c)USBdeviceinitalizationglobalvariblesusb_core(.h,.c)Sprotcolmangemnt(compliantwithcapter9oftheUSB2.0specifcation)usb_sil(.h,.c)Simplifedfunctionsforead&writeacesstothendpoints(abstractionlayerforbothUSB-FS_DeviceandOTG-FS_Devicepripherals)
usb_def.h/usb_type.hUSBdefinitonsandTtypesusedinthelibray
typedfstruct_DEVICE{uint8_tTotal_Endpoint;/Numberofendpointsthatreused/uint8_tTotal_Configuration;/umberofconfigurationavilable/}
DEVICE;2.eviceinformationstructureTheUSBcorekeepsthesetuppacketfromthehostfortheimplemntedUSBDeviceintheDevice_Infostructure.Thistructurehasthetype:DEVICE_INFOOOO.USB核将从主机获得的setup包信息保存在evice_Info结构体中。Device_Info的类型是DEVICE_INFOOOO。
typedfstruct_DEVICE_INFO{uint8_tUSBbmRequestType;/bmRequestType/uint8_tSbequest;/bequest/uint16_tuint8_tUSBwValues;/wValue/
uint16_tuint8_tSIndexs;/Index/uint16_tuint8_tUSBwLengths;/wLength/uint8_tControlStae;/oftypeCONTROL_STAE/uint8_turent_Feature;
uint8_tCurent_Configuration;/Selctedconfiguration/uint8_turent_Interface;/Selctedinterfaceofcurentconfiguration/uint8_tCurent_AlternateSting;/SelctedAlternateStingofcurentiterface/ENDPOINT_INFOCtrl_Info;}DEVICE_IF;
在DVICE_INFOOOO中,联合体uint16_t_uint8_t被定义,它可以容易的存取uint16_t或者uint8_t格式的数据。typedfunio{uint16_tw;
structBW{uint8_tb1;uint8_tb0;}bw;
}uint16_tuint8_t;Descriptionofthestructrefields:–USBbmRequestTypeisthecopyofthebmRequestTypeofasetuppacket–eestisthecopyofthebRequestofasetuppacket–USBwValuesidefinedastype:uint16_t_uint8_tandcanbeacesdthrough3macros:
#defineUSBwValueUSBwValues.w#defineSalue0Salues.b.b0
#defineUSBwValue1USBwValues.bw.b1USBwValueisthecopyofthealueofasetuppacketale0isthelowbyteofwValue,andUSBwValue1isthehighbyteofwValue.–USBwIndexsisdefinedasUSBaluesandcanbeacesdby3macros:#defineUSBwIndexUSBwIndexs.w
#defineSIndex0SIndexs.b.b0#defineUSBwIndex1USBwIndexs.bw.b1USBwIdexisthecopyoftheIndexofasetuppacketInex0isthelowbyteofwIndex,andUSBwIndex1isthehighbyteofwIndex.–USBwLegthsidefinedastype:uint16_t_uint8_tandcanbeacesdthrough3macros:
#defineUSBwLengthUSBwLengths.w#defineSLength0SLengths.b.b0#defineUSBwLength1USBwLengths.bw.b1USBwLegthisthecopyofthewLengthofasetuppacketengt0andUSBwLength1arethelowandhighbytesofwLength,respectively.–ControlStateisthestaeofthecore,theavilablevaluesaredefinedinCONTROL_STAE.
–urent_Featureisthedevicefatureatnytime.ItisafectdbytheSE_FEATURandCLEAR_FEATURErequestandretrievdbytheGET_SATUSrequest.Usercodedoesnotusethisfield.–Curent_Configurationistheconfigurationthedeviceisworkingonatnytime.ItisetandretrievdbytheSET_CONFIGURATIONandGET_CONFIGURATIONrequest,respectively.
–Curent_Interfaceistheselctedinterface.–ret_Alternatestingisthealternativestingwhichhasbeenselctedforthecurrentworkingconfigurationandinterface.ItisetandretrievdbytheSET_INTERFACEandGET_INTERFACErequest,respectively.–Ctrl_InfohastypeNDPOI_INO.Sincethistructureisusedverywhereinthelibrary,aglobalvariblepInformationisdefinedfor
easyacestotheDevice_Infotable,itisapointertotheDEVICE_INFOOOOstructure.Actualy,pInformation=&evice_Ifo.3.DevicepropertystructreTheUSBcoredispatchesthecontroltotheuserprogramwheneveritisnecesary.serhandlingproceduresaregivenianrayofDevice_Property.Thestructurehas
thetype:DEVICE_PROPOOO:typedfstruct_I_PP{void(Init)(void);/Initalizethedvice/void(Rest)(void);/Restroutineofthisdevice/
void(Proces_Staus_IN)(void);/Devicedpendentprocesafterthestaustage/void(Proces_Staus_OUT)(void);/Procedureofprocesonsetupstageofaclaspecifedrequestwithdatstage//AlclaspecifedrequestwithdatstageareprocesdinClas_Dat_SetupClas_Dat_Setup()
responsetocheckalspecialrequestandfilsENDPOINT_INFOacordingtotherquestIfNtokensarexpectd,thenwLength&wOfsetwilbefiledwithtetotaltransferingbytesandthestartingpositonIfOUTtokensarexpectd,thenrLength&rOfsetwilbefiled
withtetotalexpectdbytesandthestartingpositonithebuferIftherquestisvalid,Clas_Dat_SetupreturnsSUCES,elsUNSPORTCAUTION:SinceGET_CONFIGURATION&GET_INTERFACEarehiglyrelatedto
theindividualclases,theywilbecheckedandprocesdher./RESULT(Clas_Dat_Setup)(uint8_tRequestNo);/Procedureofprocesonsetupstageofaclaspecifedrequestwithoutdatstage/
/AlclaspecifedrequestwithoutdatstageareprocesdinClas_NoDat_SetupClas_NoDat_SetupresponsetocheckalspecialrequestandperformtherquestCAUTION:
SinceSET_CONFIGURATION&SET_INTERFACEarehiglyrelatedtotheindividualclases,theywilbecheckedandprocesdher./RESULT(Clas_NoDat_Setup)(uint8_tRequestNo);
/Clas_Get_Interface_SetingThisfunctionisusedbythefileusb_core.ctotestiftheslectdInterfaceandAlternateSting(uint8_tInterface,uint8_tAlternateSting)aresuportedbytheaplication.Thisfunctioniswritngbyuser.Itshouldreturn"SUCES"iftheInterface
andAlternateStingaresuportedbytheaplicationr"UNSPORT"iftheyarenotsuported./RESULT(Clas_Get_Interface_Seting)(uint8_tInterface,uint8_tAlternateSting);
uint8_t(GetDeviceDscriptor)(uint16_tLength);uint8_t(etConfigescriptor)(uint16_tLength);uint8_t(GetStringDescriptor)(uint16_tLength);uint8_tRxEP_bufer;
uint8_tMaxPacketSize;}DEVICE_PROP;4.Userstandarrequestructret
TheUserStandardRequestStructureistheinterfacebetwentheusercodeandthemanagementofthestandardrequest.Thestructurehasthetype:USER_STANDARD_REQUST:QQQtypedfstruct_USER_SANDARD_REQUEST{void(User_GetConfiguration)(void);/GetConfiguration/
void(ser_Setonfiguration)(void);/Setonfiguration/void(User_GetInterface)(void);/GetInterface/void(ser_SetInterface)(void);/SetInterface/void(User_GetStaus)(void);/GetStaus/void(ser_ClearFeature)(void);/ClearFeature/
void(User_SetEndPointFeature)(void);/SetEndpointFeature/void(ser_SetDeviceFature)(void);/SetDeviceFeature/void(User_SeteviceAdres)(void);/SeteviceAdres/}USER_STANDARD_REQUEST;
IftheuserwantstoimplemntspecifcodeafterecivngastandardUSBDevicerquesthehastousethecorrespondingfunctionsinthistructure.AnapplicationdevelopermustimplemntthrestructureshavingtheDEVICE_PROPOOO,Device_TableandUSER_STANDARD_REQUSTQQQtypesinordertomanageclasrequestandapplicationspecifcontrols.hediferntfieldsofthesestructuresaredescribedinSection1.4.4:usb_type.h/usb_def.h.
2.2.3usb_sil(.h,.c)Thes_silmoduleimplemntsanadditionalabstractionlayerforUSB-FS_DeviceandOTG-FS_Deviceperipherals.ItoffersimplefunctionsforacesingtheEndpointsforReadandWriteoperations.EndpointsimplifedwritefunctionThewriteoperationtoanendpointcanbeperformedthroughthefollowingfunction:
voidUSB_SIL_Write(uint32_tEPNum,uint8_tpBuferPointer,uint32_twBuferSize);Theparametrsofthisfunctionare:●EPNum:NumberoftheINendpointrelatedtothewriteoperation●pBufferPointer:PointertotheuserbuffertoberitentotheINendpoint.
●wBufferSize:NumberofdatabytestobewritentotheINendpoint.Dependingontheperipheralinterface,thisfunctiongetstheaddresoftheendpointbufferandperformsthepacketwriteoperation.EndpointsimplifedreadfunctionThereadoperationfromanendpointcanbeperformedthroughthefollowingfunction:
uint32_tUSB_SIL_Read(uint32_tEPNum,uint8_tpBuferPointer);Theparametrsofthisfunctionare:●EPNum:NumberoftheOUTendpointrelatedtothereadoperation
●pBufferPointer:PointertotheuserbuffertobefiledwiththedatareadformtheOUTendpoint.Dependingontheperipheralinterface,thisfunctionperformstwosuccesiveoperations:●GetsthenumberofdatarecivedfromthehostontherelatedOUTendpoint●CopiesthereciveddatafromtheUSBdedicatedmmorytothepBufferPointeraddres.Thenthefunctionreturnsthenumberofreciveddatabytestotheuserapplication.
uint32_tUSB_SIL_Init(void);在usb_prop.c中的xxx-inti函数中调用。USB_SIL_Write和USB_SIL_Read用户可以用它们来读取端点中的数据。2.2.4usb_type.h/usb_def.hThesefilesprovidesthemaintypesandUSBdefinitionsusedinthelibrary.
2.3AplicationInterfacelayer-HighHHHLayerTable3.plicationiterfacemodules
2.3.1usb_conf(.h)Theusb_conf.hisusedto:ForUSB-FS_Deviceperipheral●DefinetheBTABLEandalendpointaddressinthePMA.efinetheinteruptmaskacordingtotheneededevnts.ForOTG-FS_Deviceperipheral
●DefinetheEndpointnumber.efinetheinteruptmaskacordingtotheneededevnts.2.3.2usb_prop(.h,.c)ThesrmoduleisusedforimplemntingtheDevice_Property,Device_TableandUSER_STANDARD_REQUSTQQQstructuresusedbytheUSBcore.它们的具体含义在
use_core.h/.c中说明。2.3.4USB_endp(.c)USB_endpmoduleisusedfor:
●HandlingtheCTR“correctransfer”routinesforendpointsotherthanendpoint0(EP0)fortheUSB-FS_Deviceperipheral.●Handlingthe“transfercomplet”interuptroutinesforendpointsotherthanendpoint0(EP0)fortheOTG-FS_Deviceperipheral.ItalsoalowshandlingtheRxFIOlevlinteruptsforisochronousendpoints.
FileDescriptionusb_conf.hUSB-FS_Deviceonfigurationfileusb_desc(.h,.c)S-FS_evicedscriptorsusb_pro(.h,.c)USB-FS_Deviceaplication-specifcproertiesusb_endp.cCorectransferinterupthandleroutinesforno-controlendpoints
usb_istr(.h,.c)USB-FS_Deviceinterupthandlerfunctionsusb_pwr(.h,.c)S-FS_evicepowerandconectionmagemntfunctions
Forenablingtheprocesingofthesecalbackhandlersapre-procesorswitchnamedEPx_IN_Calback(forINtransfer)orEPx_OUT_Calback(forOUTtransfer)orx_RX_ISOC_CALBACK(forIsochronousuttransfer)mustbedefinedintheUSB_conf.hfile.2.3.5usb_istr(.c)
USB_istrmoduleprovidesafunctionnamedUSB_Istr()whichhandlesalUSBinterupts.ForeachUSBinteruptsource,acalbackroutinenamedX_Calback(forexample,REST_Calback)isprovidedinordertoimplemntauserinterupthandler.Toenabletheprocesingofeachcalbackroutines,apreprocesorswitchnamedX_CalbackmustbedefinedintheUSBconfigurationfileUSB_conf.h.
USB_Istr()在USB的中断服务子程序stm32f10x_it.c中的voidUSB_LP_CAN1_RX0_IRQHandler(void)中调用,这个是驱动源。2.3.6usb_pwr(.h,.c)ThismodulemanagesthepowermanagementoftheUSBdevice.ItprovidesthefunctionsshowniTable8.
Table8.Powermanagementfunctions
uint32_tPower_on(void);在usb_prop.c中的xxx-inti函数中调用。Suspend和Resume一般在voidUSB_Istr(void);中处理,当然用户也可以自己根据情况调用。
FunctionameDescriptionRESULTPower_on(void)Handleswitch-onconditonsESLTPoer_of(void)andlesitch-ofconditonsvoidSuspend(void)SetsuspendmoeoperationconditonsVoidResume(RESUME_STAEeRsumeStVal)Handlewakeupoerations
|
|