📄 a3load.c
字号:
#include "a3load.h"
BOOL GotSUD; // Received setup data flag
BOOL IsFX2;
BOOL CheckForFX2()
{
BYTE temp;
// make a backup copy of the test register
temp = INTSETUP_FX2;
// see if we are running on an FX2 by writing to a register that
// only exists on FX2 and reading back the value that should stick
INTSETUP_FX2 = 0xFF;
if (INTSETUP_FX2 == 0x0B)
{
INTSETUP_FX2 = temp;
return TRUE;
}
else
{
INTSETUP_FX2 = temp;
return FALSE;
}
}
void SetupCommand_EZUSB()
{
WORD addr, len, bc, i;
if (SETUPDAT_EZUSB[1] == VR_RAM)
{
addr = SETUPDAT_EZUSB[2]; // Get address and length
addr |= SETUPDAT_EZUSB[3] << 8;
len = SETUPDAT_EZUSB[6];
len |= SETUPDAT_EZUSB[7] << 8;
if(SETUPDAT_EZUSB[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)
OUT0BC_EZUSB = 0;
while(EP0CS_EZUSB & bmOUTBSY_EZUSB);
bc = OUT0BC_EZUSB; // Get the new bytecount
for(i=0; i<bc; i++)
*((BYTE xdata *)addr+i) = *(OUT0BUF_EZUSB+i);
addr += bc;
len -= bc;
}
}
else if(SETUPDAT_EZUSB[0] == VR_UPLOAD)
{
while(len) // Move requested data through EP0IN
{ // one packet at a time.
if(len < EP0BUFF_SIZE)
bc = len;
else
bc = EP0BUFF_SIZE;
for(i=0; i<bc; i++)
*(IN0BUF_EZUSB+i) = *((BYTE xdata *)addr+i);
IN0BC_EZUSB = (BYTE)bc; // Arm endpoint with # bytes to transfer
addr += bc;
len -= bc;
while(EP0CS_EZUSB & bmINBSY_EZUSB);
}
} // if VR_UPLOAD
} // if VR_RAM
else if (SETUPDAT_EZUSB[1] == VR_ISFX2)
{
IN0BUF_EZUSB[0] = 0; // not FX2
IN0BC_EZUSB = 1;
}
// finish off the transfer by setting the handshake bit
EP0CS_EZUSB |= bmHSNAK_EZUSB;
}
void SetupCommand_FX2()
{
WORD addr, len, bc, i;
if (SETUPDAT_FX2[1] == VR_RAM)
{
addr = SETUPDAT_FX2[2]; // Get address and length
addr |= SETUPDAT_FX2[3] << 8;
len = SETUPDAT_FX2[6];
len |= SETUPDAT_FX2[7] << 8;
if(SETUPDAT_FX2[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_FX2 = 0;
EP0BCL_FX2 = 0; // Clear bytecount to allow new data in; also stops NAKing
while(EP0CS_FX2 & bmEPBUSY);
bc = EP0BCL_FX2; // Get the new bytecount
for(i=0; i<bc; i++)
*((BYTE xdata *)addr+i) = *(EP0BUF_FX2+i);
addr += bc;
len -= bc;
}
}
else if(SETUPDAT_FX2[0] == VR_UPLOAD)
{
while(len) // Move requested data through EP0IN
{ // one packet at a time.
if(len < EP0BUFF_SIZE)
bc = len;
else
bc = EP0BUFF_SIZE;
for(i=0; i<bc; i++)
*(EP0BUF_FX2+i) = *((BYTE xdata *)addr+i);
EP0BCH_FX2 = 0;
EP0BCL_FX2 = (BYTE)bc; // Arm endpoint with # bytes to transfer
addr += bc;
len -= bc;
while(EP0CS_FX2 & bmEPBUSY);
}
} // if VR_UPLOAD
} // if VR_RAM
else if (SETUPDAT_FX2[1] == VR_ISFX2)
{
EP0BUF_FX2[0] = 1; // is FX2
EP0BCH_FX2 = 0;
EP0BCL_FX2 = 1;
}
// finish off the transfer by setting the handshake bit
EP0CS_FX2 |= bmHSNAK_FX2;
}
void main()
{
GotSUD = FALSE;
IsFX2 = CheckForFX2();
// Turn on r/w lines for external memory
PORTCCFG_EZUSB |= 0xc0;
// enable USB interrupts
EZUSB_IRQ_ENABLE();
// enable autovector
if (IsFX2)
{
INTSETUP_FX2 = bmAV2EN;
}
else
{
USBBAV_EZUSB |= 1; // enable autovectoring
}
// we only care about SETUP Data Available
if (IsFX2)
{
USBIE_FX2 = bmSUDAV;
}
else
{
USBIEN_EZUSB = bmSUDAV;
}
// enable 8051 interrupts
EA = 1;
while (1)
{
if(GotSUD) // Wait for SUDAV
{
if (IsFX2)
{
SetupCommand_FX2(); // Implement setup command
}
else
{
SetupCommand_EZUSB(); // Implement setup command
}
GotSUD = FALSE; // Clear SUDAV flag
}
}
}
void ISR_Sudav(void) interrupt 0
{
GotSUD = TRUE; // Set flag
EZUSB_IRQ_CLEAR();
if (IsFX2)
{
USBIRQ_FX2 = bmSUDAV;
}
else
{
USBIRQ_EZUSB = bmSUDAV;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -