⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bul_usbfn.cpp

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    udccr.ulValue = ReadControlRegister();
    udccr.bit.OEN = 1;
    udccr.bit.UDE = 1;
    udccr.bit.EMCE = 0 ;
    WriteControlRegister(udccr.ulValue);
    udccr.ulValue = ReadControlRegister();
    ASSERT(udccr.bit.EMCE==0);
    if (udccr.bit.EMCE==1)
        dwReturn = ERROR_INVALID_PARAMETER ;
    Unlock();
    FUNCTION_LEAVE_MSG();
    return dwReturn;
}
DWORD BulUsbDevice::Stop()
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    Lock();
    //ASSERT(m_pvMddContext!=NULL);
    //m_pvMddContext = NULL;
    // Enable Device Interrupt.
    WriteIntrCtr0Register(0);
    WriteIntrCtr1Register(0);    
    Unlock();
    FUNCTION_LEAVE_MSG();
    return ERROR_SUCCESS;
    
}
DWORD  BulUsbDevice::SetAddress( BYTE  bAddress )
{
    // Do we need handle this? NO?
    return ERROR_SUCCESS;
}
void BulUsbDevice::PowerMgr(BOOL bOff)
{
    Lock();
    if (bOff) {
        // Disable Device to simulate remove from bus.
        UDCCR udccr;
        udccr.ulValue = 0;
        udccr.bit.UDE  = 0 ;
        WriteControlRegister(udccr.ulValue);
    }
    else {
        UDCCR udccr;
        udccr.ulValue = 0;
        udccr.bit.UDE = 1 ;
        udccr.bit.OEN = 1;
        WriteControlRegister(udccr.ulValue);
        SetInterruptEvent(m_dwSysIntr);
    }
    Unlock();
}

void BulUsbDevice::PowerDown() 
{
    if (m_CurPowerState == PwrDeviceUnspecified) {
        PowerMgr(TRUE) ;
    }
}
void BulUsbDevice::PowerUp()
{
    m_fResumeOccurred = TRUE;
    if (m_CurPowerState == PwrDeviceUnspecified) {
        PowerMgr(FALSE) ;
    }
}
void BulUsbDevice::SetPowerState( CEDEVICE_POWER_STATE cpsNew )
{
    SETFNAME();
    
    // Adjust cpsNew.
    if (cpsNew != m_CurPowerState ) {
        if (cpsNew == D1 || cpsNew == D2) {
            // D1 and D2 are not supported.
            cpsNew = D0;
        }
        else if (m_CurPowerState== D4) {
            // D4 can only go to D0.
            cpsNew = D0;
        }
    }

    if (cpsNew != m_CurPowerState ) {
        BOOL bBusSucceed = FALSE;
        DEBUGMSG(ZONE_FUNCTION, (_T("%s Going from D%u to D%u\r\n"), pszFname, m_CurPowerState , cpsNew));
        if ( (cpsNew < m_CurPowerState) && m_hParent) {
            bBusSucceed = SetDevicePowerState(m_hParent, cpsNew, NULL);
            if (bBusSucceed) {
                PowerMgr(FALSE);
            }
        }

        switch (cpsNew) {
        case D0:
            KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr,sizeof(m_dwSysIntr), NULL, 0, NULL);
            break;
        case D3:
            KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &m_dwSysIntr,  sizeof(m_dwSysIntr), NULL, 0, NULL);
            break;
        case D4:
            KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr,  sizeof(m_dwSysIntr), NULL, 0, NULL);
            break;
        }

        if ( (cpsNew > m_CurPowerState ) && m_hParent  ) {
            bBusSucceed = SetDevicePowerState(m_hParent, cpsNew, NULL);
            if (bBusSucceed && cpsNew == D4) {
                PowerMgr(TRUE);
            }
        }
        m_CurPowerState = cpsNew;
    }
}
DWORD BulUsbDevice::IOControl( IOCTL_SOURCE source, DWORD dwCode, PBYTE  pbIn, DWORD cbIn, PBYTE pbOut, DWORD cbOut,PDWORD  pcbActualOut )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet = ERROR_INVALID_PARAMETER;

    switch (dwCode) {
    case IOCTL_UFN_GET_PDD_INFO:
        if ( source != BUS_IOCTL || pbOut == NULL || cbOut != sizeof(UFN_PDD_INFO) ) {
            break;
        }

        // Not currently supported.
        break;

    case IOCTL_BUS_GET_POWER_STATE:
        if (source == MDD_IOCTL) {
            PREFAST_DEBUGCHK(pbIn);
            DEBUGCHK(cbIn == sizeof(CE_BUS_POWER_STATE));

            PCE_BUS_POWER_STATE pCePowerState = (PCE_BUS_POWER_STATE) pbIn;
            PREFAST_DEBUGCHK(pCePowerState->lpceDevicePowerState);

            DEBUGMSG(ZONE_FUNCTION, (_T("%s IOCTL_BUS_GET_POWER_STATE\r\n"), pszFname));

            *pCePowerState->lpceDevicePowerState = m_CurPowerState;

            dwRet = ERROR_SUCCESS;
        }
        break;

    case IOCTL_BUS_SET_POWER_STATE:
        if (source == MDD_IOCTL) {
            PREFAST_DEBUGCHK(pbIn);
            DEBUGCHK(cbIn == sizeof(CE_BUS_POWER_STATE));

            PCE_BUS_POWER_STATE pCePowerState = (PCE_BUS_POWER_STATE) pbIn;

            PREFAST_DEBUGCHK(pCePowerState->lpceDevicePowerState);
            DEBUGCHK(VALID_DX(*pCePowerState->lpceDevicePowerState));

            DEBUGMSG(ZONE_FUNCTION, (_T("%s IOCTL_BUS_GET_POWER_STATE(D%u)\r\n"), pszFname, *pCePowerState->lpceDevicePowerState));
            SetPowerState( *pCePowerState->lpceDevicePowerState );
            dwRet = ERROR_SUCCESS;
        }
        break;
    }
    FUNCTION_LEAVE_MSG();
    return dwRet;
}
void    BulUsbDevice::ISTProcess()
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    m_ISTLock.Lock();
    DWORD dwIntr0Status = ReadIntrStatus0Register() ;
    DWORD dwIntr1Status = ReadIntrStatus1Register() ; 
    

    WriteIntrStatus0Register(dwIntr0Status) ;
    WriteIntrStatus1Register(dwIntr1Status) ; 
    DEBUGMSG(ZONE_FUNCTION, (_T("%s : BulUsbDevice dwIntr0Status 0x%x, dwIntr1Status 0x%x, dwIntr0Ctrl=0x%x, dwIntr11Ctrl=0x%x, OTGICR=0x%x \r\n "), pszFname, dwIntr0Status,dwIntr1Status,ReadIntrCtr0Register(), ReadIntrCtr1Register()));


    if (m_fIsCableAttached != IsCableAttached() || m_fResumeOccurred ) {
        m_fIsCableAttached = IsCableAttached();

        UDCCR udccr;
        udccr.ulValue = ReadControlRegister();
        udccr.bit.EMCE = 0 ;
        if (m_fIsCableAttached || m_fResumeOccurred ) {
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : Attach Detected\r\n"),pszFname));
            m_fResumeOccurred = FALSE ;
            ReInit();
        }
        else {
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : Detach Detected\r\n"),pszFname));
            DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_DETACH);
        }
    }
    // Processing Device Interrupt 
    if ( (dwIntr1Status & UDCISR1_IRCC)!=0 || m_fOTGSetupFeature) { // Setup Config or Setup Interface has been received.
        USB_DEVICE_REQUEST udr;
        UDCCR udccr;
        udccr.ulValue = ReadControlRegister();
        DEBUGMSG(ZONE_FUNCTION, (_T("%s : Setup Configuration and Interface received UDCCR=0x%x.\r\n"),pszFname,udccr.ulValue));
        udccr.bit.SMAC = 1;
        udccr.bit.EMCE = 0 ;
        WriteControlRegister(udccr.ulValue);
        m_fOTGSetupFeature = FALSE;
        if (udccr.bit.ACN != m_dwCurConfigure) { // COnfiguration has changed.
            udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
            udr.bRequest = USB_REQUEST_SET_CONFIGURATION;
            udr.wValue = (USHORT) udccr.bit.ACN;
            udr.wIndex =  0;
            udr.wLength =0;
            m_dwCurConfigure = udccr.bit.ACN ;
            DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
        }
        if (udccr.bit.AIN*0x100 + udccr.bit.AAISN != m_dwCurInterface) {
            udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
            udr.bRequest = USB_REQUEST_SET_INTERFACE;
            udr.wValue = (USHORT) udccr.bit.AAISN;
            udr.wIndex = (USHORT) udccr.bit.AIN;
            udr.wLength =  0;
            m_dwCurInterface = udccr.bit.AIN*0x100 + udccr.bit.AAISN ;
            // We can not do this because MDD will stall the endpoint.
            //DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
        }
        // For OTG.
        if (udccr.bit.BHNP !=0 &&  udccr.bit.BHNP!= m_prevUDCR.bit.BHNP) { // Host Set HNP Feature.
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : BHNP Detected\r\n"),pszFname));
            udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
            udr.bRequest = USB_REQUEST_SET_FEATURE ;
            udr.wValue =  USB_FEATURE_B_HNP_ENABLE;
            udr.wIndex =  0 ;
            udr.wLength =0;
            m_prevUDCR.bit.BHNP =  udccr.bit.BHNP ;
            DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
        }
        if (udccr.bit.AHNP !=0  && udccr.bit.AHNP != m_prevUDCR.bit.AHNP) {// Host Set HNP Support.
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : AHNP Detected\r\n"),pszFname));
            udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
            udr.bRequest = USB_REQUEST_SET_FEATURE ;
            udr.wValue =  USB_FEATURE_A_HNP_SUPPORT;
            udr.wIndex =  0 ;
            udr.wLength =0;
            m_prevUDCR.bit.AHNP = udccr.bit.AHNP;
            DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
        }
        if (udccr.bit.AALTHNP!=0 && udccr.bit.AALTHNP != m_prevUDCR.bit.AALTHNP) { // Host Set Alter HNP Support.
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : AALTHNP Detected\r\n"),pszFname));
            udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
            udr.bRequest = USB_REQUEST_SET_FEATURE ;
            udr.wValue =  USB_FEATURE_A_ALT_HNP_SUPPORT;
            udr.wIndex =  0 ;
            udr.wLength =0;
            m_prevUDCR.bit.AALTHNP = udccr.bit.AALTHNP;
            DeviceNotification(UFN_MSG_SETUP_PACKET,(DWORD) &udr);
        }
        
    }
    if ( dwIntr1Status & UDCISR1_IRRU) { // Resume Detected
        DEBUGMSG(ZONE_FUNCTION, (_T("%s : Resume Detected\r\n"),pszFname));
        DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_RESUME);
    }
    if (dwIntr1Status & UDCISR1_IRSU ) { // Suspend Detected.
        DEBUGMSG(ZONE_FUNCTION, (_T("%s : Suspend Detected\r\n"),pszFname));
        DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_SUSPEND);
    }
    if (dwIntr1Status & UDCISR1_IRRS) { // Reset Detected.
        DEBUGMSG(ZONE_FUNCTION, (_T("%s : Reset Detected\r\n"),pszFname));
        // Set DETACH First
        DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_DETACH);
        // Set ATTACH.
        DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_ATTACH);
        // Set Reset
        DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_RESET);
        // This device can only support FULL Speed.
        DeviceNotification( UFN_MSG_BUS_SPEED, BS_FULL_SPEED);
        // The HW Filters the Set Address ... Fake it here
        DeviceNotification( UFN_MSG_SET_ADDRESS, 0xFF);
        UDCCR udccr;
        USB_DEVICE_REQUEST udr;
        udccr.ulValue = ReadControlRegister();
        if (udccr.bit.ACN == m_dwCurConfigure) { // COnfiguration has changed.
            udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
            udr.bRequest = USB_REQUEST_SET_CONFIGURATION;
            udr.wValue = (USHORT) udccr.bit.ACN;
            udr.wIndex =  0;
            udr.wLength =0;
            DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
        }
        else { // THis device is not configured
            m_dwCurConfigure = MAXDWORD ;
        }
        if (udccr.bit.AIN*0x100 + udccr.bit.AAISN == m_dwCurInterface) {
            udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
            udr.bRequest = USB_REQUEST_SET_INTERFACE;
            udr.wValue = (USHORT) udccr.bit.AAISN;
            udr.wIndex = (USHORT) udccr.bit.AIN;
            udr.wLength =  0;
            // We can not do this because MDD will stall the endpoint.
            //DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
        }
        else { // THis device is not configured
            m_dwCurInterface = MAXDWORD ;
        }
        m_prevUDCR.ulValue = 0 ; // Reset Should clear all previous state;
    }
    BulEndpoint *pEndpoint;
    DWORD dwIntrStatusCopy = dwIntr0Status;
    for (DWORD dwIndex =0 ; dwIndex < UDCIR0_MAX ; dwIndex ++ ) {
        if  ((dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ))!=0 ) {
            if ((pEndpoint = ObjectIndex(dwIndex)) != NULL ) {
                pEndpoint->IST(dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ));
                pEndpoint->DeRef();
            }
        }
        dwIntrStatusCopy >>=2;
    }
    dwIntrStatusCopy = dwIntr1Status;
    for (DWORD dwIndex =UDCIR0_MAX ; dwIndex < MAX_ENDPOINT_NUMBER ; dwIndex ++ ) {
        if  ((dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ))!=0 ) {
            if ((pEndpoint = ObjectIndex(dwIndex)) != NULL ) {
                pEndpoint->IST(dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ));
                pEndpoint->DeRef();
            }
        }
        dwIntrStatusCopy >>=2;
    }
    m_ISTLock.Unlock();
    FUNCTION_LEAVE_MSG();
}

#ifdef DEBUG
const DWORD cISTTimeOut = 2000;
#else
const DWORD cISTTimeOut = INFINITE ;
#endif
DWORD BulUsbDevice::ThreadRun()
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    while (!m_bTerminated && m_hISTEvent!=NULL) {
        if ( WaitForSingleObject(m_hISTEvent,cISTTimeOut) != WAIT_OBJECT_0) {
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : Interrupt Time out dwIntr0Status=0x%x dwIntr1Status = 0x%x. dwIntr0Ctrl=0x%x, dwIntr11Ctrl=0x%x\r\n"),pszFname,
                ReadIntrStatus0Register(), ReadIntrStatus1Register(),ReadIntrCtr0Register(), ReadIntrCtr1Register()));
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : ControlRegister() =0x%x ControlStatusRegister(0)=0x%x\r\n"),pszFname,
                 ReadControlRegister(), ReadUDCRegister( ENDPOINT_CONTROL_STATUS_REGISTER_OFFSET + 0 ) ));
            continue;
        }
        ISTProcess();
        InterruptDone(m_dwSysIntr);
    }
    FUNCTION_LEAVE_MSG();
    return 1;
}

BulOTGEventThread::BulOTGEventThread(  BulUsbDevice& BulverUSBDevice, HANDLE& hOTGEvent,DWORD dwPrority)
:   m_BulverUSBDevice(BulverUSBDevice)
,   m_hOTGEvent (hOTGEvent)
,   m_dwPriority(dwPrority)
,   CMiniThread (0, TRUE) 
{
}
BulOTGEventThread::~BulOTGEventThread()
{
    m_bTerminated=TRUE;
    ThreadStart();
    SetEvent(m_hOTGEvent);
    ThreadTerminated(1000);
}

DWORD   BulOTGEventThread::ThreadRun()
{
    while (!m_bTerminated && m_hOTGEvent!=NULL) {
        if ( WaitForSingleObject(m_hOTGEvent,INFINITE)== WAIT_OBJECT_0) {
            m_BulverUSBDevice.OTGSetupFeature();
        }
        else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -