📄 fw_net.c
字号:
// is not necessary but doesn't hurt anything
USBCS &=~bmDISCON;
CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration)
// 重枚举后设置延长的周期数为0
// clear the Sleep flag.
Sleep = FALSE;
// Task Dispatcher 任务调度
while(TRUE) // Main Loop 主循环
{
if(GotSUD) // Wait for SUDAV 等待 SUDAV
{
SetupCommand(); // Implement setup command 执行 setup 命令
GotSUD = FALSE; // Clear SUDAV flag 清除 SUDAV 标志
}
// Poll User Device
// 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.
// 轮询用户设备
// 注意:空闲方式将停止处理器时钟,有两种方法可以退出空闲状态:WAKEUP引脚和在USB总线上检测到
// USB总线恢复状态。定时器将停止工作,任何其它的中断都不能唤醒处理器。
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.
// 清除 进入sleep 标志。这里在唤醒和下一次sleep期间,预防任何竞争的条件。
do
{
EZUSB_Susp(); // Place processor in idle mode. 使处理器进入空闲方式
}
while(!Rwuen && EZUSB_EXTWAKEUP());
// Must continue to go back into suspend if the host has disabled remote wakeup
// *and* the wakeup was caused by the external wakeup pin.
// 假如主机禁止远程唤醒,而外部的wakeup引脚产生唤醒信号时,必须再次返回到挂起状态。
// 8051 activity will resume here due to USB bus or Wakeup# pin activity.
// 由于USB总线或Wakeup#引脚活动,8051将恢复工作。
EZUSB_Resume(); // If source is the Wakeup# pin, signal the host to Resume.
// 如果唤醒源是Wakeup#引脚,则向主机发出恢复信号。
TD_Resume();
}
}
TD_Poll();
}
}
// Device request parser 设备请求分析
void SetupCommand(void)
{
void *dscr_ptr;
switch(SETUPDAT[1]) //SETUPDAT[1]中包含请求类型
// USB 定义了11种标准的USB设备请求,主要功能是完成USB设备的配置操作。
{
case SC_GET_DESCRIPTOR: // *** Get Descriptor 0x06 获取 指定的 描述符
if(DR_GetDescriptor())
switch(SETUPDAT[3]) //SETUPDAT[3]中包含描述符类型
{
case GD_DEVICE: // Device 0x01 设备描述符
SUDPTRH = MSB(pDeviceDscr);
SUDPTRL = LSB(pDeviceDscr);
break;
case GD_DEVICE_QUALIFIER: // Device Qualifier 0x06 设备限定描述符
SUDPTRH = MSB(pDeviceQualDscr);
SUDPTRL = LSB(pDeviceQualDscr);
break;
case GD_CONFIGURATION: // Configuration 0x02 配置描述符
SUDPTRH = MSB(pConfigDscr);
SUDPTRL = LSB(pConfigDscr);
break;
case GD_OTHER_SPEED_CONFIGURATION: // Other Speed Configuration 0x07 其他速率配置描述符
SUDPTRH = MSB(pOtherConfigDscr);
SUDPTRL = LSB(pOtherConfigDscr);
break;
case GD_STRING: // String 0x03 字符串描述符
if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]))
{
SUDPTRH = MSB(dscr_ptr);
SUDPTRL = LSB(dscr_ptr);
}
else
EZUSB_STALL_EP0(); // Stall End Point 0 Stall端点0
break;
default: // Invalid request 无效请求
EZUSB_STALL_EP0(); // Stall End Point 0 Stall端点0
}
break;
case SC_GET_INTERFACE: // *** Get Interface 0x0A 获取 接口描述符
DR_GetInterface();
break;
case SC_SET_INTERFACE: // *** Set Interface 0x0B 设置 接口描述符
DR_SetInterface();
break;
case SC_SET_CONFIGURATION: // *** Set Configuration 0x09 设置 配置描述符
DR_SetConfiguration();
break;
case SC_GET_CONFIGURATION: // *** Get Configuration 0x08 获取 配置描述符
DR_GetConfiguration();
break;
case SC_GET_STATUS: // *** Get Status 0x00 获取 状态
if(DR_GetStatus())
switch(SETUPDAT[0]) // SETUPDAT[0]中包含描述符信息
{
case GS_DEVICE: // Device 0x80 设备
EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
EP0BUF[1] = 0;
EP0BCH = 0;
EP0BCL = 2;
break;
case GS_INTERFACE: // Interface 0x81 接口
EP0BUF[0] = 0;
EP0BUF[1] = 0;
EP0BCH = 0;
EP0BCL = 2;
break;
case GS_ENDPOINT: // End Point 0x82 端点
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 Stall 端点0
}
break;
case SC_CLEAR_FEATURE: // *** Clear Feature 0x01 清除 特征
if(DR_ClearFeature())
switch(SETUPDAT[0])
{
case FT_DEVICE: // Device 0x00 设备
if(SETUPDAT[2] == 1)
Rwuen = FALSE; // Disable Remote Wakeup 禁止远程唤醒
else
EZUSB_STALL_EP0(); // Stall End Point 0 Stall 端点0
break;
case FT_ENDPOINT: // End Point 0x02 端点
if(SETUPDAT[2] == 0)
{
*(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL;
EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] );
}
else
EZUSB_STALL_EP0(); // Stall End Point 0 Stall 端点0
break;
}
break;
case SC_SET_FEATURE: // *** Set Feature 0x03 设置 特征
if(DR_SetFeature())
switch(SETUPDAT[0])
{
case FT_DEVICE: // Device 0x00 设备
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 Stall 端点0
break;
case FT_ENDPOINT: // End Point 0x02 端点
*(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL;
break;
}
break;
default: // *** Invalid Command 无效命令
if(DR_VendorCmnd())
EZUSB_STALL_EP0(); // Stall End Point 0 Stall 端点0
}
// Acknowledge handshake phase of device request
// 应答设备请求的握手段,对版本C需要,对版本B无效
EP0CS |= bmHSNAK;
}
// Wake-up interrupt handler
// 唤醒中断处理
void resume_isr(void) interrupt WKUP_VECT
{
EZUSB_CLEAR_RSMIRQ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -