CY7C68031A固件程序FW.C详解.docx_第1页
CY7C68031A固件程序FW.C详解.docx_第2页
CY7C68031A固件程序FW.C详解.docx_第3页
CY7C68031A固件程序FW.C详解.docx_第4页
CY7C68031A固件程序FW.C详解.docx_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

CY7C68031A固件程序FW.C详解(1) 2011-04-01 14:10736人阅读评论(0)收藏举报/本来要一次传上去,百度空间嫌文章太长,只好分为两篇/FW.C文件,我当初看了一个星期,也没看懂的。这里我们逐字逐句研读,/边理解,边一行一行的注释./以下是Cypress公司的官方程序,我不做改动,原英文注释保留,只增加注释/简单语句就不说了/ /?/是我不懂得的地方,希望高手补充/ /#/是以后开发可能需要改动的地方/我加的所有注释都用/四个连斜杠,便于以后不需要的时候屏蔽掉/这是在Keil UV2里编辑的,没有其它格式字符,可以直接编译/-/ File: fw.c/ Contents: Firmware frameworks task dispatcher and device request parser/ $Archive: /USB/Examples/FX2LP/bulkext/fw.c $/ $Date: 3/23/05 2:53p $/ $Revision: 8 $/-/ Copyright 2003, Cypress Semiconductor Corporation/-#include fx2.h /fx2.h 定义EZUSB的宏、数据类型等的头文件 #include fx2regs.h/fx2regs.h 定义EZUSB寄存器定义的头文件#include syncdly.h / SYNCDELAY macro /syncdly.h 同步延时宏定义/-/ Constants/-#define DELAY_COUNT 0x9248*8L / Delay for 8 sec at 24Mhz, 4 sec at 48#define _IFREQ 48000 / IFCLK constant for Synchronization Delay#define _CFREQ 48000 / CLKOUT constant for Synchronization Delay/以上设置时钟频率为48MHZ/-/ Random Macros/-#define min(a,b) (a)(b)?(a):(b)/-/ Global Variables/全局变量/-volatile BOOL GotSUD;/GotSUD是令牌包标志,准确的说是“令牌阶段数据到来”,什么是令牌包?/首先,USB一连串的数据传输、处理、响应等就叫做USB事务。/例如,上位机要读取一个描述符,那么就会触发一次USB事务。/一个完整的USB事务处理有三个阶段:令牌阶段,数据阶段,握手阶段。/每个阶段数据传输是有各种包组成的,例如令牌阶段:同步字段令牌包EOP构成。/USB主机启动事务处理,开始发送令牌包,这个时候假如说我们当前的USB设备地址号/为2(重枚举时分配的),而主机发送的地址号也为2,那么这个USB设备硬件会产生/中断,进入中断处理。也就是periph.c文件中的void ISR_Sudav(void)函数,/在这个中断处理中,设置 GotSUD标志为TRUE,表示收到令牌数据,要启动USB传输了。/然后我们固件中判断if(GotSUD),GotSUD为真,则执行SetupCommand()函数,/在这里处理控制传输,读取描述符,设置特性,处理Vendor命令等。/完毕后置GotSUD = FALSE;然后检查USB各种状态并处理:BOOL Rwuen;/Rwuen 远程唤醒标志BOOL Selfpwr;/Selfpwr 禁止或使能自供电模式 volatile BOOL Sleep; / Sleep mode enable flag/Sleep /禁止或使能休眠模式 /以下是定向USB描述符WORD pDeviceDscr; / Pointer to Device Descriptor; Descriptors may be moved/设备描述符指针WORD pDeviceQualDscr;/设备限定描述符指针 WORD pHighSpeedConfigDscr;/高速配置描述符指针WORD pFullSpeedConfigDscr;/全速配置描述符指针WORD pConfigDscr;/配置描述符指针WORD pOtherConfigDscr;/其他速率配置描述指针WORD pStringDscr; /字符串描述符指针 /-/ Prototypes/-/硬件程序的函数入口。主要有以下这些方法:/功能在函数中说明void SetupCommand(void);/void SetupCommand(void); /握手命令处理void TD_Init(void);/void TD_Init(void); /初始化,完成配置,启动时调用一次void TD_Poll(void);/void TD_Poll(void); /用户处理程序,循环调用/void IO_Init(void); /8051 IO初始化/void REG_Init(void); /8051寄存器初始化BOOL TD_Suspend(void);/BOOL TD_Suspend(void); /挂起处理BOOL TD_Resume(void);/BOOL TD_Resume(void); /唤醒处理/以下为各种描述符的获取和设置函数,重枚举时自动调用/功能在函数中说明BOOL DR_GetDescriptor(void);/DR_GetDescriptor(void)获得描述符BOOL DR_SetConfiguration(void);/ BOOL DR_SetConfiguration(void)设置配置子函数BOOL DR_GetConfiguration(void);/BOOL DR_GetConfiguration(void) 获取配置子函数BOOL DR_SetInterface(void);/ DR_SetInterface(void)配置接口子函数 BOOL DR_GetInterface(void);/ DR_GetInterface(); 获取接口子函数 BOOL DR_GetStatus(void);/DR_GetStatus(void) 获得状态BOOL DR_ClearFeature(void);/DR_ClearFeature(void) 清除特性BOOL DR_SetFeature(void);/DR_SetFeature(void)设置特性BOOL DR_VendorCmnd(void);/ DR_VendorCmnd(void) 自定义的用户请求/ this table is used by the epcs macro / /?/const char code EPCS_Offset_Lookup_Table =0, / EP1OUT1, / EP1IN2, / EP2OUT2, / EP2IN3, / EP4OUT3, / EP4IN4, / EP6OUT4, / EP6IN5, / EP8OUT5, / EP8IN;/ macro for generating the address of an endpoints control and status register (EPnCS) / /?/#define epcs(EP) (EPCS_Offset_Lookup_Table(EP & 0x7E) | (EP 128) + 0xE6A1)/-/ Code/-/ Task dispatchervoid main(void)DWORD i;WORD offset;DWORD DevDescrLen;DWORD j=0;WORD IntDescrAddr;WORD ExtDescrAddr;/ Initialize Global States/初始化全局状态变量Sleep = FALSE; / Disable sleep mode/Sleep = FALSE; /初始化用户变量 休眠使能禁止Rwuen = FALSE; / Disable remote wakeup/Rwuen = FALSE;/远程唤醒禁止Selfpwr = FALSE; / Disable self powered/Selfpwr = FALSE; /禁止自供电模式GotSUD = FALSE; / Clear Got setup data flag/GotSUD = FALSE; /清除SetUp令牌包到来标志/ Initialize user deviceTD_Init();/TD_Init(); 初始化USB/ The following section of code is used to relocate the descriptor table. / The frameworks uses SUDPTRH and SUDPTRL to automate the SETUP requests/ for descriptors. These registers only work with memory locations/ in the EZ-USB internal RAM. Therefore, if the descriptors are located/ in external RAM, they must be copied to in internal RAM. / The descriptor table is relocated by the frameworks ONLY if it is found / to be located in external memory./取得定向USB描述符的指针(地址)/这段代码用来获取USB的各个描述符在68013内存中的地址,/准确说是在RAM中的地址,在dscrpt.a51文件中有定义,/所有的描述符组成了整个的描述符表,后面会用到。pDeviceDscr = (WORD)&DeviceDscr;/pDeviceDscr = (WORD)&DeviceDscr; /设备描述符pDeviceQualDscr = (WORD)&DeviceQualDscr;/ pDeviceQualDscr = (WORD)&DeviceQualDscr; /设备限定描述符 pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;/ pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr; /高速配置描述符pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;/ pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr; /全速配置描述符pStringDscr = (WORD)&StringDscr;/ pStringDscr = (WORD)&StringDscr; /字符串描述符 / Is the descriptor table in external RAM ( 16Kbytes)? If yes,/ then relocate./ Note that this code only checks if the descriptors START in / external RAM. It will not work if the descriptor table spans/ internal and external RAM./意思是说,这段代码用来判断描述符表首址,/也就是前面的DeviceDscr、DeviceQualDscr等是否位于68013的外部RAM区,/如果是,则移除,然后将描述符表移到内部RAM区,为什么要移到内部RAM区,/因为当描述符表位于外部RAM时,USB是不工作的。那么如何判断描述符地址/是否超出内部RAM的地址呢?首先,&DeviceDscr取得整个描述符表的首地址/(它也是DeviceDscr设备描述的首址),然后和0XC000相与,为什么要和0XC000相与?/这就牵涉到68013 FX2LP(注意是LP)的内部结构图:/见数据单/上图针对的是128pin的FX2LP,如果是56或100pin的,那么没有外部RAM,/只有内部RAM。可以看到,FX2LP内部RAM从0000-FFFF,其他为外部RAM。/而内部RAM中,只有从0000-3FFF和从E000-FFFF的区域可用,其他为系统保留。/从0000-3FFF这16K bytes的内部RAM空间,叫做主RAM,对56,100,128pin来说,/都可以同时作为程序或数据存储器(对128pin来说,EA=0)。/再看&DeviceDscr & 0xC000的结果,要为“真”的话,显然,/必须&DeviceDscr=0X4000,也就是说判断的是描述表首址&DeviceDsc是否大于3FFF,/刚好是主RAM区的大小,这就是为什么要用&DeviceDscr 和 0xC000相与就来/判断实现了描述符表首地址的原因了(外部 or 内部 ram?)if (WORD)&DeviceDscr & 0xC000)/ first, relocate the descriptorsIntDescrAddr = INTERNAL_DSCR_ADDR;ExtDescrAddr = (WORD)&DeviceDscr;DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;for (i = 0; i DevDescrLen; i+)*(BYTE xdata *)IntDescrAddr+i) = *(BYTE xdata *)ExtDescrAddr+i);/判断发现描述符表首址位于外部RAM的后,紧接着就将外部RAM的描述符移到内部RAM。/这里就用到了前面定义的变量,IntDescrAddr保存内部RAM首址0X80,/ExtDescrAddr保存我们获得的当前描述符表外部RAM的首址 ,DevDescrLen/是整个描述表的长度,从DeviceDscr段到UserDscr段,在dscrptr中有定义。/然后for循环,将从ExtDescrAddr地址开始的外部RAM中的数据逐个copy到从/IntDescrAddr地址开始的内部RAM区。/ update all of the descriptor pointers/ 更新描述符指针/完毕后更新描述符指针,指向内部RAM区,通过原指针减去一个偏移量得到。pDeviceDscr = IntDescrAddr;offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;pDeviceQualDscr -= offset;pConfigDscr -= offset;pOtherConfigDscr -= offset;pHighSpeedConfigDscr -= offset;pFullSpeedConfigDscr -= offset;pStringDscr -= offset;EZUSB_IRQ_ENABLE(); / Enable USB interrupt (INT2)/ EZUSB中断使能/EZUSB_IRQ_ENABLE();预定义是EZUSB=1,ezusb是EIE寄存器的第0位,EIE.0=1,使能USB中断;EZUSB_ENABLE_RSMIRQ(); / Wake-up interrupt/使能远程唤醒中断/EZUSB_ENABLE_RSMIRQ();EICON |= 0x20,EICON.5=1,使能远程唤醒中断;INTSETUP |= (bmAV2EN | bmAV4EN); / Enable INT 2 & 4 autovectoring/使能INT2,4自动向量跳转/INTSETUP |= (bmAV2EN | bmAV4EN);使能INT2,4自动向量跳转; USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; / Enable selected interrupts/ 使能所选择中断/相关的中断意义,后面慢慢学习补充; EA = 1; / Enable 8051 interrupts/ 开8051中断#ifndef NO_RENUM/ Renumerate if necessary. Do this by checking the renum bit. If it/ is already set, there is no need to renumerate. The renum bit will/ already be set if this firmware was loaded from an eeprom.if (!(USBCS & bmRENUM) /如果RENUM位为0,则重列举EZUSB_Discon(TRUE); / renumerate 重列举#endif/这段代码即告诉USB进行重枚举,用软件设置,模拟USB断开与连接,/EZUSB_Discon(TRUE)完成断开连接/将USBCS寄存器的DICON位置1,断开USB,同时如果RENUM位为0,/则置1;然后重新连接USB。/那么,什么是重枚举呢?/首先,上面的USB枚举是对通用USB来说的,一般USB设备只有枚举过程,没有重枚举过程。也就是说其实,对EZ-USB系列来说,上面的枚举实际包含了EZ-USB枚举和重枚举两个过程:/对EZ-USB来说,枚举过程就是USB上电复位到加载固件前这段过程,此时USB设备地址号为默认的0号,枚举完成后,驱动为cypress.eeprom.missing(FX2/FX2LP来说)。然后加载固件,进行重枚举,重枚举完成后,显示驱动为cypress.ez-usb.example或其他自定义设备。/为什么EZ-USB有重枚举过程呢?这就是为了可以让主机在前期固件未加载前自动枚举,识别USB,从而可以从上位机加载固件到68013的RAM中,而无需使用ROM,EEPROM,FLASH等内存。实现“软件”架构加载程序代码,随时修改固件。/EZ-USB如何控制重枚举?/首先,EZUSB有一个寄存器USBCS,其中第1位USBCS.1为Renum控制枚举重枚举。在USB上电未加载固件代码前,Renum0,表示使用“EZUSB核心”对芯片的初始配置,处理主机设备请求,并负责把固件下载到RAM中,这个过程就是“枚举”,完成该枚举过程的设备叫做“缺省USB设备(地址号0)”,即驱动显示为“.missing”的设备。当固件被下载到8051 RAM后,此时Renum1,表示使用“增强8051核心”处理主机设备请求,并按照固件的代码(读取所有描述符)重新配置USB设备,这个过程就叫做“重枚举”,完成重枚举后,显示自定义的USB设备“.example”,实际是模拟断开与连接的过程。/用以下表表示:/事件-处理设备请求-Renum-8051动作/枚举-EZUSB核心-Renum0-8051置Renum1/重枚举-8051-Renum1-8051重置Renum0/在重枚举完成后,对控制端点0的设备请求可以由“EZUSB核心”处理或由/“增强8051核心”处理,有Renum的值决定。芯片上电时Renum0,/由“EZUSB核心”处理;一旦8051开始运行,就可以设置Renum1,/由“增强8051核心”处理,表示按照8051下载的固件代码处理。/当然,这时也可以设置Renum0,让“EZUSB核心”处理端点0的设备请求,/而让8051完成具体的USB数据传输,这样做会大大简化8051固件代码。/然后再看接下来的代码:/注意,在这段代码之前,EZUSB已经枚举完成,当然,整个过程是自动的,/我们看不见的。/ 详见/ unconditionally re-connect. If we loaded from eeprom we are/ disconnected and need to connect. If we just renumerated this/ is not necessary but doesnt hurt anythingUSBCS &=bmDISCON; /重新连接CKCON = (CKCON&(bmSTRETCH) | FW_STRETCH_VALUE; / Set stretch/ CKCON = (CKCON&(bmSTRETCH) | FW_STRETCH_VALUE;Set stretch to 0 (after renumeration)/EZ-USB执行指令MOVX(读取外部存储器)时,在两个MOVX之间可以增加的几个时钟周期数/这对于外部的较慢的存储器或外设(例如LCD)等是很合适的,外部存储器的等待时钟可以在固件中调整/但是程序存储器不会受到影响/ clear the Sleep flag.Sleep = FALSE; /清sleep休眠使能标志/紧接着主机开始读描述符,并进行配置(发送SetConfiguration),/加载驱动等,完成重枚举。CY7C68031A固件程序FW.C详解(2) 2011-04-01 14:13724人阅读评论(0)收藏举报/ Task Dispatcher/从下面的代码开始,才真正开始我们自己的USB事务处理:while(TRUE) / /Main Loop 主循环,一看就是个死循环/ Poll User DeviceTD_Poll(); /用户调度程序/TD_Poll,也就是用户调度程序,USB空闲时调用/ Check for pending SETUPif(GotSUD) /等待SETUP令牌数据的到来SetupCommand(); / Implement setup command/在SetupCommand()函数中处理控制传输的内容,不管是USB标准/设备请求还是其他非标准请求还是Vendor命令等,/在调用SetupCommand()前首先判断了一个变量GotSUD是否为“真”,/查询的GotSUD变量,是在bulkloop.c文件中被设置为“真”的:/ Setup Data Available Interrupt Handler/void ISR_Sudav(void) interrupt 0/ GotSUD = TRUE; / Set flag/ EZUSB_IRQ_CLEAR();/ USBIRQ = bmSUDAV; / Clear SUDAV IRQ/这是一个中断服务程序。这个中断是怎么触发的呢?首先弄明白以下几点:/ 【1】USB设备和主机之间传输一次数据,叫做一次USB事务处理./ 【2】一个完整的控制传输,包含设置阶段,数据阶段,状态阶段:/ 例如主机要把“0X01,0X02”传送到下位机,那么设置阶段是一次USB事务处理, 数据阶段是两次USB事务处理等等。/ 【3】一般地,每个USB事务处理包含三个阶段:令牌阶段、数据阶段、握手阶段。/ 【4】每个阶段传输的数据,USB根据类型不同,打成不同的包,叫“封包”。例如, / 令牌阶段传送令牌封包,数据阶段传送数据封包等。/ 【5】SETUP寄存中的内容即是在一次“USB事务处理”的“设置阶段”传送的, 具体包含在数据阶段的数据封包中。然后,具体调用SetupCommand()的过程为:/ (a)在USB枚举阶段,主机需要读取描述符的内容,于是发送标准请求,/ 例如case SC_GET_DESCRIPTOR读取描述符,将该请求打包,启动“USB”事务处理。/ (b)进入“USB事务处理”的设置阶段,其中,在数据阶段,USB core的端点0收到封包中的数据,并将其装载到SETUPDAT寄存器(8字节),如果顺利完成,即握手ACK后,则USB core会发出SUDAV中断请求,于是进入void ISR_Sudav(void) interrupt 0 这个中断服务程序进行处理,设置GotSUD标志为“真”。/ SUDAV,即是SetUp Arrived,SetUp数据到达。/ SUDAV,在USBIRQ中定义USBIRQ.0=SUDAV。当8字节的SetUp数据从端点0发送到SETUPDAT寄存器 后,USB core 将该位置1,清除中断请求。GotSUD = FALSE; / Clear SETUP flag 清SETUP标记/GotSUD是令牌包标志,准确的说是“令牌阶段数据到来”,什么是令牌包?/首先,USB一连串的数据传输、处理、响应等就叫做USB事务。/例如,上位机要读取一个描述符,那么就会触发一次USB事务。/一个完整的USB事务处理有三个阶段:令牌阶段,数据阶段,握手阶段。/每个阶段数据传输是有各种包组成的,例如令牌阶段:同步字段令牌包EOP构成。/USB主机启动事务处理,开始发送令牌包,这个时候假如说我们当前的USB设备地址号为2(重枚举时分配的),而主机发送的地址号也为2,那么这个USB设备硬件会产生中断,进入中断处理。也就是periph.c文件中的void ISR_Sudav(void)函数,在这个中断处理中,设置 GotSUD标志为TRUE,表示收到令牌数据,要启动USB传输了。/然后我们固件中判断if(GotSUD),GotSUD为真,则执行SetupCommand()函数,在这里处理控制传输,读取描述符,设置特性,处理Vendor命令等。/完毕后置GotSUD = FALSE;然后检查USB各种状态并处理?/ check for and handle suspend./ NOTE: Idle mode stops the processor clock. There are only two/ ways out of idle mode, the WAKEUP pin, and detection of the USB/ resume state on the USB bus. The timers will stop and the/ processor will not wake up on any other interrupts./如果USB进入了休眠状态,这里Sleep是USB休眠标志,同GotSUD一样,USB休眠后产生中断,/进入void ISR_Susp(void)函数处理,置sleep标志为TRUE。/只有两种方式可以唤醒 USB 设备,一是 WAKEUP 引脚,二是 USB 总线探测到 resume 状态if (Sleep) /检查sleep休眠使能标志if(TD_Suspend() /挂起处理 /TD_Suspend()说明:此函数是在设备进入挂起状态前调用的,开发者在其中加入适当的代码,/对设备的工作状态进行配置,可使设备处于低功耗状态并返回真值。/但是开发者可以改动TD_Suspend()的程序代码,使其返回为假,这样可以使FX2不进入挂起状态。Sleep = FALSE; / Clear the go to sleep flag. Do it here to prevent any race condition between wakeup and the next sleep./在此清除睡眠模式标志是为了避免在唤醒下一个睡眠模式之间有任何的执行状况发生doEZUSB_Susp(); / Place processor in idle mode.置8051为空闲状态while(!Rwuen & EZUSB_EXTWAKEUP(); /如果唤醒/ above. Must continue to go back into suspend if the host has disabled remote wakeup/ *and* the wakeup was caused by the external wakeup pin./ 8051 activity will resume here due to USB bus or Wakeup# pin activity.EZUSB_Resume(); /从空闲状态中恢复 / If source is the Wakeup# pin, signal the host to Resume./从空闲状态中恢复 TD_Resume();/TD_Resume()说明:当外部要求重新启动时(如,外界产生Wakeup中断或者USB总线有传输活动发生),/设备就会通过调用此函数来对处理器进行重启,也就是TD_Suspend()函数的逆操作。此时,/设备在正常电源下重新启动? BOOL HighSpeedCapable()/HighSpeedCapable() 检测是否为高速USB芯片/ this function determines if the chip is high-speed capable./ FX2 and FX2LP are high-speed capable. FX1 is not - it does/ not have a high-speed transceiver.if (GPCR2 & bmFULLSPEEDONLY)/GPCR2、bmFULLSPEEDONLY 在FX2regs.h 的定义如下:/ Feature Registers (FX2LP/FX1 only)/EXTERN xdata volatile BYTE GPCR2 _AT_ 0xE50D; / Chip Features/* Chip Feature Register (GPCR2) */#define bmFULLSPEEDONLY bmBIT4return FALSE;elsereturn TRUE; / Device request parservoid SetupCommand(void)/setupCommand(void) 设备请求剖析器void *dscr_ptr;switch(SETUPDAT1) /判断何种设备请求,8字节,参阅usb 协议/SETUPDAT1包含请求,bRequest/根据setupdat1进行分别处理/Setupdat寄存器(只读)中的定义如下/ SETUPDAT0 = bmRequestType,USB设备接口或端点的状态/ SETUPDAT1 = bmRequest,请求类型, 8字节,这里是USB 11个标准请求之一/ SETUPDAT2:3 = wValue, wValue字段,对bmRequest字段的补充 / SETUPDAT4:5 = wIndex/ SETUPDAT6:7 = wLength/传输我们自定义的命令时,bmRequestType不用处理;/bmRequest为我们自定义的命令,上位机和下位机统一即可;/wValue和wIndex我们可以自由使用,共4个字节;/wLength为接下来的“数据阶段”的数据长度。/详见 case SC_GET_DESCRIPTOR: /命令是取得描述符表if(DR_GetDescriptor() /如果取得描述符表成功switch(SETUPDAT3) / /判断是何种描述符case GD_DEVICE: /是设备描述符SUDPTRH = MSB(pDeviceDscr); /设备描述符的高位SUDPTRL = LSB(pDeviceDscr); /设备描述符的低位/SUDPTR是指向主机请求的描述符的首地址break;case GD_DEVICE_QUALIFIER: /是设备限定描述符 Device Qualifier/ only retuen a device qualifier if this is a high speed/ capable chip.if (HighSpeedCapable() /如果是高速设备SUDPTRH = MSB(pDeviceQualDscr); /设备限定描述符的高位SUDPTRL = LSB(pDeviceQualDscr); /设备限定描述符的低位elseEZUSB_STALL_EP0(); /停滞在端点0break;case GD_CONFIGURATION: /是配置描述符SUDPTRH = MSB(pConfigDscr); /配置描述符的高位SUDPTRL = LSB(pConfigDscr); /配置描述符的低位break;case GD_OTHER_SPEED_CONFIGURATION: /是其他速率配置描述符SUDPTRH = MSB(pOtherConfigDscr); /其他速率配置描述符的高位SUDPTRL = LSB(pOtherConfigDscr); /其他速率配置描述符的低位break;case GD_STRING: /是字符串描述符Stringif(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT2) /如果取得字符串成功SUDPTRH = MSB(dscr_ptr); /字符串描述符的高位SUDPTRL = LSB(dscr_ptr); /字符串描述符的低位else /如果是其它未知类型的描述符EZUSB_STALL_EP0(); /中止在端点0 Stall End Point 0break;default: /如果是其它未知类型的描述符 (无效描述符)ivalid requestEZUSB_STALL_EP0(); /中止端点0 Stall End Point 0break;case SC_GET_INTERFACE: /命令是获得接口* Get InterfaceDR_GetInterface(); /获取接口子函数break;case SC_SET_INTERFACE: / 命令是设置接口* Set InterfaceDR_SetInterface(); /设置接口子函数break;case SC_SET_CONFIGURATION: /命令是设置配置* Set ConfigurationDR_SetConfiguration(); /设置配置子函数break;case SC_GET_CONFIGURATION: /命令是获得配置 * Get ConfigurationDR_GetConfiguration(); /获取配置的子函数 break;case SC_GET_STATUS: / 命令是获得状态 * Get Statusif(DR_GetStatus() /如果获得状态成功switch(SETUPDAT0) /判断是何状态(设备、接口或端点状态)case GS_DEVICE: / 是设备状态EP0BUF0 = (BYTE)Rwuen 1) | (BYTE)Selfpwr;EP0BUF1 = 0;EP0BCH = 0;EP0BCL = 2; /长度为2break;case GS_INTERFACE: / 接口状态EP0BUF0 = 0;EP0BUF1 = 0; EP0BCH = 0;EP0BCL = 2;break;case GS_ENDPOINT: /端点状态 EP0BUF0 = *(B

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论