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

📄 hwctxt.cpp

📁 realtek562x系列驱动源码。wince
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        InterruptDone(m_SysIntrAudioDMA);

    }  // while(TRUE)

}

void CallInterruptThread(HardwareContext *pHWContext)
{
    DEBUGMSG(ZONE_INIT, (TEXT("CallInterruptThread")));
    pHWContext->InterruptThread();
}

void CallInputInterruptThread(HardwareContext *pHWContext)
{
    DEBUGMSG(ZONE_INIT, (TEXT("CallInputInterruptThread")));

    SetProcPermissions((ULONG)-1);
    pHWContext->InputInterruptThread();
}

void CallOutputInterruptThread(HardwareContext *pHWContext)
{
    DEBUGMSG(ZONE_INIT, (TEXT("CallOutputInterruptThread")));

    SetProcPermissions((ULONG)-1);
    pHWContext->OutputInterruptThread();
}

void HardwareContext::InputInterruptThread( )
{
    ULONG InputTransferred;

    DEBUGMSG(ZONE_INIT, (TEXT("InputInterruptThread")));

    while (TRUE)
    {
        WaitForSingleObject(hInputIntEvent,  INFINITE);
        if (TRUE == m_audioDeinit)
        {
            return;
        }

        DEBUGMSG(ZONE_VERBOSE, (TEXT( "DCSR_ENDINTR on intput\r\n" )) );
        Lock();

        int buffer = GetLastInputBuffer();
        InputTransferred = TransferInputBuffer(buffer);

        if( InputTransferred==0 )
        {
            StopInputDMA();
        }
        Unlock();
    }
}

void HardwareContext::OutputInterruptThread( )
{
    DEBUGMSG(ZONE_INIT, (TEXT("OutputInterruptThread")));

    while (TRUE)
    {
        WaitForSingleObject(hOutputIntEvent,  INFINITE);
        if (TRUE == m_audioDeinit)
        {
            return;
        }        
         
        DEBUGMSG(ZONE_VERBOSE, (TEXT( "DCSR_ENDINTER on output\r\n" )) );
        Lock();

        int buffer = GetNextOutputBuffer();
        ULONG Bytes = TransferOutputBuffer(buffer);

        if(!m_OutputDMARunning)
	{
            if(Bytes)
            {
                // More data to play. Restart DMA engine by loading the descriptor
	        // address reg to initialize DMA, pointing to the buffer just loaded.
                m_pDMARegisters->ddg[m_PlaybackChannel].ddadr =
                    (buffer == 0) ? (UINT32)m_vpAudioXmitA_Physical : (UINT32)m_vpAudioXmitB_Physical;;
                
                // Set the RUN bit and also enable STOPINTR so that we know DMA is done
                // on last buffer. A zero length buffer is considered the last buffer.
                m_pDMARegisters->dcsr[m_PlaybackChannel] |=  DCSR_RUN | DCSR_STOPIRQEN;
                m_OutputDMARunning=TRUE;
				
            }
            else
            {
                // No more data to play. Will stop when the previous buffer
	        //StopOutputDMA();
            }
 	}

        Unlock();
    }
}


#if !USE_I2S_INTERFACE

BOOL HardwareContext::TestAcLink()
{
    BOOL RetVal=TRUE;

    int i;

    unsigned short int Value;

    for (i=0;i<0x80;i+=2)
    {
        SafeReadCodec(i, &Value, DEV_AUDIO);
        RETAILMSG(1, (TEXT( "register::value %x %x" ),i,Value ));
    }

    return (RetVal);
}

#endif

