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

📄 hcd.c

📁 一个USB主机核的驱动程序
💻 C
字号:
/****************************************************************
*                      MT View Silicon Tech. Inc.
*
*    Copyright 2007, MT View Silicon Tech. Inc., ShangHai, China
*                    All rights reserved.
*
*
* Filename:      	hcd.c
*
* Programmer:    	Grey
*
* Created: 	 		12/xx/2007
*
* Description: 		host controller driver
*					
*              
*****************************************************************/

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

HCI		XDATA	gHci[MAX_HCI_NUM];
BYTE	XDATA	gHciMap = 0;

/*--------------------------HCD transfer control----------------------------*/
/*
 * 	process URB from USBD
 *	it is the transfer control interface of HCD
 */
extern BYTE
HciSendUrb(
	URB		*urb
	)
{
	HCI		XDATA	*hci;
	HC		XDATA	*hc;
	HC_ED	XDATA	*ed;
	HC_EP	XDATA	*ep;

	urb->Err = UNKNOW;

	hci = urb->HcPriv;
	hc = hci->Hc;

	/* allocate logic endpoint source */
	ed = HciAllocED(hci);
	if (ed == NULL)
	{
		return urb->Err; 
	}
	ed->FuncAddr = PipeDevice(urb->Pipe);//urb->FuncAddr;
	ed->EndPointNum = PipeEndpoint(urb->Pipe);//urb->EndPointNum;
//	ed->TransferType = urb->TransferType;
	if (PipeBulk(urb->Pipe))
		ed->TransferType = USB_ENDPOINT_XFER_BULK;
	else if (PipeControl(urb->Pipe))
		ed->TransferType = USB_ENDPOINT_XFER_CONTROL;
	else if (PipeInt(urb->Pipe))
		ed->TransferType = USB_ENDPOINT_XFER_INT;
	else
		ed->TransferType = USB_ENDPOINT_XFER_ISOC;

	ed->Direction = PipeIn(urb->Pipe) ? USB_DIR_IN : USB_DIR_OUT;//urb->Direction;

	ed->MaxPacketSize = urb->MaxPacketSize;
	ed->Interval = urb->Interval;
	ed->Hc = hc;
	
	/* allocate hardware endpoint source */
	ep = HcAllocHcEndpoint(hc, ed->EndPointNum);
	if (ep == NULL)
	{
		HciFreeED(hci, ed);
		return urb->Err; 
	}
	ed->Ep = ep;
	OpenHcEndpoint(hc, ed);
	
	/* transfer control */
	if (ed->TransferType == USB_ENDPOINT_XFER_CONTROL)		/* endpoint control transfer */
	{
		urb->Err = HcSetupTransaction(ed, urb->SetupPacket, 8);
		if (urb->Err != NO_ERROR)
		{
			HciFreeED(hci, ed);
			return urb->Err; 
		}

		if (ed->Direction == USB_DIR_IN)
		{
			urb->Err = HcCtrlInTransaction(ed, urb->DataBuffer, &urb->DataLength);		/* in data packet */
			if (urb->Err != NO_ERROR)
			{
				HciFreeED(hci, ed);
				return urb->Err; 
			}

			urb->Err = HcCtrlOutTransaction(ed, NULL, 0);			/* out zero data packet */
			if (urb->Err != NO_ERROR)
			{
				HciFreeED(hci, ed);
				return urb->Err; 
			}
		}/* end if (urb->Direction == URB_DIR_IN) */
		else
		{				
			if (urb->DataBuffer != NULL)
			{
				urb->Err = HcCtrlOutTransaction(ed, urb->DataBuffer, urb->DataLength);		/* out data packet */
				if (urb->Err != NO_ERROR)	
				{
					HciFreeED(hci, ed);
					return urb->Err; 
				}
			}/* end if (urb->DataBuffer != NULL) */

			urb->Err = HcCtrlInTransaction(ed, NULL, &urb->DataLength);	/* in zero data packet */
			if (urb->Err != NO_ERROR)
			{
				HciFreeED(hci, ed);
				return urb->Err; 
			}
		}/* end else */
	}/* end if (urb->TransferType == USB_ENDPOINT_XFER_CONTROL) */
	else if (ed->TransferType == USB_ENDPOINT_XFER_BULK)
	{		
		if (ed->Direction == USB_DIR_IN)
		{
			urb->Err = HcBulkInTransaction(ed, urb->DataBuffer, &urb->DataLength, urb->IsUseDMA);		/* in data packet */
			if (urb->Err != NO_ERROR)
			{
				HciFreeED(hci, ed);
				return urb->Err; 
			}
		}/* end if (urb->Direction == USB_DIR_IN) */
		else
		{
			urb->Err = HcBulkOutTransaction(ed, urb->DataBuffer, urb->DataLength, urb->IsUseDMA);		/* in data packet */
			if (urb->Err != NO_ERROR)
			{
				HciFreeED(hci, ed);
				return urb->Err; 
			}
		}/* end else */
	}

	HciFreeED(hci, ed);

	return urb->Err;
}
/*---------------------------------------------------------------------*/


/*---------------------------HCD control USB status-----------------------*/
/*
 * 	host reset USB
 */
extern VOID
HciResetUsb(
	VOID	*hcpriv
	)
{
	HCI		*hci = (HCI *)hcpriv;

	HcResetUsb(hci->Hc);
	hci->UsbStatus = USB_STATUS_NORMAL;
}


/*
 * 	host suspend USB
 */
extern VOID
HciSuspendUsb(
	VOID	*hcpriv
	)
{
	HCI		*hci = (HCI *)hcpriv;

	HcSuspendUsb(hci->Hc);
	hci->UsbStatus = USB_STATUS_SUSPEND;
}


/*
 * 	host resume USB from suspend
 */
extern VOID
HciResumeUsb(
	VOID	*hcpriv
	)
{
	HCI		*hci = (HCI *)hcpriv;

	HcResumeUsb(hci->Hc);
	hci->UsbStatus = USB_STATUS_NORMAL;
}
/*---------------------------------------------------------------------*/


/*------------------------------HCD frame--------------------------*/
/*
 * 	get current frame number
 */
extern DWORD
HciGetFrameNum(
	VOID	*hcpriv
	)
{
	HCI		*hci = (HCI *)hcpriv;

	return HcGetFrameNum(hci->Hc);	
}
/*-----------------------------------------------------------------*/


/*---------------------------HCD allocate source-----------------------*/
/*
 * 	allocate one hci control structure 
 */
extern VOID*
AllocHci(VOID)
{
	BYTE	DATA	i;
	HCI*	DATA	hci;

	i = SearchMapZero(&gHciMap, MAX_HCI_NUM);
	if (i == MAX_HCI_NUM)
		return NULL;

	SetMap(&gHciMap, i);
	hci = &gHci[i];
	memset(hci, 0, sizeof(HCI));
	hci->Set = i;

	return (VOID *)hci;
}


/*
 * 	free one hci control structure 
 */
extern VOID
FreeHci(
	VOID	*hcpriv
	)
{
	HCI		*hci = (HCI *)hcpriv;

	if (hci->Hc != NULL)
		FreeHc(hci->Hc);
	ClearMap(&gHciMap, hci->Set);
}


/*
 * 	allocate one hci endpoint descriptor 
 */
extern HC_ED*
HciAllocED(
	HCI		*hci
	)
{
	BYTE	DATA	i;
	HC_ED*	DATA	ed;

	i = SearchMapZero(&hci->EdMap, MAX_HCI_ED_NUM);
	if (i == MAX_HCI_ED_NUM)
		return NULL;

	SetMap(&hci->EdMap, i);
	ed = &hci->Ed[i];
	memset(ed, 0, sizeof(HC_ED));
	ed->Set = i;

	return ed;
}


/*
 * 	free one hci endpoint descriptor 
 */
extern VOID
HciFreeED(
	HCI		*hci,
	HC_ED	*ed
	)
{	
	if (ed->Ep != NULL)
		HcFreeHcEndpoint(hci->Hc, ed->Ep);			/* free host controller endpoint */

	ClearMap(&hci->EdMap, ed->Set);
}
/*---------------------------------------------------------------------*/


/*--------------------------------HCD init----------------------------*/
/*
 * 	open host controller, init HCI and HC
 */
extern VOID
OpenHci(
	VOID	*hcpriv
	)
{
	HCI		*hci = (HCI *)hcpriv;
	HC		*hc;
	/* init host controller driver source */
	hci->UsbStatus = USB_STATUS_RESET;
	memset(&hci->Ed[0], 0, sizeof(hci->Ed));
	hci->EdMap = 0;

	/* allocate host controller source */
	hc = AllocHc();
	if (hc == NULL)
		return;
	hci->Hc = hc;
	/* init host controller */
	OpenHc(hc);

	/* open host root hub polling interrupt */
	HcOpenRootHubPollInt(hc);
}
/*----------------------------------------------------------------------*/


/*------------------------------HCD root hub------------------------------*/
/*
 *	HCI get root hub port status.
 *	Return port status and port change. port status field is the low word of return value, 
 * 	port change field is the high word of return value.
 * 	The port status and port change is defined in USB2.0 spec table-11.21 and table-11.22 
 */
extern DWORD
HciGetRootHubPortStatus(
	VOID	*hcpriv,
	BYTE	portNum
	)
{
	HCI		*hci = (HCI *)hcpriv;

	return HcGetRootHubPortStatus(hci->Hc, portNum);
}


/*
 *	HCI enable root hub port. 
 */
extern BOOL
HciEnableRootHubPort(
	VOID	*hcpriv,
	BYTE	portNum
	)
{
	HCI		*hci = (HCI *)hcpriv;

	return HcEnableRootHubPort(hci->Hc, portNum);
}


/*-----------------------------------------------------------------------------------*/


/*-------------------------------interrupt management--------------------------------*/


extern VOID
HciInterruptService(VOID)
{
	/* if Resume interrupt */
		
		/* do Resume operation */

	/* if Session Request interrupt */

		/* do Session Request */

	/* if VBus Error interrupt */

		/* process VBus Error */

	/* if connection interrupt */

		/* process connection operation */

	/* if disconnection interrupt */

		/* process disconnection operation */

	/* if Babble interrupt */

		/* if Host mode */
			
			/* process Babble */

	/* if SOF interrupt */
		
		/* process SOF */

	/* if Endpoint 0 interrupt */

		/* process Endpoint 0 */

	/* if Tx interrupt */

		/* process Tx */

	/* if Rx interrupt */

		/* process Rx */
		
}



/*---------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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