⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.c

📁 51环境下的FAT及FAT32文件系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -