📄 hcd.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 + -