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

📄 host_811.c

📁 USB for TMS320C5402
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "host_811.h"
/*
 SL811H Modules (major routines only) 

 1) usbXfer()		 handles usd data transfer, SETUP,IN, OUT
 2) ep0Xfer()		 handles endpoint zero control pipe
 3) DataRW()		 handles data endpoint transfer pipe
 4) EnumUsbDev() 	 device enum(HIDHUB), excl. multi-interface
 6) speed_detect() SL811H slave device attachspeed detect
 7) slave_detect() Main loop control between SL811H & EZUSB & GUI
*/


 // xdata variables

//BYTE volatile xdata SL811H_ADDR      _at_         0xFFF6; USB地址口
//BYTE volatile xdata SL811H_DATA      _at_         0xFFF7; USB数据口

BYTE 		xdata 	DBUF[256];		     // at 0x2000 for general descriptors data
BYTE		xdata 	remainder;		     // Remaining byte in a USB transfer
pUSBDEV 	xdata 	uDev[MAX_DEV];	 //Multiple USB devices attributes, Max 5 devices
pDevDesc  	xdata 	pDev;			     //Device descriptor struct
pCfgDesc 	xdata 	pCfg;			      //Configuration descriptor struct
pIntfDesc 	xdata 	pIfc;			    //Interface descriptor struct
pEPDesc 	xdata 	pEnp;			     //Endpoint descriptor struct
pStrDesc 	xdata 	pStr;			    //String descriptor struct


 //Boolean Logic Defines

BOOL  	SLAVE_FOUND;				 //Slave USB device found
BOOL  	SLAVE_ENUMERATED;			// slave USB device enumeration done
BOOL  	FULL_SPEED;					 //Full-Speed = TRUE, Low-Speed = FALSE
BOOL 	BULK_OUT_DONE;				 //Set when EZUSB's OUT1 hostcmd xfer is done
BOOL 	DESC_XFER;					 //Set when there is data for EZUSB's IN1 desc xfer
BOOL 	DATA_XFER;					 //Set when there is data for EZUSB's IN3 data xfer
BOOL 	DATA_XFER_OUT;				 //Set when there is data for EZUSB's OUT3 data xfer
BOOL 	CONFIG_DONE;				 //Set when EZUSB completes its enumeration process.
BOOL 	TIMEOUT_ERR;				 //timeout error during data endpoint transfer
BOOL	DATA_STOP;					 //device unplugged during data transfer
BOOL	DATA_INPROCESS;				// set when we are in a data pipe transfer
BOOL	pLS_HUB;					 //indicate previous command is a LS device on hub

BOOL bData1;


 /*Byte Read from SL811H
 a = register address
 return = data in register
*/
BYTE SL811Read(BYTE a)
{  
	SL811H_ADDR = a;			
	return (SL811H_DATA);
}


/* Byte Write to SL811H
 a = register address
 d = data to be written to this register address
*/

void SL811Write(BYTE a, BYTE d)
{  
	SL811H_ADDR = a;	
	SL811H_DATA = d;
}

/*
 Buffer Read from SL811H
 addr = buffer start address
 s    = return buffer address where data are to be saveread
 c	= buffer data length
*/

void SL811BufRead(BYTE addr, BYTE *s, BYTE c)
{	
	SL811H_ADDR = addr;	
   	while (c--) 
		*s++ = SL811H_DATA;
}

/*
 Buffer Write  to SL811H
 addr = buffer start address
 s    = buffer address where data are to be written
 c	= buffer data length
*/

void SL811BufWrite(BYTE addr, BYTE *s, BYTE c)
{	
	SL811H_ADDR = addr;	
   	while (c--) 
		SL811H_DATA = *s++;
}


 //Swap high and low byte 

WORD WordSwap(WORD input)
{
	return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
}


 //UsbReset during enumeration of device attached directly to SL811HS

void USBReset()
{
	BYTE tmp;
    tmp =  SL811Read(CtrlReg);   
 	  SL811Write(CtrlReg,tmp|0x08);
	  USB_Delay(25);			
    SL811Write(CtrlReg,tmp);    
}


 /*
 usbXfer
 successful transfer = return TRUE
 fail transfer = return FALSE
*/

