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

📄 hwctxt.cpp

📁 freesacle mx21下的声卡alc5620的驱动程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
//
//  FUNCTION:       TransferInputBuffer
//
//  DESCRIPTION:    Actual function to transfer received data from 
//                  DMA to the indicated receive buffer. 
//                  Called by TransferInputBuffers
//
//  PARAMETERS:     
//                  bufIndex - index of receive buffer to fill
//
//  RETURNS:        
//                  Number of bytes transferred to buffer
//
//------------------------------------------------------------------------------
UINT32 HardwareContext::TransferInputBuffer(UINT8 bufIndex)
{
    ULONG BytesTransferred = 0;

    UINT8 *pBufferStart = (UINT8 *)m_Input_pbDMA_PAGES[bufIndex];
    UINT8 *pBufferEnd = pBufferStart + AUDIO_DMA_PAGE_SIZE;
    UINT8 *pBufferLast;

    __try
    {
        pBufferLast = m_InputDeviceContext.TransferBuffer(pBufferStart, pBufferEnd, NULL);
        BytesTransferred = m_InBytes[bufIndex] = pBufferLast-pBufferStart;
        //DmacSetRepeatType(m_DmaRxChannel, DMAC_REPEAT_ONCE);
        DDKDmacSetDestAddress(m_DmaRxChannel, m_DmaRxBuffer[bufIndex]);
        //DmacStartChan(m_DmaRxChannel);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("WAVDEV2.DLL:TransferInputBuffer() - EXCEPTION: %d"), GetExceptionCode()));
    }

    return BytesTransferred;
}
//------------------------------------------------------------------------------
//
//  FUNCTION:       TransferInputBuffers
//
//  DESCRIPTION:    Calls TransferInputBuffer to transfer data from 
//                  DMA to receive buffer. Also toggles the current
//                  buffer index to acheive double buffering. Stops
//                  input dma if nothing is transferred.
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  Number of bytes transferred to buffer
//
//------------------------------------------------------------------------------
UINT32 HardwareContext::TransferInputBuffers(void)
{
    UINT32 BytesTransferred = 0;
   // UINT32 DmaTransferred = 0;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+TransferInputBuffers\r\n")));
    
   // DmaTransferred = DmacGetTransSize(m_DmaRxChannel);
   // RETAILMSG(1, (TEXT("DmaTransferred(%d).\r\n"), DmaTransferred));

    BytesTransferred = TransferInputBuffer(m_RxBufIndex);
    m_RxBufIndex = (m_RxBufIndex == 0)? 1 : 0;
    
   // RETAILMSG(1, (TEXT("HardwareContext::TransferInputBuffers(%d).\r\n"), BytesTransferred));
    
    // 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();
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-TransferInputBuffers: BytesTransferred=%d\r\n"), BytesTransferred));
    return BytesTransferred;
}
//------------------------------------------------------------------------------
//
//  FUNCTION:       InterruptThread
//
//  DESCRIPTION:    Interrupt service routine for playback and recording
//                  DMA interrupts
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  None
//
//------------------------------------------------------------------------------
void HardwareContext::InterruptThread()
{
    UINT32 InputTransferred;
    UINT32 OutputTransferred;
    UINT32 intrMask;
    UINT32 DmaInterruptSource;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+InterruptThread\r\n")));

    // Fast way to access embedded pointers in wave headers in other processes.
    SetProcPermissions((ULONG)-1);

    while(TRUE)
    {
        DEBUGMSG(ZONE_INTERRUPT, (TEXT("+WaitForSingleObject\r\n")));
        WaitForSingleObject(m_hAudioInterrupt, INFINITE);
        DEBUGMSG(ZONE_INTERRUPT, (TEXT("-WaitForSingleObject\r\n")));

        //----- 1. Grab the lock -----
        
        DmaInterruptSource = 0;
        Lock();

        __try
        {
            //----- 2. Determine the interrupt source (input DMA operation or output DMA operation?) -----
            //----- NOTE:   Often, platforms use two separate DMA channels for input/output operations but
            //              have the OAL return SYSINTR_AUDIO as the interrupt source.  If this is the case,
            //              then the interrupt source (input or output DMA channel) must be determined in
            //              this step.

            intrMask = DDKDmacGetTransStatus(m_DmaTxChannel);
            
            if(intrMask != DMAC_TRANSFER_STATUS_NONE)
            {
                if(intrMask == DMAC_TRANSFER_STATUS_COMPLETE)
                {
                    DmaInterruptSource |= AUDIO_CH_OUT; 
                }
                //----- 3. Acknowledge the DMA interrupt -----
                DDKDmacClearChannelIntr(m_DmaTxChannel);
                InterruptDone(m_dwSysintrOutput);
            }
  
    	    if((DmaInterruptSource & AUDIO_CH_OUT) != 0)
            {
                if(m_OutputDMARunning == TRUE)
                {
                    OutputTransferred = TransferOutputBuffers();
                }
            }
    
            intrMask = DDKDmacGetTransStatus(m_DmaRxChannel);
          
            if(intrMask != DMAC_TRANSFER_STATUS_NONE)
            {
                if(intrMask == DMAC_TRANSFER_STATUS_COMPLETE)
                {
                    DmaInterruptSource |= AUDIO_CH_IN; 
                }
                //----- 3. Acknowledge the DMA interrupt -----
                DDKDmacClearChannelIntr(m_DmaRxChannel);
                InterruptDone(m_dwSysintrInput);
            }

            //----- 4. Handle any interrupts on the input source -----
            //         NOTE: The InterruptDone() call below automatically clears the interrupt.
            if((DmaInterruptSource & AUDIO_CH_IN) != 0)
            {
                if(m_InputDMARunning == TRUE)
                {
                    InputTransferred = TransferInputBuffers();
                }
                
            }
            
            DEBUGMSG(ZONE_INTERRUPT, (TEXT("interrupt: %d\r\n"), DmaInterruptSource));
            if(DmaInterruptSource == 0)
            {
                // Unknown interrupt!
                DEBUGMSG(ZONE_INTERRUPT, (TEXT("Unknown interrupt!\r\n")));
            }
        }
        __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("WAVDEV2.DLL:InterruptThread() - EXCEPTION: %d"), GetExceptionCode()));
        }

        //----- 10. Give up the lock ----- 
        Unlock();

    }  // while(TRUE)

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-InterruptThread\r\n")));
}




/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       AudioMute()

Description:    Mutes/unmutes the specified audio channel.

Notes:          If both audio channels are MUTED, then the chip 
                is powered down to conserve battery life.  
                Alternatively, if either audio channel is unMUTED, 
                the chip is powered up.

Returns:        Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::AudioMute(DWORD channel, BOOL bMute)
{
    BOOL bSetPlayback;
    BOOL bSetRecord;

    bSetPlayback = ((channel & AUDIO_CH_OUT) != 0)? TRUE : FALSE;
    bSetRecord = ((channel & AUDIO_CH_IN) != 0)? TRUE : FALSE;

    BSPAudioSetPowerOnOff(bSetPlayback, bSetRecord, bMute);

    return(TRUE);
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       CallInterruptThread
//
//  DESCRIPTION:    Actual function called by interrupt service thread
//
//  PARAMETERS:     
//                  pHWContext - pointer to calling HwContext
//
//  RETURNS:        
//                  None
//
//------------------------------------------------------------------------------
void CallInterruptThread(HardwareContext *pHWContext)
{
    pHWContext->InterruptThread();
}


//------------------------------------------------------------------------------
//
//  FUNCTION:       PmControlMessage
//
//  DESCRIPTION:    Power management routine.
//
//  PARAMETERS:     
//              wCode[in]   IO control code for the function to be performed. 
//                          WAV_IOControl only supports one IOCTL value 
//                          (IOCTL_WAV_MESSAGE)
//              pBufIn[in]  Pointer to the input parameter structure 
//                          (<t MMDRV_MESSAGE_PARAMS>).         
//              dwLenIn[in] Size in bytes of input parameter structure 
//                          (sizeof(<t MMDRV_MESSAGE_PARAMS>)).
//              pBufOut[out] Pointer to the return value (DWORD)    
//              dwLenOut[out]Size of the return value variable (sizeof(DWORD)).
//              pdwActualOut  Unused
//
//  RETURNS:    TRUE for success, FALSE for failure
//
//------------------------------------------------------------------------------
BOOL HardwareContext::PmControlMessage (
                                  DWORD  dwCode,
                                  PBYTE  pBufIn,
                                  DWORD  dwLenIn,
                                  PBYTE  pBufOut,
                                  DWORD  dwLenOut,
                                  PDWORD pdwActualOut)
{
    BOOL bRetVal = FALSE;

    switch (dwCode)
    {
        DEBUGMSG(ZONE_IOCTL, ( TEXT( "WAVE: PmControlMessage. \r\n" ) ) );
        // Return device specific power capabilities.
        case IOCTL_POWER_CAPABILITIES:
            {
                PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pBufOut;

                // Check arguments.
                if ( ppc && (dwLenOut >= sizeof(POWER_CAPABILITIES)) && pdwActualOut )
                {
                    // Clear capabilities structure.
                    memset( ppc, 0, sizeof(POWER_CAPABILITIES) );

                    // Set power capabilities. Supports D0 and D4.
                    ppc->DeviceDx = DX_MASK(D0)|DX_MASK(D4);

                    DEBUGMSG(ZONE_IOCTL, (TEXT("WAVE: IOCTL_POWER_CAPABILITIES = 0x%x\r\n"), ppc->DeviceDx));

                    // Update returned data size.
                    *pdwActualOut = sizeof(*ppc);
                    bRetVal = TRUE;
                }
                else
                {
                    DEBUGMSG(ZONE_ERROR, ( TEXT( "WAVE: Invalid parameter.\r\n" ) ) );
                }
                break;
            }

            // Indicate if the device is ready to enter a new device power state.
        case IOCTL_POWER_QUERY:
            {
                PCEDEVICE_POWER_STATE pDxState = (PCEDEVICE_POWER_STATE)pBufOut;

                // Check arguments.
                if (pDxState && (dwLenOut >= sizeof(CEDEVICE_POWER_STATE)) && pdwActualOut)
                {
                    DEBUGMSG(ZONE_IOCTL, (TEXT("WAVE: IOCTL_POWER_QUERY = %d\r\n"), *pDxState));

                    // Check for any valid power state.
                    if (VALID_DX (*pDxState))
                    {
                        *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
                        bRetVal = TRUE;
                    }
                    else
                    {
                        DEBUGMSG(ZONE_ERROR, ( TEXT( "WAVE: IOCTL_POWER_QUERY invalid power state.\r\n" ) ) );
                    }
                }
                else
                {
                    DEBUGMSG(ZONE_ERROR, ( TEXT( "WAVE: IOCTL_POWER_QUERY invalid parameter.\r\n" ) ) );
                }
                break;
            }

            // Request a change from one device power state to another.
        case IOCTL_POWER_SET:
            {
                PCEDEVICE_POWER_STATE pDxState = (PCEDEVICE_POWER_STATE)pBufOut;

                // Check arguments.
                if (pDxState && (dwLenOut >= sizeof(CEDEVICE_POWER_STATE)))
                {
                    DEBUGMSG(ZONE_IOCTL, ( TEXT( "WAVE: IOCTL_POWER_SET = %d.\r\n"), *pDxState));

                    // Check for any valid power state.
                    if (VALID_DX(*pDxState))
                    {
                        Lock();

                        // Power off.
                        if ( *pDxState == D4 )
                        {
                            PowerDown();
                        }
                        // Power on.
                        else
                        {
                            PowerUp();
                        }

                        m_DxState = *pDxState;

                        Unlock();

                        bRetVal = TRUE;
                    }
                    else
                    {
                        DEBUGMSG(ZONE_ERROR, ( TEXT( "WAVE: IOCTL_POWER_SET invalid power state.\r\n" ) ) );
                    }
                }
                else
                {
                    DEBUGMSG(ZONE_ERROR, ( TEXT( "WAVE: IOCTL_POWER_SET invalid parameter.\r\n" ) ) );
                }

                break;
            }

            // Return the current device power state.
        case IOCTL_POWER_GET:
            {
                if( pBufOut != NULL && 
                    dwLenOut >= sizeof(CEDEVICE_POWER_STATE) &&
                    pdwActualOut != NULL)
                {
                    *(CEDEVICE_POWER_STATE *)pBufOut = m_DxState;
                    *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
                    bRetVal = TRUE;
                }
                DEBUGMSG(ZONE_IOCTL, (TEXT("WAVE: IOCTL_POWER_GET !\r\n")));
                break;
            }

        default:
            DEBUGMSG(ZONE_ERROR, (TEXT("WAVE: Unknown IOCTL_xxx(0x%0.8X) \r\n"), dwCode));
            break;
    }

    return bRetVal;
}

⌨️ 快捷键说明

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