vend_ax.c
来自「USB芯片cy7c68013与AD转换芯片MAX115实现数据转换」· C语言 代码 · 共 590 行
C
590 行
#pragma NOIV // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
// File: periph.c
// Contents: Hooks required to implement USB peripheral function.
//
// Copyright (c) 2000 Cypress Semiconductor All rights reserved
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "Fx2regs.h"
extern BOOL GotSUD; // 接收设置数据标志
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr;
BYTE Configuration; // 当前设置
BYTE AlternateSetting; // 交替设置
sbit PA0 = IOA ^ 0;
sbit PA1 = IOA ^ 1;
sbit PA2 = IOA ^ 2;
sbit PA3 = IOA ^ 3;
sbit PA4 = IOA ^ 4;
sbit PA5 = IOA ^ 5;
sbit PA6 = IOA ^ 6;
sbit PA7 = IOA ^ 7;
// EZUSB FX2 PORTD = FD[15:8], when IFCFG[1:0]=10 and WORDWIDE=1
sbit PD0 = IOD ^ 0;
sbit PD1 = IOD ^ 1;
sbit PD2 = IOD ^ 2;
sbit PD3 = IOD ^ 3;
sbit PD4 = IOD ^ 4;
sbit PD5 = IOD ^ 5;
sbit PD6 = IOD ^ 6;
sbit PD7 = IOD ^ 7;
//-----------------------------------------------------------------------------
// 常量
//-----------------------------------------------------------------------------
#define VR_UPLOAD 0xc0
#define VR_DOWNLOAD 0x40
#define VR_ANCHOR_DLD 0xa0 // handled by core
#define VR_EEPROM 0xa2 // 上传/下载到 EEPROM
#define VR_RAM 0xa3 // 上传/下载到外部ram
#define VR_SETI2CADDR 0xa4
#define VR_GETI2C_TYPE 0xa5 // 8或16 字节地址
#define VR_GET_CHIP_REV 0xa6 // Rev A, B = 0, Rev C = 2 // NOTE: New TNG Rev
#define VR_TEST_MEM 0xa7 // runs mem test and returns result
#define VR_RENUM 0xa8 // 重枚举
#define VR_DB_FX 0xa9 // Force use of double byte address EEPROM (for FX)
#define VR_I2C_100 0xaa // put the i2c bus in 100Khz mode
#define VR_I2C_400 0xab // put the i2c bus in 400Khz mode
#define VR_NOSDPAUTO 0xac // test code. does uploads using SUDPTR with manual length override
#define VR_C1 0xC1 // put the i2c bus in 400Khz mode
#define SERIAL_ADDR 0x50
#define EP0BUFF_SIZE 0x40
#define GET_CHIP_REV() ((CPUCS >> 4) & 0x00FF) // EzUSB Chip Rev Field
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
BYTE DB_Addr; //TPM Dual Byte Address stat
BYTE I2C_Addr; //TPM I2C address
//-----------------------------------------------------------------------------
// 函数原型
//-----------------------------------------------------------------------------
void EEPROMWrite(WORD addr, BYTE length, BYTE xdata *buf); //TPM EEPROM Write
void EEPROMRead(WORD addr, BYTE length, BYTE xdata *buf); //TPM EEPROM Read
//-----------------------------------------------------------------------------
// 任务分配器挂钩
// 以下挂钩由任务分配器调用
//-----------------------------------------------------------------------------
void TD_Init(void) // 在起始调用一次
{
Rwuen = TRUE; // 使能远程唤醒
EZUSB_InitI2C(); // 初始化I2C总线
}
void TD_Poll(void) // 当设备闲置时,重复调用
{
}
BOOL TD_Suspend(void) // 在设备进入挂起方式时调用
{
return(TRUE);
}
BOOL TD_Resume(void) // 在设备恢复会调用
{
return(TRUE);
}
//-----------------------------------------------------------------------------
// 设备请求挂钩
//-----------------------------------------------------------------------------
BOOL DR_GetDescriptor(void)
{
return(TRUE);
}
BOOL DR_SetConfiguration(void) // 当设置配置指令被接受时调用
{
Configuration = SETUPDAT[2];
return(TRUE); // 由用户代码处理
}
BOOL DR_GetConfiguration(void) // 当设置配置指令被接受时调用
{
EP0BUF[0] = Configuration;
EP0BCH = 0;
EP0BCL = 1;
return(TRUE); // 由用户代码处理
}
BOOL DR_SetInterface(void) // 当设置接口命令获取时调用
{
AlternateSetting = SETUPDAT[2];
return(TRUE); // 由用户代码处理
}
BOOL DR_GetInterface(void) // 当设置接口命令获取时调用
{
EP0BUF[0] = AlternateSetting;
EP0BCH = 0;
EP0BCL = 1;
return(TRUE); // 由用户代码处理
}
BOOL DR_GetStatus(void)
{
return(TRUE);
}
BOOL DR_ClearFeature(void)
{
return(TRUE);
}
BOOL DR_SetFeature(void)
{
return(TRUE);
}
//定义自己的厂商请求
#define VR_GET_FRAMENO 0xb0//得到帧计数
#define VR_GET_MFRAMENO 0xb1//得到微帧计数
BOOL DR_VendorCmnd(void)
{
WORD addr, len, bc;
WORD ChipRev;
WORD i;
// Determine I2C boot eeprom device address; addr = 0x0 for 8 bit addr eeproms (24LC00)
I2C_Addr = SERIAL_ADDR | ((I2CS & 0x10) >> 4); // addr=0x01 for 16 bit addr eeprom (LC65)
// Indicate if it is a dual byte address part
DB_Addr = (BOOL)(I2C_Addr & 0x01); //TPM: ID1 is 16 bit addr bit - set by rocker sw or jumper
switch(SETUPDAT[1])//判断请求类型
{ //TPM handle new commands
case VR_GET_FRAMENO:
*EP0BUF = USBFRAMEL;
*(EP0BUF+1)=USBFRAMEH;
EP0BCH = 0;
EP0BCL = 2;
EP0CS |= bmHSNAK;
break;
case VR_GET_MFRAMENO:
*EP0BUF = MICROFRAME;
EP0BCH = 0;
EP0BCL = 1;
EP0CS |= bmHSNAK;
break;
case VR_GETI2C_TYPE:
*EP0BUF = DB_Addr;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
case VR_GET_CHIP_REV:
ChipRev = GET_CHIP_REV();
*EP0BUF = ChipRev;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
case VR_TEST_MEM:
*EP0BUF = 0x0F; // Fail
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
case VR_SETI2CADDR:
I2C_Addr = SETUPDAT[2];
break;
case VR_I2C_100:
/*I2CTL &= ~bm400KHZ;
EP0BCH = 0;
EP0BCL = 0;*/
// Serial_SendChar('A', 0);
break;
case VR_C1:
CPUCS = 0x10; // CLKSPD[1:0]=10, for 48MHz operation
// CLKOE=0, don't drive CLKOUT
IFCONFIG = 0xE8;
// IFCLKSRC=1 , FIFOs executes on internal clk source
// xMHz=1 , 48MHz internal clk rate
// IFCLKOE=1 , Don't drive IFCLK pin signal at 48MHz
// IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk
// ASYNC=1 , master samples asynchronous
// GSTATE=0 , Don't drive GPIF states out on PORTE[2:0], debug WF
// IFCFG[1:0]=00, Port
OEA=0xFD;//OEA,OEB,OED控制口的输入输出使能,1为输出,0为输入
OEB=0xff;
OED=0xff;
IOA=0xFF;//IOA,IOB.IOD 为端口上输入输出数据
PA2=0;//读
IOB=0x01;
IOD=0x30;
EZUSB_Delay(100);
PA2=1;//写
EZUSB_Delay(100);
OEB=0x00;//端点B、D输入
OED=0x00;
PA0=1;
EZUSB_Delay(100);
PA0=0; //转换开始
EZUSB_Delay(100);
PA0=1;
while (PA1==1); //等待中断到来
EZUSB_Delay(100);
PA4=0; //片选信号有效
PA2=0; //读数据
EZUSB_Delay(100);
*EP0BUF =IOB;
*(EP0BUF+1) = IOD; //通过EP0端点发送到主机
PA2=1;
PA4=1;
EP0BCH = 0;
EP0BCL = 2;
EP0CS |= bmHSNAK;
break;
case VR_I2C_400:
I2CTL |= bm400KHZ;
EP0BCH = 0;
EP0BCL = 0;
break;
case VR_RENUM:
*EP0BUF = 7;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
EZUSB_Delay(1000);
EZUSB_Discon(TRUE); // renumerate until setup received
break;
case VR_NOSDPAUTO:
// we want specify our own length for the transfer so
// disable the automatic length feature of the Setup Data Autopointer
SUDPTRCTL &= ~bmSDPAUTO;
EP0BCH = SETUPDAT[7];
EP0BCL = SETUPDAT[6];
SUDPTRH = SETUPDAT[3];
SUDPTRL = SETUPDAT[2];
break;
case VR_DB_FX:
DB_Addr = 0x01; //TPM: need to assert double byte
I2C_Addr |= 0x01; //TPM: need to assert double byte
// NOTE: This case falls through !
case VR_RAM:
case VR_EEPROM:
addr = SETUPDAT[2]; // Get address and length
addr |= SETUPDAT[3] << 8;
len = SETUPDAT[6];
len |= SETUPDAT[7] << 8;
// Is this an upload command ?
if(SETUPDAT[0] == VR_UPLOAD)
{
while(len) // Move requested data through EP0IN
{ // one packet at a time.
while(EP0CS & bmEPBUSY);
if(len < EP0BUFF_SIZE)
bc = len;
else
bc = EP0BUFF_SIZE;
// Is this a RAM upload ?
if(SETUPDAT[1] == VR_RAM)
{
for(i=0; i<bc; i++)
*(EP0BUF+i) = *((BYTE xdata *)addr+i);
}
else
{
for(i=0; i<bc; i++)
*(EP0BUF+i) = 0xcd;
EEPROMRead(addr,(WORD)bc,(WORD)EP0BUF);
}
EP0BCH = 0;
EP0BCL = (BYTE)bc; // Arm endpoint with # bytes to transfer
addr += bc;
len -= bc;
}
}
// Is this a download command ?
else if(SETUPDAT[0] == VR_DOWNLOAD)
{
while(len) // Move new data through EP0OUT
{ // one packet at a time.
// Arm endpoint - do it here to clear (after sud avail)
EP0BCH = 0;
EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing
while(EP0CS & bmEPBUSY);
bc = EP0BCL; // Get the new bytecount
// Is this a RAM download ?
if(SETUPDAT[1] == VR_RAM)
{
for(i=0; i<bc; i++)
*((BYTE xdata *)addr+i) = *(EP0BUF+i);
}
else
EEPROMWrite(addr,bc,(WORD)EP0BUF);
addr += bc;
len -= bc;
}
}
break;
}
return(FALSE); // no error; command handled OK
}
//-----------------------------------------------------------------------------
// USB中断处理
// 由USB中断跳转表调用
//-----------------------------------------------------------------------------
// 设置数据有效中断处理
void ISR_Sudav(void) interrupt 0
{
// enable the automatic length feature of the Setup Data Autopointer
// in case a previous transfer disbaled it
SUDPTRCTL |= bmSDPAUTO;
GotSUD = TRUE; // 设置表志
EZUSB_IRQ_CLEAR();
USBIRQ = bmSUDAV; // 清除SUDAV IRQ
}
// 设置令牌中断处理
void ISR_Sutok(void) interrupt 0
{
EZUSB_IRQ_CLEAR();
USBIRQ = bmSUTOK; // 清除 SUTOK IRQ
}
void ISR_Sof(void) interrupt 0
{
EZUSB_IRQ_CLEAR();
USBIRQ = bmSOF; //清除 SOF IRQ
}
void ISR_Ures(void) interrupt 0
{
if (EZUSB_HIGHSPEED())
{
pConfigDscr = pHighSpeedConfigDscr;
pOtherConfigDscr = pFullSpeedConfigDscr;
}
else
{
pConfigDscr = pFullSpeedConfigDscr;
pOtherConfigDscr = pHighSpeedConfigDscr;
}
EZUSB_IRQ_CLEAR();
USBIRQ = bmURES; // 清除URES IRQ
}
void ISR_Susp(void) interrupt 0
{
Sleep = TRUE;
EZUSB_IRQ_CLEAR();
USBIRQ = bmSUSP;
}
void ISR_Highspeed(void) interrupt 0
{
if (EZUSB_HIGHSPEED())
{
pConfigDscr = pHighSpeedConfigDscr;
pOtherConfigDscr = pFullSpeedConfigDscr;
}
else
{
pConfigDscr = pFullSpeedConfigDscr;
pOtherConfigDscr = pHighSpeedConfigDscr;
}
EZUSB_IRQ_CLEAR();
USBIRQ = bmHSGRANT;
}
void ISR_Ep0ack(void) interrupt 0
{
}
void ISR_Stub(void) interrupt 0
{
}
void ISR_Ep0in(void) interrupt 0
{
}
void ISR_Ep0out(void) interrupt 0
{
}
void ISR_Ep1in(void) interrupt 0
{
}
void ISR_Ep1out(void) interrupt 0
{
}
void ISR_Ep2inout(void) interrupt 0
{
}
void ISR_Ep4inout(void) interrupt 0
{
}
void ISR_Ep6inout(void) interrupt 0
{
}
void ISR_Ep8inout(void) interrupt 0
{
}
void ISR_Ibn(void) interrupt 0
{
}
void ISR_Ep0pingnak(void) interrupt 0
{
}
void ISR_Ep1pingnak(void) interrupt 0
{
}
void ISR_Ep2pingnak(void) interrupt 0
{
}
void ISR_Ep4pingnak(void) interrupt 0
{
}
void ISR_Ep6pingnak(void) interrupt 0
{
}
void ISR_Ep8pingnak(void) interrupt 0
{
}
void ISR_Errorlimit(void) interrupt 0
{
}
void ISR_Ep2piderror(void) interrupt 0
{
}
void ISR_Ep4piderror(void) interrupt 0
{
}
void ISR_Ep6piderror(void) interrupt 0
{
}
void ISR_Ep8piderror(void) interrupt 0
{
}
void ISR_Ep2pflag(void) interrupt 0
{
}
void ISR_Ep4pflag(void) interrupt 0
{
}
void ISR_Ep6pflag(void) interrupt 0
{
}
void ISR_Ep8pflag(void) interrupt 0
{
}
void ISR_Ep2eflag(void) interrupt 0
{
}
void ISR_Ep4eflag(void) interrupt 0
{
}
void ISR_Ep6eflag(void) interrupt 0
{
}
void ISR_Ep8eflag(void) interrupt 0
{
}
void ISR_Ep2fflag(void) interrupt 0
{
}
void ISR_Ep4fflag(void) interrupt 0
{
}
void ISR_Ep6fflag(void) interrupt 0
{
}
void ISR_Ep8fflag(void) interrupt 0
{
}
void ISR_GpifComplete(void) interrupt 0
{
}
void ISR_GpifWaveform(void) interrupt 0
{
}
void EEPROMWriteByte(WORD addr, BYTE value)
{
BYTE i = 0;
BYTE xdata ee_str[3];
if(DB_Addr)
ee_str[i++] = MSB(addr);
ee_str[i++] = LSB(addr);
ee_str[i++] = value;
EZUSB_WriteI2C(I2C_Addr, i, ee_str);
EZUSB_WaitForEEPROMWrite(I2C_Addr);
}
void EEPROMWrite(WORD addr, BYTE length, BYTE xdata *buf)
{
BYTE i;
for(i=0;i<length;++i)
EEPROMWriteByte(addr++,buf[i]);
}
void EEPROMRead(WORD addr, BYTE length, BYTE xdata *buf)
{
BYTE i = 0;
BYTE j = 0;
BYTE xdata ee_str[2];
if(DB_Addr)
ee_str[i++] = MSB(addr);
ee_str[i++] = LSB(addr);
EZUSB_WriteI2C(I2C_Addr, i, ee_str);
// for(j=0; j < length; j++)
// *(buf+j) = 0xcd;
EZUSB_ReadI2C(I2C_Addr, length, buf);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?