📄 usb.c
字号:
#include "common.h"
#include "usb.h"
unsigned char PassToggleCheckSoftware();
extern XXGFLAGS bdata bXXGFlags; //union XXGFLAGS is defined in common.h
XXGPKG usbstack; //struct XXGPKG is defined in usb.h
//usbstack holds parameters to be passed to low-level functions
extern UINT8 xdata DBUF[SECT_LEN];
//???\|/
USBDEV data uDev;
//pUSBDEV xdata uDev; // Multiple USB devices attributes, Max 5 devices
void usbBufRead(unsigned char *s, unsigned char c)
{
unsigned char i;
unsigned char *addr;
addr = s;
// if(BufStatusAddr&0x01) //bufstatus[0]=1:empty
// {
// Scratch = 0xab;
// }
// else
// {
for(i=0;i<c;i++)
{
ACC = BufAddr;
*addr = ACC;
addr++;
}
// }
}
void usbBufWrite(unsigned char *s, unsigned char c)
{
unsigned char *addr;
addr = s;
if(BufStatusAddr&0x02) //bufstatus[1]=1:full
return;
else
{
while(c)
{
ACC = *addr;
BufAddr = ACC;
addr++;
c--;
}
}
}
//*****************************************************************************************
// USB variables initialization
//*****************************************************************************************
void usbReset(void)
{
unsigned char temp;
temp = SieCtrl;
SieCtrl = temp|0x04; // SE0 reset
DelayMs(20);
SieCtrl = temp;
DelayMs(20); // reset recovery
SieStat0 = 0xff; // clear status regs
SieStat1 = 0xff;
}
//*****************************************************************************************
// usbXfer:
// successful transfer = return TRUE
// fail transfer = return FALSE
//*****************************************************************************************
#define MAX_NAK_CNT 200
static unsigned char ConsecutiveNAKCount = 0;
unsigned char usbXfer(unsigned char endPoint)
{
unsigned char xferLen, cmd;
unsigned char intr, result;
unsigned char devTglSt; // device toggle state
bXXGFlags.DATA_STOP=FALSE;
bXXGFlags.TIMEOUT_ERR=FALSE;
//------------------------------------------------
// Define data transfer payload
//------------------------------------------------
if (usbstack.wLen >= usbstack.wPayload) // select proper data payload
xferLen = usbstack.wPayload; // limit to wPayload size
else // else take < payload len
xferLen = usbstack.wLen;
TxPktlen = xferLen; // data transfer length
// For IN token, simply send IN token
if (usbstack.pid==PID_IN)
{
// BufRst = 0x00;
BufSel = USB2MCU; //src=USB,dest=CPU
BufRst = 0x01; // reset wr ptr
BufRst = 0x00;
cmd = READ;
}
// For OUT token
else if(usbstack.pid==PID_OUT) // for OUT tokens
{
if(xferLen)
{
BufRst = 0x03;
BufRst = 0x00;
BufSel = MCU2USB; //src=CPU,dest=USB
usbBufWrite(usbstack.buffer,xferLen); // data to transfer on USB
if (xferLen < 64)
{
BufRst = 0x03; // flip buffer state for bus read
BufRst = 0x00;
}
}
if (bXXGFlags.bToggle) // DATA0 or DATA1
cmd = WRITE1;
else
cmd = WRITE0;
}
// For SETUP token
else
{
if(xferLen)
{
intr=usbstack.setup.wLength;
usbstack.setup.wValue=WordSwap(usbstack.setup.wValue);
usbstack.setup.wIndex=WordSwap(usbstack.setup.wIndex);
usbstack.setup.wLength=WordSwap(usbstack.setup.wLength);
BufRst = 0x03;
BufRst = 0x00;
BufSel = MCU2USB; //src=CPU,dest=USB
usbBufWrite((unsigned char *)&usbstack.setup,xferLen);
if (xferLen < 64)
{
BufRst = 0x03;
BufRst = 0x00;
}
usbstack.setup.wLength=intr;
}
cmd = SETUP;
}
// here goes the packet.....
SieStat0 = 0xff; // clear status register before each transfer
SieStat1 = 0xff;
TxCtrl = cmd; // Send packet
//------------------------------------------------
// Main loop for completing a wLen data trasnfer
//------------------------------------------------
DelayUs(20); // add some delay here...
ConsecutiveNAKCount = 0;
while(TRUE) //
{
DelayUs(10); // more delay before polling the status.
intr = SieStat0;
if(usbstack.pid==PID_IN)
{
//
// if (intr & PKT_DATA) // got data packet
// {
// SieStat0 = PKT_DATA;
// devTglSt = (intr & DEV_TGL); // store toggle state
//
// }
if (intr & PKT_VLD)
{
ConsecutiveNAKCount = 0;
SieStat0 = PKT_VLD;
#ifdef OLD_CHIP
if(PassToggleCheckSoftware())
#else
if (devTglSt == bXXGFlags.bToggle)
#endif
// if (1) // skip toggle check
{
bXXGFlags.bToggle = ~bXXGFlags.bToggle;
if(xferLen<64)
{
BufRst = 0x03;
BufRst = 0x00;
}
// ready to read data from buffer
usbstack.wLen -= (unsigned int)xferLen;
if(usbstack.wLen==0) // last packet
{
if(!bXXGFlags.bIN_ISR)
usbBufRead(usbstack.buffer, xferLen);
else
BufSel = USB2MP3; //src=USB,dest=MP3
Scratch = 0x0; // kill some time...
Scratch = 0x0;
Scratch = 0x0;
Scratch = 0x0;
if(xferLen<64) // set buffer empty flag
{
BufRst = 0x03;
BufRst = 0x00;
}
else
{
BufRst = 0x01;
BufRst = 0x00;
}
BufSel = USB2MCU; //src=USB,dest=CPU
result = DEV_ACK;
break;
}
else
{
if(!bXXGFlags.bIN_ISR) // actual CPU read
usbBufRead(usbstack.buffer, xferLen);
else
BufSel = USB2MP3; //src=USB,dest=MP3
Scratch = 0x0; // kill some time...
Scratch = 0x0;
Scratch = 0x0;
Scratch = 0x0;
if(xferLen<64)
{
BufRst = 0x03;
BufRst = 0x00;
}
else
{
BufRst = 0x01;
BufRst = 0x00;
}
usbstack.buffer += xferLen;
if (usbstack.wLen >= usbstack.wPayload)
xferLen = usbstack.wPayload;
else
xferLen = usbstack.wLen;
cmd = READ;
BufSel = USB2MCU; //src=USB,dest=CPU
TxPktlen = xferLen;
TxCtrl = cmd;
}
}
else
{
if(xferLen<64) // set buffer empty flag
{
BufRst = 0x03;
BufRst = 0x00;
}
BufSel = USBFLSH; //src=USB,dest=FLUSH
Scratch = 0x0; // kill some time...
Scratch = 0x0;
Scratch = 0x0;
Scratch = 0x0;
if(xferLen<64) // set buffer empty flag
{
BufRst = 0x03;
BufRst = 0x00;
}
else
{
BufRst = 0x01;
BufRst = 0x00;
}
BufSel = USB2MCU; //src=USB,dest=CPU
cmd = READ;
TxCtrl = cmd;
}
}
// else if(intr & PKT_ERR) // got bad packet
// {
// SieStat0 = PKT_ERR;
// BufRst = 0x01; // reset write pointer
// BufRst = 0x00;
// TxCtrl = cmd;
// }
else if(intr & DEV_NAK) // device nak'd IN token
{
SieStat0 = DEV_NAK;
if(ConsecutiveNAKCount < MAX_NAK_CNT)
ConsecutiveNAKCount = ConsecutiveNAKCount + 1;
else
return FALSE;
// P1 = 0xF8;
// P1 = intr;
BufRst = 0x01; // reset write pointer
BufRst = 0x00;
DelayMs(1);
TxCtrl = cmd;
}
else if(intr & DEV_TO) // turnaround time expired
{
// glitch filter, don't need to clear
if (SieStat0 & DEV_TO) // packet is not coming!
{
BufRst = 0x01; // reset write pointer
BufRst = 0x00;
TxCtrl = cmd; // Send command again!
}
}
else if (intr & DEV_STALL)
{
SieStat0 = DEV_STALL;
bXXGFlags.SLAVE_STALLED = TRUE;
break;
}
}
else // pid != PID_IN
{
if(intr & DEV_ACK)
{
result = DEV_ACK;
SieStat0 = DEV_ACK;
break;
}
else if(intr & DEV_TO) // turnaround time expired
{
// SieStat0 = DEV_TO;
if (SieStat0 & DEV_TO) // packet is not coming!
{
BufRst = 0x02; // reset read pointer
BufRst = 0x00;
TxCtrl = cmd; // Send SETUP/OUT again!
}
}
}
}//end of while(TRUE)
if (result == DEV_ACK) // on ACK transmission
{
return TRUE;
} // return OK
return FALSE; // fail transmission
}
//*****************************************************************************************
// Control Endpoint 0's USB Data Xfer
// ep0Xfer, endpoint 0 data transfer
//*****************************************************************************************
unsigned char ep0Xfer(void)
{
TxEpnum = 0x0; // always set end point to zero!!
//----------------------------------------------------
// SETUP token with 8-byte request on endpoint 0
//----------------------------------------------------
usbstack.pid=PID_SETUP;
// BufSel = MCU2USB; // src=CPU, dest=USB;
if (!usbXfer(0))
return FALSE;
usbstack.pid = PID_IN; // default for setup stage
// BufSel = USB2MCU; //src=USB, dest=CPU;
//----------------------------------------------------
// IN or OUT data stage on endpoint 0
//----------------------------------------------------
usbstack.wLen=usbstack.setup.wLength;
if (usbstack.wLen) // if there are data for transfer
{
if (usbstack.setup.bmRequest & 0x80) // IN token
{
usbstack.pid = PID_IN;
bXXGFlags.bToggle=1; // expect data1 from device
// BufSel = USB2MCU; //src=USB,dest=CPU;
if(!usbXfer(0))
return FALSE;
//usbstack.wPayload = 0;
usbstack.pid = PID_OUT;
// BufSel = MCU2USB; //src=CPU,dest=USB;
}
else // OUT token
{
usbstack.pid = PID_OUT;
// BufSel = MCU2USB; //src=CPU,dest=USB;
if(!usbXfer(0))
return FALSE;
usbstack.pid = PID_IN;
// BufSel = USB2MCU; //src=USB,dest=CPU;
}
}
DelayMs(2); // allow device to complete request
//----------------------------------------------------
// Status stage IN or OUT zero-length data packet
//----------------------------------------------------
usbstack.wLen=0;
// uDev.bData1[0] = 0x1; // always data1 from device
bXXGFlags.bToggle=1; // status stage is always Data1
if(!usbXfer(0))
return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -