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

📄 test.cpp

📁 mx27 f14v2 源代码。包括ADS板上诸多驱动的源码。
💻 CPP
字号:
//-----------------------------------------------------------------------------
//
// 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.
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004-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
//
//-----------------------------------------------------------------------------
//
//  File:  test.cpp
//
//  This file contains test code for the DMA driver.
//
//-----------------------------------------------------------------------------
#include "main.h"
#include "globals.h"
#include "bsp.h"

typedef __int64 timer_type;
//-----------------------------------------------------------------------------
// External Functions


//-----------------------------------------------------------------------------
// External Variables


//-----------------------------------------------------------------------------
// Defines
#define DMA_TEST_CHANNEL1 15
#define DMA_TEST_CHANNEL2 14

#define IRQ_TEST1 IRQ_DMACH15
#define IRQ_TEST2 IRQ_DMACH14

#ifdef DMAC_CHANNEL_INVALID
#undef DMAC_CHANNEL_INVALID
#endif
#define DMAC_CHANNEL_INVALID 0xff
//-----------------------------------------------------------------------------
// Types


//-----------------------------------------------------------------------------
// Global Variables


//-----------------------------------------------------------------------------
// Local Functions


//-----------------------------------------------------------------------------
// Local Variables


//------------------------------------------------------------------------------
//
// Function: OpenCloseChanTest
//
// This function tests open and close operation of the DMA virtual channels.
// The test will attempt to open all available channels and verify that the
// correct virtual channel ID is returned.  All successfully opened channels
// are then closed.
//
// Parameters:
//      uiMsg
//           [in] Message code.
//
//      tpParam
//           [in] Additional message-dependent data.
//
//      lpFTE
//           [in] Function table entry that generated this call.
//
// Returns:
//      TPR_PASS if the test passed, TPR_FAIL if the test fails, or possibly other
//      special conditions.
//
//------------------------------------------------------------------------------
TESTPROCAPI OpenCloseChanTest(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
{
    INT i, rc = TPR_PASS;
    UINT8 chan[DMAC_NUM_CHANNELS];

    // The shell doesn't necessarily want us to execute the test. Make sure
    // first.
    if(uMsg != TPM_EXECUTE)
    {
        return TPR_NOT_HANDLED;
    }

    g_pKato->Log(LOG_COMMENT, TEXT("Starting OpenCloseChanTest..."));

    // Clear out the channel array
    memset(chan, 0, sizeof(chan));

    // For each available channel
    for (i = 0; i < DMAC_NUM_CHANNELS; i++)
    {
        // Get a channel handle
        chan[i] = DDKDmacRequestChan(i);
        RETAILMSG(1, (TEXT("DDKDmacRequestChan(%d) return 0x%x\r\n"), i, chan[i]));

    }

    // Determine number of channels successfully opened
    for (i = 0; i < DMAC_NUM_CHANNELS; i++)
    {
        // Stop once we hit open request failure
        if (chan[i] == DMAC_CHANNEL_INVALID) break;

    }

    // If we did not open any channels successfully
    if (i == 0)
    {
        g_pKato->Log(LOG_FAIL, TEXT("FAILURE:  OpenCloseChanTest could not open any channels"));
        rc = TPR_FAIL;
    }
    else
    {
        g_pKato->Log(LOG_COMMENT, TEXT("Successfully opened %d channels"), i);
    }

    // Make sure remaining open requests returned open failure
    for ( ; i < DMAC_NUM_CHANNELS; i++)
    {
        // Stop if we hit any open request successes
        if (chan[i] != DMAC_CHANNEL_INVALID) break;

    }

    // If we hit more open request successes
    if (i != DMAC_NUM_CHANNELS)    
    {
        g_pKato->Log(LOG_FAIL, TEXT("FAILURE:  OpenCloseChanTest opened suceeded beyond available channels"));
        rc = TPR_FAIL;
    }


    // Close all channels successfully opened
    for (i = 0; i < DMAC_NUM_CHANNELS; i++)
    {
        // If open was successful
        if (chan[i] !=  DMAC_CHANNEL_INVALID)
        {
            if (! DDKDmacReleaseChan(chan[i]))
            {
                g_pKato->Log(LOG_FAIL, TEXT("DDKDmacReleaseChan failed:  chan[%d] = %d"), i, chan[i]);
                rc = TPR_FAIL;
            }
            else
                g_pKato->Log(LOG_COMMENT, TEXT("DDKDmacReleaseChan success: chan[%d] = %d"), i, chan[i]);
        }
    }

    g_pKato->Log(LOG_COMMENT, TEXT("Ending OpenCloseChanTest..."));

    return rc;

}


//------------------------------------------------------------------------------
//
// Function: Mem2MemTest
//
// This function tests the DMA's ability to perform a memory-to-memory
// transfer. Two virtual channels are requested and then two buffers are used
// to define a memory transfer.  The transfer is done in both directions and
// the results are verified.  This transfer is interrupt-driven and uses
// the standard OAL interrupt registration procedures normally used by
// device drivers.
//
// Parameters:
//      uiMsg
//           [in] Message code.
//
//      tpParam
//           [in] Additional message-dependent data.
//
//      lpFTE
//           [in] Function table entry that generated this call.
//
// Returns:
//      TPR_PASS if the test passed, TPR_FAIL if the test fails, or possibly other
//      special conditions.

//
//------------------------------------------------------------------------------
TESTPROCAPI Mem2MemTest(UINT uMsg, TPPARAM tpParam, LPFUNCTION_TABLE_ENTRY lpFTE)
{
    INT rc = TPR_FAIL;
    DMA_ADAPTER_OBJECT dmaAdapter = { sizeof(DMA_ADAPTER_OBJECT), Internal, 0 };
    PHYSICAL_ADDRESS phyAddr[4];
    PUINT8 pBuf[4];
    UINT8 chan1, chan2;
    HANDLE hEvent1 = NULL;
    HANDLE hEvent2 = NULL;

    UINT32 irq;
    UINT32 sysintr1 = SYSINTR_UNDEFINED;
    UINT32 sysintr2 = SYSINTR_UNDEFINED;
    //UINT32 status[2];
    UINT32 bufSize = 32*1024;
    DMAC_CHANNEL_CFG dmaCfg1, dmaCfg2;

    timer_type finish_count_1, start_count_1;
    timer_type finish_count_2, start_count_2;
    timer_type resolution;

    QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>(&resolution) );


            
    // The shell doesn't necessarily want us to execute the test. Make sure
    // first.
    if(uMsg != TPM_EXECUTE)
    {
        return TPR_NOT_HANDLED;
    }

    g_pKato->Log(LOG_COMMENT, TEXT("Starting Mem2MemTest..."));

    // Request the first memory-to-memory channel
    chan1 = DDKDmacRequestChan(DMA_TEST_CHANNEL1);

    if (chan1 == DMAC_CHANNEL_INVALID) 
    {
        g_pKato->Log(LOG_FAIL, TEXT("DDKDmacRequestChan failed!"));
        goto cleanUp;
    }

    // Request the second memory-to-memory channel
    chan2 = DDKDmacRequestChan(DMA_TEST_CHANNEL2);

    if (chan2 == DMAC_CHANNEL_INVALID) 
    {
        g_pKato->Log(LOG_FAIL, TEXT("DDKDmacRequestChan failed!"));
        goto cleanUp;
    }


    g_pKato->Log(LOG_COMMENT, TEXT("CHAN1 = %d"), chan1);
    g_pKato->Log(LOG_COMMENT, TEXT("CHAN2 = %d"), chan2);
    
    // Allocate buffers for memory-to-memory transfer testing
    pBuf[0] = (PUINT8) HalAllocateCommonBuffer(&dmaAdapter, 4*bufSize, &phyAddr[0], FALSE);
    if (pBuf[0] == NULL)
    {
        g_pKato->Log(LOG_FAIL, TEXT("HalAllocateCommonBuffer failed!"));
        goto cleanUp;
    }
            
    pBuf[1] = pBuf[0] + bufSize;
    pBuf[2] = pBuf[1] + bufSize;
    pBuf[3] = pBuf[2] + bufSize;

    phyAddr[1].LowPart = phyAddr[0].LowPart + bufSize;
    phyAddr[2].LowPart = phyAddr[1].LowPart + bufSize;
    phyAddr[3].LowPart = phyAddr[2].LowPart + bufSize;
    
    g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[0] UA = 0x%x, PA = 0x%x "), 
        pBuf[0], phyAddr[0].LowPart);
    g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[1] UA = 0x%x, PA = 0x%x "), 
        pBuf[1], phyAddr[1].LowPart);
    g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[2] UA = 0x%x, PA = 0x%x "), 
        pBuf[2], phyAddr[2].LowPart);
    g_pKato->Log(LOG_COMMENT, TEXT("DMA common buffer[3] UA = 0x%x, PA = 0x%x "), 
        pBuf[3], phyAddr[3].LowPart);

    // Create event for signaling end of transfer
    hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
    hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (hEvent1 == NULL || hEvent2 == NULL)
    {
        g_pKato->Log(LOG_FAIL, TEXT("CreateEvent failed!"));
        goto cleanUp;
    }

    // Request the first SYSINTR from OAL
    // Request channel may turn out return different available channel no
    irq = IRQ_DMACH0+chan1;

    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(irq), 
        &sysintr1, sizeof(sysintr1), NULL))
    {
        g_pKato->Log(LOG_FAIL, TEXT("IOCTL_HAL_REQUEST_SYSINTR failed!"));
        goto cleanUp;
    }        
    
    g_pKato->Log(LOG_COMMENT, TEXT("IRQ1 = %d, SYSINTR1 = %d"), irq, sysintr1);

    // Request the second SYSINTR from OAL
    // Request channel may turn out return different available channel no
    irq = IRQ_DMACH0+chan2;

    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(irq), 
        &sysintr2, sizeof(sysintr2), NULL))
    {
        g_pKato->Log(LOG_FAIL, TEXT("IOCTL_HAL_REQUEST_SYSINTR failed!"));
        goto cleanUp;
    }        
    
    g_pKato->Log(LOG_COMMENT, TEXT("IRQ2 = %d, SYSINTR2 = %d"), irq, sysintr2);

    // Register our interrupt 
    if (!InterruptInitialize(sysintr1, hEvent1, NULL, 0))
    {
        g_pKato->Log(LOG_FAIL, TEXT("InterruptInitialize failed!"));
        goto cleanUp;
    }

     if (!InterruptInitialize(sysintr2, hEvent2, NULL, 0))
    {
        g_pKato->Log(LOG_FAIL, TEXT("InterruptInitialize failed!"));
        goto cleanUp;
    }        
        
        
    // Initialize buffers
    memset(pBuf[0], 0x00, bufSize);
    memset(pBuf[1], 0xFF, bufSize);
    memset(pBuf[2], 0xFF, bufSize);
    memset(pBuf[3], 0x00, bufSize);

  
    dmaCfg1.SrcAddr = phyAddr[0].LowPart;
    dmaCfg1.DstAddr = phyAddr[2].LowPart;
    dmaCfg1.DataSize = bufSize;
    dmaCfg1.DstMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
    dmaCfg1.SrcMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
    dmaCfg1.MemDirIncrease = TRUE;
    dmaCfg1.DstSize = DMAC_TRANSFER_SIZE_32BIT;
    dmaCfg1.SrcSize = DMAC_TRANSFER_SIZE_32BIT;
    dmaCfg1.RepeatType = DMAC_REPEAT_DISABLED;
    dmaCfg1.ExtReqEnable = FALSE;
    //dmaCfg1.ReqSrc = 0;
    dmaCfg1.BurstLength = 4;
    dmaCfg1.ReqTimeout = FALSE;
    dmaCfg1.ReqTOCounter = 0;
    dmaCfg1.BusClkCounter = 0;

    dmaCfg2.SrcAddr = phyAddr[1].LowPart;
    dmaCfg2.DstAddr = phyAddr[3].LowPart;
    dmaCfg2.DataSize = bufSize;
    dmaCfg2.DstMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
    dmaCfg2.SrcMode = DMAC_TRANSFER_MODE_LINEAR_MEMORY;
    dmaCfg2.MemDirIncrease = TRUE;
    dmaCfg2.DstSize = DMAC_TRANSFER_SIZE_32BIT;
    dmaCfg2.SrcSize = DMAC_TRANSFER_SIZE_32BIT;
    dmaCfg2.RepeatType = DMAC_REPEAT_DISABLED;
    dmaCfg2.ExtReqEnable = FALSE;
    //dmaCfg2.ReqSrc = 0;
    dmaCfg2.BurstLength = 4;
    dmaCfg2.ReqTimeout = FALSE;
    dmaCfg2.ReqTOCounter = 0;
    dmaCfg2.BusClkCounter = 0;


    if(DDKDmacConfigureChan(chan1, &dmaCfg1) == DMAC_CHANNEL_INVALID)
    {
         g_pKato->Log(LOG_FAIL, TEXT("DDKDmacConfigureChan failed!"));
         goto cleanUp;
    }

    if(DDKDmacConfigureChan(chan2, &dmaCfg2) == DMAC_CHANNEL_INVALID)
    {
         g_pKato->Log(LOG_FAIL, TEXT("DDKDmacConfigureChan failed!"));
         goto cleanUp;
    }


    // PreClear any interrupt status
    DDKDmacClearChannelIntr(chan1);
    DDKDmacClearChannelIntr(chan2);


    // Enable the interrupt status
    DDKDmacEnableChannelIntr(chan1);
    DDKDmacEnableChannelIntr(chan2);
    

    QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &start_count_1 ) );
    // Start the transfer
    if (!DDKDmacStartChan(chan1))
    {
        g_pKato->Log(LOG_FAIL, TEXT("DDKDmacStartChan failed!"));
        goto cleanUp;
    }

    QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &start_count_2 ) );
    if (!DDKDmacStartChan(chan2))
    {
        g_pKato->Log(LOG_FAIL, TEXT("DDKDmacStartChan failed!"));
        goto cleanUp;
    }


    // Wait for interrupt signaling end of transfer
    if (WaitForSingleObject(hEvent1, 5000) != WAIT_OBJECT_0)
    {
        g_pKato->Log(LOG_FAIL, TEXT("WaitForSingleObject failed!"));
        goto cleanUp;
    }
    QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &finish_count_1 ) );

    // Wait for interrupt signaling end of transfer
    if (WaitForSingleObject(hEvent2, 5000) != WAIT_OBJECT_0)
    {
        g_pKato->Log(LOG_FAIL, TEXT("WaitForSingleObject failed!"));
        goto cleanUp;
    }
    QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &finish_count_2 ) );

    
    // Check transfer results
    if (memcmp(pBuf[0], pBuf[2], bufSize) != 0)
    {
        g_pKato->Log(LOG_FAIL, TEXT("Transfer failed!"));
        goto cleanUp;
    }

   
    if (memcmp(pBuf[1], pBuf[3], bufSize) != 0)
    {
        g_pKato->Log(LOG_FAIL, TEXT("Transfer failed!"));
        goto cleanUp;
    }
            
    g_pKato->Log(LOG_COMMENT, TEXT("Transfer #1 completed successfully..."));
    
    // Signal interrupt processing complete and disable the interrupt
    InterruptDone(sysintr1);
    InterruptDone(sysintr2);

    RETAILMSG(1, (TEXT("1) Finish_Count = %d\r\n"), finish_count_1));
    RETAILMSG(1, (TEXT("1) Diff = %d\r\n"), (finish_count_1-start_count_1)));
    RETAILMSG(1, (TEXT("1) Total %dms\r\n"), (finish_count_1-start_count_1)*1000/resolution));

    RETAILMSG(1, (TEXT("2) Finish_Count = %d\r\n"), finish_count_2));
    RETAILMSG(1, (TEXT("2) Diff = %d\r\n"), (finish_count_2-start_count_2)));
    RETAILMSG(1, (TEXT("2) Total %dms\r\n"), (finish_count_2-start_count_2)*1000/resolution));
    
    rc = TPR_PASS;

cleanUp:    
    g_pKato->Log(LOG_COMMENT, TEXT("Ending Mem2MemTest..."));
    InterruptDone(sysintr1);
    InterruptDisable(sysintr1);
    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &sysintr1, sizeof(sysintr1), 
        NULL, 0, NULL);
    DDKDmacReleaseChan(chan1);
    InterruptDone(sysintr2);
    InterruptDisable(sysintr2);
    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &sysintr2, sizeof(sysintr2), 
        NULL, 0, NULL);
    DDKDmacReleaseChan(chan2);

    return rc;

}

⌨️ 快捷键说明

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