int usbXfer(BYTE usbaddr, BYTE endpoint, BYTE pid, BYTE iso, WORD wPayload, WORD wLen, BYTE buffer)
{  
	BYTE xdata 	cmd, result, timeout, intr;
	BYTE xdata 	xferLen, bufLen, data0, data1, dataX, addr;
	
	/*------------------------------------------------
	 Default setting for usb trasnfer
	------------------------------------------------*/
	bufLen = dataX = timeout = 0;					//reset all
	data0 = EP0_Buf;								 //DATA0 buffer address
	data1 = data0 + (BYTE)wPayload;					// DATA1 buffer address
	DATA_STOP =	TIMEOUT_ERR = FALSE;				// set default conditions

	/*------------------------------------------------
	 Define data transfer payload
	------------------------------------------------*/
	if (wLen = wPayload)  							// select proper data payload
		xferLen = wPayload;							 //limit to wPayload size 
	else											      //else take  payload len
		xferLen = wLen;									

	/*------------------------------------------------
	 For IN token
	------------------------------------------------*/
	if (pid==PID_IN)								 //for current IN tokens
	{												
		if(FULL_SPEED)								
			cmd = sDATA0_RD;						 //FSFS on Hub, sync to sof
		else										   // LS, no sync to sof for IN
			cmd = DATA0_RD;							
	}
	/*------------------------------------------------
	 For OUT token
	------------------------------------------------*/
	else if(pid==PID_OUT)							 //for OUT tokens
	{  	
		if(xferLen)									    //only when there are	
			SL811BufWrite(data0,buffer,xferLen); 	// data to transfer on USB

		if(FULL_SPEED)								
			cmd = sDATA0_WR;						 //FSFS on Hub, sync to sof
		else										      //LS, no sync to sof for OUT
			cmd = DATA0_WR;							
		                             //implement data toggle
		bData1 = uDev[usbaddr].bData1[endpoint];
        uDev[usbaddr].bData1[endpoint] = (uDev[usbaddr].bData1[endpoint]  0  1); // DataToggle
		if(bData1)
          cmd = 0x40;                               //Set Data1 bit in command
	}
	/8------------------------------------------------
	 For SETUPOUT token
	------------------------------------------------*/
	else											 //for current SETUPOUT tokens
	{  	
		if(xferLen)									 //only when there are	
			SL811BufWrite(data0,buffer,xferLen); 	 //data to transfer on USB

		if(FULL_SPEED)								
			cmd = sDATA0_WR;						 //FSFS on Hub, sync to sof
		else										      //LS, no sync to sof for OUT
			cmd = DATA0_WR;							
	}

	/*------------------------------------------------
	 Isochronous data transfer setting
	------------------------------------------------*/
	if (iso) 
		cmd = ISO_BIT;                     		 //if iso setup ISO mode

	/*------------------------------------------------
	 For EP0's INOUT token data, start with DATA1
	 Control Endpoint0's status stage.
	 For data endpoint, INOUT data, start 
	------------------------------------------------*/
	if (endpoint == 0 && pid != PID_SETUP) 			 //for Ep0's INOUT token
		cmd = 0x40; 								 //always set DATA1

	/*------------------------------------------------
	 Arming of USB data transfer for the first pkt
	------------------------------------------------*/
	SL811Write(EP0Status,((endpoint&0x0F)pid));	 //PID + EP address
	SL811Write(EP0Counter,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

	/*------------------------------------------------
	 Main loop for completing a wLen data trasnfer
	------------------------------------------------*/
	while(TRUE)
	{   
		//---------------Wait for done interrupt------------------
		while(TRUE)												// always ensure requested device is
		{														 //inserted at all time, then you will
			intr = SL811Read(IntStatus);						 //wait for interrupt to be done, and 
			if((intr & USB_RESET)  (intr & INSERT_REMOVE))	 //proceed to parse result from slave 
			{													                  //device.
				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
		{	

			// SETUP TOKEN
			if(pid == PID_SETUP)								// do nothing for SETUPOUT token 
				break;											 //exit while(1) immediately

			 //OUT TOKEN				
			else if(pid == PID_OUT)
			{
				wLen  -= (WORD)xferLen;							 //update remainding wLen value
				bufLen = xferLen;
				if(wLen){
			        uDev[usbaddr].bData1[endpoint] = (uDev[usbaddr].bData1[endpoint]  0  1); // DataToggle
					cmd   ^= 0x40;    								// toggle DATA0DATA1
					dataX++;										 //point to next dataX
					addr    = (dataX & 1)  data1data0; 		 //select next address for data
					xferLen = (BYTE)(wLen=wPayload)  wPayloadwLen;	 //get data length required
					buffer += bufLen;
					SL811BufWrite(addr,buffer,xferLen); 	 //data to transfer on USB
					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
				}
				else
					break;
			}

			// IN TOKEN
			else if(pid == PID_IN)
			{													 //for IN token only
				wLen  -= (WORD)xferLen;						//	 update remainding wLen value
				cmd   ^= 0x40;    								// toggle DATA0DATA1
				dataX++;										// point to next dataX

				/*------------------------------------------------	
				 If host requested for more data than the slave 
				 have, and if the slave's data len is a multiple
				 of its endpoint payload sizelast xferLen. Do 
				 not overwrite data in previous buffer.
				------------------------------------------------*/	
				if(remainder==xferLen)							// empty data detected
					bufLen = 0;									 //do not overwriten previous data
				else											// reset bufLen to zero
					bufLen = xferLen;							// update previous buffer length
				
				/*------------------------------------------------	
				 Arm for next data transfer when requested data 
				 length have not reach zero, i.e. wLen!=0, and
				 last xferlen of data was completed, i.e.
				 remainder is equal to zero, not a short pkt
				------------------------------------------------	*/
				if(!remainder && wLen)							// remainder==0 when last xferLen
				{												 //was all completed or wLen!=0
					addr    = (dataX & 1)  data1data0; 		// select next address for data
					xferLen = (BYTE)(wLen=wPayload)  wPayloadwLen;	 //get data length required
					if (FULL_SPEED)								// sync with SOF transfer
						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
				}				

				/*------------------------------------------------
				 Copy last IN token data pkt from prev transfer
				 Check if there was data available during the
				 last data transfer
				------------------------------------------------*/
				if(bufLen)										
				{	
					SL811BufRead(((dataX&1)data0data1), buffer, bufLen);
					buffer += bufLen;								
				}

				/*------------------------------------------------
				 Terminate on short packets, i.e. remainder!=0
				 a short packet or empty data packet OR when 
				 requested data len have completed, i.e.wLen=0
				 For a LOWSPEED device, the 1st device descp,
				 wPayload is default to 64-byte, LS device will
				 only send back a max of 8-byte device descp,
				 and host detect this as a short packet, and 
				 terminate with OUT status stage
				------------------------------------------------*/
				if(remainder  !wLen)
					break;
			}							
		}
		
		//-------------------------NAK----------------------------
		if (result & EP0_NAK)						//			 NAK Detected
		{														
			if(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

⌨️ 快捷键说明

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