📄 fw.c
字号:
//-----------------------------------------------------------------------------
// File: fw.c
// Contents: Firmware frameworks task dispatcher and device request parser
// source.
//
// Copyright (c) 2002 Cypress Semiconductor, Inc. All rights reserved
//
// $Archive: /USB/ez811/firmware/host/fw.c $
// $Date: 1/23/02 11:25a $
// $Revision: 4 $
//-----------------------------------------------------------------------------
#include "ezusb.h"
#include "ezregs.h"
//-----------------------------------------------------------------------------
// Random Macros
//-----------------------------------------------------------------------------
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
volatile BOOL GotSUD;
BOOL Rwuen;
BOOL Selfpwr;
volatile BOOL Sleep; // Sleep mode enable flag
WORD pDeviceDscr; // Pointer to Device Descriptor; Descriptors may be moved
WORD pConfigDscr;
WORD pStringDscr;
//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
void SetupCommand(void);
void TD_Init(void);
void TD_Poll(void);
BOOL TD_Suspend(void);
BOOL TD_Resume(void);
BOOL DR_GetDescriptor(void);
BOOL DR_SetConfiguration(void);
BOOL DR_GetConfiguration(void);
BOOL DR_SetInterface(void);
BOOL DR_GetInterface(void);
BOOL DR_GetStatus(void);
BOOL DR_ClearFeature(void);
BOOL DR_SetFeature(void);
BOOL DR_VendorCmnd(void);
//-----------------------------------------------------------------------------
// Code
//-----------------------------------------------------------------------------
// Task dispatcher
void main(void)
{
DWORD i;
WORD offset;
DWORD DevDescrLen;
DWORD j=0;
WORD IntDescrAddr;
WORD ExtDescrAddr;
// 初始化全局变量
Sleep = FALSE; // 睡眠状态无效
Rwuen = FALSE; // 远程唤醒无效
Selfpwr = FALSE; // 自供电无效
GotSUD = FALSE; // 清除"得到装载数据"标志位
// 初始化用户设备
TD_Init();
// 分配描述表
pDeviceDscr = (WORD)&DeviceDscr;
pConfigDscr = (WORD)&ConfigDscr;
pStringDscr = (WORD)&StringDscr;
if ((WORD)&DeviceDscr & 0xe000)
{
IntDescrAddr = INTERNAL_DSCR_ADDR;
ExtDescrAddr = (WORD)&DeviceDscr;
DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;
for (i = 0; i < DevDescrLen; i++)
*((BYTE xdata *)IntDescrAddr+i) = 0xCD;
for (i = 0; i < DevDescrLen; i++)
*((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i);
pDeviceDscr = IntDescrAddr;
offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
pConfigDscr -= offset;
pStringDscr -= offset;
}
EZUSB_IRQ_ENABLE(); // 使能USB中断(INT2)
EZUSB_ENABLE_RSMIRQ(); // 使能远程唤醒中断
// 8051负责所有的USB事件,包括已经发生的
PORTCCFG |= 0xc0; // 开启外部存储器的读写信号线
USBBAV = USBBAV | 1 & ~bmBREAK; // 关闭断点和自动矢量
USBIEN |= bmSUDAV | bmSUTOK | bmSUSP | bmURES; // 使能选中的中断
EA = 1; // 使能8051中断
#ifndef NO_RENUM
// Note: at full speed, high speed hosts may take 5 sec to detect device
EZUSB_Discon(TRUE); // Renumerate
#endif
CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration)
// 任务分配
while(TRUE) // 主循环
{
if(GotSUD) // 等待SUDAV
{
SetupCommand(); // 执行设备请求
GotSUD = FALSE; // 清除SUDAV标志位
}
// 枚举用户设备
if (Sleep) // 睡眠状态下,无法枚举用户设备,需要先将设备复位
{
if(TD_Suspend()) // 设备挂起
{
Sleep = FALSE; // 清除睡眠状态标志位,避免程序在睡眠与唤醒状态之间循环
do
{
EZUSB_Susp(); // 使处理器处于闲置状态
}
while(!Rwuen && EZUSB_EXTWAKEUP());
// 如果主机将远程唤醒置为无效,则设备必须继续挂起
EZUSB_Resume(); // EZ-USB复位
TD_Resume(); // 设备复位
}
}
TD_Poll(); // 反复检测
}
}
// 设备请求的执行
void SetupCommand(void)
{
void *dscr_ptr;
DWORD i;
switch(SETUPDAT[1])
{
case SC_GET_DESCRIPTOR: // 得到描述符
if(DR_GetDescriptor())
switch(SETUPDAT[3])
{
case GD_DEVICE: // 设备
SUDPTRH = MSB(pDeviceDscr);
SUDPTRL = LSB(pDeviceDscr);
break;
case GD_CONFIGURATION: // 配置
if(dscr_ptr = (void *)EZUSB_GetConfigDscr(SETUPDAT[2]))
{
SUDPTRH = MSB(dscr_ptr);
SUDPTRL = LSB(dscr_ptr);
}
else
EZUSB_STALL_EP0(); // 装载端点0
break;
case GD_STRING: // 字符串
if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]))
{
STRINGDSCR *sdp;
BYTE len;
sdp = dscr_ptr;
len = sdp->length;
if (len > SETUPDAT[6])
len = SETUPDAT[6]; // 只限于请求的长度
while (len)
{
for(i=0; i<min(len,64); i++)
*(IN0BUF+i) = *((BYTE xdata *)sdp+i);
// 设置长度和开启端点
EZUSB_SET_EP_BYTES(IN0BUF_ID,min(len,64));
len -= min(len,64);
(BYTE *)sdp += 64;
while(EP0CS & 0x04);
}
EZUSB_SET_EP_BYTES(IN0BUF_ID,0);
// 清除HS-nak位
EP0CS = bmHS;
}
else
EZUSB_STALL_EP0(); // 装载端点0
break;
default: // 无效的请求
EZUSB_STALL_EP0(); // 装载端点0
}
break;
case SC_GET_INTERFACE: // 得到接口
DR_GetInterface();
break;
case SC_SET_INTERFACE: // 设置接口
DR_SetInterface();
break;
case SC_SET_CONFIGURATION: // 设置配置
DR_SetConfiguration();
break;
case SC_GET_CONFIGURATION: // 得到配置
DR_GetConfiguration();
break;
case SC_GET_STATUS: // 得到状态
if(DR_GetStatus())
switch(SETUPDAT[0])
{
case GS_DEVICE: // 设备
IN0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
IN0BUF[1] = 0;
EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
break;
case GS_INTERFACE: // 接口
IN0BUF[0] = 0;
IN0BUF[1] = 0;
EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
break;
case GS_ENDPOINT: // 端点
IN0BUF[0] = EPIO[EPID(SETUPDAT[4])].cntrl & bmEPSTALL;
IN0BUF[1] = 0;
EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
break;
default: // 无效的指令
EZUSB_STALL_EP0(); // 装载端点0
}
break;
case SC_CLEAR_FEATURE: // 清除特征
if(DR_ClearFeature())
switch(SETUPDAT[0])
{
case FT_DEVICE: // 设备
if(SETUPDAT[2] == 1)
Rwuen = FALSE; // 使远程唤醒无效
else
EZUSB_STALL_EP0(); // 装载端点0
break;
case FT_ENDPOINT: // 端点
if(SETUPDAT[2] == 0)
{
EZUSB_UNSTALL_EP( EPID(SETUPDAT[4]) );
EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] );
}
else
EZUSB_STALL_EP0(); // 装载端点0
break;
}
break;
case SC_SET_FEATURE: // 设置特征
if(DR_SetFeature())
switch(SETUPDAT[0])
{
case FT_DEVICE: // 设备
if(SETUPDAT[2] == 1)
Rwuen = TRUE; // 使能远程唤醒
else
EZUSB_STALL_EP0(); // 装载端点0
break;
case FT_ENDPOINT: // 端点
if(SETUPDAT[2] == 0)
EZUSB_STALL_EP( EPID(SETUPDAT[4]) );
else
EZUSB_STALL_EP0(); // 装载端点0
break;
}
break;
default: // 无效指令
if(DR_VendorCmnd())
EZUSB_STALL_EP0(); // 装载端点0
}
// 获取设备请求的握手阶段
EP0CS |= bmBIT1;
}
// 唤醒中断处理
void resume_isr(void) interrupt WKUP_VECT
{
EZUSB_CLEAR_RSMIRQ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -