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

📄 host_811.c

📁 基于Embest开发环境
💻 C
📖 第 1 页 / 共 3 页
字号:
//#include "host_811.h"
#include "44b.h"
#include <stdlib.h>

#include "USB_SYS.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(HID/HUB), excl. multi-interface
// 6) speed_detect(): SL811H slave device attach/speed detect
// 7) slave_detect(): Main loop control between SL811H & EZUSB & GUI


//*****************************************************************************************
//variables
//*****************************************************************************************
//
BYTE 		 	DBUF[512];		// at 0x2000 for general descriptors data//~~~做什么用的?
BYTE		 	remainder;		// Remaining byte in a USB transfer
pUSBDEV 	 	uDev[MAX_DEV];	// Multiple USB devices attributes, Max 5 devices//~~Max 2 吧?
pDevDesc  	 	pDev;			// Device descriptor struct
pCfgDesc 	 	pCfg;			// Configuration descriptor struct
pIntfDesc 	 	pIfc;			// Interface descriptor struct
pEPDesc 	 	pEnp;			// Endpoint descriptor struct
pStrDesc 	 	pStr;			// String descriptor struct

//*****************************************************************************************
// Boolean Logic Defines//~~arm不支持布尔类型,用byte类型代替
//*****************************************************************************************
BYTE  	SLAVE_FOUND;				// Slave USB device found
BYTE  	SLAVE_ENUMERATED;			// slave USB device enumeration done
BYTE  	FULL_SPEED;					// Full-Speed = TRUE, Low-Speed = FALSE
BYTE 	BULK_OUT_DONE;				// Set when EZUSB's OUT1 hostcmd xfer is done
BYTE 	DESC_XFER;					// Set when there is data for EZUSB's IN1 desc xfer
BYTE 	DATA_XFER;					// Set when there is data for EZUSB's IN3 data xfer
BYTE 	DATA_XFER_OUT;				// Set when there is data for EZUSB's OUT3 data xfer
BYTE 	CONFIG_DONE;				// Set when EZUSB completes its enumeration process.
BYTE 	TIMEOUT_ERR;				// timeout error during data endpoint transfer
BYTE	DATA_STOP;					// device unplugged during data transfer
BYTE	DATA_INPROCESS;				// set when we are in a data pipe transfer
BYTE	pLS_HUB;					// indicate previous command is a LS device on hub

BYTE   bData1;					//~~标识是data0还是data1


//*****************************************************************************************
// 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 save/read
// c	= buffer data length
//*****************************************************************************************

void SL811BufRead(BYTE addr, BYTE *s, BYTE c)
{	
	SL811H_ADDR = addr;	
   	while (c--) 
   		{
   		USB_Delay(1);
		*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--) 
		{
		USB_Delay(1);
		SL811H_DATA = *s++;}
}


//*****************************************************************************************
// UsbReset during enumeration of device attached directly to SL811HS
//*****************************************************************************************

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

//*****************************************************************************************
// usbXfer:
// successful transfer = return TRUE
// fail transfer = return FALSE
// 此函数完成setup/in/out事务的传输;   相当重要的usb 传输函数
//*****************************************************************************************


int usbXfer(BYTE usbaddr, BYTE endpoint, BYTE pid, BYTE iso, WORD wPayload, WORD wLen, BYTE *buffer)
{  
	//~~usbaddr设备号(udev的数组元素标号),endpoint是端点号,pid是包标识符
	//~~wlen是发送接收数据长度,buffer是数据缓冲区,wpayload是最大载荷,是811中缓冲区长度
	
	BYTE  	cmd, result, timeout, intr;		
	//~~cmd写给EP0Control的值,result是ep0中断后EP0Status的值,intr是读取IntStatus的值
	
	BYTE  	xferLen, bufLen, data0, data1, dataX, addr;		//~~去掉xdata
	//~~xferlen是每次实际传送的数据长度,data0/1是811中data0/1的缓冲区地址,
	//~~buflen记录buffer中数据传送到哪个位子了
	//~~addr记录第二次以后的传送是data0的buffer还是data1的buffur
	//~~datax是帮助addr确定本次传送是data0的buffer中的数据还是data1的buffer中的数据
	
	//------------------------------------------------
	// 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//~~本来为bool类型

	//------------------------------------------------
	// 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;	// FS/FS on Hub, sync to sof//~~原来为sDATA0_RD
		else										// LS, no sync to sof for IN
			cmd = DATA0_RD;	
			//Uart_Printf("%x\n",cmd);						
	}
	//------------------------------------------------
	// 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;	// FS/FS on Hub, sync to sof//~~原来为sDATA0_WR
		else										// LS, no sync to sof for OUT
			cmd = DATA0_WR;							
		// implement data toggle
		bData1 = uDev[usbaddr].bData1[endpoint];//~~bdata1是bool型,标示data0还是data1
    uDev[usbaddr].bData1[endpoint] = (uDev[usbaddr].bData1[endpoint] ? 0 : 1); // DataToggle
		if(bData1)
          cmd |= 0x40;                              // Set Data1 bit in command
	}
	//------------------------------------------------
	// For SETUP/OUT token
	//------------------------------------------------
	else											// for current SETUP/OUT tokens
	{  	
		if(xferLen)	
		SL811BufWrite(data0,buffer,xferLen); 	// data to transfer on USB
		
		if(FULL_SPEED)								
			cmd = sDATA0_WR;		// FS/FS on Hub, sync to sof//~~原来为sDATA0_WR
		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 IN/OUT token data, start with DATA1
	// Control Endpoint0's status stage.
	// For data endpoint, IN/OUT data, start ????
	//------------------------------------------------
	if (endpoint == 0 && pid != PID_SETUP) 			// for Ep0's IN/OUT token
				//~~端点0时说明是控制传输,并且不是setup包,那么肯定先传输data1
		cmd |= 0x40; 								// always set DATA1
        //Uart_Printf("%x\n",cmd);
	//------------------------------------------------
	// 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
    //Uart_Printf("%x\n",SL811Read(EP0Control));
	//------------------------------------------------
	// 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 
			//Uart_Printf("%x",intr);
			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);
		//Uart_Printf("%x\n",result);						// read EP0status register

⌨️ 快捷键说明

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