//------------------------------------------------------------------------------------------------------------
// Function: FillDescriptors
// 
// Purpose: Fill the descriptors with appropriate data
//
// Note: This code could be cleaner, but I want to be explicit on the programming of descriptors
//
//-------------------------------------------------------------------------------------------------------------
BOOL HardwareContext::FillOutputDescriptors( void )
{
    union DmaCmdReg     CmdBuff;
    memset (&CmdBuff,0, sizeof (CmdBuff));

        // set individual bit fields to for debug.  

#define USE_BITFIELD
#ifdef USE_BITFIELD  
        
        // set values with bit fields
        CmdBuff.DcmdReg.len = AUDIO_BUFFER_SIZE;  //length of memory buffer
        CmdBuff.DcmdReg.width = 0x3;    // binary 11 (see quick Quick Reference sheet to DMA programming in the cotulla EAS)
        CmdBuff.DcmdReg.size = 0x3;     // binary 11 
        CmdBuff.DcmdReg.endian = 0;     // little endian
        CmdBuff.DcmdReg.flybyt = 0;     // Flowthrough
        CmdBuff.DcmdReg.flybys = 0;     // Flowthrough
        CmdBuff.DcmdReg.endirqen = 1;   // 1 means Interrupt when decrement length = 0;
        CmdBuff.DcmdReg.startirqen = 0; // 1 means Interrupt when the desc is loaded
        CmdBuff.DcmdReg.flowtrg = 1;    // 1 means the target is an external peripheral
        CmdBuff.DcmdReg.flowsrc = 0;    // 1 means the source is an external peripheral (and needs flow con
        CmdBuff.DcmdReg.inctrgadd = 0;  // 1 means increment the target address (since it's memory) 
        CmdBuff.DcmdReg.incsrcadd = 1;  // 1 means increment the source address (since it's a peripheral)
#else  
        // set value based on masks
        CmdBuff.DcmdDword = DMAC_AC97_XMITAB_CMD_MASK | AUDIO_BUFFER_SIZE; 
#endif

        //
        // fill XmitA Descriptor
        //

        m_vpAudioXmitA->ddadr= (UINT32)m_vpAudioXmitB_Physical ;             // address of the next (XmitB) descriptor

#if USE_I2S_INTERFACE

		m_vpAudioXmitA->dtadr=  DMAC_IIS_AUDIO_XMIT_FIFO;                   // source address of the IIS XmitA buffer

#else

        m_vpAudioXmitA->dtadr=  DMAC_AC97_AUDIO_XMIT_FIFO;                   // source address of the AC97 XmitA buffer

#endif

        m_vpAudioXmitA->dsadr= (UINT32)(m_Output_pbDMA_PAGES_Physical[0]);   // destination address of the XmitA buffer
        m_vpAudioXmitA->dcmd = CmdBuff.DcmdDword ;                           // size and cmd values of the XmitA buffer

        //
        // fill XmitB Descriptor
        //

        m_vpAudioXmitB->ddadr= (UINT32)m_vpAudioXmitA_Physical;              // address of the next (XmitA) descriptor

#if USE_I2S_INTERFACE

		m_vpAudioXmitB->dtadr= DMAC_IIS_AUDIO_XMIT_FIFO;                    // source address of the IIS XmitB buffer

#else

        m_vpAudioXmitB->dtadr= DMAC_AC97_AUDIO_XMIT_FIFO;                    // source address of the AC97 XmitB buffer

#endif


        m_vpAudioXmitB->dsadr= (UINT32)(m_Output_pbDMA_PAGES_Physical[1]) ;  // destination address of the XmitB buffer
        m_vpAudioXmitB->dcmd = CmdBuff.DcmdDword ;                           // size and cmd values of the XmitB buffer

        return TRUE;
}

//------------------------------------------------------------------------------------------------------------
// Function: FillDescriptors
// 
// Purpose: Fill the descriptors with appropriate data
//
// Note: This code could be cleaner, but I want to be explicit on the programming of descriptors
//
//-------------------------------------------------------------------------------------------------------------
BOOL HardwareContext::FillInputDescriptors( void )
{
    union DmaCmdReg     CmdBuff;
    memset (&CmdBuff,0, sizeof (CmdBuff));

        // set individual bit fields to for debug.  

#define USE_BITFIELD
#ifdef USE_BITFIELD  
        
        // set values with bit fields  
        CmdBuff.DcmdReg.len = AUDIO_BUFFER_SIZE;  //length of the memory buffer
        CmdBuff.DcmdReg.width = 0x3;    // binary 11 (see quick Quick Reference sheet to DMA programming in the cotulla EAS)
        CmdBuff.DcmdReg.size = 0x3;     // binary 11 
        CmdBuff.DcmdReg.endian = 0;     // little endian
        CmdBuff.DcmdReg.flybyt = 0;     // Flowthrough
        CmdBuff.DcmdReg.flybys = 0;     // Flowthrough
        CmdBuff.DcmdReg.endirqen = 1;   // 1 means Interrupt when decrement length = 0;
        CmdBuff.DcmdReg.startirqen = 0; // 1 means Interrupt when the desc is loaded
        CmdBuff.DcmdReg.flowtrg = 0;    // 1 means the target is an external peripheral
        CmdBuff.DcmdReg.flowsrc = 1;    // 1 means the source is an external peripheral (and needs flow control)
        CmdBuff.DcmdReg.inctrgadd = 1;  // 1 means increment the target address (since it's memory) 
        CmdBuff.DcmdReg.incsrcadd = 0;  // 1 means increment the source address (since it's a peripheral)
#else  
        // set value based on masks
        CmdBuff.DcmdDword = DMAC_AC97_RCVAB_CMD_MASK | AUDIO_BUFFER_SIZE;  
#endif

        //
        // fill RcvA Descriptor
        //

        m_vpAudioRcvA-> ddadr= (UINT32)m_vpAudioRcvB_Physical;           // address of the next (RcvB) descriptor
        m_vpAudioRcvA-> dtadr= (UINT32)(m_Input_pbDMA_PAGES_Physical[0]);                        // source address of the AC97/IIS RcvA buffer

#if USE_I2S_INTERFACE

		m_vpAudioRcvA-> dsadr= DMAC_IIS_AUDIO_RCV_FIFO;           // destination address of the RcvA buffer

#else

        m_vpAudioRcvA-> dsadr= DMAC_AC97_AUDIO_RCV_FIFO;           // destination address of the RcvA buffer

#endif

        m_vpAudioRcvA-> dcmd = CmdBuff.DcmdDword ;                                                           // size and cmd values of the RcvA buffer

        //
        // fill RcvB Descriptor
        //

        m_vpAudioRcvB-> ddadr= (UINT32)m_vpAudioRcvA_Physical ;             // address of the next (RcvA) descriptor
        m_vpAudioRcvB-> dtadr= (UINT32)(m_Input_pbDMA_PAGES_Physical[1]);                        // source address of the AC97/IIS RcvB buffer

#if USE_I2S_INTERFACE

		m_vpAudioRcvB-> dsadr= DMAC_IIS_AUDIO_RCV_FIFO;                         // destination address of the RcvB buffer	

#else

        m_vpAudioRcvB-> dsadr= DMAC_AC97_AUDIO_RCV_FIFO;                         // destination address of the RcvB buffer

#endif

        m_vpAudioRcvB-> dcmd = CmdBuff.DcmdDword ;                                                           // size and cmd values of the RcvB buffer

        return TRUE;
}

