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

📄 host_811.c

📁 基于Embest开发环境
💻 C
📖 第 1 页 / 共 3 页
字号:
		remainder = SL811Read(EP0Counter);						// remainder value in last pkt xfer
        //Uart_Printf("remainder=%x\n",remainder);
		//-------------------------ACK----------------------------
		if (result & EP0_ACK)									// Transmission ACK
		{	

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

			// OUT TOKEN				
			else if(pid == PID_OUT)
			{
				wLen  -= (WORD)xferLen;							// update remainding wLen value
				bufLen = xferLen;										//记录buffer中数据传送到哪个位子了
				if(wLen){														//如果数据没发送完
			        uDev[usbaddr].bData1[endpoint] = (uDev[usbaddr].bData1[endpoint] ? 0 : 1); // DataToggle
					cmd   ^= 0x40;    								// toggle DATA0/DATA1//~~data0/data1选择位取反
					dataX++;										// point to next dataX
					addr    = (dataX & 1) ? data1:data0; 		// select next address for data
					xferLen = (BYTE)(wLen>=wPayload) ? wPayload:wLen;	// 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 DATA0/DATA1
				//Uart_Printf("wLen=%x\n",wLen);
				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 size/last xferLen. Do 
				// not overwrite data in previous buffer.
				//------------------------------------------------	
				if(remainder==xferLen)							// empty data detected
							//~~remainder=ep0xferlen-实际接收到的数据,如果remaidner==xferlen则
							//~~发送的数据等于0,那么buflen就应该为0
				    {//Uart_Printf("remainder=%x",remainder);
					bufLen = 0;		}							// do not overwriten previous data}
				else											// reset bufLen to zero
					{bufLen = xferLen;							// update previous buffer length
				    //Uart_Printf("remainder=%x",remainder);
				    }
				//------------------------------------------------	
				// 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
				   //~~如果remaider为0(接收到的数据为ep0xferlen),并且wlen不为0(还有要接收的数据)
				{												// was all completed or wLen!=0
					addr    = (dataX & 1) ? data1:data0; 		// select next address for data
					xferLen = (BYTE)(wLen>=wPayload) ? wPayload:wLen;	// 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
				//~~把811缓存里面的数据搬移到buffer里面-----------
				if(bufLen)										
				{	
					SL811BufRead(((dataX&1)?data0:data1), buffer, bufLen);
					buffer += bufLen;								
				}
				//Uart_Printf("remainder=%x\n",remainder);
				//------------------------------------------------
				// 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
		{														
			if(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 
				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
			break;										// 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
//~~完成控制传输***************************************************************************

int ep0Xfer(BYTE usbaddr, WORD payload, pSetupPKG setup, BYTE *pData)
{
	BYTE  	pid  = PID_IN;				//~~xdata去掉//~~pid用于记录“状态信息步骤”的令牌包
	//WORD  	wLen = WordSwap(setup->wLength);//??? swap back for correct length//~~xdata去掉
	WORD  	wLen = (setup->wLength);
	//Uart_Printf("%x \n",wLen); /////.....................GC
	BYTE  	ep0 = 0;
	BYTE    *set=(BYTE*)setup;						// always endpoint zero//~~xdata去掉
	//Uart_Printf("%x,%x,%x,%x,%x\n",setup->bmRequest,setup->bRequest,setup->wValue,setup->wIndex,setup->wLength);
//Uart_Printf("%x,%x,%x,%x,%x,%x,%x,%x\n",*(set)++,*(set++),*(set++),*(set++),*(set++),*(set++),*(set++),*(set++));			
	//----------------------------------------------------
	// SETUP token with 8-byte request on endpoint 0
	//----------------------------------------------------
	if (!usbXfer(usbaddr, ep0, PID_SETUP, 0, payload, 8, (BYTE*)setup)) 
   		return FALSE;

	//----------------------------------------------------
	// IN or OUT data stage on endpoint 0	
	//----------------------------------------------------
   	//Uart_Printf("%x,%x,%x,%x,%x,%x,%x,%x\n",setup->bmRequest,setup->bRequest,setup->wValue,setup->wIndex,setup->wLength,usbaddr,ep0,payload);
   	if (wLen)											// if there are data for transfer
	{
		if (setup->bmRequest & 0x80)					// host-to-device : IN token//~~错了吧,设备到主机吧
		{
			pid  = PID_OUT;		//~~为了配合“状态信息步骤”中,主机读是out事务,主机写是in事务
	//Uart_Printf("%x\n",wLen);		
			if(!usbXfer(usbaddr, ep0, PID_IN, 0, payload, wLen, pData))
				return FALSE;
			payload = 0;		//~~为了“状态信息步骤”中主机发送0长度的数据包
		}
		else											// device-to-host : OUT token
   		{							
			if(!usbXfer(usbaddr, ep0, PID_OUT, 0, payload, wLen, pData))
				return FALSE;
		}
	}

	//----------------------------------------------------
	// Status stage IN or OUT zero-length data packet
	//----------------------------------------------------
	if(!usbXfer(usbaddr, ep0, pid, 0, payload, 0, NULL))
		return FALSE;

	return TRUE;											
}


//*****************************************************************************************
// Control endpoint//~~控制传输终极函数
//*****************************************************************************************
int VendorCmd(BYTE usbaddr,BYTE bReq,BYTE bCmd,WORD wValue,WORD wIndex,WORD wLen,BYTE *pData)
{ 
    SetupPKG	setup;
    //struct asdf  abcd;
    //att	attri;
    //Uart_Printf("%d\n",sizeof(abcd));
    //Uart_Printf("%d\n",sizeof(struct asdf));
    //SetupPKG  *setup=(SetupPKG*)malloc(sizeof(SetupPKG));		//~~xdata去掉
    //Uart_Printf("%d\n",sizeof(SetupPKG));
    //Uart_Printf("%d\n",sizeof(setup));
    //Uart_Printf("%d\n",sizeof(attri));
    //if(malloc(sizeof(pSetupPKG))==NULL)
    //	{	Uart_Printf("not enough to allocate for the setup!\n");
    //		exit(1);
    //	}
    setup.bmRequest  = bReq;
    setup.bRequest   = bCmd;
    setup.wValue     = wValue;
    setup.wIndex     = wIndex;
    //setup.wLength    = WordSwap(wLen);
    setup.wLength    = (wLen);
    //BYTE *setu=(BYTE*)setup;
//Uart_Printf("%x,%x,%x,%x,%x\n",bReq,bCmd,wValue,wIndex,wLen);
//Uart_Printf("%x,%x,%x,%x,%x,%x,%x,%x\n",*(BYTE*)&setup,*((BYTE*)&setup+1),*((BYTE*)&setup+2),*((BYTE*)&setup+3),*((BYTE*)&setup+4),*((BYTE*)&setup+5),*((BYTE*)&setup+6),*((BYTE*)&setup+7));
//Uart_Printf("%x,%x,%x,%x,%x\n",setup.bmRequest,setup.bRequest,setup.wValue,setup.wIndex,setup.wLength);
   	return ep0Xfer(usbaddr, uDev[usbaddr].wPayLoad[0], &setup, pData);
}

//*****************************************************************************************
// Set Device Address : 
//*****************************************************************************************
int SetAddress(WORD addr)
{	

	return VendorCmd(0,0,SET_ADDRESS,addr, 0, 0, NULL);
	
}

//*****************************************************************************************
// Set Device Configuration : 
//*****************************************************************************************
int Set_Configuration(BYTE usbaddr, WORD wVal)	//~~wval是bConfigurationValue字段的值

⌨️ 快捷键说明

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