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

📄 hwctxt.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        DMA_initialize_LLI(&g_InputDMA, 2);
        DMA_set_initial_LLI(&g_InputDMA, 1);
        DMA_set_LLI_entry(&g_InputDMA, 0, LLI_NEXT_ENTRY, AC97_get_pcmin_physical_buffer_address(),
                            m_InputDMABufferPhyPage[0], AUDIO_DMA_PAGE_SIZE);
        DMA_set_LLI_entry(&g_InputDMA, 1, LLI_FIRST_ENTRY, AC97_get_pcmin_physical_buffer_address(),
                            m_InputDMABufferPhyPage[1], AUDIO_DMA_PAGE_SIZE);
    }

CleanUp:

    WAV_MSG((_T("[WAV] --InitInputDMA()\n\r")));

    return bRet;
}


BOOL
HardwareContext::InitInterruptThread()
{
    DWORD Irq;
    DWORD dwPriority;

    Irq = g_OutputDMA.dwIRQ;
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(DWORD), &m_dwSysintrOutput, sizeof(DWORD), NULL))
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Output DMA IOCTL_HAL_REQUEST_SYSINTR Failed \n\r")));
        return FALSE;
    }

    Irq = g_InputDMA.dwIRQ;
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(DWORD), &m_dwSysintrInput, sizeof(DWORD), NULL))
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Input DMA IOCTL_HAL_REQUEST_SYSINTR Failed \n\r")));
        return FALSE;
    }

    m_hOutputDMAInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (m_hOutputDMAInterrupt == NULL)
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Output DMA CreateEvent() Failed \n\r")));
        return(FALSE);
    }

    m_hInputDMAInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (m_hInputDMAInterrupt == NULL)
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Input DMA CreateEvent() Failed \n\r")));
        return(FALSE);
    }

    if (!InterruptInitialize(m_dwSysintrOutput, m_hOutputDMAInterrupt, NULL, 0))
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Output DMA InterruptInitialize() Failed \n\r")));
        return FALSE;
    }

    if (! InterruptInitialize(m_dwSysintrInput, m_hInputDMAInterrupt, NULL, 0))
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Input DMA InterruptInitialize() Failed \n\r")));
        return FALSE;
    }


    m_hOutputDMAInterruptThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0,
                            (LPTHREAD_START_ROUTINE)CallInterruptThreadOutputDMA, this, 0, NULL);

    if (m_hOutputDMAInterruptThread == NULL)
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Output DMA CreateThread() Failed \n\r")));
        return FALSE;
    }

    m_hInputDMAInterruptThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0,
                            (LPTHREAD_START_ROUTINE)CallInterruptThreadInputDMA, this, 0, NULL);

    if (m_hInputDMAInterruptThread == NULL)
    {
        WAV_ERR((_T("[WAV:ERR] InitInterruptThread() : Input DMA CreateThread() Failed \n\r")));
        return FALSE;
    }

    dwPriority = GetInterruptThreadPriority();

    // Bump up the priority since the interrupt must be serviced immediately.
    CeSetThreadPriority(m_hOutputDMAInterruptThread, dwPriority);
    CeSetThreadPriority(m_hInputDMAInterruptThread, dwPriority);
    WAV_INF((_T("[WAV:INF] InitInterruptThread() : IST Priority = %d\n\r"), dwPriority));

    return(TRUE);
}


BOOL
HardwareContext::DeinitInterruptThread()
{
    return TRUE;
}


DWORD
HardwareContext::GetInterruptThreadPriority()
{
    HKEY hDevKey;
    DWORD dwValType;
    DWORD dwValLen;
    DWORD dwPrio = INTERRUPT_THREAD_PRIORITY_DEFAULT;
    LONG lResult;

    hDevKey = OpenDeviceKey((LPWSTR)m_DriverIndex);
    if (INVALID_HANDLE_VALUE != hDevKey)
    {
        dwValLen = sizeof(DWORD);
        lResult = RegQueryValueEx(hDevKey, TEXT("Priority256"), NULL, &dwValType, (PUCHAR)&dwPrio, &dwValLen);
        RegCloseKey(hDevKey);
    }
    else
    {
        WAV_ERR((_T("[WAV:ERR] GetInterruptThreadPriority() : OpenDeviceKey() Failed\n\r")));
    }

    return dwPrio;
}


ULONG
HardwareContext::TransferOutputBuffer(DWORD dwStatus)
{
    ULONG BytesTransferred = 0;
    ULONG BytesTotal = 0;

    dwStatus &= (DMA_DONEA|DMA_DONEB|DMA_BIU);

    WAV_MSG((_T("[WAV] TransferOutputBuffer(0x%08x)\n\r"), dwStatus));

    switch (dwStatus)
    {
    case 0:
    case DMA_BIU:
        // No done bits set- must not be my interrupt
        return 0;
    case DMA_DONEA|DMA_DONEB|DMA_BIU:
        // Load B, then A
        BytesTransferred = FillOutputBuffer(OUTPUT_DMA_BUFFER1);
        // fall through
    case DMA_DONEA: // This should never happen!
    case DMA_DONEA|DMA_BIU:
        BytesTransferred += FillOutputBuffer(OUTPUT_DMA_BUFFER0);        // charlie, A => B
        break;
    case DMA_DONEA|DMA_DONEB:
        // Load A, then B
        BytesTransferred = FillOutputBuffer(OUTPUT_DMA_BUFFER0);
        BytesTransferred += FillOutputBuffer(OUTPUT_DMA_BUFFER1);
        break;
    case DMA_DONEB|DMA_BIU: // This should never happen!
    case DMA_DONEB:
        // Load B
        BytesTransferred += FillOutputBuffer(OUTPUT_DMA_BUFFER1);        // charlie, B => A
        break;
    }

    // If it was our interrupt, but we weren't able to transfer any bytes
    // (e.g. no full buffers ready to be emptied)
    // and all the output DMA buffers are now empty, then stop the output DMA
    BytesTotal = m_nOutByte[OUTPUT_DMA_BUFFER0]+m_nOutByte[OUTPUT_DMA_BUFFER1];

    if (BytesTotal == 0)
    {
        StopOutputDMA();
    }
    else
    {
        StartOutputDMA();        // for DMA resume when wake up
    }

    return BytesTransferred;
}


ULONG
HardwareContext::FillOutputBuffer(int nBufferNumber)
{
    ULONG BytesTransferred = 0;
    PBYTE pBufferStart = m_OutputDMABufferVirPage[nBufferNumber];
    PBYTE pBufferEnd = pBufferStart + AUDIO_DMA_PAGE_SIZE;
    PBYTE pBufferLast;

    WAV_MSG((_T("[WAV] FillOutputBuffer(%d)\n\r"), nBufferNumber));

    __try
    {
        pBufferLast = m_OutputDeviceContext.TransferBuffer(pBufferStart, pBufferEnd, NULL);

        BytesTransferred = pBufferLast-pBufferStart;
        m_nOutByte[nBufferNumber] = BytesTransferred;

        // Enable if you need to clear the rest of the DMA buffer
        StreamContext::ClearBuffer(pBufferLast, pBufferEnd);

        if(nBufferNumber == OUTPUT_DMA_BUFFER0)            // Output Buffer A
        {
            m_OutputDMAStatus &= ~DMA_DONEA;
            m_OutputDMAStatus |= DMA_STRTA;
        }
        else                                // Output Buffer B
        {
            m_OutputDMAStatus &= ~DMA_DONEB;
            m_OutputDMAStatus |= DMA_STRTB;
        }
    }
    __except(GetExceptionCode()==STATUS_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
    {
        WAV_ERR((_T("[WAV:ERR] FillOutputBuffer() : Exception ccurs [%d]\n\r"), GetExceptionCode()));
    }

    return BytesTransferred;
}


ULONG
HardwareContext::TransferInputBuffers(DWORD dwStatus)
{
    ULONG BytesTransferred=0;

    dwStatus &= (DMA_DONEA|DMA_DONEB|DMA_BIU);

    WAV_MSG((_T("[WAV] TransferInputBuffers(0x%08x)\n\r"), dwStatus));

    switch (dwStatus)
    {
    case 0:
    case DMA_BIU:
        // No done bits set- must not be my interrupt
        return 0;
    case DMA_DONEA|DMA_DONEB|DMA_BIU:
        // Load B, then A
        BytesTransferred = FillInputBuffer(INPUT_DMA_BUFFER1);
        // fall through
    case DMA_DONEA: // This should never happen!
    case DMA_DONEA|DMA_BIU:
        // Load A
        BytesTransferred += FillInputBuffer(INPUT_DMA_BUFFER0);
        break;
    case DMA_DONEA|DMA_DONEB:
        // Load A, then B
        BytesTransferred = FillInputBuffer(INPUT_DMA_BUFFER0);
        BytesTransferred += FillInputBuffer(INPUT_DMA_BUFFER1);
        break;
    case DMA_DONEB|DMA_BIU: // This should never happen!
    case DMA_DONEB:
        // Load B
        BytesTransferred += FillInputBuffer(INPUT_DMA_BUFFER1);
        break;
    }

    // If it was our interrupt, but we weren't able to transfer any bytes
    // (e.g. no empty buffers ready to be filled)
    // Then stop the input DMA
    if (BytesTransferred==0)
    {
        StopInputDMA();
    }
    else
    {
        StartInputDMA();        // for DMA resume when wake up
    }

    return BytesTransferred;
}


ULONG
HardwareContext::FillInputBuffer(int nBufferNumber)
{
    ULONG BytesTransferred = 0;

    PBYTE pBufferStart = m_InputDMABufferVirPage[nBufferNumber];
    PBYTE pBufferEnd = pBufferStart + AUDIO_DMA_PAGE_SIZE;
    PBYTE pBufferLast;

    WAV_MSG((_T("[WAV] FillInputBuffer(%d)\n\r"), nBufferNumber));

    __try
    {
        pBufferLast = m_InputDeviceContext.TransferBuffer(pBufferStart, pBufferEnd, NULL);
        BytesTransferred = m_nInByte[nBufferNumber] = pBufferLast-pBufferStart;

        if(nBufferNumber == INPUT_DMA_BUFFER0)            // Input Buffer A
        {
            m_InputDMAStatus &= ~DMA_DONEA;
            m_InputDMAStatus |= DMA_STRTA;
        }
        else                                                // Input Buffer B
        {
            m_InputDMAStatus &= ~DMA_DONEB;
            m_InputDMAStatus |= DMA_STRTB;
        }

    }
    __except(GetExceptionCode()==STATUS_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
    {
        WAV_ERR((_T("[WAV:ERR] FillInputBuffer() : Exception ccurs [%d]\n\r"), GetExceptionCode()));
    }

    return BytesTransferred;
}


void
HardwareContext::WriteCodecRegister(UCHAR Reg, USHORT Val)
{
    AC97_write_codec(Reg, Val);
}


USHORT
HardwareContext::ReadCodecRegister(UCHAR Reg)
{
    return AC97_read_codec(Reg);
}


BOOL
HardwareContext::CodecPowerControl()
{

    if( m_bInputDMARunning & m_bOutputDMARunning )
    {
        WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() ADC & DAC On\n\r")));
        WriteCodecRegister(WM9713_POWER_CONTROL, AC97_PWR_D0);    // ADC, DAC power up
    }
    else if( m_bInputDMARunning )
    {
        WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() ADC On\n\r")));
        WriteCodecRegister(WM9713_POWER_CONTROL, AC97_PWR_PR1);    // DAC power down
    }
    else if( m_bOutputDMARunning )
    {
        WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() DAC On\n\r")));
        WriteCodecRegister(WM9713_POWER_CONTROL, AC97_PWR_PR0);    // ADC power down
    }
    else
    {
        WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() ADC & DAC Off\n\r")));
        WriteCodecRegister(WM9713_POWER_CONTROL, AC97_PWR_PR1|AC97_PWR_PR0);    // ADC, DAC power down
    }

    return(TRUE);
}


BOOL
HardwareContext::CodecMuteControl(DWORD channel, BOOL bMute)
{
    USHORT volume;

    if((channel & DMA_CH_OUT ))// && !m_bOutputDMARunning )
    {
        if(bMute)
        {
            volume = ReadCodecRegister(WM9713_HEADPHONE_VOL);
            WriteCodecRegister(WM9713_HEADPHONE_VOL, volume|0x8080);
        }
        else
        {
            volume = ReadCodecRegister(WM9713_HEADPHONE_VOL);
            WriteCodecRegister(WM9713_HEADPHONE_VOL, volume&~0x8080);
        }
    }

    if( (channel & DMA_CH_IN))// && !m_bInputDMARunning )
    {
        if(bMute)
        {
            volume = ReadCodecRegister(WM9713_RECORD_VOL);
            WriteCodecRegister(WM9713_RECORD_VOL, volume|0x8000);
        }
        else
        {
            volume = ReadCodecRegister(WM9713_RECORD_VOL);
            WriteCodecRegister(WM9713_RECORD_VOL, volume&~0x8000);
        }
    }

    return(TRUE);
}


void HardwareContext::SetSpeakerEnable(BOOL bEnable)
{
    // Code to turn speaker on/off here
    return;
}


void CallInterruptThreadOutputDMA(HardwareContext *pHWContext)
{
    pHWContext->InterruptThreadOutputDMA();
}


void CallInterruptThreadInputDMA(HardwareContext *pHWContext)
{
    pHWContext->InterruptThreadInputDMA();
}


⌨️ 快捷键说明

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