📄 cydown.c
字号:
//-----------------------------------------------------------------------------
// File: CyDown.c
//-----------------------------------------------------------------------------
#include "lp.h"
#include "lpregs.h"
#include "syncdly.h" // 同步延时宏
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define DELAY_COUNT 0x9248*8L // 延时计数
#define _IFREQ 48000
#define _CFREQ 48000
//-----------------------------------------------------------------------------
// 比较函数
//-----------------------------------------------------------------------------
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
volatile BOOL GotSUD;
BOOL Rwuen;
BOOL Selfpwr;
volatile BOOL Sleep; // 休眠模式使能信号
WORD pDeviceDscr;
WORD pDeviceQualDscr;
WORD pHighSpeedConfigDscr;
WORD pFullSpeedConfigDscr;
WORD pConfigDscr;
WORD pOtherConfigDscr;
WORD pStringDscr;
//-----------------------------------------------------------------------------
// 函数声明
//-----------------------------------------------------------------------------
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);
BOOL DR_LED1(void); //显示数字0
BOOL DR_LED2(void); //显示数字1
BOOL DR_LED3(void); //显示数字2
BOOL DR_LED4(void); //显示字符A
BOOL DR_LED5(void); //显示数字F
// 端点映射
const char code EPCS_Offset_Lookup_Table[] =
{
0, // EP1OUT
1, // EP1IN
2, // EP2OUT
2, // EP2IN
3, // EP4OUT
3, // EP4IN
4, // EP6OUT
4, // EP6IN
5, // EP8OUT
5, // EP8IN
};
#define epcs(EP) (EPCS_Offset_Lookup_Table[(EP & 0x7E) | (EP > 128)] + 0xE6A1)
//-----------------------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------------------
//任务线程
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();
//定向USB描述符
pDeviceDscr = (WORD)&DeviceDscr;
pDeviceQualDscr = (WORD)&DeviceQualDscr;
pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;
pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;
pStringDscr = (WORD)&StringDscr;
if ((WORD)&DeviceDscr & 0xC000)
{
// 重定向描述符
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);
// 更新描述符指针
pDeviceDscr = IntDescrAddr;
offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
pDeviceQualDscr -= offset;
pConfigDscr -= offset;
pOtherConfigDscr -= offset;
pHighSpeedConfigDscr -= offset;
pFullSpeedConfigDscr -= offset;
pStringDscr -= offset;
}
EZUSB_IRQ_ENABLE(); // 使能USB中断
EZUSB_ENABLE_RSMIRQ(); //远程唤醒中断
INTSETUP |= (bmAV2EN | bmAV4EN); // 使能INT 2 & 4 自动向量
USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; // 使能选择的中断
EA = 1; // 使能8051全局中断
#ifndef NO_RENUM
// 检查重列举
if(!(USBCS & bmRENUM))
{
EZUSB_Discon(TRUE); //重列举
}
#endif
// 连接
USBCS &=~bmDISCON;
CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE;
//清Sleep标记
Sleep = FALSE;
//任务线程
while(TRUE) //主循环
{
//列举用户设备
TD_Poll();
if(GotSUD)
{
SetupCommand();
GotSUD = FALSE; // 清SETUP标记
}
//检查并处理
if (Sleep)
{
if(TD_Suspend())
{
Sleep = FALSE; //清Sleep标记
do
{
EZUSB_Susp(); //空闲状态处理
}
while(!Rwuen && EZUSB_EXTWAKEUP());
EZUSB_Resume();
TD_Resume();
}
}
}
}
BOOL HighSpeedCapable()
{
// 高速USB处理
if (REVID & 0xF0) //检查是fx2lp/fx1还是fx2.
{
// fx2lp 或 fx1 的处理
if (GPCR2 & bmHIGHSPEEDCAPABLE)
return TRUE;
else
return FALSE;
}
else
{
// fx2 的处理
return TRUE;
}
}
// 设备请求
void SetupCommand(void)
{
void *dscr_ptr;
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_DEVICE_QUALIFIER: //设备限定
if (HighSpeedCapable())
{
SUDPTRH = MSB(pDeviceQualDscr);
SUDPTRL = LSB(pDeviceQualDscr);
}
else
{
EZUSB_STALL_EP0();
}
break;
case GD_CONFIGURATION: // 配置
SUDPTRH = MSB(pConfigDscr);
SUDPTRL = LSB(pConfigDscr);
break;
case GD_OTHER_SPEED_CONFIGURATION: // 其它速率配置
SUDPTRH = MSB(pOtherConfigDscr);
SUDPTRL = LSB(pOtherConfigDscr);
break;
case GD_STRING: // 字符串
if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]))
{
SUDPTRH = MSB(dscr_ptr);
SUDPTRL = LSB(dscr_ptr);
}
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: // 设备
EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
EP0BUF[1] = 0;
EP0BCH = 0;
EP0BCL = 2;
break;
case GS_INTERFACE: // 接口
EP0BUF[0] = 0;
EP0BUF[1] = 0;
EP0BCH = 0;
EP0BCL = 2;
break;
case GS_ENDPOINT: // 端点
EP0BUF[0] = *(BYTE xdata *) epcs(SETUPDAT[4]) & bmEPSTALL;
EP0BUF[1] = 0;
EP0BCH = 0;
EP0BCL = 2;
break;
default: //无效命令
EZUSB_STALL_EP0();
}
break;
case SC_CLEAR_FEATURE: // 清除特性
if(DR_ClearFeature())
switch(SETUPDAT[0])
{
case FT_DEVICE: // 设备
if(SETUPDAT[2] == 1)
Rwuen = FALSE; // 禁止远程唤醒
else
EZUSB_STALL_EP0();
break;
case FT_ENDPOINT:
if(SETUPDAT[2] == 0)
{
*(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL;
EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] );
}
else
EZUSB_STALL_EP0();
break;
}
break;
case SC_SET_FEATURE: // 设置特性
if(DR_SetFeature())
switch(SETUPDAT[0])
{
case FT_DEVICE:
if(SETUPDAT[2] == 1)
Rwuen = TRUE;
else if(SETUPDAT[2] == 2)
break;
else
EZUSB_STALL_EP0();
break;
case FT_ENDPOINT:
*(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL;
break;
default:
EZUSB_STALL_EP0();
}
break;
case SC_LED1: //显示数字0
DR_LED1();
break;
case SC_LED2: //显示数字1
DR_LED2();
break;
case SC_LED3: //显示数字2
DR_LED3();
break;
case SC_LED4: //显示字符A
DR_LED4();
break;
case SC_LED5: //显示字符F
DR_LED5();
break;
default: // 无效命令
if(DR_VendorCmnd())
EZUSB_STALL_EP0(); // 停止断点0
}
//握手
EP0CS |= bmHSNAK;
}
// 唤醒中断
void resume_isr(void) interrupt WKUP_VECT
{
EZUSB_CLEAR_RSMIRQ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -