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

📄 811.c

📁 USB驱动芯片sl811h的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"DSP28_Device.h"

FLAGS   	Flags;
PKG 		usb;
pUSBDEV		uDev;	// Multiple USB devices attributes, Max 5 devices
Uint16		DBUF[BUFFER_LENGTH];

//*****************************************************************************************
// SL811H variables initialization
//*****************************************************************************************
Uint16	SL811Read(Uint16	addr)
		{
			Uint16	val;
			SL811AddrPort = addr;
			val = SL811DataPort;
			val = val & 0x00FF;
			return val;
		}
void	SL811Write(Uint16	addr,Uint16	 val)
		{
			SL811AddrPort = addr;
			SL811DataPort = val;
		}
void	SL811BufRead(Uint16	  addr, Uint16	*Str, Uint16  Counter)
		{
			SL811AddrPort = addr;
			while(Counter--)
				{
					*Str++ = SL811DataPort;
				}	
		}
void	SL811BufWrite(Uint16  addr, Uint16  *Str, Uint16  Counter)
		{
			SL811AddrPort = addr;
			while(Counter--)
				{
					SL811DataPort = *Str++;
				}
		}
Uint16	WordSwap(Uint16	input)
		{
			return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
		}
		
Uint16	LSwapINT16(Uint16	dData1,Uint16	dData2)
		{
    		unsigned int dData;
    		dData = ((dData2<<8)&0xff00)|(dData1&0x00ff);
			return dData;
		}

void 	DelayMs(unsigned int nFactor)
		{
			Uint16	i;
			Uint16	j;
			for(i=0; i<nFactor; i++)
				{
					for(j=0;j<5000;j++)j=j;		          
				}
		}

void 	USBReset(void)
		{
			Uint16	temp;
    		temp=SL811Read(CtrlReg);   
 			SL811Write(CtrlReg,temp|0x08);
			DelayMs(25);
			SL811Write(CtrlReg,temp);    
		}


