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

📄 hc_otg.c

📁 一个USB主机核的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************
*                      MT View Silicon Tech. Inc.
*
*    Copyright 2007, MT View Silicon Tech. Inc., ShangHai, China
*                    All rights reserved.
*
*
* Filename:      	hc_otg.c
*
* Programmer:    	Grey
*
* Created: 	 		01/xx/2008
*
* Description: 		usb host controller for otg core
*					
*              
*****************************************************************/

#include "hc_otg.h"
#include <string.h>

HC 		XDATA	gHc[MAX_HC_NUM];
BYTE	XDATA	gHcMap = 0;

/*---------------------------------HCD transfer control--------------------------------*/
/*
 *	setup transaction
 *	send setup packet and check response
 */
extern BYTE
HcSetupTransaction(
	HC_ED			*ed,
	BYTE			*dat,
	WORD			length	
	)
{
	WORD	DATA	temp;
	WORD	DATA	to;

	/* set function address */
	WriteOTGReg8(otg_CommonUSB_FAddr, ed->FuncAddr);
	/* set endpoint number index */
	WriteOTGReg8(otg_CommonUSB_Index, ed->Ep->Index);

	/* load data into FIFO */
	LoadFIFOData((BYTE *)&otg_EndpointFIFO[0], dat, length);
	
	/* send setup packet */
	SetBitOTGReg16(otg_IndexedCSR_CSR0, (CSR0_hrw_SetupPkt | CSR0_hrs_TxPktRdy));		/* note: these two bit must be set together */

	/* Wait EndPoint 0 Tx interrupt */
	to = TRANSACTION_TIME_OUT;
	while(to)
	{
		temp = ReadOTGReg16(otg_IndexedCSR_CSR0);
		if ((temp & CSR0_hrs_TxPktRdy) == 0)
			break;
		to--;
	}/* end while */
	if (to == 0)
		return DEVICE_NOT_RESPONDING;

	if ((temp & CSR0_hrc_RxStall) != 0)
	{
		ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_RxStall);	/* get STALL response */
		return STALL;
	}
	else if ((temp & CSR0_hrc_Error) != 0)
	{
		ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_Error);		/* get ERROR response */	
		return ERR;
	}
	else if ((temp & CSR0_hrc_NAKTimeout) != 0)
	{
		ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_NAKTimeout);		/* get NAK timeoue response */
		return NAK_TIME_OUT;
	}
	else
	{
		return NO_ERROR;			/* no STALL, ERROR, NAKTimeout */
	}
}


/*
 *	control in transaction
 *	receive control transfer data packets and zero data status packet
 */
