📄 vend_ax.c
字号:
//-----------------------------------------------------------------------------
// File: vend_ax.c
// Contents: Hooks required to implement USB peripheral function.
//
// $Archive: /USB/Examples/FX2LP/vend_ax/Vend_Ax.c $
// $Date: 9/07/05 2:54p $
// $Revision: 4 $
//
//
//-----------------------------------------------------------------------------
// Copyright 2003, Cypress Semiconductor Corporation
//-----------------------------------------------------------------------------
#pragma NOIV // Do not generate interrupt vectors
#include "fx2.h"
#include "fx2regs.h"
#include "eeprom.h"
extern BOOL GotSUD; // Received setup data flag
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr;
BYTE Configuration; // Current configuration
BYTE AlternateSetting; // Alternate settings
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define VR_UPLOAD 0xc0
#define VR_DOWNLOAD 0x40
#define VR_ANCHOR_DLD 0xa0 // handled by core
#define VR_EEPROM 0xa2 // loads (uploads) EEPROM
#define VR_RAM 0xa3 // loads (uploads) external ram
#define VR_SETI2CADDR 0xa4
#define VR_GETI2C_TYPE 0xa5 // 8 or 16 byte address
#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 // renum
#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 EP0BUFF_SIZE 0x40
#define GET_CHIP_REV() REVID
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
BYTE DB_Addr; // Dual Byte Address stat
BYTE I2C_Addr; // I2C address
BYTE EE_Page_Size; // EEPROM page size
//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
void TD_Init(void) // Called once at startup
{
Rwuen = TRUE; // Enable remote-wakeup
EE_Page_Size = 0; // Set the page size to 0, so we know to calculate it on an EEPROM write
// 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); // ID1 is 16 bit addr bit - set by rocker sw or jumper
}
void TD_Poll(void) // Called repeatedly while the device is idle
{
}
BOOL TD_Suspend(void) // Called before the device goes into suspend mode
{
return(TRUE);
}
BOOL TD_Resume(void) // Called after the device resumes
{
return(TRUE);
}
//-----------------------------------------------------------------------------
// Device Request hooks
// The following hooks are called by the end point 0 device request parser.
//-----------------------------------------------------------------------------
BOOL DR_GetDescriptor(void)
{
return(TRUE);
}
BOOL DR_SetConfiguration(void) // Called when a Set Configuration command is received
{
Configuration = SETUPDAT[2];
return(TRUE); // Handled by user code
}
BOOL DR_GetConfiguration(void) // Called when a Get Configuration command is received
{
EP0BUF[0] = Configuration;
EP0BCH = 0;
EP0BCL = 1;
return(TRUE); // Handled by user code
}
BOOL DR_SetInterface(void) // Called when a Set Interface command is received
{
AlternateSetting = SETUPDAT[2];
return(TRUE); // Handled by user code
}
BOOL DR_GetInterface(void) // Called when a Set Interface command is received
{
EP0BUF[0] = AlternateSetting;
EP0BCH = 0;
EP0BCL = 1;
return(TRUE); // Handled by user code
}
BOOL DR_GetStatus(void)
{
return(TRUE);
}
BOOL DR_ClearFeature(void)
{
return(TRUE);
}
BOOL DR_SetFeature(void)
{
return(TRUE);
}
BOOL DR_VendorCmnd(void)
{
WORD addr, len, bc;
WORD ChipRev;
WORD i;
switch(SETUPDAT[1])
{ //TPM handle new commands
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;
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)
{
// calculate the page size if we haven't already.
// THIS IS A DESTRUCTIVE CALL - WILL ERASE THE EEPROM
if (!EE_Page_Size)
EE_Page_Size = EEPROMGetPageSize(); // Initialize EEPROM variables
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
{
for (i = 0; i < bc; )
{
// This write is normally one page long. Two special cases:
// Starting from a non-page aligned address (addr & (EE_Page_Size - 1)) != 0
// Less than a page left
BYTE pageSize = EE_Page_Size;
if (EE_Page_Size != 1)
{
if (((addr+i) & (EE_Page_Size - 1)) != 0)
pageSize = EE_Page_Size - ((addr+i) & (EE_Page_Size - 1));
if (bc-i < pageSize)
pageSize = bc-i;
}
EEPROMWritePage(addr+i, EP0BUF+i, pageSize);
i+= pageSize;
}
}
addr += bc;
len -= bc;
}
}
break;
}
return(FALSE); // no error; command handled OK
}
//-----------------------------------------------------------------------------
// USB Interrupt Handlers
// The following functions are called by the USB interrupt jump table.
//-----------------------------------------------------------------------------
// Setup Data Available Interrupt Handler
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; // Set flag
EZUSB_IRQ_CLEAR();
USBIRQ = bmSUDAV; // Clear SUDAV IRQ
}
// Setup Token Interrupt Handler
void ISR_Sutok(void) interrupt 0
{
EZUSB_IRQ_CLEAR();
USBIRQ = bmSUTOK; // Clear SUTOK IRQ
}
void ISR_Sof(void) interrupt 0
{
EZUSB_IRQ_CLEAR();
USBIRQ = bmSOF; // Clear 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; // Clear 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
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -