📄 hc_otg.c
字号:
/****************************************************************
* 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 + -