extern BYTE
HcCtrlInTransaction(
	HC_ED			*ed,
	BYTE			*dat,
	WORD			*length
	)
{
	WORD	DATA	temp;
	WORD	DATA	remainLength;
	WORD	DATA	to;

	/* set function address */
	WriteOTGReg8(otg_CommonUSB_FAddr, ed->FuncAddr);
	/* set endpoint number index */
	WriteOTGReg8(otg_CommonUSB_Index, ed->Ep->Index);

	if (dat == NULL)	/* zero data in for status packet */
	{
		SetBitOTGReg16(otg_IndexedCSR_CSR0, (CSR0_hrw_StatusPkt | CSR0_hrw_ReqPkt));		/* set setup and status bit */
		/* wait Endpoint 0 Rx interrupt */
		to = TRANSACTION_TIME_OUT;
		while(to)
		{
			temp = ReadOTGReg16(otg_IndexedCSR_CSR0);
			if ((temp & CSR0_hrc_RxPktRdy) != 0)
				break;
			to--;
		}/* end while */
		if (to == 0)
			return DEVICE_NOT_RESPONDING;

		if ((temp & CSR0_hrc_RxStall) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_RxStall);		/* get STALL response */
			return STALL;
		}
		else if ((temp & CSR0_hrc_Error) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_Error);		/* get ERROR response */
			return ERR;
		}
		else if ((temp & CSR0_hrc_NAKTimeout) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_NAKTimeout);		/* get NAK timeoue response */
			return NAK_TIME_OUT;
		}
		else
		{
			ClrBitOTGReg16(otg_IndexedCSR_CSR0, (CSR0_hrw_StatusPkt | CSR0_hrc_RxPktRdy));
			return NO_ERROR;				/* no STALL, ERROR, NAKTimeout */
		}
	}/* end if (dat != NULL) */
	else
	{
		remainLength = *length;
		while(remainLength)	
		{
			SetBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrw_ReqPkt);		/* set request packet, start IN phase */
			/* wait Endpoint 0 Rx interrupt */
			to = TRANSACTION_TIME_OUT;
			while(to)
			{
				temp = ReadOTGReg16(otg_IndexedCSR_CSR0);
				if ((temp & CSR0_hrc_RxPktRdy) != 0)
					break;
				to--;
			}/* end while */
			if (to == 0)
				return DEVICE_NOT_RESPONDING;

			if ((temp & CSR0_hrc_RxStall) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_RxStall);		/* get STALL response */
				return STALL;
			}
			else if ((temp & CSR0_hrc_Error) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_Error);		/* get ERROR response */
				return ERR;
			}
			else if ((temp & CSR0_hrc_NAKTimeout) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_NAKTimeout);		/* get NAK timeoue response */
				return NAK_TIME_OUT;
			}
			else
			{
				temp = ReadOTGReg16(otg_IndexedCSR_Count0);
				UnloadFIFOData((BYTE *)&otg_EndpointFIFO[0], dat, temp);
				ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_RxPktRdy);
				remainLength -= temp;
				dat += temp;
				if (temp < ed->MaxPacketSize)
					break;
			}
		}/* end while */	
		*length -= remainLength;
		return NO_ERROR;				/* no STALL, ERROR, NAKTimeout */ 
	}/* end else */
}


/*
 *	control out transaction
 *	send control transfer data packets and zero data status packet
 */
extern BYTE
HcCtrlOutTransaction(
	HC_ED			*ed,
	BYTE			*dat,
	WORD			length
	)
{
	WORD	DATA	temp;
	WORD	DATA	opLength;
	WORD	DATA	to;

	/* set function address */
	WriteOTGReg8(otg_CommonUSB_FAddr, ed->FuncAddr);
	/* set endpoint number index */
	WriteOTGReg8(otg_CommonUSB_Index, ed->Ep->Index);

	if (dat == NULL)		/* zero data out for status packet */
	{
		SetBitOTGReg16(otg_IndexedCSR_CSR0, (CSR0_hrw_StatusPkt | CSR0_hrs_TxPktRdy));		/* set OUT and status bit */
		/* wait Endpoint 0 Tx interrupt */
		to = TRANSACTION_TIME_OUT;
		while(to)
		{
			temp = ReadOTGReg16(otg_IndexedCSR_CSR0);
			if ((temp & CSR0_hrs_TxPktRdy) == 0)
				break;
			to--;
		}/* end while */
		if (to == 0)
			return DEVICE_NOT_RESPONDING;

		if ((temp & CSR0_hrc_RxStall) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_RxStall);		/* get STALL response */
			return STALL;
		}
		else if ((temp & CSR0_hrc_Error) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_Error);		/* get ERROR response */
			return ERR;
		}
		else if ((temp & CSR0_hrc_NAKTimeout) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_NAKTimeout);		/* get NAK timeoue response */
			return NAK_TIME_OUT;
		}
		else
		{
			return NO_ERROR;			/* no STALL, ERROR, NAKTimeout */
		}
	}
	else
	{
		while(length)
		{
			if (length < ed->MaxPacketSize)
				opLength = length;
			else
				opLength = ed->MaxPacketSize;
		
			/* load data into endpoint0 FIFO */
			LoadFIFOData((BYTE *)&otg_EndpointFIFO[0], dat, opLength);
			/* set OUT bit */
			SetBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrs_TxPktRdy);

			/* wait Endpoint 0 Tx interrupt */
			to = TRANSACTION_TIME_OUT;
			while(to)
			{
				temp = ReadOTGReg16(otg_IndexedCSR_CSR0);
				if ((temp & CSR0_hrs_TxPktRdy) == 0)
					break;
				to--;
			}/* end while */
			if (to == 0)
				return DEVICE_NOT_RESPONDING;

			if ((temp & CSR0_hrc_RxStall) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_RxStall);		/* get STALL response */
				return STALL;
			}
			else if ((temp & CSR0_hrc_Error) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_Error);		/* get ERROR response */
				return ERR;
			}
			else if ((temp & CSR0_hrc_NAKTimeout) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hrc_NAKTimeout);		/* get NAK timeoue response */
				return NAK_TIME_OUT;
			}
			else
			{
				length -= opLength;
				dat += opLength;
			}
		}/* end while */
		return NO_ERROR;			/* no STALL, ERROR, NAKTimeout */
	}/* end else */
}


/*
 *	bulk in transaction
 *	receive bulk transfer data packets, DMA option
 */
extern BYTE
HcBulkInTransaction(
	HC_ED			*ed,
	BYTE			*dat,
	WORD			*length,
	BOOL			isUseDMA
	)
{
	WORD	DATA	temp;
	DWORD	DATA	temp1;
	WORD	DATA	remainLength;
	WORD	DATA	to;

	/* set function address */
	WriteOTGReg8(otg_CommonUSB_FAddr, ed->FuncAddr);
	/* set endpoint number index */
	WriteOTGReg8(otg_CommonUSB_Index, ed->Ep->Index);

	if (!isUseDMA)		/* using DMA control data transfer */
	{
		remainLength = *length;
		while(remainLength)
		{
			SetBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrw_ReqPkt);			/* send first in token */
			/* Wait EndPoint Rx interrupt */
			to = TRANSACTION_TIME_OUT;
			while(to)
			{
				temp = ReadOTGReg16(otg_IndexedCSR_RxCSR);
				if ((temp & RxCSR_hrc_RxPktRdy) != 0)
					break;
				to--;
			}/* end while */	
			if (to == 0)
				return DEVICE_NOT_RESPONDING;

			if ((temp & RxCSR_hrc_RxStall) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_RxStall);		/* get STALL response */
				return STALL;
			}
			else if ((temp & RxCSR_hrc_Error) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_Error);		/* get ERROR response */
				return ERR;
			}
			else if ((temp & RxCSR_hrc_DataError_NAKTimeout) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_DataError_NAKTimeout);		/* get NAK timeoue response */
				return NAK_TIME_OUT;
			}		
			else
			{
				temp = ReadOTGReg16(otg_IndexedCSR_RxCount);
				UnloadFIFOData((BYTE *)&otg_EndpointFIFO[ed->Ep->Index], dat, temp);
				ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_RxPktRdy);
				remainLength -= temp;
				dat += temp;
				if (temp < ed->MaxPacketSize)
					break;
			}
		}/* end while */
		*length -= remainLength;
		return NO_ERROR;
	}/* end if (!isUseDMA) */
	else
	{
		/* config DMA */
		WriteOTGReg32(otg_DMA_Addr, (WORD)dat);
		WriteOTGReg32(otg_DMA_Count, *length);
		WriteOTGReg32(otg_DMA_Ctrl, 0);
		SetBitOTGReg32(otg_DMA_Ctrl, (ed->Ep->Index << 4));
		SetBitOTGReg32(otg_DMA_Ctrl, (DMA_Ctrl_EnDMA | DMA_Ctrl_Mode | DMA_Ctrl_IntrEn));
		/* get max packet size value */
		temp = ed->MaxPacketSize;
		temp |= ((BULK_EP_FIFO_SIZE / ed->MaxPacketSize - 1) << 11);
		WriteOTGReg16(otg_IndexedCSR_RxMaxP, temp);	
		/* config request packet count of Rx endpoint */
		temp = *length / ed->MaxPacketSize;
		WriteOTGReg32(&otg_RqPktCount[ed->Ep->Index], temp);
		/* config CSR */
		SetBitOTGReg16(otg_IndexedCSR_RxCSR, (RxCSR_hrw_AutoClear | RxCSR_hrw_AutoReq | RxCSR_hrw_DMAReqEnab | RxCSR_hrw_DMAReqMode)); //config RXCSR

		SetBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrw_ReqPkt);			/* send first in token */
		/* wait DMA unload data */
		to = TRANSACTION_TIME_OUT;
		while(to)
		{
			temp1 = ReadOTGReg32(otg_DMA_Intr);
			if ((temp1 & DMA_Intr_Ch1) != 0)	
				break;
			to--;
		}/* end while */
		if (to == 0)
			return DEVICE_NOT_RESPONDING;

		ClrBitOTGReg16(otg_IndexedCSR_RxCSR, (RxCSR_hrw_AutoClear | RxCSR_hrw_AutoReq | RxCSR_hrw_DMAReqEnab | RxCSR_hrw_DMAReqMode)); //config RXCSR
		ClrBitOTGReg32(otg_DMA_Ctrl, (DMA_Ctrl_EnDMA | DMA_Ctrl_Mode | DMA_Ctrl_IntrEn));
		temp = ReadOTGReg16(otg_IndexedCSR_RxCSR);

		if ((temp & RxCSR_hrc_RxStall) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_RxStall);		/* get STALL response */
			return STALL;
		}
		else if ((temp & RxCSR_hrc_Error) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_Error);		/* get ERROR response */
			return ERR;
		}
		else if ((temp & RxCSR_hrc_DataError_NAKTimeout) != 0)
		{
			ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_DataError_NAKTimeout);		/* get NAK timeoue response */
			return NAK_TIME_OUT;
		}		
		else
		{
			return NO_ERROR;
		}
	}/* end else */
}


/*
 *	bulk out transaction
 *	send bulk transfer data packets, DMA option
 */
extern BYTE
HcBulkOutTransaction(
	HC_ED			*ed,
	BYTE			*dat,
	WORD			length,
	BOOL			isUseDMA
	)
{
	WORD	DATA	temp;
	DWORD	DATA	temp1;
	WORD	DATA	opLength;
	WORD	DATA	to;

	/* set function address */
	WriteOTGReg8(otg_CommonUSB_FAddr, ed->FuncAddr);
	/* set endpoint number index */
	WriteOTGReg8(otg_CommonUSB_Index, ed->Ep->Index);

	if (!isUseDMA)		/* using DMA control data transfer */
	{
		while(length)
		{
			if (length < ed->MaxPacketSize)
				opLength = length;
			else
				opLength = ed->MaxPacketSize;
			/* load data into FIFO */
			LoadFIFOData((BYTE *)&otg_EndpointFIFO[ed->Ep->Index], dat, opLength);
			/* send out token */
			SetBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrs_TxPktRdy);
			/* Wait EndPoint Tx interrupt */
			to = TRANSACTION_TIME_OUT;
			while(to)
			{
				temp = ReadOTGReg16(otg_IndexedCSR_TxCSR);
				if ((temp & TxCSR_hrs_TxPktRdy) == 0)
					break;
				to--;
			}/* end while */	
			if (to == 0)
				return DEVICE_NOT_RESPONDING;

			/* check CSR response */
			if ((temp & TxCSR_hrc_RxStall) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrc_RxStall);		/* get STALL response */
				return STALL;
			}
			else if ((temp & TxCSR_hrc_Error) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrc_Error);			/* get ERROR response */
				return ERR;
			}
			else if ((temp & TxCSR_hrc_NAKTimeout_IncompTx) != 0)
			{
				ClrBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrc_NAKTimeout_IncompTx);		/* get NAK timeoue response */
				return NAK_TIME_OUT;
			}
			else
			{
				length -= opLength;
				dat += opLength;
			}	
		}/* end while */
		return NO_ERROR;			/* no STALL, ERROR, NAKTimeout */
	}/* end if (!isUseDMA) */
	else
	{
		/* config DMA */
		WriteOTGReg32(otg_DMA_Addr, (WORD)dat);
		WriteOTGReg32(otg_DMA_Count, length);
		WriteOTGReg32(otg_DMA_Ctrl, 0);
		SetBitOTGReg32(otg_DMA_Ctrl, (ed->Ep->Index << 4));

⌨️ 快捷键说明

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