//------------------------------------------------------------------------------------------------------------
// Function: StopDmac
// 
// Purpose: To stop DMA transmit
//-------------------------------------------------------------------------------------------------------------
void  HardwareContext::StopDmac(int Channel)
{
    m_pDMARegisters->dcsr[Channel] &=  ~DCSR_RUN;  //clear the run but

    return;
}

//------------------------------------------------------------------------------------------------------------
// Function: ClearDmac
// 
// Purpose: To clear DMA status
//-------------------------------------------------------------------------------------------------------------
VOID  HardwareContext::ClearDmac(int Channel)
{
    DWORD dwDCSR;

    dwDCSR  = m_pDMARegisters->dcsr[Channel];

    if(dwDCSR & DCSR_STOPINTR)
    {
        dwDCSR &= ~DCSR_STOPIRQEN;
    }

    // Clear the status
    m_pDMARegisters->dcsr[Channel] = dwDCSR;

    return;
}

//------------------------------------------------------------------------------------------------------------
// Function: AC97SetSampleRate
// 
// Purpose: Write the sample rate value to the ac97 codec
//-------------------------------------------------------------------------------------------------------------
BOOL HardwareContext::SetSampleRate(unsigned short int SampleRate, WAPI_INOUT apidir )
{
    short int RetVal=TRUE;
    unsigned short int value = 0;

    switch(SampleRate)
    {
        case 8000:
            value = KHZ08_000;
            break;
        case 11025:
    	    value = KHZ11_025;
    	    break;
    	case 16000:
    	    value = KHZ16_000;
    	    break;
    
        case 22050:
            value = KHZ22_050;
    	    break;
    
    	case 32000:
    	    value = KHZ32_000;
    	    break;
    
        case 44100:
             value = KHZ44_100;
    	     break;
    
        case 48000:
             value = KHZ48_000;
   	     break;
        default:
    	    DEBUGCHK(0);  //we sent a bad rate
    	    RetVal=FALSE;
    	    return (RetVal);
    }


#if USE_I2S_INTERFACE

   if (apidir == WAPI_IN)
    {
        RetVal=SetI2sSampleRate(SampleRate); //set the input sample rate
    }
    else
    {
        RetVal=SetI2sSampleRate(SampleRate); //set the output sample rate
    }

#else    

    if (apidir == WAPI_IN)
    	    RetVal=SafeWriteCodec((XLLP_UINT16_T)AUDIO_ADC_RATE,value , DEV_AUDIO); //set the input sample rate
    else
    	    RetVal=SafeWriteCodec((XLLP_UINT16_T)AUDIO_DAC_RATE,value , DEV_AUDIO); //set the output sample rate

#endif

    return (RetVal);
}

void HardwareContext::DumpDmacRegs()
{
#if 0

        int i;

        DEBUGMSG(ZONE_ERROR, (TEXT( "gsr %x, posr %x, pocr %x, pisr %x, picr %x\r\n" ),
                m_pAc97regs->GSR,
                m_pAc97regs->POSR,
                m_pAc97regs->POCR,
                m_pAc97regs->PISR,
                m_pAc97regs->PICR
                ) );

        
        for (i=0; i< 16; i++)
                DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->dcsr[%d]     %x \r\n" ),i,m_pDMARegisters->dcsr[i] ) );
   
        //skip rsvd section rsvd0[44];
        DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->dint         %x \r\n" ),m_pDMARegisters->dint ) );

    //skip rsvd seciton rsvd1[3];

        for (i=0; i< 39; i++)
                DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->drcmr[%d]    %x \r\n" ),i,m_pDMARegisters->drcmr[i] ) );

        for (i=0; i<16; i++)
        {

                DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].ddadr  %x \r\n" ),i,m_pDMARegisters->ddg[i].ddadr ) );
                DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].dsadr  %x \r\n" ),i,m_pDMARegisters->ddg[i].dsadr ) );
                DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].dtadr  %x \r\n" ),i,m_pDMARegisters->ddg[i].dtadr ) );
                DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].dcmd   %x \r\n" ),i,m_pDMARegisters->ddg[i].dcmd ) );


⌨️ 快捷键说明

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