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

在文档《DvkUsersGuide.pdf》里有main函数的描述:

这里写图片描述

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

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

 }
}

以下代码用于初始化全局状态变量:
 // 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;

这里写图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值