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

📄 dma.cpp

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // number of frames per block
    OUTREG32(&pDMAReg->DMA4_CFN, 1);

    // source frame index and element index
    OUTREG32(&pDMAReg->DMA4_CSFI, 0);
    OUTREG32(&pDMAReg->DMA4_CSEI, 0);

    // destination frame index and element index
    OUTREG32(&pDMAReg->DMA4_CDFI, 0);
    OUTREG32(&pDMAReg->DMA4_CDEI, 0);

#if defined(DEBUG)
    DumpDMA_LC(L"Init Output", pDMAReg);
#endif

    DEBUGMSG(ZONE_FUNCTION, (L"-OMAP2420DMAContext::WInitOutputDMA()\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function: HWStartInputDMA ()
//  
//  Start the output DMA. 
//

void 
OMAP2420DMAContext::HWStartInputDMA()
{
    OMAP2420_DMA_REGS  *pDMAReg;

    DEBUGMSG(ZONE_FUNCTION, (L"OMAP2420DMAContext::HWStartInputDMA()\r\n"));

    pDMAReg = m_pInDMAReg;

#ifdef PROFILE_MIXER
    GetInputDeviceContext(0)->StartMixerProfiler();
#endif

    // enable the channel
    SETREG32(&pDMAReg->DMA4_CLNK_CTRL, DMA_CLNK_CTRL_ENABLE_LINK);
    SETREG32(&pDMAReg->DMA4_CCR, DMA_CCR_ENABLE);

#if defined(DEBUG)
    DumpDMA_LC(L"Start Input", pDMAReg);
    CheckDMAStatus(pDMAReg, TRUE);
#endif

    HWEnableInputChannel(TRUE);

    DEBUGMSG(ZONE_FUNCTION, (L"-OMAP2420DMAContext::HWStartInputDMA()\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function: HWStopInputDMA ()
//  
//  Stop the input DMA. 
//

void 
OMAP2420DMAContext::HWStopInputDMA()
{
    OMAP2420_DMA_REGS  *pDMAReg;
    DWORD i, dwVal;

    DEBUGMSG(ZONE_FUNCTION, (L"+OMAP2420DMAContext::HWStopInputDMA()\r\n"));

    pDMAReg = m_pInDMAReg;

    // disable the DMA channel link and wait for reading to finish
    CLRREG32(&pDMAReg->DMA4_CLNK_CTRL, DMA_CLNK_CTRL_ENABLE_LINK);
    dwVal = INREG32(&pDMAReg->DMA4_CCR);
    for (i = 0; (i < DMA_SAFETY_LOOP_NUM) && (dwVal & DMA_CCR_RD_ACTIVE); i++)
    {
        Sleep(1);
        dwVal = INREG32(&pDMAReg->DMA4_CCR);
    }

    // disable DMA on the channel
    CLRREG32(&pDMAReg->DMA4_CCR, DMA_CCR_ENABLE);

    // clear pending interrupts
    OUTREG32(&pDMAReg->DMA4_CSR, INREG32(&pDMAReg->DMA4_CSR));
    DMA_ControllerSet(m_hCont, DMACP_L3IntAck, 1 << AUDIO_INPUT_DMA_CHANNEL);

    // disable the rest of the channel
    HWEnableInputChannel(FALSE);

#if defined(DEBUG)
    DumpDMA_LC(L"Stop Input", pDMAReg);
    CheckDMAStatus(pDMAReg, FALSE);
#endif

#ifdef PROFILE_MIXER
    LARGE_INTEGER liTotalTime; 
    LARGE_INTEGER liMixerTime;

    GetInputDeviceContext(0)->StopMixerProfiler(&liTotalTime,&liMixerTime);

    DEBUGMSG(ZONE_DMA, (L"OMAP2420DMAContext::HWStopInputDMA: "
        L"Total capture time: %dms, %dms while mixing\r\n", (DWORD) (liTotalTime.QuadPart), (DWORD) (liMixerTime.QuadPart)
    ));
#endif

    DEBUGMSG(ZONE_FUNCTION, (L"-OMAP2420DMAContext::HWStopInputDMA()\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function: HWStartOutputDMA ()
//  
//  Stop the output DMA. 
//

void 
OMAP2420DMAContext::HWStartOutputDMA()
{
    OMAP2420_DMA_REGS  *pDMAReg;
    
    DEBUGMSG(ZONE_FUNCTION, (L"+OMAP2420DMAContext::HWStartOutputDMA()\r\n"));

#ifdef PROFILE_MIXER
    GetOutputDeviceContext(0)->StartMixerProfiler();
#endif

    pDMAReg = m_pOutDMAReg;

    // enable the channel
    SETREG32(&pDMAReg->DMA4_CLNK_CTRL, DMA_CLNK_CTRL_ENABLE_LINK);
    SETREG32(&pDMAReg->DMA4_CCR, DMA_CCR_ENABLE);

#if defined(DEBUG)
    DumpDMA_LC(L"Start Output", pDMAReg);
    CheckDMAStatus(pDMAReg, TRUE);
#endif

    HWEnableOutputChannel(TRUE);

    DEBUGMSG(ZONE_FUNCTION, (L"-OMAP2420DMAContext::HWStartOutputDMA()\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function: HWStopOutputDMA ()
//  
//  Stop the output DMA. 
//

void 
OMAP2420DMAContext::HWStopOutputDMA()
{
    OMAP2420_DMA_REGS  *pDMAReg;
    DWORD i, dwVal;

    DEBUGMSG(ZONE_FUNCTION, (L"+OMAP2420DMAContext::HWStopOutputDMA()\r\n"));

    pDMAReg = m_pOutDMAReg;

    // disable the DMA channel link and wait for writing to finish
    CLRREG32(&pDMAReg->DMA4_CLNK_CTRL, DMA_CLNK_CTRL_ENABLE_LINK);
    dwVal = INREG32(&pDMAReg->DMA4_CCR);
    for (i = 0; (i < DMA_SAFETY_LOOP_NUM) && (dwVal & DMA_CCR_WR_ACTIVE); i++)
    {
        Sleep(1);
        dwVal = INREG32(&pDMAReg->DMA4_CCR);
    }

    // disable DMA on the channel
    CLRREG32(&pDMAReg->DMA4_CCR, DMA_CCR_ENABLE);

    // clear pending interrupts
    OUTREG32(&pDMAReg->DMA4_CSR, INREG32(&pDMAReg->DMA4_CSR));
    DMA_ControllerSet(m_hCont, DMACP_L2IntAck, 1 << AUDIO_OUTPUT_DMA_CHANNEL);

    // disable the rest of the channel
    HWEnableOutputChannel(FALSE);

#if defined(DEBUG)
    DumpDMA_LC(L"Stop Output", pDMAReg);
    CheckDMAStatus(pDMAReg, FALSE);
#endif

#ifdef PROFILE_MIXER
    LARGE_INTEGER liTotalTime; 
    LARGE_INTEGER liMixerTime;

    GetOutputDeviceContext(0)->StopMixerProfiler(&liTotalTime,&liMixerTime);

    DEBUGMSG(ZONE_DMA,(L"OMAP2420DMAContext::HWStopOutputDMA: "
        L"Total play time: %dms, %dms while mixing\r\n", (DWORD) (liTotalTime.QuadPart), (DWORD) (liMixerTime.QuadPart)
    ));
#endif

    DEBUGMSG(ZONE_FUNCTION, (L"-OMAP2420DMAContext::HWStopOutputDMA()\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function: HWTransferInputBuffers ()
//  
//  Transfer capture buffers. 
//

ULONG 
OMAP2420DMAContext::HWTransferInputBuffers()
{
    ULONG BytesTransferred=0;
    OMAP2420_DMA_REGS  *pDMAReg;
    DWORD dwVal, dwOffset;

    pDMAReg = m_pInDMAReg;

    // read the CSR register, clear interrupt bits
    dwVal = INREG32(&pDMAReg->DMA4_CSR);
    OUTREG32(&pDMAReg->DMA4_CSR, dwVal);
    DMA_ControllerSet(m_hCont, DMACP_L3IntAck, 1 << AUDIO_INPUT_DMA_CHANNEL);

    DEBUGMSG(ZONE_FUNCTION, (L"+OMAP2420DMAContext::HWTransferInputBuffers() %08X\n", dwVal));

    // an error occured
    if (dwVal & DMA_CSR_DROP)
    {
        DEBUGMSG(ZONE_ERROR|ZONE_DMA, (L"OMAP2420DMAContext::HWTransferInputBuffers: "
            L"RX DMA CSR error = 0x%x\r\n", dwVal
        ));
    }

    // make sure this is a HALF or FRAME interrupt
    if (!(dwVal & (DMA_CSR_HALF|DMA_CSR_FRAME)))
    {
        DEBUGMSG(ZONE_DMA, (L"OMAP2420DMAContext::HWTransferInputBuffers: "
            L"NOT input interrupt %08X\n", dwVal
        ));
        return BytesTransferred;
    }

    // if both HALF and FRAME are on, then we lost one of them
    if ((dwVal & (DMA_CSR_HALF|DMA_CSR_FRAME)) == (DMA_CSR_HALF|DMA_CSR_FRAME))
    {
        DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWTransferInputBuffers: "
            L"Input buffer interrupt lost\r\n"
        ));

        // pick HALF or FRAME based on which half of the frame the read pointer is in
        dwOffset = INREG32(&pDMAReg->DMA4_CSAC) - INREG32(&pDMAReg->DMA4_CSSA);
        dwVal = (dwOffset >= AUDIO_DMA_PAGE_SIZE) ? DMA_CSR_HALF : DMA_CSR_FRAME;
    }

    // HALF interrupt, reload page 0
    if (dwVal & DMA_CSR_HALF)
    {
        BytesTransferred += TransferInputBuffer(0);
    }

    // FRAME interrupt, reload page 1
    if (dwVal & DMA_CSR_FRAME)
    {
        BytesTransferred += TransferInputBuffer(1);
    }

    // stop DMA when there's no more data
    if (BytesTransferred == 0)
    {
        StopInputDMA();
    }

    return BytesTransferred;
}

//------------------------------------------------------------------------------
//
//  Function: HWTransferOutputBuffers ()
//  
//  Transfer playback buffers. 
//

ULONG 
OMAP2420DMAContext::HWTransferOutputBuffers()
{
    ULONG BytesTransferred=0;
    OMAP2420_DMA_REGS  *pDMAReg;
    DWORD dwVal, dwOffset;

    pDMAReg = m_pOutDMAReg;

    // read the DMA CSR register, clear interrupt bits.
    dwVal = INREG32(&pDMAReg->DMA4_CSR);
    OUTREG32(&pDMAReg->DMA4_CSR, dwVal);
    DMA_ControllerSet(m_hCont, DMACP_L2IntAck, 1 << AUDIO_OUTPUT_DMA_CHANNEL);

    DEBUGMSG(ZONE_FUNCTION, (L"OMAP2420DMAContext::HWTransferOutputBuffers() %08X\n", dwVal));

    // an error occured
    if (dwVal & DMA_CSR_DROP)
    {
        DEBUGMSG(ZONE_ERROR|ZONE_DMA, (L"OMAP2420DMAContext::HWTransferOutputBuffers: "
            L"TX DMA CSR error = 0x%x\r\n", dwVal
        ));
    }

    // make sure this is a HALF or FRAME interrupt
    if (!(dwVal & (DMA_CSR_HALF|DMA_CSR_FRAME)))
    {
        DEBUGMSG(ZONE_DMA, (L"OMAP2420DMAContext::HWTransferOutputBuffers: "
            L"NOT output interrupt %08X\n", dwVal
        ));
        return BytesTransferred;
    }

    // if both HALF and FRAME are on, then we lost an interrupt
    if ((dwVal & (DMA_CSR_HALF|DMA_CSR_FRAME)) == (DMA_CSR_HALF|DMA_CSR_FRAME))
    {   
        DEBUGMSG(ZONE_ERROR|ZONE_DMA, (L"OMAP2420DMAContext::HWTransferOutputBuffers: "
            L"Ooutput buffer interrupt lost\r\n"
        ));

        // pick HALF or FRAME based on which half of the frame the write pointer is in
        dwOffset = INREG32(&pDMAReg->DMA4_CSAC) - INREG32(&pDMAReg->DMA4_CSSA);
        dwVal = (dwOffset >= AUDIO_DMA_PAGE_SIZE) ? DMA_CSR_HALF : DMA_CSR_FRAME;
    }

    // HALF interrupt, reload page 0
    if (dwVal & DMA_CSR_HALF)
    {
        BytesTransferred += TransferOutputBuffer(0);
    }

    // FRAME interrupt, reload page 1
    if (dwVal & DMA_CSR_FRAME)
    {   
        BytesTransferred += TransferOutputBuffer(1);
    }

    // stop DMA when there's no more data
    if (BytesTransferred == 0)
    {
        StopOutputDMA();
    }

    DEBUGMSG(ZONE_FUNCTION, (L"-OMAP2420DMAContext::HWTransferOutputBuffers() %08X %d\r\n", dwVal, BytesTransferred));

    return BytesTransferred;
}

//------------------------------------------------------------------------------
//
//  Function: DumpDMA_LC ()
//  
//  dump DMA logical channel registers
//

#if defined(DEBUG)
static void 
DumpDMA_LC(PTSTR szChannel, OMAP2420_DMA_REGS *pCh)
{
    DEBUGMSG(ZONE_DMA,(L"AC: %s Channel\r\n", szChannel, GetTickCount()));
    DEBUGMSG(ZONE_DMA,(L"AC:    CSDP:      %08X\r\n", INREG32(&pCh->DMA4_CSDP)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CCR:       %08X\r\n", INREG32(&pCh->DMA4_CCR)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CICR:      %08X\r\n", INREG32(&pCh->DMA4_CICR)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CSR:       %08X\r\n", INREG32(&pCh->DMA4_CSR)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CSSA:      %08X\r\n", INREG32(&pCh->DMA4_CSSA)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CDSA:      %08X\r\n", INREG32(&pCh->DMA4_CDSA)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CEN:       %08X\r\n", INREG32(&pCh->DMA4_CEN)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CFN:       %08X\r\n", INREG32(&pCh->DMA4_CFN)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CSFI:      %08X\r\n", INREG32(&pCh->DMA4_CSFI)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CSEI:      %08X\r\n", INREG32(&pCh->DMA4_CSEI)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CSAC:      %08X\r\n", INREG32(&pCh->DMA4_CSAC)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CDAC:      %08X\r\n", INREG32(&pCh->DMA4_CDAC)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CDEI:      %08X\r\n", INREG32(&pCh->DMA4_CDEI)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CDFI:      %08X\r\n", INREG32(&pCh->DMA4_CDFI)));
    DEBUGMSG(ZONE_DMA,(L"AC:    COLOR:     %08X\r\n", INREG32(&pCh->DMA4_COLOR)));
    DEBUGMSG(ZONE_DMA,(L"AC:    CLNK_CTRL: %08X\r\n", INREG32(&pCh->DMA4_CLNK_CTRL)));
}
#endif

⌨️ 快捷键说明

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