您的位置:首页 > 大数据 > 人工智能

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

2015-08-05 11:42 274 查看
书接上回


  下面这段代码不解释,但我把注释翻译一下:

  下面部分用来对描述符表重新定位,固件框架使用SUDPTRH and SUDPTRL自动响应描述符的SETUP请求。这两个寄存器只能处理EZ-USB内部RAM的地址,所以,如果描述符存在于片外RAM,则他们必须被复制到片内RAM(16K)。

// 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;
   }


  第一个&是取值符号,取设备描述符的地址;第二个&是按位与运算符。

我没有看懂是怎么判断the descriptor table in external RAM (> 16Kbytes)

Enable USB interrupt (INT2)

EZUSB_IRQ_ENABLE();            // Enable USB interrupt (INT2)


#define EZUSB_IRQ_ENABLE()   EUSB = 1


sfr EIE    = 0xE8; // EIE Bit Values differ from Reg320
                        /*  EIE  */
         sbit EUSB    = 0xE8+0;
         sbit EI2C    = 0xE8+1;
         sbit EIEX4   = 0xE8+2;
         sbit EIEX5   = 0xE8+3;
         sbit EIEX6   = 0xE8+4;


Enable Wake-up interrupt

EZUSB_ENABLE_RSMIRQ();            // Wake-up interrupt


#define EZUSB_ENABLE_RSMIRQ()      (EICON |= 0x20)      // Enable Resume Interrupt (EPFI_)


INTSETUP |= (bm***2EN | bm***4EN);     // Enable INT 2 & 4 autovectoring

USBIE |= bmSUD*** | 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


  其中,函数EZUSB_Discon(TRUE)源自库函数,源代码为,(这里先不做解释):

void EZUSB_Discon(BOOL renum)
{

   if(renum)                                 // If renumerate (i.e. 8051 will handle SETUP commands)
      USBCS |= (bmDISCON | bmRENUM);        // disconnect from USB and set the renumerate bit
   else
      USBCS |= bmDISCON;                     // just disconnect from USB

   EZUSB_Delay(1500);      // Wait 1500 ms

   USBIRQ = 0xff;          // Clear any pending USB interrupt requests.  They're for our old life.
   EPIRQ = 0xff;
   EZUSB_IRQ_CLEAR();

   USBCS &=~bmDISCON;      // reconnect USB
}


  唉,下面的也不是很懂!!

// 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;


  硬着头皮往下看主循环;

// Poll User Device
TD_Poll();

// Check for pending SETUP
if(GotSUD)
{
   SetupCommand();          // Implement setup command
   GotSUD = FALSE;          // Clear SETUP flag
}


  函数TD_Poll()在前面已经说过了。

  GotSUD出现在SUD***的中断服务程序里:

// Setup Data Available Interrupt Handler
void ISR_Sudav(void) interrupt 0
{
   GotSUD = TRUE;            // Set flag
   EZUSB_IRQ_CLEAR();
   USBIRQ = bmSUD***;         // Clear SUD*** IRQ
}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: