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

📄 transfer.c

📁 zlg/fs源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define TRANSFER_GLOBALS

#include "config.h"



INT8U Control_Setup(	USB_Device_Request *dev_req,
							endpoint_info *epi_ptr)
							
{
	INT8U uc_SetupBuf[8];
	INT8U uc_Data0Addr;
	INT8U uc_Intr;
	INT8U uc_Result;
	INT8U uc_Timeout;
	
	uc_Timeout = 0;
	uc_Data0Addr = EP0_Buf;
	
	uc_SetupBuf[0] = dev_req->bmRequestType;
	uc_SetupBuf[1] = dev_req->bRequest;
	uc_SetupBuf[2] = (INT8U)(dev_req->wValue);
	uc_SetupBuf[3] = (INT8U)(dev_req->wValue>>8);	
	uc_SetupBuf[4] = (INT8U)(dev_req->wIndex);
	uc_SetupBuf[5] = (INT8U)(dev_req->wIndex>>8);
	uc_SetupBuf[6] = (INT8U)(dev_req->wLength);
	uc_SetupBuf[7] = (INT8U)(dev_req->wLength>>8);

	
	SL811BufWrite(uc_Data0Addr, uc_SetupBuf, 8);
	SL811Write(EP0Status,((epi_ptr->endpoint_descriptor.bEndpointAddress&0x0F)|PID_SETUP));						// PID + EP address
	SL811Write(EP0Counter,epi_ptr->dvi_ptr->address);										// USB address
	SL811Write(EP0Address, uc_Data0Addr);													// buffer address, start with "data0"
	SL811Write(EP0XferLen, 8);															// data transfer length
	SL811Write(IntStatus, INT_CLEAR); 														// clear interrupt status
	SL811Write(EP0Control, sDATA0_WR);													// Enable ARM and USB transfer start here	

WaitForOver:
	
	while(1) {
		uc_Intr = SL811Read(IntStatus);							// wait for interrupt to be done, and 
		if((uc_Intr & USB_RESET) || (uc_Intr & INSERT_REMOVE))			// proceed to parse result from slave 
		{													// device.
			return 0xff;										// flag true, so that main loop will 
		}													// know this condition and exit gracefully
		if(uc_Intr & USB_A_DONE)								
			break;											// interrupt done !!!
	}

	SL811Write(IntStatus, INT_CLEAR);
	USB_Delay(50);
	uc_Result = SL811Read(EP0Status);

	if (uc_Result & EP0_ACK) {
		return 0;
	}

	if (uc_Result & EP0_STALL) {
		return 0;
	}
	
	if (uc_Result & EP0_NAK) {
		if (++uc_Timeout >= TIMEOUT_RETRY) {
			return 0xff;
		}
		SL811Write(IntStatus, INT_CLEAR); 
		SL811Write(EP0Control, sDATA0_WR);
		goto WaitForOver;
	}

	if (uc_Result & EP0_TIMEOUT) {
		if (++uc_Timeout >= TIMEOUT_RETRY) {
			return 0xff;
		}
		SL811Write(IntStatus, INT_CLEAR); 
		SL811Write(EP0Control, sDATA0_WR);
		goto WaitForOver;
	}

	// EP0_OVERFLOW, EP0_ERROR, EP0_SEQUENCE, EP0_SETUP
	return 0xff;			
}



	


INT8U Control_Out(	INT8U *data_ptr,
						INT16U size,
						endpoint_info *epi_ptr)
{
	INT8U uc_Data0Addr;
	INT8U uc_Data1Addr;
	INT8U uc_TranLen;
	INT8U uc_UnTranLen;
	INT8U uc_Cmd;
	INT8U uc_Result;
	INT8U uc_Timeout;
	INT8U uc_Intr;
	//INT8U uc_BufLen;
	INT8U uc_Addr;
	INT8U uc_Toggle;
	uc_Timeout = 0;
	uc_Toggle = 1;
	uc_Data0Addr = EP0_Buf;
	uc_Data1Addr = uc_Data0Addr+ epi_ptr->endpoint_descriptor.wMaxPacketSize;
	
	uc_Addr = uc_Data1Addr;
	uc_TranLen = m_MIN(epi_ptr->endpoint_descriptor.wMaxPacketSize, size);
	uc_Cmd = sDATA0_WR|0x40;
	SL811BufWrite(uc_Addr, data_ptr, uc_TranLen);
	SL811Write(EP0Status, ((epi_ptr->endpoint_descriptor.bEndpointAddress&0x0F)|PID_OUT));					// PID + EP address
	SL811Write(EP0Counter, epi_ptr->dvi_ptr->address);									// USB address
	SL811Write(EP0Address, uc_Addr);												// buffer address, start with "data0"
	SL811Write(EP0XferLen, uc_TranLen);												// data transfer length
	SL811Write(IntStatus,INT_CLEAR); 													// clear interrupt status
	SL811Write(EP0Control, uc_Cmd);														// Enable ARM and USB transfer start here
	
WaitForOver:
	
	while(1) {
		uc_Intr = SL811Read(IntStatus);							// wait for interrupt to be done, and 
		if((uc_Intr & USB_RESET) || (uc_Intr & INSERT_REMOVE))			// proceed to parse result from slave 
		{													// device.
			return 0xff;										// flag true, so that main loop will 
		}													// know this condition and exit gracefully
		if(uc_Intr & USB_A_DONE)								
			break;											// interrupt done !!!
	}

	SL811Write(IntStatus, INT_CLEAR);
	USB_Delay(50);
	uc_Result = SL811Read(EP0Status);
	uc_UnTranLen = SL811Read(EP0Counter);

	if (uc_Result & EP0_ACK) {
		size -= uc_TranLen;
		data_ptr += uc_TranLen;
		uc_Toggle = !uc_Toggle;
		if (size) {
			uc_Addr = (uc_Toggle&1)?uc_Data1Addr:uc_Data0Addr;
			uc_TranLen = m_MIN(size, epi_ptr->endpoint_descriptor.wMaxPacketSize);
			uc_Cmd ^= 0x40;
			uc_Cmd |= 0x20;
			SL811BufWrite(uc_Addr, data_ptr, uc_TranLen);
			SL811Write(EP0XferLen, uc_TranLen);
			SL811Write(EP0Address, uc_Addr);
			SL811Write(IntStatus, INT_CLEAR);
			SL811Write(EP0Control, uc_Cmd);
			goto WaitForOver;
		}
		else {
			return 0;
		}
		
	}
	
	if (uc_Result & EP0_STALL) {
		return 0;
	}
	
	if (uc_Result & EP0_NAK) {
		if (++uc_Timeout >= TIMEOUT_RETRY) {
			return 0xff;
		}
		SL811Write(IntStatus, INT_CLEAR); 
		SL811Write(EP0Control, sDATA0_WR);
		goto WaitForOver;
	}

	if (uc_Result & EP0_TIMEOUT) {
		if (++uc_Timeout>= TIMEOUT_RETRY) {
			return 0xff;
		}
		SL811Write(IntStatus, INT_CLEAR); 
		SL811Write(EP0Control, sDATA0_WR);
		goto WaitForOver;
	}

	// EP0_OVERFLOW, EP0_ERROR, EP0_SEQUENCE, EP0_SETUP
	return 0xff;			
}


INT8U Control_In(	INT8U *data_ptr,
						INT16U size,
						endpoint_info *epi_ptr)
{
	INT8U uc_Data0Addr;
	INT8U uc_Data1Addr;
	INT8U uc_TranLen;
	INT8U uc_UnTranLen;
	INT8U uc_Cmd;
	INT8U uc_Result;
	INT8U uc_Timeout;
	INT8U uc_Intr;
	//INT8U uc_BufLen;
	INT8U uc_Addr;
	INT8U uc_Toggle;
	uc_Timeout = 0;
	uc_Toggle = 1;
	uc_Data0Addr = EP0_Buf;
	uc_Data1Addr = uc_Data0Addr+ epi_ptr->endpoint_descriptor.wMaxPacketSize;
	
	uc_Addr = uc_Data1Addr;
	uc_TranLen = m_MIN(epi_ptr->endpoint_descriptor.wMaxPacketSize, size);
	uc_Cmd = sDATA0_RD|0x40;
	SL811Write(EP0Status, ((epi_ptr->endpoint_descriptor.bEndpointAddress&0x0F)|PID_IN));	// PID + EP address
	SL811Write(EP0Counter, epi_ptr->dvi_ptr->address);									// USB address
	SL811Write(EP0Address, uc_Addr);												// buffer address, start with "data0"
	SL811Write(EP0XferLen, uc_TranLen);												// data transfer length
	SL811Write(IntStatus,INT_CLEAR); 													// clear interrupt status
	SL811Write(EP0Control, uc_Cmd);														// Enable ARM and USB transfer start here
	
WaitForOver:
	
	while(1) {
		uc_Intr = SL811Read(IntStatus);							// wait for interrupt to be done, and 
		if((uc_Intr & USB_RESET) || (uc_Intr & INSERT_REMOVE))			// proceed to parse result from slave 
		{													// device.
			return 0xff;										// flag true, so that main loop will 
		}													// know this condition and exit gracefully
		if(uc_Intr & USB_A_DONE)								
			break;											// interrupt done !!!
	}

	SL811Write(IntStatus, INT_CLEAR);
	USB_Delay(50);
	uc_Result = SL811Read(EP0Status);
	uc_UnTranLen = SL811Read(EP0Counter);

	if (uc_Result & EP0_ACK) {
		SL811BufRead(((uc_Toggle&1)?uc_Data1Addr:uc_Data0Addr), data_ptr, uc_TranLen);
		data_ptr += uc_TranLen;
		size -= uc_TranLen;
		uc_Toggle = !uc_Toggle;
		if (size) {
			uc_Addr = (uc_Toggle&1)?uc_Data1Addr:uc_Data0Addr;
			uc_TranLen = m_MIN(size, epi_ptr->endpoint_descriptor.wMaxPacketSize);
			uc_Cmd ^= 0x40;
			uc_Cmd |= 0x20;
			SL811Write(EP0XferLen, uc_TranLen);
			SL811Write(EP0Address, uc_Addr);
			SL811Write(IntStatus, INT_CLEAR);
			SL811Write(EP0Control, uc_Cmd);
			goto WaitForOver;
		}
		else {
			return 0;
		}
		
	}
	
	if (uc_Result & EP0_STALL) {
		return 0;
	}
	
	if (uc_Result & EP0_NAK) {
		if (++uc_Timeout >= TIMEOUT_RETRY) {
			return 0xff;
		}
		SL811Write(IntStatus, INT_CLEAR); 
		SL811Write(EP0Control, sDATA0_WR);
		goto WaitForOver;
	}

	if (uc_Result & EP0_TIMEOUT) {
		if (++uc_Timeout>= TIMEOUT_RETRY) {
			return 0xff;
		}
		SL811Write(IntStatus, INT_CLEAR); 
		SL811Write(EP0Control, sDATA0_WR);
		goto WaitForOver;
	}

	// EP0_OVERFLOW, EP0_ERROR, EP0_SEQUENCE, EP0_SETUP
	return 0xff;		
}

INT16U Control_Transfer(	USB_Device_Request	*dev_req, 
							device_instance *dvi_ptr, 
							INT8U *data_ptr )
{

⌨️ 快捷键说明

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