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

书接上回

  下面这段代码不解释,但我把注释翻译一下:
  下面部分用来对描述符表重新定位,固件框架使用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 |= (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

  其中,函数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出现在SUDAV的中断服务程序里:

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

这里写图片描述

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值