bul_usbfn.cpp

来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,861 行 · 第 1/5 页

CPP
1,861
字号
    udccr.ulValue = ReadControlRegister();
    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);
#ifndef ENABLE_SERIAL_AUTO_CONNECTION
        m_fIsCableAttached = FALSE;
#endif
        CablePowerOff();
    }
    else {
        UDCCR udccr;
        udccr.ulValue = 0;
        udccr.bit.UDE = 1 ;
        WriteControlRegister(udccr.ulValue);
    }
    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);
            if (m_fResumeOccurred)
            {
               m_fForceResume = FALSE;
               ReInit();
#ifdef ENABLE_SERIAL_AUTO_CONNECTION
               if (m_fIsCableAttached) {
                  RETAILMSG(1, (TEXT("----->BulUsbDevice::SetPowerState - Attach\r\n")));
                  m_fIsCableAttached = FALSE;
                  SetEvent(m_hISTEvent);
               }
               else {
                  RETAILMSG(1, (TEXT("----->BulUsbDevice::SetPowerState - Detach\r\n")));
                  m_fResumeOccurred = FALSE;
               }
#else
               CablePowerOn();
#endif
            };
            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;
}

#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;
        }
        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\r\n "), pszFname, dwIntr0Status,dwIntr1Status,ReadIntrCtr0Register(), ReadIntrCtr1Register() ));

#ifdef ENABLE_SERIAL_AUTO_CONNECTION
        if (m_fResumeOccurred)    {
           m_fResumeOccurred = FALSE;
           Sleep(5000);
           m_fIsCableAttached = FALSE;
           DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_DETACH);

           Sleep(5000);
           CablePowerOn();

           m_fForceResume = TRUE;
           continue;
        };
#endif

        // Check Cable in any Interrupt.
//      if (m_fIsCableAttached != IsCableAttached()) {
        if ((m_fIsCableAttached != IsCableAttached()) && (!m_fForceResume)) {
            m_fIsCableAttached = IsCableAttached();

             UDCCR udccr;
            udccr.ulValue = ReadControlRegister();
            udccr.bit.EMCE = 0 ;
            if (m_fIsCableAttached) {
                DEBUGMSG(ZONE_FUNCTION, (_T("%s : Attach Detected\r\n"),pszFname));
                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) { // 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);
            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);
            }
            
        }
        if ( dwIntr1Status & UDCISR1_IRRU) { // Resume Detected
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : Resume Detected\r\n"),pszFname));

#ifdef ENABLE_SERIAL_AUTO_CONNECTION
            if (m_fForceResume)
            {
               UDCCR udccr;
               udccr.ulValue = ReadControlRegister();
               udccr.bit.UDR = 0 ;
               WriteControlRegister(udccr.ulValue);
               m_fForceResume = FALSE;
            }
#endif

        }
        if (dwIntr1Status & UDCISR1_IRSU ) { // Suspend Detected.
            DEBUGMSG(ZONE_FUNCTION, (_T("%s : Suspend Detected\r\n"),pszFname));

#ifdef ENABLE_SERIAL_AUTO_CONNECTION
            if (m_fForceResume)
            {
               UDCCR udccr;
               udccr.ulValue = ReadControlRegister();
               udccr.bit.UDR = 1 ;
               WriteControlRegister(udccr.ulValue);
               continue;
            }
#endif
        }
        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 ;
            }

        }
        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;
        }
        InterruptDone(m_dwSysIntr);
    }
    FUNCTION_LEAVE_MSG();
    return 1;
}


DWORD
WINAPI
UfnPdd_Deinit(
    PVOID pvPddContext

⌨️ 快捷键说明

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