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

📄 bul_usbfn.cpp

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        m_bNeedAck = FALSE;
        if (m_fBackedudr) {
            m_bNeedAck = TRUE;
            m_bSetupDirIn = ((m_backup_udr.bmRequestType & USB_REQUEST_DEVICE_TO_HOST)!=0?TRUE:FALSE);
            m_fZeroPacket = FALSE;
            m_fBackedudr = FALSE;
            m_cur_udr = m_backup_udr ;
            m_pUsbDevice->DeviceNotification(UFN_MSG_SETUP_PACKET, (DWORD) &m_backup_udr);
            if (!m_fInIST) {
                IST(EPINT_PACKET_COMPLETE);
            }
        }
        else if (m_bSetupDirIn && !m_fInIST )
            IST(EPINT_PACKET_COMPLETE);
        DEBUGMSG(ZONE_TRANSFER, (_T("%s Complete\r\n"),pszFname));
    }
    else
        DEBUGMSG(ZONE_TRANSFER, (_T("%s Skipped\r\n"),pszFname));
    Unlock();
    return ERROR_SUCCESS;
}
DWORD   BulEndpointZero::IST(DWORD dwIRBit)
{
    Lock();
    BOOL bContinue = TRUE;
    m_fInIST = TRUE;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    if ((dwIRBit & EPINT_FIFO_ERROR)!=0) { // FIFO Error. End
        DWORD dwUdccsr;
        dwUdccsr = ReadControlStatusRegister();
        DEBUGMSG(ZONE_TRANSFER, (_T("FIFO Error on Endpoint Zero UDCCSR=0x%x"),dwUdccsr));
    };
    while (bContinue && (dwIRBit & EPINT_PACKET_COMPLETE)!=0) {
        bContinue = FALSE;
        m_fStalled = FALSE; // Endpoint Zero is auto clear stall condition.
        UDCCSR udccsr;
        udccsr.ulValue = ReadControlStatusRegister();
        DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero ReadControlStatusRegister()=0x%x\n"),udccsr.ulValue));
        udccsr.ep0bit.FST = 0;
        if (udccsr.ep0bit.SA !=0 && udccsr.ep0bit.OPC==0) {
            m_pUsbDevice->IncBadSetupCounter();
            RETAILMSG(1, (_T("Endpoint Zero FAILED SETUP  udccsr=0x%x. Sent STALL \n"),udccsr.ulValue));
            udccsr.ep0bit.FST = 1;
        }
        if (udccsr.ep0bit.OPC) {
            if ( udccsr.ep0bit.SA ) { // This is setup Packet.
                if (m_pCurTransfer) { // Outstanding transfer.
                    //DebugBreak();
                    DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero Current Transfer Canceled\n")));
                    WriteControlStatusRegister( udccsr.ulValue);
                    PSTransfer pTransfer = CompleteTransfer( UFN_CANCELED_ERROR );
                    Unlock();
                    m_pUsbDevice->MddTransferComplete(pTransfer);
                    Lock();
                }
                ASSERT(ReadByteCountRegister() == sizeof (USB_DEVICE_REQUEST));
                union {
                    USB_DEVICE_REQUEST udr;
                    DWORD dw8Byte[2];
                };
                dw8Byte[0] = ReadDataRegister();
                dw8Byte[1] = ReadDataRegister();
                DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero Setup bmRequestType = 0xx%x, bRequest=0x%x, wValue=0x%x,wIndex=0x%x,wLength=0x%x\n"),
                    udr.bmRequestType,udr.bRequest,udr.wValue,udr.wIndex,udr.wLength));
                
                if (m_bNeedAck) { // Previous setup haven't ack yet. Disable Interrupt and wait for the Ack.
                    m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,FALSE);
                    DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero Disable Interrupt")));
                    m_fBackedudr = TRUE;
                    m_backup_udr = udr;
                    WriteControlStatusRegister( udccsr.ulValue);
                   continue;
                }
                else {
                    m_bNeedAck = TRUE;
                    m_bSetupDirIn = ((udr.bmRequestType & USB_REQUEST_DEVICE_TO_HOST)!=0?TRUE:FALSE);
                    bContinue = TRUE ;
                    m_fZeroPacket = FALSE;
                    m_cur_udr = udr ;
                    WriteControlStatusRegister( udccsr.ulValue);
                    m_pUsbDevice->DeviceNotification(UFN_MSG_SETUP_PACKET, (DWORD) &udr);
                }
                continue;
            }
            else if ( ReadByteCountRegister() == 0 ) { // ACK from Host.
                bContinue = TRUE; 
            }
            else if (m_pCurTransfer ) {
                if((m_pCurTransfer->dwFlags & USB_IN_TRANSFER)==0) { // Out Data.
                    BOOL bComplete =  (ReadByteCountRegister()<m_epDesc.wMaxPacketSize);
                    DWORD dwSize = (m_pCurTransfer->cbTransferred< m_pCurTransfer->cbBuffer? m_pCurTransfer->cbBuffer-m_pCurTransfer->cbTransferred: 0);
                    if (dwSize!=0) {
                        dwSize= ReceiveData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred , dwSize);
                        m_pCurTransfer->cbTransferred += dwSize;
                    }

                    bComplete = (bComplete || (m_pCurTransfer->cbTransferred>= m_pCurTransfer->cbBuffer));
                    // Check for the completeion.
                    if ( bComplete ) {
                        WriteControlStatusRegister( udccsr.ulValue);
                        PSTransfer pTransfer =CompleteTransfer(UFN_NO_ERROR);
                        bContinue = TRUE;
                        Unlock();
                        m_pUsbDevice->MddTransferComplete(pTransfer);
                        Lock();
                        continue;
                    }
                }
                else { // Error
                    udccsr.ep0bit.FST = 1;
                }
            }
            else { // Transfer Not queue yet. 
                //m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,FALSE);
                // Do not clean OPC
                udccsr.ep0bit.OPC = 0;
            }

        }
        
        if (udccsr.ep0bit.IPR==0 ) {
        // Because the Ep0 is half duplex. We assume the direction is correct.
            if (m_pCurTransfer && (m_pCurTransfer->dwFlags & USB_IN_TRANSFER)!=0 &&
                    m_pCurTransfer->cbTransferred <= m_pCurTransfer->cbBuffer) {
                DWORD dwTotalData = m_pCurTransfer->cbBuffer - m_pCurTransfer->cbTransferred ;
                dwTotalData = min (dwTotalData,m_epDesc.wMaxPacketSize) ;
                // Spec 12.5.5
                DWORD dwReturn = XmitData(((PBYTE)m_pCurTransfer->pvBuffer)+ m_pCurTransfer->cbTransferred, dwTotalData );
                ASSERT(dwReturn == dwTotalData);
                m_pCurTransfer->cbTransferred += dwReturn;
                if (dwTotalData< m_epDesc.wMaxPacketSize) {
                    udccsr.ep0bit.IPR = 1;
                    m_fZeroPacket = FALSE;
                }
                else 
                    m_fZeroPacket = (m_cur_udr.wLength > m_pCurTransfer->cbTransferred);
            }
        }
        else 
            udccsr.ep0bit.IPR = 0 ; // Do not set when there is packet.
            
        if (udccsr.ep0bit.SST) { // Stall happens.
            m_pUsbDevice->IncEp0StallCounter() ;
            DEBUGMSG(ZONE_TRANSFER, (_T("Stall Sent on Zero endpoint =0x%x"),m_dwEndpointIndex));
        }
        // Clean the status.
        WriteControlStatusRegister( udccsr.ulValue);
        if (m_pCurTransfer &&m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer && !m_fZeroPacket ) {// Complete anyway
            PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
            Unlock();
            m_pUsbDevice->MddTransferComplete(pTransfer);
            Lock();            
        }
        
    }
    m_fInIST = FALSE;
    Unlock();
    FUNCTION_LEAVE_MSG();
    return ERROR_SUCCESS;
}
DWORD   BulEndpointIn::IST(DWORD dwIRBit)
{
    Lock();
    BOOL bContinue = TRUE;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    if ((dwIRBit & EPINT_FIFO_ERROR)!=0) { // FIFO Error. End
        DWORD dwUdccsr;
        dwUdccsr = ReadControlStatusRegister();
        DEBUGMSG(ZONE_WARNING, (_T("FIFO Error on Endpoint IN(%d) UDCCSR=0x%x"),m_dwEndpointIndex,dwUdccsr));
    }

    while (bContinue) 
    { // Loop until all the event clear.
        bContinue = FALSE;
        UDCCSR udccsr;
        udccsr.ulValue = ReadControlStatusRegister();
        DEBUGMSG(ZONE_TRANSFER, (_T(" IN::IST(%d) UDCCSR=0x%x"),m_dwEndpointIndex,udccsr.ulValue));
        if (m_fStalled && (udccsr.epbit.PC!=0 || udccsr.epbit.TRN!=0) ) {
            // Stall has been clear silently. So we generate Faking Clear Feature for Endpoint Zero
            m_fStalled = FALSE;
            udccsr.epbit.PC = udccsr.epbit.TRN = udccsr.epbit.FEF = 0;
            WriteControlStatusRegister(udccsr.ulValue);
            bContinue = TRUE;
            SendFakeFeature(USB_REQUEST_CLEAR_FEATURE,USB_FEATURE_ENDPOINT_STALL);
            continue;
        }
        if ( udccsr.epbit.PC!=0 ) { // Packet Complete.
            if (udccsr.epbit.DPE!=0 ) { // Data Packet Error
                WriteControlStatusRegister(udccsr.ulValue);
                PSTransfer pTransfer = CompleteTransfer( UFN_NOT_COMPLETE_ERROR );
                Unlock();
                m_pUsbDevice->MddTransferComplete(pTransfer);
                Lock();                
                continue;
            }
            if ( m_pCurTransfer && !m_fZeroPacket &&  m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
                WriteControlStatusRegister(udccsr.ulValue);        
                PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
                Unlock();
                m_pUsbDevice->MddTransferComplete(pTransfer);
                Lock();                
                continue;
            }
            bContinue = TRUE;
        }
        udccsr.epbit.SP = 0;
        if ( udccsr.epbit.FS!=0 && m_pCurTransfer!=NULL  && 
                (m_pCurTransfer->cbTransferred < m_pCurTransfer->cbBuffer || m_fZeroPacket) )  { // Include Eaqual for 0 packet.
            ASSERT((m_pCurTransfer->dwFlags & USB_IN_TRANSFER)!=NULL);
            DWORD dwXmitLength = (m_fZeroPacket?0:m_pCurTransfer->cbBuffer-m_pCurTransfer->cbTransferred);
            dwXmitLength = XmitData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred, dwXmitLength );
            m_pCurTransfer->cbTransferred += dwXmitLength;
            m_fZeroPacket = FALSE;
            if (dwXmitLength < m_epDesc.wMaxPacketSize) {
                udccsr.epbit.SP = 1;
                m_fZeroPacket = FALSE;
            }
            else
                m_fZeroPacket = FALSE;
            bContinue = TRUE;
        }
        if (udccsr.epbit.SST) {
            DEBUGMSG(ZONE_WARNING, (_T("Stall send on In Endpoint = 0x%x"),m_dwEndpointIndex));
            // We have to assume we clean stall here because this no more interrupt.
            udccsr.epbit.FST = 0 ;
            m_fStalled = FALSE;
            bContinue = TRUE;
            WriteControlStatusRegister(udccsr.ulValue);        
            SendFakeFeature(USB_REQUEST_CLEAR_FEATURE,USB_FEATURE_ENDPOINT_STALL);
            continue;
        }
        WriteControlStatusRegister(udccsr.ulValue);        
    }
    Unlock();
    FUNCTION_LEAVE_MSG();
    return ERROR_SUCCESS;
}
DWORD   BulEndpointOut::IST(DWORD dwIRBit)
{
    Lock();
    BOOL bContinue = TRUE;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    if ((dwIRBit & EPINT_FIFO_ERROR)!=0) { // FIFO Error. End
        DWORD dwUdccsr;
        dwUdccsr = ReadControlStatusRegister();
        DEBUGMSG(ZONE_WARNING, (_T("FIFO Error on Endpoint Out(%d) UDCCSR=0x%x"),m_dwEndpointIndex,dwUdccsr));
    }

    while (bContinue) {
        bContinue = FALSE;
        UDCCSR udccsr;
        udccsr.ulValue = ReadControlStatusRegister();
        DEBUGMSG(ZONE_TRANSFER, (_T(" Out::IST(%d) UDCCSR=0x%x"),m_dwEndpointIndex,udccsr.ulValue));
        if (m_fStalled && (udccsr.epbit.PC!=0 || udccsr.epbit.TRN!=0) ) {
            // Stall has been clear silently. So we generate Faking Clear Feature for Endpoint Zero
            m_fStalled = FALSE;
            udccsr.epbit.PC = udccsr.epbit.TRN = udccsr.epbit.FEF = 0;
            WriteControlStatusRegister(udccsr.ulValue);
            bContinue = TRUE;
            SendFakeFeature(USB_REQUEST_CLEAR_FEATURE,USB_FEATURE_ENDPOINT_STALL);
            continue;
        }
        // Unload in data if there is any
        if  ( udccsr.epbit.FS!=0 && m_pCurTransfer!=NULL  && 
                m_pCurTransfer->cbTransferred < m_pCurTransfer->cbBuffer)  { // Include Eaqual for 0 packet.
            DWORD dwReceiveLength = min (ReadByteCountRegister(),m_pCurTransfer->cbBuffer - m_pCurTransfer->cbTransferred);
            dwReceiveLength = ReceiveData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred,dwReceiveLength);
            m_pCurTransfer->cbTransferred += dwReceiveLength;
            if (m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
                WriteControlStatusRegister(udccsr.ulValue);
                PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
                Unlock();
                m_pUsbDevice->MddTransferComplete(pTransfer);
                Lock();
                continue;
            }
            else
                bContinue = TRUE;
                
        }
        if ( udccsr.epbit.PC!=0 ) { // Packet Complete.
            if (udccsr.epbit.DPE!=0 ) { // Data Packet Error
                WriteControlStatusRegister(udccsr.ulValue);
                PSTransfer pTransfer = CompleteTransfer( UFN_NOT_COMPLETE_ERROR );
                Unlock();
                m_pUsbDevice->MddTransferComplete(pTransfer);
                Lock();                
                continue;
            }
            if ( m_pCurTransfer) {
                BOOL fShortPacket = FALSE;
                if (udccsr.epbit.BNE_BNF!=0 &&
                        m_pCurTransfer->cbTransferred < m_pCurTransfer->cbBuffer)  { // Last Try.
                    DWORD dwReceiveLength = min (ReadByteCountRegister(),m_pCurTransfer->cbBuffer - m_pCurTransfer->cbTransferred);
                    dwReceiveLength = ReceiveData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred,dwReceiveLength);
                    m_pCurTransfer->cbTransferred += dwReceiveLength;
                    fShortPacket = (dwReceiveLength!=0 && dwReceiveLength<m_epDesc.wMaxPacketSize) ;
                    
                }
                if (m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
                    WriteControlStatusRegister(udccsr.ulValue);
                    PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
                    Unlock();
                    m_pUsbDevice->MddTransferComplete(pTransfer);
                    Lock();                
                    continue;
                }
                else if (udccsr.epbit.SP || fShortPacket ){
                    WriteControlStatusRegister(udccsr.ulValue);
                    PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
                    Unlock();
                    m_pUsbDevice->MddTransferComplete(pTransfer);
                    Lock();                
                    continue;
                }
                bContinue = TRUE;
            }
            else { // Not ready yet.
                //m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,FALSE);
                // Do not clean anything
                udccsr.epbit.PC = 0;
                bContinue = FALSE;
            }
        }
        if (udccsr.epbit.SST) {
            DEBUGMSG(ZONE_WARNING, (_T("Stall Sent on Out endpoint =0x%x"),m_dwEndpointIndex));
            m_fStalled = TRUE;
            bContinue = TRUE;
        }
        if (udccsr.ulValue)
            WriteControlStatusRegister(udccsr.ulValue);
    }
    Unlock();
    FUNCTION_LEAVE_MSG();
    return ERROR_SUCCESS;
}
BulUsbDevice::BulUsbDevice(LPCTSTR lpActivePath )
:   CRegistryEdit(lpActivePath)
,   CMiniThread (0, TRUE)   
{
    m_pUsbDevReg = NULL;
    m_hISTEvent = NULL;
    m_pDCCLKReg = NULL;
    m_fDoubleBuffer = TRUE;
    m_pvMddContext = NULL;
    m_dwCurConfigure = MAXDWORD;
    m_dwCurInterface = MAXDWORD;
    m_pfnNotify = NULL;
    m_CurPowerState = PwrDeviceUnspecified ;
    m_hParent = CreateBusAccessHandle(lpActivePath);  
    m_pOTGEventThread = NULL;
    m_fOTGSetupFeature = FALSE;
}

BulUsbDevice::~BulUsbDevice()
{
    if (m_pOTGEventThread)
        delete m_pOTGEventThread;
    if (m_hISTEvent) {
        m_bTerminated=TRUE;
        ThreadStart();
        SetEvent(m_hISTEvent);
        ThreadTerminated(1000);
        InterruptDisable( m_dwSysIntr );         
        CloseHandle(m_hISTEvent);
    };
    for (DWORD dwIndex =0 ; dwIndex <MAX_ENDPOINT_NUMBER; dwIndex ++) {
        RemoveObjectBy( dwIndex );
    }
    
    if (m_pUsbDevReg!=NULL) {
        WriteIntrCtr0Register(0);
        WriteIntrCtr1Register(0);
        WriteControlRegister(0) ;

⌨️ 快捷键说明

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