📄 pdd.c
字号:
RETAILMSG(1,(L"PRIME failed on EP0\r\n") );
if ( INREG32(&pOtgReg->ENDPTSETUPSTAT) & 1 )
{
GetSetupPacket(pPdd, data);
RETAILMSG(1,(L"New setup received when priming=%x, %x\r\n", data[0], data[1]));
DEBUGCHK ( pPdd->ep[0]->bPagesLocked == 0 );
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_SETUP_PACKET, (DWORD)data);
RETAILMSG(1,(L"Status for td0=%x, tb=%x\r\n",
pPdd->qhbuffer->qh[0].dtd.status,pPdd->qhbuffer->qh[0].dtd.tb));
}
retry = 1;
goto again;
}
pPdd->qhbuffer->bPrimed[0] = TRUE;
UNLOCK();
}
//-------------------------------------------------------------
//
// Function: PrimeQh0ForZeroTransfer
//
// This is to prime the end point 0 and is used during the handshake status
//
// Parameters:
// pPdd - Pointer to the USBFN_PDD
// bIN - TRUE : IN transfer
// FALSE: OUT transfer
//
// Return: NULL
//
//------------------------------------------------------------------
static void
PrimeQh0ForZeroTransfer(USBFN_PDD *pPdd, BOOL bIN )
{
volatile CSP_USB_REG * pOtgReg=&(pPdd->pUSBDRegs->OTG);
int endp;
USB_ENDPTSTAT_T stat;
DWORD *pStat = (DWORD*)&stat;
USB_ENDPTPRIME_T edptprime;
DWORD *pPrime=(DWORD * )&edptprime;
*pPrime = 0;
if ( bIN )
{
edptprime.PETB = 1;
endp = 1;
}
else
{
edptprime.PERB = 1;
endp = 0;
}
CeLogMsg(_T("PrimeFZLT: %s"), bIN ? _T("IN") : _T("OUT"));
*pStat = INREG32(&pOtgReg->ENDPTSTATUS);
if ( (bIN && (stat.ETBR & 1)) || (!bIN && (stat.ERBR & 1)) )
{
RETAILMSG(1, (_T("Can not prime for ZLT (%s): busy\r\n"),
bIN ? _T("IN") : _T("OUT")) );
return;
}
memset(&(pPdd->qhbuffer->qh[endp]),0, sizeof(USBD_dQH_T)-2*sizeof(DWORD));
pPdd->qhbuffer->bPrimed[endp] = FALSE;
// Endpoint 0
pPdd->qhbuffer->qh[endp].ios= (endp == 0 ? 1 : 0);
pPdd->qhbuffer->qh[endp].mpl=USB_FULL_HIGH_SPEED_CONTROL_MAX_PACKET_SIZE;
pPdd->qhbuffer->qh[endp].zlt=1;
//overlayer default
{
DWORD t;
t=DescriptorPhy(pPdd, (DWORD)&(pPdd->qhbuffer->td[endp]));
t>>=5;
pPdd->qhbuffer->qh[endp].dtd.next_dtd=t;
pPdd->qhbuffer->qh[endp].dtd.T=0;
}
// OUTREG32(&pOtgReg->ENDPTSETUPSTAT, 0xffff);
memset (&(pPdd->qhbuffer->td[endp]), 0, sizeof(USBD_dTD_T));
pPdd->qhbuffer->td[endp].T=1;
pPdd->qhbuffer->td[endp].next_dtd=0xDEAD;
pPdd->qhbuffer->td[endp].status=0x80; // Active
pPdd->qhbuffer->td[endp].ioc=1;
pPdd->qhbuffer->td[endp].tb=0;
// leave all bp null for a null transfer
OUTREG32(&pOtgReg->ENDPTPRIME, *pPrime); // prime Out transition
while(INREG32(&pOtgReg->ENDPTPRIME) & *pPrime)
{
;
}
*pStat = INREG32(&pOtgReg->ENDPTSTATUS);
if ( (bIN && ((stat.ETBR & 1) == 0)) || (!bIN && ((stat.ERBR & 1) == 0)) )
{
USB_ENDPTCOMPLETE_T edptcomp;
DWORD *pEpc;
pEpc = (DWORD*)&edptcomp;
*pEpc = INREG32(&pOtgReg->ENDPTCOMPLETE);
if ( (bIN && ((edptcomp.ETCE & 1) == 0)) || (!bIN && ((edptcomp.ERCE & 1) == 0)) )
{
RETAILMSG(1,(_T("################ Failed to prime for ZLT %s\r\n"), bIN ? TEXT("IN") : TEXT("OUT")));
}
}
pPdd->qhbuffer->bPrimed[endp] = TRUE;
}
//-------------------------------------------------------------
//
// Function: HandleUSBReset
//
// This is to handle the USB Reset interrupt
//
// Parameters:
// pPdd - Pointer to USBFN_PDD
//
// Return: NULL
//
//------------------------------------------------------------------
static void
HandleUSBReset(USBFN_PDD *pPdd)
{
volatile CSP_USB_REG * pOtgReg=&(pPdd->pUSBDRegs->OTG);
USB_PORTSC_T state;
DWORD * tPortsc;
LOCK();
// clear all setup notification bits
OUTREG32(&pOtgReg->ENDPTSETUPSTAT, INREG32(&pOtgReg->ENDPTSETUPSTAT));
// clear all complete bits
OUTREG32(&pOtgReg->ENDPTCOMPLETE, INREG32(&pOtgReg->ENDPTCOMPLETE));
// wait for all prime (if any in progress) to complete, then flush all
while ( INREG32(&pOtgReg->ENDPTPRIME) )
{
;
}
OUTREG32(&pOtgReg->ENDPTFLUSH, 0xFFFFFFFF);
// and check that we're still in RESET
tPortsc = (DWORD*)&state;
*tPortsc = INREG32(&pOtgReg->PORTSC[USBD_PORT_NUM]);
if ( state.PR == 0 )
{
DEBUGMSG(ZONE_WARNING,(_T("HandleUSBReset: Not still in reset condition. Possibly reset controller??\r\n")));
}
UNLOCK();
// no need to free TDs since they are statically allocated.
}
//----------------------------------------------------------------
//
// Function: UfnPdd_PowerDown
//
// This is power down function for USB PDD function driver
//
// Parameters:
// pPddContext - PDD Context
//
// Return:
// NULL
//
//----------------------------------------------------------------
VOID WINAPI UfnPdd_PowerDown(VOID *pPddContext)
{
int i = 0;
USBFN_PDD *pPdd = (USBFN_PDD *)(pPddContext);
RETAILMSG(1, (L"UfnPdd_PowerDown+\r\n"));
if (pPdd->bInUSBFN)
{
USB_CTRL_T ctrl;
USB_PORTSC_T portsc;
USB_USBCMD_T usbcmd;
DWORD *temp3;
DWORD *temp2;
DWORD *temp;
if (pPdd->bUSBCoreClk == FALSE)
{
// We know it is suspend already ...why bother to
// further processing anything.
// We use bUSBCoreClk as checking since this is the last thing to
// do b4 we go to suspend.
DEBUGMSG(ZONE_POWER, (TEXT("UfnPdd_PowerDown no action required\r\n")));
return;
}
// Stop USB Run/Stop CMD
temp2 = (DWORD *)&usbcmd;
*temp2 = INREG32(&pPdd->pUSBDRegs->OTG.USBCMD);
usbcmd.RS = 0;
OUTREG32(&pPdd->pUSBDRegs->OTG.USBCMD, *temp2);
DEBUGMSG(ZONE_POWER, (TEXT("PowerDown USBCMD = 0x%x\r\n"), INREG32(&pPdd->pUSBDRegs->OTG.USBCMD)));
// Clear USB Interrupt
pPdd->dwUSBIntrValue = INREG32(&pPdd->pUSBDRegs->OTG.USBINTR);
OUTREG32(&pPdd->pUSBDRegs->OTG.USBINTR, 0x00);
DEBUGMSG(ZONE_POWER, (TEXT("PowerDown USBINTR = 0x%x\r\n"), INREG32(&pPdd->pUSBDRegs->OTG.USBINTR)));
// Clear USBSTS
OUTREG32(&pPdd->pUSBDRegs->OTG.USBSTS, INREG32(&pPdd->pUSBDRegs->OTG.USBSTS));
temp = (DWORD *)&portsc;
*temp = INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0]);
portsc.WKOC = 1;
portsc.WKDC = 1;
portsc.WKCN = 1;
OUTREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0], *temp);
DEBUGMSG(ZONE_POWER, (TEXT("PowerDown PORTSC= 0x%x\r\n"), INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0])));
// Switch ULPI to suspend mode
//SetPHYPowerMgmt(pPdd->pUSBDRegs, TRUE);
// Disable wakeup condition
temp3 = (DWORD *)&ctrl;
*temp3 = INREG32(&pPdd->pUSBDRegs->USB_CTRL);
// We have to disable the wakeup, or it will fail in following condition:
// - Unplug the USB device cable and plug in a DOK
// - Unplug the DOK and wake it up by pressing the power on button
//ctrl.OWIE = 1;
//ctrl.OUIE = 1;
ctrl.OWIE = 0;
ctrl.OUIE = 0;
OUTREG32(&pPdd->pUSBDRegs->USB_CTRL, *temp3);
DEBUGMSG(ZONE_POWER, (TEXT("PowerDown USBCTRL=0x%x\r\n"), INREG32(&pPdd->pUSBDRegs->USB_CTRL)));
// Set PORTSC PHCD to 1
temp = (DWORD *)&portsc;
*temp = INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0]);
portsc.PHCD = 1;
OUTREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0], *temp);
DEBUGMSG(ZONE_POWER, (TEXT("PowerDown PORTSC= 0x%x\r\n"), INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0])));
// We need to wait for SUSPEND bit set
//while((INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0]) & 0x80) == 0x00)
// Sleep(0);
if (pPdd->bUSBPanicMode)
{
DEBUGMSG(ZONE_POWER, (TEXT("Panic Mode off\r\n")));
pPdd->bUSBPanicMode = FALSE;
#if 1 /*ERIC0907, need implemented?*/
DEBUGMSG(0, (TEXT("DDKClockDisablePanicMode : 5\r\n")));
#else
DDKClockDisablePanicMode();
#endif
}
// Stop USB Clock now
if (pPdd->bUSBCoreClk)
{
DEBUGMSG(ZONE_POWER, (TEXT("USB Clock stop\r\n")));
pPdd->bUSBCoreClk = FALSE;
USBClockDisable(TRUE);
}
}
RETAILMSG(1, (TEXT("UfnPdd_PowerDown-\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_PowerUp
//
// This function is called during Power Up
//
// Parameters:
// pPddContext - Pointer to USBFN_PDD
//
// Return:
// NULL
//
//------------------------------------------------------------------------------
VOID WINAPI UfnPdd_PowerUp(VOID *pPddContext)
{
USBFN_PDD *pPdd = (USBFN_PDD *)(pPddContext);
DEBUGMSG(ZONE_POWER, (_T("UsbPdd_PowerUp with bInUSBFN %d\r\n"), pPdd->bInUSBFN) );
RETAILMSG(1, (_T("UsbPdd_PowerUp+ (bInUSBFN %d\r\n)"), pPdd->bInUSBFN) );
if (pPdd->bInUSBFN)
{
USB_CTRL_T ctrl;
USB_USBCMD_T usbcmd;
DWORD *temp3;
DWORD *temp2;
// Start USB Clock now
if (pPdd->bUSBCoreClk == FALSE)
{
DEBUGMSG(ZONE_POWER, (TEXT("USB Clock start\r\n")));
pPdd->bUSBCoreClk = TRUE;
USBClockDisable(FALSE);
}
if (pPdd->bUSBPanicMode == FALSE)
{
DEBUGMSG(ZONE_POWER, (TEXT("Panic Mode On\r\n")));
pPdd->bUSBPanicMode = TRUE;
#if 1 /*ERIC0907 need implemented?*/
DEBUGMSG(0, (TEXT("DDKClockEnablePanicMode : 6\r\n")));
#else
DDKClockEnablePanicMode();
#endif
}
RETAILMSG(1, (TEXT("PowerUp:USBSTS(0x%x) PORTSC(0x%x)\r\n"),
INREG32(&pPdd->pUSBDRegs->OTG.USBSTS), INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0]) ));
// Force resume first
if (INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0]) & 0x800000)
{
// Clear the PHCD
OUTREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0], (INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0]) & ~0x800000));
StallExecution(500);
// Force Resume bit
OUTREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0], INREG32(&pPdd->pUSBDRegs->OTG.PORTSC[0])|0x40);
RETAILMSG(1, (TEXT("Force resume\r\n")));
}
//Disable wakeup condition
temp3 = (DWORD *)&ctrl;
*temp3 = INREG32(&pPdd->pUSBDRegs->USB_CTRL);
DEBUGMSG(ZONE_POWER, (TEXT("PowerUp wakeup = 0x%x\r\n"), *temp3));
if (ctrl.OWIR == 1)
{
*temp3 = 0;
ctrl.OWIE = 1;
CLRREG32(&pPdd->pUSBDRegs->USB_CTRL, *temp3);
}
// Switch ULPI to resume mode
//SetPHYPowerMgmt(pPdd->pUSBDRegs, FALSE);
// Enable back all interrupt
OUTREG32(&pPdd->pUSBDRegs->OTG.USBINTR, pPdd->dwUSBIntrValue);
DEBUGMSG(ZONE_POWER, (TEXT("Wakeup Interrupt Setting 0x%x\r\n"),
pPdd->dwUSBIntrValue));
// Start USB Run/Stop CMD
temp2 = (DWORD *)&usbcmd;
*temp2 = INREG32(&pPdd->pUSBDRegs->OTG.USBCMD);
usbcmd.RS = 1;
OUTREG32(&pPdd->pUSBDRegs->OTG.USBCMD, *temp2);
DEBUGMSG(ZONE_POWER, (TEXT("PowerUp USBCMD = 0x%x\r\n"), INREG32(&pPdd->pUSBDRegs->OTG.USBCMD)));
pPdd->bResume = TRUE;
SetInterruptEvent(pPdd->sysIntr);
}
RETAILMSG(1,(TEXT("UsbPdd_PowerUp-\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: UpdateDevicePower
//
// UpdateDevice according to self power state and PM power state.
//
// Parameter:
// pPdd - Pointer to USBFN_PDD
//
// Return:
// Current Power state
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -