?? periph.c
字號:
// programs and other OSes.
if ( (
#ifndef NO_WP
(bWriteProtectEnable && !NAND_WP_SWITCH) ||
#endif
bEject) || // Read the (active low) WP switch if it's enabled
(xFerLen2>>1 != (xSector&0x7f)) // BOT: if (dataTransferLen/512 != gSectorcount)
)
{
sensePtr = senseWriteProtected;
stallEP2OUT();
cmd = USBS_FAILED;
break;
}
nWritePages();
cmd = ChkErr();
break;
default:
cmd = IDECommand();
break;
}
sendUSBS(cmd);
LED0_OFF();
}
//-----------------------------------------------------------------------------
// Handle NAND Error report here
//-----------------------------------------------------------------------------
bit ChkErr()
{
if (bErr==0) { dataTransferLen=0; return USBS_PASSED; }
else dataTransferLen = (DWORD)gSectorcount<<9;
if (directionIn)
{
nCopyBlock(); // Correct ECC and remap the block
while( !(P_EP4CS & bmEPEMPTY) ); // stall on the Status
P_EP4CS = bmEPSTALL;
}
return USBS_FAILED;
}
//-----------------------------------------------------------------------------
// Stalls EP2OUT endpoint.
//-----------------------------------------------------------------------------
void stallEP2OUT()
{
// Check to see if stall is needed. If it is, STALL the endpoint.
// After we have set the STALL, make sure we didn't get the last packet while we were STALLing.
WORD x;
if (EP2468STAT & bmEP2EMPTY)
x = 0;
else
x = EP2FIFOBCL + (EP2FIFOBCH << 8) + EP2BC;
// Round up to allow for odd xfer lengths
// if (dataTransferLen > ((x + 1) & 0xfffe))
if (dataTransferLen > x)
{
P_EP2CS |= bmEPSTALL;
EZUSB_Delay(100);
if (P_EP2CS & bmEPSTALL)
x=1234;
// If the host has already cleared the STALL, the EP will be empty here, but we will drop safely through the if()
if (EP2468STAT & bmEP2EMPTY)
x = 0;
else
x = EP2FIFOBCL + (EP2FIFOBCH << 8) + EP2BC;
if (dataTransferLen > x)
{
ResetAndArmEp2(); // Stall no longer needed
P_EP2CS = 0; // Clear stall bit
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void sendUSBS(BYTE passOrFail)
{
while ( ((P_EP4CS & (bmEPFULL|bmEPSTALL) ) ) ); // Wait for an available buffer
ResetAndArmEp2();
// Fill the buffer & send the data back to the host
AUTOPTRL2 = LSB(EP4FIFOBUF);
P_XAUTODAT2 = 'U'; // Believe it or not, this is pretty efficient!
P_XAUTODAT2 = 'S';
P_XAUTODAT2 = 'B';
P_XAUTODAT2 = 'S';
P_XAUTODAT2 = MSB(cbwTagLow);
P_XAUTODAT2 = LSB(cbwTagLow);
P_XAUTODAT2 = MSB(cbwTagHi);
P_XAUTODAT2 = LSB(cbwTagHi);
// have to store LSB first
P_XAUTODAT2 = ((BYTE *)&dataTransferLen)[3]; // "Residue"
P_XAUTODAT2 = ((BYTE *)&dataTransferLen)[2]; // "Residue"
P_XAUTODAT2 = ((BYTE *)&dataTransferLen)[1]; // "Residue"
P_XAUTODAT2 = ((BYTE *)&dataTransferLen)[0]; // "Residue"
P_XAUTODAT2 = passOrFail; // Status
EP4BCH = 0;
EP4BCL = 13;
// Stall the IN endpoint if we're in phase error state.
if (phaseErrorState)
{
while( !(P_EP4CS & bmEPEMPTY) )
;
P_EP4CS = bmEPSTALL;
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void failedIn()
{
// Stall if the host is still expecting data. Make sure
// endpoint is empty before doing the stall.
if (dataTransferLen)
{
if (!bShortPacketSent && SHORT_PACKET_BEFORE_STALL)
{
while( !(P_EP4CS & bmEPEMPTY) )
;
EP4BCH = 0; // Terminate with NULL packet, then STALL. This
EP4BCL = 0; // addresses an issue with the current EHCI driver (1/02)
}
while( !(P_EP4CS & bmEPEMPTY) )
;
P_EP4CS = bmEPSTALL;
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void mymemmovexx(BYTE xdata * dest, BYTE xdata * src, WORD len)
{
AUTOPTR1H = MSB(dest);
AUTOPTR1L = LSB(dest);
while (len--)
P_XAUTODAT1 = *src++;
}
//-----------------------------------------------------------------------------
// 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
{
EZUSB_IRQ_CLEAR();
INT2CLR = bmSUDAV; // Clear SUDAV IRQ
SetupCommand();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ISR_Ures(void) interrupt 0
{
// whenever we get a USB reset, we should revert to full speed mode
wPacketSize = FS_BULK_PACKET_SIZE;
EP4AUTOINLENH = MSB(wPacketSize);
EP4AUTOINLENL = LSB(wPacketSize);
P_FIFORESET = 0x04;
ResetAndArmEp2();
// clear the stall and busy bits that may be set
P_EP2CS = 0; // set EP2OUT to empty and clear stall
P_EP4CS = 0; // set EP4IN to empty and clear stall
// Initialize USB variables to make chapter 9 happy
AlternateSetting = Configuration = 0;
EZUSB_IRQ_CLEAR();
INT2CLR = bmURES; // Clear URES IRQ
if (currentState != UNCONFIGURED)
{
EA = 0;
// force a soft reset after the iret.
softReset();
}
}
//-----------------------------------------------------------------------------
// Timer ISR -- Cannot be placed with the other ISRs because we want the
// compiler to generate the vector.
//-----------------------------------------------------------------------------
void ISRtimer0() interrupt 1
{
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ISR_Susp(void) interrupt 0
{
Sleep = TRUE;
EZUSB_IRQ_CLEAR();
INT2CLR = bmSUSP;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ISR_Highspeed(void) interrupt 0
{
if (EZUSB_HIGHSPEED())
wPacketSize = HS_BULK_PACKET_SIZE;
EP4AUTOINLENH = MSB(wPacketSize);
EP4AUTOINLENL = LSB(wPacketSize);
EZUSB_IRQ_CLEAR();
INT2CLR = bmHSGRANT;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ResetAndArmEp2()
{
// adjust stretch to allow for synchronization delay. We are about
// to do several back to back writes to registers that require a
// synchroniztion delay. Increasing stretch allows us to meet
// the delay requirement. See "Synchroniztion Delay" in the Technical
// Reference Manual for more information
P_FIFORESET = 2;
// we're double-buffered, so we need to arm EP2 two times
P_OUTPKTEND = 0x82;
// Reset the stretch to 0
_nop_(); // this delay is good enough, need only 1 nop
P_OUTPKTEND = 0x82;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -