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

📄 ctd.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// 
// 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:  
//     CTd.cpp
// 
// Abstract: Provides interface to UHCI host controller
// 
// Notes: 
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2005-2006, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
//
//------------------------------------------------------------------------------


#include <windows.h>
#include "ctd.h"
#include "trans.h"
#include "cpipe.h"
#ifdef FREESCALE_HANG_DEBUG
#undef FREESCALE_HANG_DEBUG
#endif
//#define FREESCALE_HANG_DEBUG	1
//******************************************************************************
void * CNextLinkPointer::operator new(size_t stSize, CPhysMem * const pCPhysMem)
//
// Purpose: Operator overloading for "new" in CNextLinkPointer
//
// Parameters: 
//
// Returns: Virtual address of the allocated memory
//
// ******************************************************************
{
    PVOID pVirtAddr=0;
    PVOID pReturnLink=NULL;
    if (stSize<sizeof(PVOID))
        stSize = sizeof(PVOID);
    if (pCPhysMem && stSize ) {
        while (pVirtAddr==NULL) {
            if (!pCPhysMem->AllocateMemory( DEBUG_PARAM( TEXT("CNextLinkPointer")) stSize, (PUCHAR *)&pVirtAddr,CPHYSMEM_FLAG_HIGHPRIORITY | CPHYSMEM_FLAG_NOBLOCK)) {
                pVirtAddr=NULL;
                break;
            }
            else {
                // Structure can not span 4k Page bound. refer EHCI 3. Note.
                DWORD dwPhysAddr =  pCPhysMem->VaToPa((PUCHAR)pVirtAddr);
                if ((dwPhysAddr & 0xfffff000)!= ((dwPhysAddr + stSize-1) & 0xfffff000)) {
                    // Cross Page bound. trash it.
                    pVirtAddr= NULL;
                };
            }
        }
    }
    return pVirtAddr;
}

//******************************************************************
void CNextLinkPointer::operator delete(void * /*pointer*/)
//
// Purpose: Operator overloading for "delete" in CNextLinkPointer
//
// Parameters: 
//
// Returns: Nothing
//
// ******************************************************************
{
    ASSERT(FALSE); // Can not use this operator.
}

CITD::CITD(CITransfer * pIsochTransfer)
: m_pTrans(pIsochTransfer)
, m_CheckFlag(CITD_CHECK_FLAG_VALUE)
{
    ASSERT( (&(nextLinkPointer.dwLinkPointer))+ 15 == (&(iTD_BufferPagePointer[6].dwITD_BufferPagePointer)));// Check for Data Intergraty.
//    m_pNext=NULL;
    
    for (DWORD dwCount=0;dwCount<MAX_PHYSICAL_BLOCK;dwCount++) 
        iTD_BufferPagePointer[dwCount].dwITD_BufferPagePointer = 0;
    
    for (dwCount=0; dwCount<MAX_TRNAS_PER_ITD; dwCount++) 
        iTD_StatusControl[dwCount].dwITD_StatusControl=0;
    
    m_dwPhys = (m_pTrans?(m_pTrans->m_pCPipe->GetCPhysMem())-> VaToPa((PBYTE)this):0);
    
}

//******************************************************************
void CITD::ReInit(CITransfer * pIsochTransfer)
//
// Purpose: Re-initalize the high speed isoch transfer descriptor
//
// Parameters: pIsochTransfer - pointer to CITransfer
//
// Returns: Nothing
//
// ******************************************************************
{
    nextLinkPointer.dwLinkPointer=1;
    m_pTrans =pIsochTransfer ;    
    for (DWORD dwCount=0;dwCount<MAX_PHYSICAL_BLOCK;dwCount++) 
        iTD_BufferPagePointer[dwCount].dwITD_BufferPagePointer = 0;
    
    for (dwCount=0; dwCount<MAX_TRNAS_PER_ITD; dwCount++) 
        iTD_StatusControl[dwCount].dwITD_StatusControl=0;
    
    m_dwPhys = (m_pTrans?(m_pTrans->m_pCPipe->GetCPhysMem())-> VaToPa((PBYTE)this):0);
}

//********************************************************************
void CITD::SetIOC(BOOL bSet)
//
// Purpose: Set the Interrupt On Completion (IOC) bit on the Isoch Transfer descriptor
//
// Parameters: bSet - TRUE : Set IOC, FALSE: Clear IOC
//
// Returns: Nothing
//
// ******************************************************************
{
    CheckStructure ();
    if (bSet) {
        for (int iCount = MAX_TRNAS_PER_ITD-1;iCount>0;iCount--)
            if (iTD_StatusControl[iCount].iTD_SCContext.TransactionLength!=0) {
                iTD_StatusControl[iCount].iTD_SCContext.InterruptOnComplete=1;
                break;
            }
    }
    else {
        for (int iCount =0;iCount< MAX_TRNAS_PER_ITD;iCount++)
            if (iTD_StatusControl[iCount].iTD_SCContext.TransactionLength!=0) 
                iTD_StatusControl[iCount].iTD_SCContext.InterruptOnComplete=0;
    }
}

//****************************************************************************************************************
DWORD CITD::IssueTransfer(DWORD dwNumOfTrans,PDWORD pdwTransLenArray, PDWORD pdwFrameAddrArray,BOOL bIoc,BOOL bIn)
//
// Purpose: Perform actual transfer of the data on the high speed isochronous transfer
//
// Parameters: dwNumOfTrans - total number of transactions on the TD
//             pdwTransLenArray - array containing the len of each transaction
//             pdwFrameAddrArray - array containing address [buffer pointer] of each transaction
//             bIoc - if Interrupt On Completion (IOC) bit should be set
//             bIn - IN or OUT transcation
//
// Returns: Number of transcations successfully setup
//
// ******************************************************************
{
    CheckStructure ();
    if (dwNumOfTrans ==NULL || dwNumOfTrans>MAX_TRNAS_PER_ITD ||pdwTransLenArray==NULL || pdwFrameAddrArray==NULL) {
        ASSERT(FALSE);
        return 0;
    }
    // Initial Buffer Pointer.
    for (DWORD dwCount=0;dwCount<MAX_PHYSICAL_BLOCK;dwCount++) 
        iTD_BufferPagePointer[dwCount].dwITD_BufferPagePointer = 0;
    
    DWORD dwCurBufferPtr=0;
    DWORD dwCurValidPage = ((DWORD)-1) &  EHCI_PAGE_ADDR_MASK;
    for (dwCount=0;dwCount<MAX_TRNAS_PER_ITD +1  && dwCount < dwNumOfTrans +1 && dwCurBufferPtr < MAX_PHYSICAL_BLOCK ;dwCount++) {
        if (dwCurValidPage !=  ((*(pdwFrameAddrArray+dwCount))&EHCI_PAGE_ADDR_MASK) ) {
            dwCurValidPage = iTD_BufferPagePointer[dwCurBufferPtr].dwITD_BufferPagePointer 
                    = (*(pdwFrameAddrArray+dwCount) ) & EHCI_PAGE_ADDR_MASK;
            if (*(pdwTransLenArray +dwCount)==0) { // Endof Transfer
                break;
            }
            dwCurBufferPtr ++;
        }
    }

    // Add the Cross Boundary page pointer if any
    if (*(pdwFrameAddrArray+MAX_TRNAS_PER_ITD) != 0)
    {
        dwCurValidPage = iTD_BufferPagePointer[dwCurBufferPtr].dwITD_BufferPagePointer 
                  = (*(pdwFrameAddrArray+MAX_TRNAS_PER_ITD) ) & EHCI_PAGE_ADDR_MASK;        
        dwCurBufferPtr++;
    }
        

    USB_ENDPOINT_DESCRIPTOR endptDesc = m_pTrans->m_pCPipe->GetEndptDescriptor();
    
    iTD_BufferPagePointer[0].iTD_BPPContext1.DeviceAddress= m_pTrans->m_pCPipe->GetDeviceAddress();
    iTD_BufferPagePointer[0].iTD_BPPContext1.EndPointNumber=endptDesc.bEndpointAddress;
    iTD_BufferPagePointer[1].iTD_BPPContext2.MaxPacketSize=endptDesc.wMaxPacketSize & 0x7ff;
    iTD_BufferPagePointer[1].iTD_BPPContext2.Direction=(bIn?1:0);
    iTD_BufferPagePointer[2].iTD_BPPContext3.Multi=((endptDesc.wMaxPacketSize>>11) & 3)+1;
    ASSERT(((endptDesc.wMaxPacketSize>>11)&3)!=3);
    
    // Initial Transaction 
    dwCurValidPage = (*pdwFrameAddrArray) &  EHCI_PAGE_ADDR_MASK;
    dwCurBufferPtr=0;    
    for (dwCount=0; dwCount<MAX_TRNAS_PER_ITD; dwCount++) {
        iTD_StatusControl[dwCount].dwITD_StatusControl=0;
        if (dwCount < dwNumOfTrans) {
            if (dwCurValidPage != (*(pdwFrameAddrArray+dwCount)&EHCI_PAGE_ADDR_MASK)) {
                dwCurValidPage = *(pdwFrameAddrArray+dwCount)&EHCI_PAGE_ADDR_MASK;
                if (*(pdwTransLenArray+dwCount) != 0)
                    dwCurBufferPtr ++;                
            }
            iTD_StatusControl[dwCount].iTD_SCContext.TransactionLength = *(pdwTransLenArray+dwCount);
            iTD_StatusControl[dwCount].iTD_SCContext.TransationOffset  = (*(pdwFrameAddrArray+dwCount) & EHCI_PAGE_OFFSET_MASK);
            iTD_StatusControl[dwCount].iTD_SCContext.PageSelect = dwCurBufferPtr;
            iTD_StatusControl[dwCount].iTD_SCContext.Active = 1;
            if (dwCount == dwNumOfTrans -1 && bIoc )  { // if thiere is last one and interrupt on completion. do it.
                iTD_StatusControl[dwCount].iTD_SCContext.InterruptOnComplete=1;
            }
        }
        
        RETAILMSG(0, (TEXT("Status[%d]-TxLen(%d),TxOffset(0x%x),PageSel(%d)\r\n"),
            dwCount, iTD_StatusControl[dwCount].iTD_SCContext.TransactionLength,
            iTD_StatusControl[dwCount].iTD_SCContext.TransationOffset, iTD_StatusControl[dwCount].iTD_SCContext.PageSelect));

    }
    
    return (dwNumOfTrans<MAX_TRNAS_PER_ITD?dwNumOfTrans:MAX_TRNAS_PER_ITD);
    
};

//**********************************************************************************
CSITD::CSITD(CSITransfer * pTransfer,CSITD * pPrev)
: m_pTrans(pTransfer)
, m_CheckFlag(CSITD_CHECK_FLAG_VALUE)
// 
// Purpose: Constructor for Spilt Isochronous Transfer
//
// Parameters: pIsochTransfer - pointer to CITransfer
//
// Returns: Nothing
//
// ******************************************************************

{
    ASSERT((&(nextLinkPointer.dwLinkPointer))+ 6 == &(backPointer.dwLinkPointer)); // Check for Data Intergraty.
    sITD_CapChar.dwSITD_CapChar=0;
    microFrameSchCtrl.dwMicroFrameSchCtrl=0;
    sITD_TransferState.dwSITD_TransferState=0;
    sITD_BPPage[0].dwSITD_BPPage=0;
    sITD_BPPage[1].dwSITD_BPPage=0;
    backPointer.dwLinkPointer=1; // Invalid Back Link

    UCHAR S_Mask = (m_pTrans?m_pTrans->m_pCPipe->GetSMask():1);
    ASSERT(S_Mask!=0);
    if (S_Mask==0) // Start Mask has to be present
        S_Mask=1;
    microFrameSchCtrl.sITD_MFSCContext.SplitStartMask=S_Mask;
    microFrameSchCtrl.sITD_MFSCContext.SplitCompletionMask=(m_pTrans?m_pTrans->m_pCPipe->GetCMask():0);
    m_pPrev=pPrev;
    m_dwPhys =(m_pTrans?(m_pTrans->m_pCPipe->GetCPhysMem())-> VaToPa((PBYTE)this):0);
}

⌨️ 快捷键说明

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