📄 hc_otg.c
字号:
SetBitOTGReg32(otg_DMA_Ctrl, (DMA_Ctrl_EnDMA | DMA_Ctrl_Direction | 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_TxMaxP, temp);
/* config CSR */
SetBitOTGReg16(otg_IndexedCSR_TxCSR, (TxCSR_hrw_AutoSet | TxCSR_hrw_DMAReqEnab | TxCSR_hrw_DMAReqMode)); //config TxCSR
/* wait DMA load 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_TxCSR, (TxCSR_hrw_AutoSet | TxCSR_hrw_DMAReqEnab | TxCSR_hrw_DMAReqMode));
ClrBitOTGReg32(otg_DMA_Ctrl, (DMA_Ctrl_EnDMA | DMA_Ctrl_Direction | DMA_Ctrl_Mode | DMA_Ctrl_IntrEn));
temp = ReadOTGReg16(otg_IndexedCSR_RxCSR);
/* 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
{
return NO_ERROR; /* no STALL, ERROR, NAKTimeout */
}
}/* end else */
}
/*------------------------------------------------------------------------------------*/
/*-------------------------------HC source allocate ----------------------------------*/
/*
* allocate host controller source
*/
extern HC*
AllocHc(VOID)
{
BYTE DATA i;
HC* DATA hc;
i = SearchMapZero(&gHcMap, MAX_HC_NUM);
if (i == MAX_HC_NUM)
return NULL;
SetMap(&gHcMap, i);
hc = &gHc[i];
memset(hc, 0, sizeof(HC));
hc->Set = i;
return &gHc[i];
}
/*
* free host controller source
*/
extern VOID
FreeHc(
HC *hc
)
{
ClearMap(&gHcMap, hc->Set);
}
extern HC_EP*
HcAllocHcEndpoint(
HC *hc,
BYTE epNum
)
{
BYTE DATA i;
HC_EP* DATA ep;
if (epNum == 0)
{
SetMap(&hc->HcEpMap, 0);
ep = &hc->Ep[0];
ep->Index = 0;
}
else
{
i = SearchMapZero(&hc->HcEpMap, MAX_HC_ENDPOINT_NUM);
if (i == MAX_HC_ENDPOINT_NUM)
return NULL;
SetMap(&hc->HcEpMap, i);
ep = &hc->Ep[i];
ep->Index = i;
}
return ep;
}
/*
* free one HC endpoint
*/
extern VOID
HcFreeHcEndpoint(
HC *hc,
HC_EP *ep
)
{
ClearMap(&hc->HcEpMap, ep->Index);
}
/*
* open one HC endpoint
*/
extern VOID
OpenHcEndpoint(
HC *hc,
HC_ED *ed
)
{
WORD DATA temp;
hc = hc;
if (ed->EndPointNum == 0)
{
/* set function address */
// WriteOTGReg8(otg_CommonUSB_FAddr, ed->FuncAddr);
/* set endpoint number index */
WriteOTGReg8(otg_CommonUSB_Index, 0);
SetBitOTGReg16(otg_IndexedCSR_CSR0, CSR0_hs_FlushFIFO);
return;
}/* end if (ed->EndPointNum == 0) */
/* set function address */
// WriteOTGReg8(otg_CommonUSB_FAddr, ed->FuncAddr);
/* set endpoint number index */
WriteOTGReg8(otg_CommonUSB_Index, ed->Ep->Index);
if (ed->Direction == USB_DIR_IN)
{
ClrBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrw_Mode); /* Rx endpoint */
WriteOTGReg8(otg_IndexedCSR_host_RxType, 0);
WriteOTGReg8(otg_IndexedCSR_host_RxType, ed->EndPointNum); /* set transfer type */
ClrBitOTGReg8(otg_IndexedCSR_host_RxType, RxType_rw_Protocol);
SetBitOTGReg8(otg_IndexedCSR_host_RxType, (ed->TransferType << 4));
WriteOTGReg16(otg_IndexedCSR_RxMaxP, ed->MaxPacketSize); /* set max packet size */
WriteOTGReg8(otg_IndexedCSR_host_RxInterval, ed->Interval); /* set endpoint interval */
// SetBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hs_ClrDataTog); /* clear data toggle */
// if ((ReadOTGReg16(otg_IndexedCSR_RxCSR) & RxCSR_hrc_RxPktRdy) != 0)
// SetBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hs_FlushFIFO); /* flush FIFO */
temp = ReadOTGReg16(otg_IndexedCSR_RxCSR);
if ((temp & RxCSR_hrc_RxStall) != 0)
{
ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_RxStall); /* get STALL response */
}
else if ((temp & RxCSR_hrc_Error) != 0)
{
ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_Error); /* get ERROR response */
}
else if ((temp & RxCSR_hrc_DataError_NAKTimeout) != 0)
{
ClrBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hrc_DataError_NAKTimeout); /* get NAK timeoue response */
}
}
else
{
SetBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrw_Mode); /* Tx endpoint */
WriteOTGReg8(otg_IndexedCSR_host_TxType, 0);
WriteOTGReg8(otg_IndexedCSR_host_TxType, ed->EndPointNum); /* set transfer type */
ClrBitOTGReg8(otg_IndexedCSR_host_TxType, TxType_rw_Protocol);
SetBitOTGReg8(otg_IndexedCSR_host_TxType, (ed->TransferType << 4));
WriteOTGReg16(otg_IndexedCSR_TxMaxP, ed->MaxPacketSize); /* set max packet size */
WriteOTGReg8(otg_IndexedCSR_host_TxInterval, ed->Interval); /* set endpoint interval */
// SetBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hs_ClrDataTog); /* clear data toggle */
// if ((ReadOTGReg16(otg_IndexedCSR_TxCSR) & TxCSR_hrc_FIFONotEmpty) != 0)
// SetBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hs_FlushFIFO); /* flush FIFO */
temp = ReadOTGReg16(otg_IndexedCSR_TxCSR);
if ((temp & TxCSR_hrc_RxStall) != 0)
{
ClrBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrc_RxStall); /* get STALL response */
}
else if ((temp & TxCSR_hrc_Error) != 0)
{
ClrBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrc_Error); /* get ERROR response */
}
else if ((temp & TxCSR_hrc_NAKTimeout_IncompTx) != 0)
{
ClrBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hrc_NAKTimeout_IncompTx); /* get NAK timeoue response */
}
}
}
/*------------------------------------------------------------------------------------*/
/*----------------------------------HC status control---------------------------------*/
/*
* host reset USB
*/
extern VOID
HcResetUsb(
HC *hc
)
{
hc = hc;
SetBitOTGReg8(otg_CommonUSB_Power, Power_hrw_Reset);
WaitMs(20);
ClrBitOTGReg8(otg_CommonUSB_Power, Power_hrw_Reset);
}
/*
* host suspend USB
*/
extern VOID
HcSuspendUsb(
HC *hc
)
{
hc = hc;
SetBitOTGReg8(otg_CommonUSB_Power, Power_hs_SuspendMode);
}
/*
* host resume USB from suspend
*/
extern VOID
HcResumeUsb(
HC *hc
)
{
hc = hc;
SetBitOTGReg8(otg_CommonUSB_Power, Power_hrw_Resume);
WaitMs(20);
ClrBitOTGReg8(otg_CommonUSB_Power, Power_hrw_Resume);
}
/*------------------------------------------------------------------------------------*/
/*----------------------------------HC frame---------------------------------*/
/*
* get current frame number
*/
extern DWORD
HcGetFrameNum(
HC *hc
)
{
hc = hc;
return ReadOTGReg16(otg_CommonUSB_Frame);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------HC init----------------------------*/
/*
* open host controller
*/
extern VOID
OpenHc(
HC *hc
)
{
BYTE DATA i;
hc->HcType = "otg_host";
hc->HcIDStr = "mvsilicon";
memset(&hc->Ep[0], 0, sizeof(hc->Ep));
hc->HcEpMap = 0;
hc->IsRHPortConn = FALSE;
memset(&hc->Port, 0, sizeof(hc->Port));
/* init otg host mode */
ForceOTGADevMode();
ForceOTGVBusValid();
if (HIGH_SPEED_EN)
SetBitOTGReg8(otg_CommonUSB_Power, Power_hrw_HSEnab);
else
ClrBitOTGReg8(otg_CommonUSB_Power, Power_hrw_HSEnab);
if (PHY_SUSPEND_MODE_PIN_EN)
SetBitOTGReg8(otg_CommonUSB_Power, Power_hrw_EnSuspendMode);
else
ClrBitOTGReg8(otg_CommonUSB_Power, Power_hrw_EnSuspendMode);
/* enable all usb interrupt */
WriteOTGReg8(otg_CommonUSB_IntrUSBE, 0xFF);
/* clear endpoint data toggle and flush fifo */
for (i = 1; i < MAX_HC_ENDPOINT_NUM; ++i)
{
WriteOTGReg8(otg_CommonUSB_Index, i);
SetBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hs_ClrDataTog); /* clear data toggle */
SetBitOTGReg16(otg_IndexedCSR_RxCSR, RxCSR_hs_FlushFIFO); /* flush FIFO */
SetBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hs_ClrDataTog); /* clear data toggle */
SetBitOTGReg16(otg_IndexedCSR_TxCSR, TxCSR_hs_FlushFIFO); /* flush FIFO */
}
/* start a session */
SetBitOTGReg8(otg_CtrlFIFO_DevCtl, DevCtl_rw_Session); /* check the ID pin sensing and verify the core and PHY IDDIG input. */
}
/*--------------------------------------------------------------------*/
/*------------------------------HC root hub------------------------------*/
BOOL XDATA gIsPortConn = FALSE; /* support only one port */
/*
* open root hub polling interrupt
* the interval of polling is 250ms
*/
extern VOID
HcOpenRootHubPollInt(
HC *hc
)
{
hc = hc;
TMOD = 0x11; /* set timer0 16bit counter */
TL1 = 0xB0; /* time unit is 50ms */
TH1 = 0x3C;
ET1 = 1;
TR1 = 1;
EA = 1;
}
/*
* root hub polling interrupt service
*/
extern VOID
HcRootHubPollInt(VOID) interrupt 3 using 2
{
BYTE DATA temp;
static BYTE DATA cnt = 0;
TL1 = 0xB0; /* time unit is 50ms */
TH1 = 0x3C;
if (cnt < 5) /* poll interval = 250ms */
{
cnt++;
return;
}
cnt = 0;
/* read register */
temp = *otg_CommonUSB_IntrUSB;
/* check OTG_STATUS_READ_OK signal, wait OTG_STATUS_READ_OK == 1 */
while((*otg_op_status & OTG_STATUS_READ_OK) == 0);
/* check OTG_READ_REQ signal */
if ((*otg_op_status & OTG_READ_REQ) != 0) /* OTG_READ_REQ == 1 */
temp = *otg_rd_read_data;
if ((temp & IntUSB_Conn) != 0)
gIsPortConn = TRUE;
else if ((temp & IntUSB_DisCon) != 0)
gIsPortConn = FALSE;
}
/*
* Get root hub port status and change information
* 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.
*/
extern DWORD
HcGetRootHubPortStatus(
HC *hc,
BYTE portNum
)
{
DWORD retVal = 0;
BOOL temp;
if (portNum != 0) /* support only one port */
return 0;
/* update port connect status */
EnterCritical();
temp = gIsPortConn;
ExitCritical();
if (!hc->IsRHPortConn && temp) /* new device connection */
{
hc->IsRHPortConn = TRUE;
hc->Port.PortStatus |= (HUB_PORT_CONNECTION | HUB_PORT_POWER);
hc->Port.PortChange |= HUB_C_PORT_CONNECTION;
}
else if (hc->IsRHPortConn && !temp) /* device disconnection */
{
hc->IsRHPortConn = FALSE;
hc->Port.PortStatus &= ~(HUB_PORT_CONNECTION | HUB_PORT_ENABLE | HUB_PORT_POWER);
hc->Port.PortChange |= HUB_C_PORT_CONNECTION;
}
else
{
hc->Port.PortChange &= ~HUB_C_PORT_CONNECTION;
}
retVal = hc->Port.PortChange;
retVal <<= 16;
retVal += hc->Port.PortStatus;
return retVal;
}
/*
* enable root hub one port
*/
extern BOOL
HcEnableRootHubPort(
HC *hc,
BYTE portNum
)
{
BYTE DATA temp;
if (portNum != 0) /* support only one port */
return FALSE;
hc->Port.PortStatus &= ~HUB_PORT_ENABLE;
/* check host mode */
temp = ReadOTGReg8(otg_CtrlFIFO_DevCtl);
if ((temp & DevCtl_r_HostMode) == 0)
return FALSE; /* not host mode */
HcResetUsb(hc);
/* check device speed */
temp = ReadOTGReg8(otg_CtrlFIFO_DevCtl);
if ((temp & DevCtl_r_LSDev) != 0)
{
hc->Port.PortStatus |= HUB_PORT_LOW_SPEED; /* low-speed device connected */
hc->Port.PortStatus &= ~HUB_PORT_HIGH_SPEED;
}
else if ((temp & DevCtl_r_FSDev) != 0)
{
temp = ReadOTGReg8(otg_CommonUSB_Power);
if ((temp & Power_hr_HSMode) == 0)
{
hc->Port.PortStatus &= ~HUB_PORT_LOW_SPEED; /* full-speed device connected */
hc->Port.PortStatus &= ~HUB_PORT_HIGH_SPEED;
}
else
{
hc->Port.PortStatus &= ~HUB_PORT_LOW_SPEED; /* high-speed device connected */
hc->Port.PortStatus |= HUB_PORT_HIGH_SPEED;
}
}
else
{
return FALSE;
}
/* wait SOF send */
while(1)
{
temp = ReadOTGReg8(otg_CommonUSB_IntrUSB);
if ((temp & IntUSB_SOF) != 0)
break;
}
hc->Port.PortStatus |= HUB_PORT_ENABLE;
return TRUE;
}
/*----------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -