EZ-USB固件框架的追踪研读之main函数1

来源:互联网 发布:c语言定义一个函数 编辑:程序博客网 时间:2024/06/05 09:52
在文档《DvkUsersGuide.pdf》里有main函数的描述:

这里写图片描述

这里写图片描述
这里写图片描述

源码如下:
// 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 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();       }       } }}

以下代码用于初始化全局状态变量:
 // 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
//-----------------------------------------------------------------------------// Global Variables//-----------------------------------------------------------------------------volatile BOOL   GotSUD;BOOL      Rwuen;BOOL      Selfpwr;volatile BOOL   Sleep;                  // Sleep mode enable flag

还是不懂,变量是怎样跟相关功能连接起来的!!!


函数TD_Init()用于初始化用户设备:
void TD_Init(void)             // Called once at startup{  BREAKPT &= ~bmBPEN;        Rwuen = TRUE;            // 使能远程唤醒  CPUCS=((CPUCS & ~bmCLKSPD) | bmCLKSPD1);     //USB时钟频率  IFCONFIG |=0x40;  EP1OUTCFG = 0xA0;  EP1INCFG = 0xA0;  SYNCDELAY;  EP2CFG = 0xA2;  SYNCDELAY;                      EP4CFG = 0xA0;  SYNCDELAY;                      EP6CFG = 0xE2;  SYNCDELAY;                      EP8CFG = 0xE0;  // 由于缺省的端点是双重因此需要写两次  SYNCDELAY;                      EP2BCL = 0x80;                //写EP2OUT比特两次  SYNCDELAY;                      EP2BCL = 0x80;  SYNCDELAY;                      EP4BCL = 0x80;                //写EP4OUT比特两次  SYNCDELAY;                      EP4BCL = 0x80;      //使能双自动指针  AUTOPTRSETUP |= 0x01;}

文档里这样说道:
这里写图片描述

只说是,用于全局的状态变量和设备的初始化,需在ReNumeration 和 the Task Dispatcher开始之前调用。并未说明这样初始化的依据。在另一份文档里,发现这样初始化是为了使用端点2、4、6、8进行批量的数据发送和接收:

这里写图片描述

那么,我就只能采用笨方法逐句地看TD_Init()这个函数了。

1、禁用 Breakpoint
BREAKPT &= ~bmBPEN; 
首先找到了变量BREAKPT的声明:
EXTERN xdata volatile BYTE BREAKPT           _AT_ 0xE605;  // Breakpoint
其在文档里的表述:

这里写图片描述

#define bmBPEN       bmBIT1

2、
Rwuen = TRUE;            // 使能远程唤醒

3、选择CPU的时钟速度:48MHZ
CPUCS=((CPUCS & ~bmCLKSPD) | bmCLKSPD1);       //USB时钟频率
文档中关于CPUCS的描述;

这里写图片描述
这里写图片描述

#define bmCLKSPD     (bmBIT4 | bmBIT3)#define bmCLKSPD1    bmBIT4

5、选择内部FIFO and GPIF时钟频率为48MHZ
IFCONFIG |=0x40;

这里写图片描述


6、使能EP1OUT和EP1IN,端点类型为批量传输
EP1OUTCFG = 0xA0;EP1INCFG = 0xA0;

这里写图片描述

这里写图片描述


7、同步延时
SYNCDELAY;

这里写图片描述


8、
  EP2CFG = 0xA2;  SYNCDELAY;                      EP4CFG = 0xA0;  SYNCDELAY;                      EP6CFG = 0xE2;  SYNCDELAY;                      EP8CFG = 0xE0;

这里写图片描述
这里写图片描述

这里写图片描述


9、设置EP2和EP4的“ maximum buffer sizes”
  // 由于缺省的端点是双重因此需要写两次  SYNCDELAY;                      EP2BCL = 0x80;                //写EP2OUT比特两次  SYNCDELAY;                      EP2BCL = 0x80;  SYNCDELAY;                      EP4BCL = 0x80;                //写EP4OUT比特两次  SYNCDELAY;                      EP4BCL = 0x80;    

这里写图片描述

我也没搞懂,这个是啥意思!!!


10、使能双自动指针
  //使能双自动指针  AUTOPTRSETUP |= 0x01;

这里写图片描述

1 0
原创粉丝点击