Uint16	usbXfer(void)
		{
			Uint16	intr,result,remainder,dataX,bufLen,addr,timeout;		
			Uint16	data0,data1,xferLen;
			Uint16	cmd;
			Uint16	out[8];
			
			data0 = EP0_Buf;
			data1 = EP0_Buf + usb.wPayLoad;	
			Flags.bits.DATA_STOP = FALSE;
			Flags.bits.TIMEOUT_ERR = FALSE;
			if (usb.wLen > usb.wPayLoad)
				xferLen = usb.wPayLoad;
			else
				xferLen = usb.wLen;
			if (usb.pid == PID_IN)
				cmd = sDATA0_RD;
			else if (usb.pid == PID_OUT)
				{
					if (xferLen)
						SL811BufWrite(data0,usb.buffer,xferLen);
					cmd = sDATA0_WR;
					Flags.bits.bData1 = uDev.bData1[usb.endpoint];
        			uDev.bData1[usb.endpoint] = (uDev.bData1[usb.endpoint] ? 0 : 1); 
		
					if(Flags.bits.bData1)
          				cmd |= 0x40;                              						
				}
			else{
					if(xferLen)									
						{										
							intr   = usb.setup.wLength;			
							out[0] = usb.setup.bmRequest;
							out[1] = usb.setup.bRequest;
							out[2] = usb.setup.wValue & 0x00FF;
							out[3] = usb.setup.wValue>>8;
							out[4] = usb.setup.wIndex;
							out[5] = usb.setup.wIndex>>8;
							out[6] = usb.setup.wLength;
							out[7] = usb.setup.wLength>>8;
							SL811BufWrite(data0,out,xferLen);
							usb.setup.wLength = intr;
						}
					cmd = sDATA0_WR;							
				}
			if (usb.endpoint == 0 && usb.pid != PID_SETUP)
				cmd = cmd | 0x40;
				
			SL811Write(EP0Status,((usb.endpoint & 0x0F)|usb.pid));	// PID + EP address
			SL811Write(EP0Counter,usb.usbaddr);		// USB address
			SL811Write(EP0Address,data0);			// buffer address, start with "data0"
			SL811Write(EP0XferLen,xferLen);			// data transfer length
			SL811Write(IntStatus,INT_CLEAR); 		// clear interrupt status
			SL811Write(EP0Control,cmd);				// Enable ARM and USB transfer start here
			while(TRUE)
				{   
				while(TRUE)												// always ensure requested device is
					{														// inserted at all time, then you will
						intr = SL811Read(IntStatus);	
						if((intr & USB_RESET) || (intr & INSERT_REMOVE))	// proceed to parse result from slave 
						{													// device.
							Flags.bits.DATA_STOP = TRUE;								// if device is removed, set DATA_STOP
							return FALSE;									// flag true, so that main loop will 
						}													// know this condition and exit gracefully
						if(intr & USB_A_DONE)								
							break;				// interrupt done !!!
					}

				SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
				result 	  = SL811Read(EP0Status);						// read EP0status register
				remainder = SL811Read(EP0Counter);						// remainder value in last pkt xfer

		//-------------------------ACK----------------------------
				if (result & EP0_ACK)									// Transmission ACK
					{	
						if(usb.pid == PID_SETUP)	// SETUP TOKEN								// do nothing for SETUP/OUT token 
							break;											// exit while(1) immediately
						else if(usb.pid == PID_OUT) // OUT TOKEN
							break;						
						else if(usb.pid == PID_IN)	// IN TOKEN
							{							// for IN token only
								usb.wLen  -= xferLen;	// update remainding wLen value
								cmd   ^= 0x40;    		// toggle DATA0/DATA1
								dataX++;				// point to next dataX
								if(remainder==xferLen)	// empty data detected
									bufLen = 0;			// do not overwriten previous data
								else					// reset bufLen to zero
									bufLen = xferLen;	// update previous buffer length
								if(!remainder && usb.wLen)							// remainder==0 when last xferLen
									{												// was all completed or wLen!=0
										addr    = (dataX & 1) ? data1:data0; 		// select next address for data
										xferLen = (usb.wLen>=usb.wPayLoad) ? usb.wPayLoad:usb.wLen;	// get data length required								
										cmd |= 0x20;								// always sync SOF when FS, regardless 
										SL811Write(EP0XferLen, xferLen); 			// select next xfer length
										SL811Write(EP0Address, addr);           	// data buffer addr 
										SL811Write(IntStatus,INT_CLEAR);			// is a LS is on Hub.
										SL811Write(EP0Control,cmd);					// Enable USB transfer and re-arm
									}				
								if(bufLen)										
									{	
										SL811BufRead(((dataX&1)?data0:data1), usb.buffer, bufLen);
										usb.buffer += bufLen;								
									}
								if(remainder || !usb.wLen)
										break;
							}// PID IN							
					}
//-------------------------NAK----------------------------
				if (result & EP0_NAK)									// NAK Detected
					{														
						if(usb.endpoint==0)										// on ep0 during enumeration of LS device
							{													// happen when slave is not fast enough,
								SL811Write(IntStatus,INT_CLEAR);				// clear interrupt status, need to
								SL811Write(EP0Control,cmd);						// re-arm and request for last cmd, IN token
               					result = 0;                                     // respond to NAK status only
							}
						else												// normal data endpoint, exit now !!! , non-zero ep
							break;											// main loop control the interval polling
					}
	
		//-----------------------TIMEOUT--------------------------
				if (result & EP0_TIMEOUT)								// TIMEOUT Detected
					{														
						if(usb.endpoint==0)										// happens when hub enumeration
							{
								if(++timeout >= TIMEOUT_RETRY)
									{	
				   						timeout--;
										break;										// exit on the timeout detected	
									}
								SL811Write(IntStatus,INT_CLEAR);				// clear interrupt status, need to
								SL811Write(EP0Control,cmd);						// re-arm and request for last cmd again
							}
						else												
							{													// all other data endpoint, data transfer 
								Flags.bits.TIMEOUT_ERR = TRUE;								// failed, set flag to terminate transfer
								break;											// happens when data transfer on a device
							}													// through the hub
					}

		//-----------------------STALL----------------------------
				if (result & EP0_STALL)  								// STALL detected
					return TRUE;										// for unsupported request.
																		
		//----------------------OVEFLOW---------------------------
				if (result & EP0_OVERFLOW)  							// OVERFLOW detected
					break;
		//-----------------------ERROR----------------------------
				if (result & EP0_ERROR)  								// ERROR detected
					break;
			}	// end of While(1)
   
			if (result & EP0_ACK) 	// on ACK transmission
				return TRUE;		// return OK

			return FALSE;			// fail transmission
		}

//*****************************************************************************************
// Control Endpoint 0's USB Data Xfer
// ep0Xfer, endpoint 0 data transfer
//*****************************************************************************************
Uint16	ep0Xfer(void)
		{
			usb.endpoint =0;
			usb.pid = PID_SETUP;
			usb.wLen = 8;
			if (!usbXfer()) 
   				return FALSE;
			usb.pid  = PID_IN;
	//----------------------------------------------------
	// IN or OUT data stage on endpoint 0	
	//----------------------------------------------------
			usb.wLen=usb.setup.wLength;
   			if (usb.wLen)											// if there are data for transfer
				{
					if (usb.setup.bmRequest & 0x80)		// host-to-device : IN token
						{
							usb.pid  = PID_IN;				
							if(!usbXfer())
								return FALSE;
							usb.pid  = PID_OUT;
						}
					else{											// device-to-host : OUT token
							usb.pid  = PID_OUT;
							if(!usbXfer())
								return FALSE;
							usb.pid  = PID_IN;
						}
				}
			DelayMs(100);
	//----------------------------------------------------
	// Status stage IN or OUT zero-length data packet
	//----------------------------------------------------
			usb.wLen=0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -