"); //-->
由于要用fpga给电脑传输视频信息,所以决定用cypress公司的cy7c68013A来作为usb、设备的主控芯片,看了好2周的usb的书,基本上算是把大概的协议搞清楚了,今天开始着手开发固件,这些示例都是以官方示例的基础上更改过来的。
dscr.a51。usb的描述符文件。包括设备描述 ,接口描述符,端点描述符,字符串描述符等。用于描述设备的总体信息。包括pid,vid,设备类和设备子类等。一个usb设备只能有一个设备描述符。配置描述符一般描述usb设备的配置信息。可以有一个或者多个配置,每个配置必须有一个配置描述符。字符串描述符用来保存一些供应商的名称,设备序列号,供应商名称等的文本信息。接口描述符用来表述usb接口中各个接口的特性。,包括接口号,端点个数,所属的设备和子类等等。
端点描述符表述usb设备端点的特性,包括所支持的传输类型、传输方向、最大的数据包长度、和访问间隔等信息。
;;----------------------------------------------------------------------------- ;; File: dscr.a51 ;; Contents: This file contains descriptor data tables. 此文件包含描述符表 ;; ;; $Archive: /USB/Examples/Fx2lp/bulkloop/dscr.a51 $ ;; $Date: 9/01/03 8:51p $ ;; $Revision: 3 $ ;; ;; ;;----------------------------------------------------------------------------- ;; Copyright 2003, Cypress Semiconductor Corporation ;;-----------------------------------------------------------------------------;;----------------------------------------------------------------------------- DSCR_DEVICE equ 1 ;; Descriptor type: Device 描述类型:设备 DSCR_CONFIG equ 2 ;; Descriptor type: Configuration 描述类型:配置 DSCR_STRING equ 3 ;; Descriptor type: String 描述类型:字符串 DSCR_INTRFC equ 4 ;; Descriptor type: Interface 描述类型:接口 DSCR_ENDPNT equ 5 ;; Descriptor type: Endpoint 描述类型:端点 DSCR_DEVQUAL equ 6 ;; Descriptor type: Device Qualifier 描述类型:设备速度类型,告诉或全速设备所独有 DSCR_DEVICE_LEN equ 18 DSCR_CONFIG_LEN equ 9 DSCR_INTRFC_LEN equ 9 DSCR_ENDPNT_LEN equ 7 DSCR_DEVQUAL_LEN equ 10 ET_CONTROL equ 0 ;; Endpoint type: Control 端点类型,控制传输 ET_ISO equ 1 ;; Endpoint type: Isochronous 端点类型,等时传输 ET_BULK equ 2 ;; Endpoint type: Bulk 端点类型,块传输 ET_INT equ 3 ;; Endpoint type: Interrupt 端点类型,中断 public DeviceDscr, DeviceQualDscr, HighSpeedConfigDscr, FullSpeedConfigDscr, StringDscr, UserDscr DSCR SEGMENT CODE PAGE ;;----------------------------------------------------------------------------- ;; Global Variables ;;----------------------------------------------------------------------------- rseg DSCR ;; locate the descriptor table in on-part memory. DeviceDscr: db DSCR_DEVICE_LEN ;; Descriptor length 设备描述符的长度,18字节。 db DSCR_DEVICE ;; Decriptor type 描述类型 dw 0002H ;; Specification Version (BCD) 符合usb2.0规范 db 00H ;; Device class 设备类代码 db 00H ;; Device sub-class 设备子类代码 db 00H ;; Device sub-sub-class 设备协议代码 db 64 ;; Maximum packet size 端点0的最大包大小 dw 3412H ;; Vendor ID 厂商id vid dw 7856H ;; Product ID (Sample Device) 产品id pid dw 0000H ;; Product version ID 设备版本 db 1 ;; Manufacturer string index 厂商的字符串描述索引 db 2 ;; Product string index 产品的描述符索引 db 0 ;; Serial number string index 设备序列号的字符串描述符索引 db 1 ;; Number of configurations 可能的配置数目 DeviceQualDscr: db DSCR_DEVQUAL_LEN ;; Descriptor length 高速设备独有的描述符,支持全速和高速的设备,必须有一个这个描述符 db DSCR_DEVQUAL ;; Decriptor type dw 0002H ;; Specification Version (BCD) db 00H ;; Device class db 00H ;; Device sub-class db 00H ;; Device sub-sub-class db 64 ;; Maximum packet size db 1 ;; Number of configurations db 0 ;; Reserved HighSpeedConfigDscr: db DSCR_CONFIG_LEN ;; Descriptor length 配置描述符,高速设备描述符 db DSCR_CONFIG ;; Descriptor type 描述类型 =0x02 db (HighSpeedConfigDscrEnd-HighSpeedConfigDscr) mod 256 ;; Total Length (LSB) 描述符总长度,低字节 db (HighSpeedConfigDscrEnd-HighSpeedConfigDscr) / 256 ;; Total Length (MSB) 高字节 db 1 ;; Number of interfaces 接口数目 db 1 ;; Configuration number 配置值 db 0 ;; Configuration string 配置的字符串描述符索引 db 10000000b ;; Attributes (b7 - buspwr, b6 - selfpwr, b5 - rwu) 配置的属性 db 50 ;; Power requirement (div 2 ma) 最大电流 ;; Interface Descriptor 接口描述符 db DSCR_INTRFC_LEN ;; Descriptor length db DSCR_INTRFC ;; Descriptor type 04h db 0 ;; Zero-based index of this interface 接口号 db 0 ;; Alternate setting 替换设置号数 db 2 ;; Number of end points 除了端点0外,支持的端点数目是2 db 0ffH ;; Interface class 接口类代码,制定为厂商定义类 db 00H ;; Interface sub class 接口有子类代码 db 00H ;; Interface sub sub class 接口协议代码 db 0 ;; Interface descriptor string index 此接口的字符串描述符索引 ;; Endpoint Descriptor 端点描述符 db DSCR_ENDPNT_LEN ;; Descriptor length db DSCR_ENDPNT ;; Descriptor type db 82H ;; Endpoint number, and direction 端点号,和方向 db ET_BULK ;; Endpoint type 端点传输类型 db 00H ;; Maximun packet size (LSB) 数据包大小低位 db 04H ;; Max packect size (MSB) db 00H ;; Polling interval 轮巡间隔 ;; Endpoint Descriptor db DSCR_ENDPNT_LEN ;; Descriptor length db DSCR_ENDPNT ;; Descriptor type db 08H ;; Endpoint number, and direction db ET_BULK ;; Endpoint type db 00H ;; Maximun packet size (LSB) db 02H ;; Max packect size (MSB) db 00H ;; Polling interval HighSpeedConfigDscrEnd: FullSpeedConfigDscr: db DSCR_CONFIG_LEN ;; Descriptor length db DSCR_CONFIG ;; Descriptor type db (FullSpeedConfigDscrEnd-FullSpeedConfigDscr) mod 256 ;; Total Length (LSB) db (FullSpeedConfigDscrEnd-FullSpeedConfigDscr) / 256 ;; Total Length (MSB) db 1 ;; Number of interfaces db 1 ;; Configuration number db 0 ;; Configuration string db 10000000b ;; Attributes (b7 - buspwr, b6 - selfpwr, b5 - rwu) db 50 ;; Power requirement (div 2 ma) ;; Interface Descriptor db DSCR_INTRFC_LEN ;; Descriptor length db DSCR_INTRFC ;; Descriptor type db 0 ;; Zero-based index of this interface db 0 ;; Alternate setting db 4 ;; Number of end points db 0ffH ;; Interface class db 00H ;; Interface sub class db 00H ;; Interface sub sub class db 0 ;; Interface descriptor string index ;; Endpoint Descriptor db DSCR_ENDPNT_LEN ;; Descriptor length db DSCR_ENDPNT ;; Descriptor type db 02H ;; Endpoint number, and direction db ET_BULK ;; Endpoint type db 40H ;; Maximun packet size (LSB) db 00H ;; Max packect size (MSB) db 00H ;; Polling interval ;; Endpoint Descriptor db DSCR_ENDPNT_LEN ;; Descriptor length db DSCR_ENDPNT ;; Descriptor type db 04H ;; Endpoint number, and direction db ET_BULK ;; Endpoint type db 40H ;; Maximun packet size (LSB) db 00H ;; Max packect size (MSB) db 00H ;; Polling interval ;; Endpoint Descriptor db DSCR_ENDPNT_LEN ;; Descriptor length db DSCR_ENDPNT ;; Descriptor type db 86H ;; Endpoint number, and direction db ET_BULK ;; Endpoint type db 40H ;; Maximun packet size (LSB) db 00H ;; Max packect size (MSB) db 00H ;; Polling interval ;; Endpoint Descriptor db DSCR_ENDPNT_LEN ;; Descriptor length db DSCR_ENDPNT ;; Descriptor type db 88H ;; Endpoint number, and direction db ET_BULK ;; Endpoint type db 40H ;; Maximun packet size (LSB) db 00H ;; Max packect size (MSB) db 00H ;; Polling interval FullSpeedConfigDscrEnd: StringDscr: //字符串描述符 StringDscr0: //字符串0 db StringDscr0End-StringDscr0 ;; String descriptor length 描述长度 db DSCR_STRING // 描述类型 db 09H,04H //设备所支持的语言代码,表示是英语 StringDscr0End: StringDscr1: db StringDscr1End-StringDscr1 ;; String descriptor length 制造商的字符串描述符 db DSCR_STRING db 'C',00 db 'y',00 db 'p',00 db 'r',00 db 'e',00 db 's',00 db 's',00 StringDscr1End: StringDscr2: db StringDscr2End-StringDscr2 ;; Descriptor length 产品的字符串描述符 db DSCR_STRING db 'E',00 db 'Z',00 db '-',00 db 'U',00 db 'S',00 db 'B',00 StringDscr2End: UserDscr: //空描述符,表述描述符表的结束 dw 0000H end
fw.c文件,代表主程序文件,usb协议等都在这里实现,包括断电上电枚举,重枚举,唤醒以及调用用户自己的程序和控制命令等等都在这里完成。它首先进行一系列通用初始化设置,并调用void TD_Init(void)函数来实现用户的特殊初始化设置。之后,程序会一直监视是否有指令收到,并在空闲的时候反复调用TD_Poll()函数来实现我们用户的功能
//----------------------------------------------------------------------------- // 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" #include "fx2regs.h" #include "syncdly.h" // SYNCDELAY macro //----------------------------------------------------------------------------- // Constants 目录 //----------------------------------------------------------------------------- #define DELAY_COUNT 0x9248*8L // Delay for 8 sec at 24Mhz, 4 sec at 48 在24Mhz的时钟下延迟8秒,48Mhz的时钟下延迟4秒。 #define _IFREQ 48000 // IFCLK constant for Synchronization Delay #define _CFREQ 48000 // CLKOUT constant for Synchronization Delay #define SC_SetData 0xAB //自定义指令 //----------------------------------------------------------------------------- // Random Macros //----------------------------------------------------------------------------- #define min(a,b) (((a)<(b))?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b)) //----------------------------------------------------------------------------- // Global Variables //----------------------------------------------------------------------------- volatile BOOL GotSUD; //防止编译器优化 BOOL Rwuen; BOOL Selfpwr; volatile BOOL Sleep; // Sleep mode enable flag 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 TD_Init(void); void TD_Poll(void); void DR_SetData(void); //自定义函数 BOOL TD_Suspend(void); BOOL TD_Resume(void); BOOL DR_GetDescriptor(void); BOOL DR_SetConfiguration(void); BOOL DR_GetConfiguration(void); BOOL DR_SetInterface(void); BOOL DR_GetInterface(void); BOOL DR_GetStatus(void); BOOL DR_ClearFeature(void); BOOL DR_SetFeature(void); BOOL DR_VendorCmnd(void); // this table is used by the epcs macro const char code EPCS_Offset_Lookup_Table[] = { 0, // EP1OUT 1, // EP1IN 2, // EP2OUT 2, // EP2IN 3, // EP4OUT 3, // EP4IN 4, // EP6OUT 4, // EP6IN 5, // EP8OUT 5, // EP8IN }; // macro for generating the address of an endpoint's control and status register (EPnCS) #define epcs(EP) (EPCS_Offset_Lookup_Table[(EP & 0x7E) | (EP > 128)] + 0xE6A1) //----------------------------------------------------------------------------- // Code //----------------------------------------------------------------------------- // Task dispatcher void main(void) { DWORD i; WORD offset; DWORD DevDescrLen; DWORD j=0; WORD IntDescrAddr; WORD ExtDescrAddr; // Initialize Global States Sleep = FALSE; // Disable sleep mode Rwuen = FALSE; // Disable remote wakeup Selfpwr = FALSE; // Disable self powered GotSUD = FALSE; // Clear "Got setup data" flag // Initialize user device TD_Init(); // 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. pDeviceDscr = (WORD)&DeviceDscr; pDeviceQualDscr = (WORD)&DeviceQualDscr; pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr; pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr; 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. if ((WORD)&DeviceDscr & 0xC000) { // first, relocate the descriptors IntDescrAddr = 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); // update all of the descriptor pointers 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_ENABLE_RSMIRQ(); // Wake-up interrupt INTSETUP |= (bmAV2EN | bmAV4EN); // Enable INT 2 & 4 autovectoring USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; // Enable selected interrupts EA = 1; // Enable 8051 interrupts #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)) { EZUSB_Discon(TRUE); // renumerate } #endif // unconditionally re-connect. If we loaded from eeprom we are // disconnected and need to connect. If we just renumerated this // is not necessary but doesn't hurt anything USBCS &=~bmDISCON; CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch // clear the Sleep flag. Sleep = FALSE; // Task Dispatcher while(TRUE) // Main Loop { // Poll User Device TD_Poll(); // Check for pending SETUP if(GotSUD) { SetupCommand(); // Implement setup command GotSUD = FALSE; // Clear SETUP flag } // 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. if (Sleep) { if(TD_Suspend()) { Sleep = FALSE; // Clear the "go to sleep" flag. Do it here to prevent any race condition between wakeup and the next sleep. do { EZUSB_Susp(); // Place processor in idle mode. } 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(); } } } } BOOL HighSpeedCapable() { // 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) return FALSE; else return TRUE; } // Device request parser void SetupCommand(void) { void *dscr_ptr; switch(SETUPDAT[1]) { case SC_GET_DESCRIPTOR: // *** Get Descriptor if(DR_GetDescriptor()) switch(SETUPDAT[3]) { case GD_DEVICE: // Device SUDPTRH = MSB(pDeviceDscr); SUDPTRL = LSB(pDeviceDscr); 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); } else { EZUSB_STALL_EP0(); } break; case GD_CONFIGURATION: // Configuration SUDPTRH = MSB(pConfigDscr); SUDPTRL = LSB(pConfigDscr); break; case GD_OTHER_SPEED_CONFIGURATION: // Other Speed Configuration SUDPTRH = MSB(pOtherConfigDscr); SUDPTRL = LSB(pOtherConfigDscr); break; case GD_STRING: // String if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2])) { SUDPTRH = MSB(dscr_ptr); SUDPTRL = LSB(dscr_ptr); } else EZUSB_STALL_EP0(); // Stall End Point 0 break; default: // Invalid request EZUSB_STALL_EP0(); // Stall End Point 0 } break; case SC_GET_INTERFACE: // *** Get Interface DR_GetInterface(); break; case SC_SET_INTERFACE: // *** Set Interface DR_SetInterface(); break; case SC_SET_CONFIGURATION: // *** Set Configuration DR_SetConfiguration(); break; case SC_GET_CONFIGURATION: // *** Get Configuration DR_GetConfiguration(); break; case SC_GET_STATUS: // *** Get Status if(DR_GetStatus()) switch(SETUPDAT[0]) { case GS_DEVICE: // Device EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case GS_INTERFACE: // Interface EP0BUF[0] = 0; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case GS_ENDPOINT: // End Point EP0BUF[0] = *(BYTE xdata *) epcs(SETUPDAT[4]) & bmEPSTALL; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; default: // Invalid Command EZUSB_STALL_EP0(); // Stall End Point 0 } break; case SC_CLEAR_FEATURE: // *** Clear Feature if(DR_ClearFeature()) switch(SETUPDAT[0]) { case FT_DEVICE: // Device if(SETUPDAT[2] == 1) Rwuen = FALSE; // Disable Remote Wakeup else EZUSB_STALL_EP0(); // Stall End Point 0 break; case FT_ENDPOINT: // End Point if(SETUPDAT[2] == 0) { *(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL; EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] ); } else EZUSB_STALL_EP0(); // Stall End Point 0 break; } break; case SC_SET_FEATURE: // *** Set Feature if(DR_SetFeature()) switch(SETUPDAT[0]) { case FT_DEVICE: // Device if(SETUPDAT[2] == 1) Rwuen = TRUE; // Enable Remote Wakeup else if(SETUPDAT[2] == 2) // Set Feature Test Mode. The core handles this request. However, it is // necessary for the firmware to complete the handshake phase of the // control transfer before the chip will enter test mode. It is also // necessary for FX2 to be physically disconnected (D+ and D-) // from the host before it will enter test mode. break; else EZUSB_STALL_EP0(); // Stall End Point 0 break; case FT_ENDPOINT: // End Point *(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL; break; default: EZUSB_STALL_EP0(); // Stall End Point 0 } break; case SC_SetData: DR_SetData(); break; default: // *** Invalid Command if(DR_VendorCmnd()) EZUSB_STALL_EP0(); // Stall End Point 0 } // Acknowledge handshake phase of device request EP0CS |= bmHSNAK; } // Wake-up interrupt handler void resume_isr(void) interrupt WKUP_VECT { EZUSB_CLEAR_RSMIRQ(); }
bulkloop.c批量循环文件
//----------------------------------------------------------------------------- // File: bulkloop.c // Contents: Hooks required to implement USB peripheral function. 通过钩子请求配置usb外围设备的功能 // // $Archive: /USB/Examples/FX2LP/bulkloop/bulkloop.c $ // $Date: 3/23/05 2:55p $ // $Revision: 4 $ // // //----------------------------------------------------------------------------- // Copyright 2003, Cypress Semiconductor Corporation //----------------------------------------------------------------------------- #pragma NOIV // Do not generate interrupt vectors 不产生中断向量 #include "fx2.h" #include "fx2regs.h" #include "syncdly.h" // SYNCDELAY macro 同步宏 extern BOOL GotSUD; // Received setup data flag 接受设置数据标志 extern BOOL Sleep; // extern BOOL Rwuen; extern BOOL Selfpwr; BYTE Configuration; // Current configuration 当前配置 BYTE AlternateSetting; // Alternate settings 可替代的设置 #define VR_NAKALL_ON 0xD0 #define VR_NAKALL_OFF 0xD1 void user_init(void) { OEA|=0x03; } //----------------------------------------------------------------------------- // Task Dispatcher hooks 任务收发钩子 // The following hooks are called by the task dispatcher. //----------------------------------------------------------------------------- void TD_Init(void) // Called once at startup 一旦开始就开始唤醒 { CPUCS = 0x10; IFCONFIG = 0xCB; FIFORESET = 0x80; // reset all FIFOs 重置fifo SYNCDELAY; FIFORESET = 0x02; SYNCDELAY; FIFORESET = 0x04; SYNCDELAY; FIFORESET = 0x06; SYNCDELAY; FIFORESET = 0x08; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; PINFLAGSAB = 0xCB; SYNCDELAY; PINFLAGSCD = 0x00; SYNCDELAY; PORTACFG = 0x00; SYNCDELAY; FIFOPINPOLAR = 0x00; SYNCDELAY; EP2AUTOINLENH = 0x04; SYNCDELAY; EP2AUTOINLENL = 0x00; SYNCDELAY; EP1OUTCFG = 0xA0; EP1INCFG = 0xA0; SYNCDELAY; EP2FIFOCFG = 0x4D; EP2CFG = 0xEB; SYNCDELAY; EP4CFG = 0x00; SYNCDELAY; EP6CFG = 0x00; SYNCDELAY; EP8FIFOCFG = 0x31; EP8CFG = 0xA0; AUTOPTRSETUP |= 0x01; } void TD_Poll(void) { } BOOL TD_Suspend(void) // Called before the device goes into suspend mode 在设备挂起之前被唤醒 { return(TRUE); } BOOL TD_Resume(void) // Called after the device resumes 设备恢复之后被唤醒 { return(TRUE); } //----------------------------------------------------------------------------- // Device Request hooks 设备请求钩子 // The following hooks are called by the end point 0 device request parser. 在最后一个端点0设备请求分析 钩子被访问 //----------------------------------------------------------------------------- BOOL DR_GetDescriptor(void) { return(TRUE); } BOOL DR_SetConfiguration(void) // Called when a Set Configuration command is received 当设置包被接受到时call { Configuration = SETUPDAT[2]; return(TRUE); // Handled by user code 通过用户代码操作 } BOOL DR_GetConfiguration(void) // Called when a Get Configuration command is received 当请求包被接受到时被访问 { EP0BUF[0] = Configuration; EP0BCH = 0; EP0BCL = 1; return(TRUE); // Handled by user code } BOOL DR_SetInterface(void) // Called when a Set Interface command is received 当接口设置名令被接收到时被访问 { AlternateSetting = SETUPDAT[2]; return(TRUE); // Handled by user code } BOOL DR_GetInterface(void) // Called when a Set Interface command is received 当设置接口命令被接收到时被访问 { EP0BUF[0] = AlternateSetting; EP0BCH = 0; EP0BCL = 1; return(TRUE); // Handled by user code } BOOL DR_GetStatus(void) { return(TRUE); } BOOL DR_ClearFeature(void) { return(TRUE); } BOOL DR_SetFeature(void) { return(TRUE); } BOOL DR_VendorCmnd(void) { BYTE tmp; switch (SETUPDAT[1]) { case VR_NAKALL_ON: tmp = FIFORESET; tmp |= bmNAKALL; SYNCDELAY; FIFORESET = tmp; break; case VR_NAKALL_OFF: tmp = FIFORESET; tmp &= ~bmNAKALL; SYNCDELAY; FIFORESET = tmp; break; default: return(TRUE); } return(FALSE); } //----------------------------------------------------------------------------- // USB Interrupt Handlers 中断处理程序 // The following functions are called by the USB interrupt jump table. 下面的程序功能在产生usb中断跳转表 时被访问 //----------------------------------------------------------------------------- // Setup Data Available Interrupt Handler 设置可用的数据中断处理程序 void ISR_Sudav(void) interrupt 0 { GotSUD = TRUE; // Set flag 设置标志 EZUSB_IRQ_CLEAR(); USBIRQ = bmSUDAV; // Clear SUDAV IRQ 清除设备就绪中断请求 } // Setup Token Interrupt Handler 设置请求的中断处理程序 void ISR_Sutok(void) interrupt 0 { EZUSB_IRQ_CLEAR(); USBIRQ = bmSUTOK; // Clear SUTOK IRQ 清除设备就绪中断请求 } void ISR_Sof(void) interrupt 0 { EZUSB_IRQ_CLEAR(); USBIRQ = bmSOF; // Clear SOF IRQ 清楚sof中断请求 } void ISR_Ures(void) interrupt 0 { // whenever we get a USB reset, we should revert to full speed mode 无论什么时候的usb复位,我们都应该回复全速模式 pConfigDscr = pFullSpeedConfigDscr; ((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR; pOtherConfigDscr = pHighSpeedConfigDscr; ((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR; EZUSB_IRQ_CLEAR(); USBIRQ = bmURES; // Clear URES IRQ 清除uses中断请求 } void ISR_Susp(void) interrupt 0 { Sleep = TRUE; EZUSB_IRQ_CLEAR(); USBIRQ = bmSUSP; } void ISR_Highspeed(void) interrupt 0 { if (EZUSB_HIGHSPEED()) { pConfigDscr = pHighSpeedConfigDscr; ((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR; pOtherConfigDscr = pFullSpeedConfigDscr; ((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR; } EZUSB_IRQ_CLEAR(); USBIRQ = bmHSGRANT; } void ISR_Ep0ack(void) interrupt 0 { } void ISR_Stub(void) interrupt 0 { } void ISR_Ep0in(void) interrupt 0 { } void ISR_Ep0out(void) interrupt 0 { } void ISR_Ep1in(void) interrupt 0 { } void ISR_Ep1out(void) interrupt 0 { } void ISR_Ep2inout(void) interrupt 0 { } void ISR_Ep4inout(void) interrupt 0 { } void ISR_Ep6inout(void) interrupt 0 { } void ISR_Ep8inout(void) interrupt 0 { } void ISR_Ibn(void) interrupt 0 { } void ISR_Ep0pingnak(void) interrupt 0 { } void ISR_Ep1pingnak(void) interrupt 0 { } void ISR_Ep2pingnak(void) interrupt 0 { } void ISR_Ep4pingnak(void) interrupt 0 { } void ISR_Ep6pingnak(void) interrupt 0 { } void ISR_Ep8pingnak(void) interrupt 0 { } void ISR_Errorlimit(void) interrupt 0 { } void ISR_Ep2piderror(void) interrupt 0 { } void ISR_Ep4piderror(void) interrupt 0 { } void ISR_Ep6piderror(void) interrupt 0 { } void ISR_Ep8piderror(void) interrupt 0 { } void ISR_Ep2pflag(void) interrupt 0 { } void ISR_Ep4pflag(void) interrupt 0 { } void ISR_Ep6pflag(void) interrupt 0 { } void ISR_Ep8pflag(void) interrupt 0 { } void ISR_Ep2eflag(void) interrupt 0 { } void ISR_Ep4eflag(void) interrupt 0 { } void ISR_Ep6eflag(void) interrupt 0 { } void ISR_Ep8eflag(void) interrupt 0 { } void ISR_Ep2fflag(void) interrupt 0 { } void ISR_Ep4fflag(void) interrupt 0 { } void ISR_Ep6fflag(void) interrupt 0 { } void ISR_Ep8fflag(void) interrupt 0 { } void ISR_GpifComplete(void) interrupt 0 { } void ISR_GpifWaveform(void) interrupt 0 { } void DR_SetData(void) { EP0BUF[0]=0xAB; EP0BCH=0; EP0BCL=2; EZUSB_Delay(100); //系统自带的函数 IOD=EP0BUF[1]; EP6FIFOBUF[0]=0x07; EP6FIFOBUF[1]=0x06; EP0CS |= bmHSNAK; }
EZUSB.LIB 库文件
ipregs.h寄存器定义的头文件
syncdly.h同步延时宏定义
usbjmptb.OBJ包括中断向量地址的OBJ代码
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。