📄 bul_usbotg.cpp
字号:
AddressSpace = 0 ;
if (!BusTransBusAddrToStatic( m_hParent,Internal,0, ioPhysicalBase, sizeof(BULVERDE_USBD_REG),&AddressSpace, &m_pUSBDStaticAddr) ||
AddressSpace!=0) {
m_pUSBDStaticAddr = NULL;
}
DEBUGMSG(ZONE_OTG_FUNCTION,(TEXT("CBulverdeOTG::MapHardware: m_pUSBDReg = 0x%x,m_pUSBDStaticAddr=0x%x\r\n"),m_pUSBDReg,m_pUSBDStaticAddr));
PHYSICAL_ADDRESS gpioPhysicalBase = {BULVERDE_BASE_REG_PA_GPIO,0 };
v_pGPIORegs = (P_XLLP_GPIO_T) MmMapIoSpace(gpioPhysicalBase, sizeof(XLLP_GPIO_T), FALSE);
}
}
ASSERT(m_pUSBDReg!=NULL && m_pUSBDStaticAddr!=NULL && v_pGPIORegs!=NULL);
return (m_pUSBDReg!=NULL && m_pUSBDStaticAddr!=NULL && v_pGPIORegs!=NULL);
}
BOOL CBulverdeOTG::ConfigurePinout()
{
//; set up the gpios that will be required for otg
//; note that the otg gpio will be the usb_p2 lines
//;
//
//; the table below is based on the schematic page 24 of the Main Board for Mainstone II
//; and it assumes the UDC:UP2OCR.SEOS field will be set to 4 or 5.
//;
//; signal gpio af dir function
//; usb_p2_1 35 2 I Ext OTG Transceiver Interrupt
//; usb_p2_2 34 1 O OE_Tp_Int_n
//; usb_p2_3 n/a
//; usb_p2_4 36 1 O D-
//; usb_p2_5 40 3 I D+
//; usb_p2_6 39 1 O Speed
//; usb_p2_7 n/a
//; usb_p2_8 37 1 O Suspend
//
//; same table, just ordered by gpio instead of usb_p labels...
//; the table below is based on the schematic page 24 of the Main Board for Mainstone II
//; and it assumes the UDC:UP2OCR.SEOS field will be set to 4 or 5.
//;
//; signal gpio af dir function
//; usb_p2_2 34 1 O OE_Tp_Int_n
//; usb_p2_1 35 2 I Ext OTG Transceiver Interrupt
//; usb_p2_4 36 1 O D-
//; usb_p2_8 37 1 O Suspend
//; usb_p2_6 39 1 O Speed
//; usb_p2_5 40 3 I D+
//; usb_p2_7 n/a
//; usb_p2_3 n/a
v_pGPIORegs->GPCR1 = ( XLLP_GPIO_BIT_USB_P2_1 | XLLP_GPIO_BIT_USB_P2_2 /*| XLLP_GPIO_BIT_USB_P2_3*/ |XLLP_GPIO_BIT_USB_P2_4
|XLLP_GPIO_BIT_USB_P2_5 | XLLP_GPIO_BIT_USB_P2_6 /*| XLLP_GPIO_BIT_USB_P2_7*/ |XLLP_GPIO_BIT_USB_P2_8 );
v_pGPIORegs->GPDR1 &= ~( XLLP_GPIO_BIT_USB_P2_1 /*| XLLP_GPIO_BIT_USB_P2_3 */| XLLP_GPIO_BIT_USB_P2_5/*|XLLP_GPIO_BIT_USB_P2_7*/);
v_pGPIORegs->GPDR1 |= ( XLLP_GPIO_BIT_USB_P2_2 | XLLP_GPIO_BIT_USB_P2_4 | XLLP_GPIO_BIT_USB_P2_6|XLLP_GPIO_BIT_USB_P2_8);
v_pGPIORegs->GAFR1_L &= ~(XLLP_GPIO_AF_BIT_USB_P2_2_MASK|XLLP_GPIO_AF_BIT_USB_P2_1_MASK|XLLP_GPIO_AF_BIT_USB_P2_4_MASK/*|XLLP_GPIO_AF_BIT_USB_P2_3_MASK*/|
XLLP_GPIO_AF_BIT_USB_P2_6_MASK|XLLP_GPIO_AF_BIT_USB_P2_5_MASK/*|XLLP_GPIO_AF_BIT_USB_P2_7_MASK*/|XLLP_GPIO_AF_BIT_USB_P2_8_MASK);
v_pGPIORegs->GAFR1_L |= (XLLP_GPIO_AF_BIT_USB_P2_2|XLLP_GPIO_AF_BIT_USB_P2_1|XLLP_GPIO_AF_BIT_USB_P2_4/*|XLLP_GPIO_AF_BIT_USB_P2_3*/|
XLLP_GPIO_AF_BIT_USB_P2_6|XLLP_GPIO_AF_BIT_USB_P2_5/*|XLLP_GPIO_AF_BIT_USB_P2_7*/|XLLP_GPIO_AF_BIT_USB_P2_8);
return TRUE;
}
BOOL CBulverdeOTG::IOControl(DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
BOOL bReturn = FALSE;
switch (dwCode) {
case IOCTL_BUS_USBOTG_BULVERDE_GET_EVENT:
if (pBufOut && dwLenOut >= sizeof(HANDLE) ) {
*(HANDLE *)pBufOut = m_hOTGFeatureEvent;
bReturn = TRUE;
if (pdwActualOut)
*pdwActualOut = sizeof(HANDLE);
}
break;
default:
bReturn = USBOTG::IOControl(dwCode,pBufIn,dwLenIn,pBufOut,dwLenOut,pdwActualOut);
break;
}
ASSERT(bReturn);
return bReturn;
}
USBOTG_TRANSCEIVER_CTL CBulverdeOTG::SetupTransCtr(USBOTG_OUTPUT usbOtgOutput)
{
USBOTG_TRANSCEIVER_CTL usbOtgTransCtl;
usbOtgTransCtl.ul = 0;
usbOtgTransCtl.bit.DM_PullDown = 1;
usbOtgTransCtl.bit.DM_PullUp= 0;
if (usbOtgOutput.bit.loc_con) {
usbOtgTransCtl.bit.DP_PullUp=1;
usbOtgTransCtl.bit.DP_PullDown =0;
}
else {
usbOtgTransCtl.bit.DP_PullUp=0;
usbOtgTransCtl.bit.DP_PullDown =1;
usbOtgTransCtl.bit.vbusDischange = 0;
}
usbOtgTransCtl.bit.ID_PullDown =0;
usbOtgTransCtl.bit.vbusDrv = usbOtgOutput.bit.drv_vbus;
usbOtgTransCtl.bit.vbusCharge = usbOtgOutput.bit.chrg_vbus ;
//usbOtgTransCtl.bit.vbusDischange = 0;
if (usbOtgTransCtl.bit.vbusDrv ==0 && usbOtgTransCtl.bit.vbusCharge == 0 )
usbOtgTransCtl.bit.vbusDischange = 1;
return usbOtgTransCtl ;
}
// OTG PDD Function.
BOOL CBulverdeOTG::SessionRequest(BOOL fPulseLocConn, BOOL fPulseChrgVBus)
{
m_SyncAccess.Lock();
USBOTG_TRANSCEIVER_CTL usbOtgTransCtl = SetupTransCtr(m_UsbOtgOutputValues);
Sleep(2);
if (fPulseLocConn) {
usbOtgTransCtl.bit.DP_PullUp=1;
usbOtgTransCtl.bit.DP_PullDown =0;
m_pP1301Tranceiver->SetTransceiver(usbOtgTransCtl);
Sleep(10);
usbOtgTransCtl.bit.DP_PullUp=0;
usbOtgTransCtl.bit.DP_PullDown =1;
m_pP1301Tranceiver->SetTransceiver(usbOtgTransCtl);
}
usbOtgTransCtl = SetupTransCtr(m_UsbOtgOutputValues);
if (fPulseChrgVBus) {
usbOtgTransCtl.bit.vbusCharge =1;
usbOtgTransCtl.bit.vbusDischange = 0;
m_pP1301Tranceiver->SetTransceiver(usbOtgTransCtl);
Sleep(80);
usbOtgTransCtl.bit.vbusCharge =0;
usbOtgTransCtl.bit.vbusDischange = 1;
m_pP1301Tranceiver->SetTransceiver(usbOtgTransCtl);
}
m_SyncAccess.Unlock();
return TRUE;
}
BOOL CBulverdeOTG::NewStateAction(USBOTG_STATES usbOtgState , USBOTG_OUTPUT usbOtgOutput)
{
m_SyncAccess.Lock();
USBOTG_OUTPUT lusbOtgOutput = usbOtgOutput;
if (lusbOtgOutput.bit.loc_sof) {// Switch to Host.
m_pP1301Tranceiver->SetTransceiver(SetupTransCtr(lusbOtgOutput));
UP2OCR up2ocr;
up2ocr.ul = 0;
up2ocr.bit.SEOS = 5;
up2ocr.bit.DMPDE = up2ocr.bit.DPPDE = 1;
m_pUSBDReg->up2ocr = up2ocr.ul;
//m_pUSBDReg->up3ocr = 0;
SetEvent(GetOtgAConnectEvent());
DEBUGMSG(ZONE_OTG_FUNCTION, (L"CBulverdeOTG::NewStateAction:USB Host up2ocr.ul =0x%x\r\n",up2ocr.ul));
// We should reset bus if possible
} else {// Otherwise stay in Function.
if (!m_UsbOtgInput.bit.b_usbfn_active && lusbOtgOutput.bit.loc_con) // Device Have not ready yet.
lusbOtgOutput.bit.loc_con = 0 ;
m_pP1301Tranceiver->SetTransceiver(SetupTransCtr(lusbOtgOutput));
UP2OCR up2ocr;
up2ocr.ul = 0;
up2ocr.bit.HXS=0;
up2ocr.bit.SEOS = 4;
m_pUSBDReg->up2ocr = up2ocr.ul;
m_pUSBDReg->up3ocr = 0;
DEBUGMSG(ZONE_OTG_FUNCTION, (L"CBulverdeOTG::NewStateAction:USB Function up2ocr.ul =0x%x up3ocr=0x%x\r\n",up2ocr.ul,m_pUSBDReg->up3ocr));
}
if (lusbOtgOutput.bit.loc_sof || lusbOtgOutput.bit.loc_con)
m_pP1301Tranceiver->EnableDataLineInterrupt(FALSE);
else
m_pP1301Tranceiver->EnableDataLineInterrupt(TRUE);
m_SyncAccess.Unlock();
return TRUE;
}
BOOL CBulverdeOTG::IsSE0()
{
USBOTG_TRANSCEIVER_STATUS usbTransceiverStatus;
DEBUGMSG(ZONE_OTG_FUNCTION, (L"CBulverdeOTG::IsSE0:\r\n"));
if (m_pP1301Tranceiver && m_pP1301Tranceiver->GetTransceiver(&usbTransceiverStatus)) {
return ((usbTransceiverStatus.bit.DP_HI==0 && usbTransceiverStatus.bit.DM_HI==0)?TRUE:FALSE);
}
else
return FALSE;
}
BOOL CBulverdeOTG::UpdateInput()
{
USBOTG_TRANSCEIVER_STATUS usbTransceiverStatus;
DEBUGMSG(ZONE_OTG_FUNCTION, (L"CBulverdeOTG::UpdateInput:\r\n"));
if (m_pP1301Tranceiver && m_pP1301Tranceiver->GetTransceiver(&usbTransceiverStatus)) {
if (m_UsbOtgOutputValues.bit.loc_con || m_UsbOtgOutputValues.bit.loc_sof)
m_UsbOtgInput.bit.a_conn = m_UsbOtgInput.bit.b_conn = 1;
else
m_UsbOtgInput.bit.a_conn = m_UsbOtgInput.bit.b_conn =
((usbTransceiverStatus.bit.DP_HI==0 && usbTransceiverStatus.bit.DM_HI==0)?0:1) ;
m_UsbOtgInput.bit.a_sess_vld = usbTransceiverStatus.bit.aSessValid;
if (m_UsbOtgOutputValues.bit.drv_vbus)
//we can't set this because it make hw and sw un-sync
m_UsbOtgInput.bit.a_vbus_vld = 1;
else
m_UsbOtgInput.bit.a_vbus_vld = usbTransceiverStatus.bit.aBusValid;
//
m_UsbOtgInput.bit.b_sess_end = usbTransceiverStatus.bit.bSessEnd ;
m_UsbOtgInput.bit.b_sess_vld = usbTransceiverStatus.bit.bSessValid;
m_UsbOtgInput.bit.id = (usbTransceiverStatus.bit.ID!=0?1:0);
m_UsbOtgInput.bit.a_srp_det = m_UsbOtgInput.bit.a_sess_vld ;
DEBUGMSG(ZONE_OTG_FUNCTION, (L"CBulverdeOTG::UpdateInput:m_UsbOtgInput.ul=%x\r\n",m_UsbOtgInput.ul));
// Update Output if there is any.
/*
USBOTG_OUTPUT usbOtgOutput = m_UsbOtgOutputValues;
if (!m_UsbOtgInput.bit.b_usbfn_active && usbOtgOutput.bit.loc_con) // Device Have not ready yet.
usbOtgOutput.bit.loc_con = 0 ;
m_pP1301Tranceiver->SetTransceiver(SetupTransCtr(usbOtgOutput));
*/
}
DEBUGMSG(ZONE_OTG_FUNCTION, (L"-CBulverdeOTG::UpdateInput:\r\n"));
return TRUE;
}
BOOL CBulverdeOTG::StateChangeNotification (USBOTG_TRANSCEIVER_STATUS_CHANGE usbStatusChange, USBOTG_TRANSCEIVER_STATUS usbTransceiverStatus)
{
m_SyncAccess.Lock();
UpdateInput();
m_SyncAccess.Unlock();
EventNotification();
return TRUE;
}
BOOL CBulverdeOTG::ISTProcess()
{
PREFAST_ASSERT(m_pUSBDReg!=NULL) ;
m_SyncAccess.Lock();
UDCOTG udcOtgIsr ;
udcOtgIsr.ul = m_pUSBDReg->udc_otgisr;
DEBUGMSG(ZONE_OTG_THREAD, (L"CBulverdeOTG::ISTProcess() udcOtgIsr=0x%x\r\n",udcOtgIsr.ul));
if (udcOtgIsr.bit.XR || udcOtgIsr.bit.XF) {
m_pP1301Tranceiver->ISTThreadRun();
}
if (udcOtgIsr.bit.SF) {
SetEvent(m_hOTGFeatureEvent);
}
m_pUSBDReg->udc_otgisr = udcOtgIsr.ul; // Clear the bit.
m_SyncAccess.Unlock();
return TRUE;
}
BOOL CBulverdeOTG::ISTTimeout()
{
USBOTG_TRANSCEIVER_STATUS usbOtgTransStatus;
USBOTG_TRANSCEIVER_STATUS_CHANGE usbOtgStatusChange;
usbOtgStatusChange.ul = usbOtgTransStatus.ul = 0;
m_pP1301Tranceiver->GetISP1301Change(&usbOtgStatusChange);
m_pP1301Tranceiver->GetTransceiver(&usbOtgTransStatus);
DEBUGMSG(ZONE_OTG_THREAD, (L"CBulverdeOTG::ISTTimeout() udcOtgIsr=0x%x,udcOtgicr=0x%x,m_pUSBDReg+0x1c = 0x%x\r\n",
m_pUSBDReg->udc_otgisr,m_pUSBDReg->udc_otgicr, *(PDWORD)((PBYTE)m_pUSBDReg+0x1c)));
DEBUGMSG(ZONE_OTG_THREAD, (L"CBulverdeOTG::ISTTimeout() usbOtgStatusChange =0x%x, usbOtgTransStatus= 0x%x\r\n",
usbOtgStatusChange.ul,usbOtgTransStatus.ul));
return TRUE;
}
// Class Factory.
USBOTG * CreateUSBOTGObject(LPTSTR lpActivePath)
{
return new CBulverdeOTG(lpActivePath);
}
void DeleteUSBOTGObject(USBOTG * pUsbOtg )
{
if (pUsbOtg)
delete pUsbOtg;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -