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

📄 bul_usbfn.cpp

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: 

        bul_usbfn.cpp

Abstract:

        Bulverde USB Function Driver.

--*/

#include <windows.h>
#include <ceddk.h>
#include <ddkreg.h>
#include <nkintr.h> // needed for SYSINTR_NOP
#include "bul_usbfn.h"
#include "bulverde_base_regs.h"
#include <pm.h>

BOOL BulEndpoint::Init (PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
            BYTE bConfigurationValue, BYTE bInterfaceNumber, BYTE bAlternateSetting)
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    BOOL bReturn = FALSE;
    Lock();
    m_bConfigurationValue= bConfigurationValue;
    m_bInterfaceNumber = bInterfaceNumber;
    m_bAlternateSetting =bAlternateSetting;
#ifndef BULVERDE_MULTI_INTEFACE_FIXED
    m_bInterfaceNumber = 0;
    m_bAlternateSetting =0;
#endif
    m_fZeroPacket = FALSE;
    m_fStalled = FALSE;
    // Change address according
    
    if ( pEndpointDesc && m_pUsbDevice!=NULL && m_dwEndpointIndex < MAX_ENDPOINT_NUMBER) {
        pEndpointDesc->bEndpointAddress = (UCHAR)((pEndpointDesc->bEndpointAddress & 0x80) | m_dwEndpointIndex);
        m_epDesc = *pEndpointDesc;
        bReturn = ReInit();
    }
    Unlock();
    FUNCTION_LEAVE_MSG();
    return bReturn;
}
BOOL   BulEndpoint::ReInit()
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    UDCCSR udccsr;
    udccsr.ulValue = 0;
    udccsr.epbit.PC = udccsr.epbit.TRN= udccsr.epbit.SST = udccsr.epbit.FEF =1;
    WriteControlStatusRegister(udccsr.ulValue);
    DEBUGMSG(ZONE_INIT, (_T("%s (%d)udccsr.ulValue= 0x%x\r\n"),pszFname,m_dwEndpointIndex,udccsr.ulValue));
    
    UDCCRAX udccrax;
    udccrax.ulValue = 0;
    udccrax.bit.CN = (m_bConfigurationValue & 3);
    udccrax.bit.ISN = (m_bInterfaceNumber & 0x7);
    udccrax.bit.AISN = m_bAlternateSetting & 0x7;
    udccrax.bit.EN = m_epDesc.bEndpointAddress & 0xf;
    udccrax.bit.ET = m_epDesc.bmAttributes & 0x3;
    udccrax.bit.ED = ((m_epDesc.bEndpointAddress & 0x80)!=0?1:0);
    udccrax.bit.MPS = m_epDesc.wMaxPacketSize & 0x3ff ;
    
    udccrax.bit.DE = 0;
    // Only In and Isochronouse transfer can use double buffer
    if (((m_epDesc.bEndpointAddress & 0x80) != 0 || (m_epDesc.bmAttributes & 0x3) == 1 ) && m_fDoubleBuffer)
        udccrax.bit.DE = 1 ;
        
    udccrax.bit.EE = 1;
    WriteConfigurationRegister(udccrax.ulValue);
    DEBUGMSG(ZONE_INIT, (_T("%s(%d) udccrax.ulValue= 0x%x\r\n"),pszFname,m_dwEndpointIndex,udccrax.ulValue));
    FUNCTION_LEAVE_MSG();
    return TRUE;
}
DWORD BulEndpoint::StallEndpoint()
{
    UDCCSR udccsr, udccsrWrite;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    Lock();
    udccsr.ulValue = ReadControlStatusRegister();
    udccsrWrite.ulValue = 0;
    udccsrWrite.epbit.DME = udccsr.epbit.DME;
    udccsrWrite.epbit.FST = 1; // Force Stall.
    udccsrWrite.epbit.SST = 1; // Clear Previous Stall Sent if there is any.
    WriteControlStatusRegister(udccsrWrite.ulValue);
    m_fStalled = TRUE;
    Unlock();
    FUNCTION_LEAVE_MSG();
    return ERROR_SUCCESS;
}
DWORD BulEndpoint::ClearEndpointStall()
{
    Lock();
    m_fStalled = FALSE;
    Unlock();
    return ERROR_SUCCESS;
}
DWORD BulEndpoint::ResetEndpoint()
{
    UDCCSR udccsr;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    DEBUGMSG(ZONE_WARNING, (_T("ResetEndpoint+ (%d) UDCCSR =0x%x UDCCRAX = 0x%x"),m_dwEndpointIndex, ReadControlStatusRegister(),ReadConfigurationRegister()));
    Lock();
    udccsr.ulValue = ReadControlStatusRegister();
    udccsr.epbit.PC = udccsr.epbit.TRN= udccsr.epbit.SST = udccsr.epbit.FEF =1;
    WriteControlStatusRegister(udccsr.ulValue);
    Unlock();
    DEBUGMSG(ZONE_WARNING, (_T("ResetEndpoint- (%d) UDCCSR =0x%x UDCCRAX = 0x%x"),m_dwEndpointIndex, ReadControlStatusRegister(),ReadConfigurationRegister()));
    FUNCTION_LEAVE_MSG();
    return ERROR_SUCCESS;
}
DWORD BulEndpoint::IsEndpointHalted(PBOOL pfHalted )
{
    Lock();
    if (m_fStalled)
        IST(0);
    if (pfHalted)
        *pfHalted = m_fStalled;
    Unlock();
    return ERROR_SUCCESS;
}
PSTransfer BulEndpoint::CompleteTransfer(DWORD dwError)
{
    if (m_pCurTransfer) {
        PSTransfer  pCurTransfer = m_pCurTransfer;
        m_pCurTransfer->dwUsbError= dwError;
        m_pCurTransfer = NULL;
        return pCurTransfer ;
    }
    return NULL;
}

DWORD BulEndpoint::IssueTransfer(PSTransfer pTransfer )
{
    DWORD dwReturn = ERROR_SUCCESS;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    Lock();
    DEBUGMSG(ZONE_FUNCTION, (_T("ReadConfigurationRegister (%d) UDCCSR =0x%x"),m_dwEndpointIndex,ReadConfigurationRegister()));
    
    if (pTransfer!=NULL && m_pCurTransfer == NULL && (pTransfer->cbBuffer==0 || pTransfer->pvBuffer!=NULL) ) { // If it is valid.        
        if (((pTransfer->dwFlags & USB_IN_TRANSFER)!= 0 )== ((m_epDesc.bEndpointAddress & 0x80)!=0)) {
            pTransfer ->pvPddData = (PVOID)m_dwEndpointIndex;
            m_pCurTransfer = pTransfer;
            m_pCurTransfer->cbTransferred = 0;
            m_pCurTransfer->pvPddData = (PVOID) m_dwEndpointIndex;
            m_fZeroPacket = (m_pCurTransfer->cbBuffer== 0 || m_pCurTransfer->pvBuffer== 0);
            m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,TRUE);
            // Trigger First IST.
            IST(EPINT_PACKET_COMPLETE);
        }
        else 
            dwReturn = ERROR_INVALID_DATA;
    }
    else 
        dwReturn = ERROR_NOT_READY;
    Unlock();
    FUNCTION_LEAVE_MSG();
    ASSERT(dwReturn == ERROR_SUCCESS);
    return dwReturn ;
}
DWORD BulEndpoint::AbortTransfer(PSTransfer pTransfer )
{
    DWORD dwReturn = ERROR_SUCCESS;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    Lock();
    PSTransfer pNotifyTransfer = NULL;
    if (pTransfer == m_pCurTransfer && m_pCurTransfer!=NULL) {
        ResetEndpoint();
        pNotifyTransfer = CompleteTransfer(UFN_CANCELED_ERROR);
    }
    else
        dwReturn = ERROR_INVALID_DATA;
    Unlock();
    if (pNotifyTransfer)
        m_pUsbDevice->MddTransferComplete(pNotifyTransfer);
    FUNCTION_LEAVE_MSG();
    return dwReturn;
}
DWORD BulEndpoint::XmitData(PBYTE pBuffer, DWORD dwLength)
{
    SETFNAME();
    DEBUGMSG(ZONE_FUNCTION, (_T("%s pBuffer=0x%x, dwLegnth= 0x%x\r\n"),pszFname,pBuffer,dwLength));
    if (pBuffer==NULL || dwLength==0 )
        return 0;
    // Spec 12.4.2
    union {
        BYTE  bData[4];
        DWORD dwData;
    } ;
    if (dwLength > m_epDesc.wMaxPacketSize)
        dwLength = m_epDesc.wMaxPacketSize;
    
    for (DWORD dwIndex = 0; dwIndex< dwLength; ) { 
        for ( DWORD dwCount = 0; dwCount < sizeof(DWORD) && dwIndex< dwLength ; dwCount ++, dwIndex++) {
            bData[dwCount] = *(pBuffer++);
        }
        if (dwCount >= sizeof(DWORD)) {
            WriteDataRegister(dwData);
        }
        else {
            for (DWORD dwCount2=0; dwCount2 < dwCount; dwCount2 ++)
                WriteDataRegisterByte(bData[dwCount2]);
        }
    };
    DEBUGMSG(ZONE_FUNCTION, (_T("%s Complete dwLength = 0x%x\r\n"),pszFname,dwLength));
    return dwLength;
}
DWORD BulEndpoint::ReceiveData(PBYTE pBuffer, DWORD dwLength)
{
    SETFNAME();
    DEBUGMSG(ZONE_FUNCTION, (_T("%s pBuffer=0x%x, dwLegnth= 0x%x\r\n"),pszFname,pBuffer,dwLength));
    PREFAST_ASSERT(pBuffer!=NULL);
    // Spec 12.4.2
    union {
        BYTE  bData[4];
        DWORD dwData;
    } ;
    DWORD dwAvailableDataSize = ReadByteCountRegister();
    DWORD dwDataRead;
    DWORD dwIndex;
    DWORD dwTotalRead = 0;
    while (dwAvailableDataSize) {
        dwData = ReadDataRegister();
        if (dwAvailableDataSize>=sizeof(DWORD)) {
            dwAvailableDataSize -= sizeof(DWORD);
            dwDataRead = sizeof(DWORD);
        }
        else {
            dwDataRead = dwAvailableDataSize;
            dwAvailableDataSize = 0;
        }
        for (dwIndex = 0 ; dwIndex < dwDataRead && dwIndex < dwLength; dwIndex ++) {
            *(pBuffer++) = bData[dwIndex];
            dwTotalRead ++;
        }
        dwLength -= dwIndex;
    }
    DEBUGMSG(ZONE_FUNCTION, (_T("%s Complete dwTotalRead = 0x%x\r\n"),pszFname,dwTotalRead));
    return dwTotalRead;
}
void BulEndpoint::SendFakeFeature(BYTE bRequest,WORD wFeatureSelector)
{
    USB_DEVICE_REQUEST udr;
    PREFAST_DEBUGCHK(m_pUsbDevice!=NULL);
    udr.bmRequestType = USB_REQUEST_FOR_ENDPOINT;
    udr.bRequest = bRequest;
    udr.wValue = wFeatureSelector ;
    udr.wIndex = m_epDesc.bEndpointAddress ;
    udr.wLength =0;
    m_pUsbDevice->DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
BOOL BulEndpointZero:: Init( PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
            BYTE bConfigurationValue, BYTE bInterfaceNumber, BYTE bAlternateSetting)
{
    Lock();
    m_fBackedudr = FALSE;
    BOOL bReturn = FALSE;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    m_bConfigurationValue= bConfigurationValue;
    m_bInterfaceNumber = bInterfaceNumber;
    m_bAlternateSetting =bAlternateSetting;
    
    if ( pEndpointDesc && m_pUsbDevice!=NULL && m_dwEndpointIndex < MAX_ENDPOINT_NUMBER) {
        m_epDesc = *pEndpointDesc;
        if ((m_epDesc.wMaxPacketSize & 0x3ff) >= EP0_MAX_PACKET_SIZE) {
            m_epDesc.wMaxPacketSize = pEndpointDesc->wMaxPacketSize = EP0_MAX_PACKET_SIZE;
        
            bReturn = ReInit();
        }
    }
    Unlock();
    FUNCTION_LEAVE_MSG();
    return bReturn;
}
BOOL BulEndpointZero::ReInit()
{
    m_bNeedAck = FALSE;
    m_bSetupDirIn = FALSE;
    UDCCSR udccsr;
    udccsr.ulValue = 0;        
    udccsr.ep0bit.SA = udccsr.ep0bit.SST = udccsr.ep0bit.FTF =udccsr.ep0bit.OPC=1;
    WriteControlStatusRegister(udccsr.ulValue);
    
    UDCCR udccr;
    udccr.ulValue = 0;
    udccr.bit.EMCE = 1;
    m_pUsbDevice->WriteControlRegister(udccr.ulValue);
    return TRUE;
}
DWORD BulEndpointZero::ResetEndpoint()
{
    UDCCSR udccsr;
    SETFNAME();
    FUNCTION_ENTER_MSG();
    Lock();
    m_bNeedAck = FALSE;
    udccsr.ulValue = 0;        
    udccsr.ep0bit.SA = udccsr.ep0bit.SST = udccsr.ep0bit.FTF =udccsr.ep0bit.OPC=1;
    WriteControlStatusRegister(udccsr.ulValue);
    Unlock();
    FUNCTION_LEAVE_MSG();
    return ERROR_SUCCESS;
}
DWORD BulEndpointZero::IssueTransfer(PSTransfer pTransfer )
{   
    Lock();
    SETFNAME();
    FUNCTION_ENTER_MSG();
    DWORD dwReturn = ERROR_SUCCESS;
    if (pTransfer!=NULL && pTransfer->pvBuffer!=NULL && m_pCurTransfer == NULL) { // If it is valid.                
        m_pCurTransfer = pTransfer;
        m_pCurTransfer->cbTransferred = 0;
        m_pCurTransfer->pvPddData = (PVOID) m_dwEndpointIndex;
        
        UDCCSR udccsr;
        udccsr.ulValue = ReadControlStatusRegister();
        udccsr.ep0bit.FST = 0; //
        m_pCurTransfer->cbTransferred = 0;
        m_fZeroPacket = (m_pCurTransfer->cbBuffer== 0 || m_pCurTransfer->pvBuffer== 0);

        if (dwReturn == ERROR_SUCCESS) {
            m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,TRUE);
        }
        else {
            // We no long handle this because of return error.
            m_pCurTransfer = NULL;
        }
    }
    else 
        dwReturn = ERROR_INVALID_DATA;
    FUNCTION_LEAVE_MSG();
    Unlock();
    return dwReturn;
}
DWORD BulEndpointZero::SendControlStatusHandshake()
{
    Lock();
    SETFNAME();
    DWORD dwReturn = ERROR_SUCCESS ;
    if (m_pCurTransfer == NULL && m_bNeedAck) { // No Transfer.
        m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,TRUE);
        if (!m_bSetupDirIn) {
            UDCCSR udccsr;
            udccsr.ulValue = ReadControlStatusRegister();
            udccsr.ep0bit.SA = 0 ;
            udccsr.ep0bit.FST = 0; //
            udccsr.ep0bit.SST = 0;
            udccsr.ep0bit.IPR = 1; // Sent Zero Packet.
            udccsr.ep0bit.OPC = 0;
            WriteControlStatusRegister(udccsr.ulValue);
        }

⌨️ 快捷键说明

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