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

📄 hwctxt.cpp

📁 老外的一个开源项目
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        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
        m_vpAudioXmitB->DTADR= DMAC_AC97_AUDIO_XMIT_FIFO;                    // source address of the AC97 XmitB buffer
        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 RcvA buffer
        m_vpAudioRcvA-> DSADR= DMAC_AC97_AUDIO_RCV_FIFO;           // destination address of the RcvA buffer
        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 RcvB buffer
        m_vpAudioRcvB-> DSADR= DMAC_AC97_AUDIO_RCV_FIFO;                         // destination address of the RcvB buffer
        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 = UCB_DR_8000;
            break;
        case 11025:
    	    value = UCB_DR_11025;
    	    break;
    	case 16000:
    	    value = UCB_DR_16000;
    	    break;
    
        case 22050:
            value = UCB_DR_22050;
    	    break;
    
    	case 32000:
    	    value = UCB_DR_32000;
    	    break;
    
        case 44100:
             value = UCB_DR_44100;
    	     break;
    
        case 48000:
             value = UCB_DR_48000;
   	     break;
        default:
    	    DEBUGCHK(0);  //we sent a bad rate
    	    RetVal=FALSE;
    	    return (RetVal);
    }
    
    if (apidir == WAPI_IN)
    	    RetVal=SafeWriteAC97((UINT16_T)AUDIO_ADC_RATE,value ); //set the input sample rate
    else
    	    RetVal=SafeWriteAC97((UINT16_T)AUDIO_DAC_RATE,value ); //set the output sample rate
    
    return (RetVal);
}

void HardwareContext::DumpDmacRegs()
{
        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 ) );


        }

}

void HardwareContext::InitCodec(void)
{
    static DWORD VendorId=0;
    unsigned short int VidTemp=0;
    unsigned short int Ac97RegisterData=0;
    unsigned short int FeatureCrs1Data=0;

    DEBUGMSG(ZONE_INIT, (TEXT("HardwareContext::InitCodec\r\n")));

    //Force VRA (variable rate audio) to be on 
    SafeWriteAC97(EXTENDED_AUDIO_CTRL, VRA_ENABLED_MASK);

    //Default is AUDIO_MIC_INPUT_MONO
    SafeWriteAC97(RECORD_SELECT, 0x0);

    //Set the output volume from the OS 
    SafeWriteAC97(MASTER_VOLUME, 0);

    //Set the record gain value. The ADC is 20-bit but AC97 PCDR register is only 16-bit.
    //Setting to 0x0F0F might cause clipping.
    SafeWriteAC97(RECORD_GAIN, 0x0808);

    //Enable microphone Boost, but keep the line from mic to speakers muted.
    SafeWriteAC97(MIC_VOLUME, 0x8040);

    //Set bass and treble to a good sounding value
    SafeWriteAC97(FEATURE_CSR1, 0x5400);

    //Get vendor ID
    if(VendorId == 0)
    {
        SafeReadAC97(VENDOR_ID1, &VidTemp);

        VendorId= (VidTemp <<16); //ffffffffssssssss // f=first ascii s = second ascii

        SafeReadAC97(VENDOR_ID2, &VidTemp);

        VendorId |=VidTemp;       //ttttttttrrrrrrrr //t = third ascii, r=rev #
        VendorId &= 0xfffffff0;//trim of version number
    }

    //
    //compliant codecs such as Crystal require the PCM volume
    //if it's a ucb1400 then don't write the PCM volume (although it shouldn't hurt)
    //
    //vendor specific 
    switch (VendorId)
    {
      case 0x50534300: //philips UCB1400
        SafeWriteAC97(FEATURE_CSR2, PWR_SMART_CODEC);

        //
        //CAREFULL, writing the FEATURE_CSR1 could mess up the touch screen
        //

        SafeReadAC97(FEATURE_CSR1,&Ac97RegisterData);

        Ac97RegisterData = Ac97RegisterData & EQ_MASK;          //get just EQ data

        SafeReadAC97(FEATURE_CSR1,&FeatureCrs1Data);

        //mask off eq data

        FeatureCrs1Data = FeatureCrs1Data &  0x8000;            // lob off reserved bit (must be 0)
        FeatureCrs1Data = FeatureCrs1Data & ~EQ_MASK;           // lob off eq data
        FeatureCrs1Data = FeatureCrs1Data | Ac97RegisterData;   // stored EQ data with actual Feature data 
                        
        //comment out headphone enable to save power, use an app to turn it on instead
        //HACK: If the capabiliters reads 0x2a0 it's rev 2a, if its 0x2a then its rev 1b.
        SafeReadAC97(0, (UINT16 *)&m_ResetCaps);
        if (m_ResetCaps==REV_2A)
        {
            FeatureCrs1Data = FeatureCrs1Data | (unsigned short) HPEN_MASK; //turn on head phone
            m_CodecType=UCB14002A;
            DEBUGMSG(ZONE_VERBOSE, (TEXT( "-- UCB14002A \r\n")   ) );   
        }
        else
        {
            m_CodecType=UCB14001B;
            DEBUGMSG(ZONE_VERBOSE, (TEXT( "-- UCB14001b \r\n")   ) );   

        }
        SafeWriteAC97(FEATURE_CSR1, FeatureCrs1Data);

        break;

      default:  //vanilla AC97
        SafeWriteAC97(PCM_OUT_VOL, 0x1f1f);
        DEBUGMSG(ZONE_VERBOSE, (TEXT( "-- vanilla AC97 \r\n")   ) );    
        break;
    }

    return;
}

void HardwareContext::DeInitCodec(void)
{
    DEBUGMSG(ZONE_INIT, (TEXT("HardwareContext::DeInitCodec\r\n")));

    // Power down Codec
    // SafeWriteAC97(AC97_CR_POWERDOWN_CTRL_STAT, 0x1000);

    return;
}

void  HardwareContext::PowerDown()
{
    m_Sleeping=TRUE;

    DEBUGMSG(ZONE_FUNCTION | ZONE_VERBOSE, (TEXT("WaveDev2: PowerDown\r\n")));

    // Power down AC97 link
//    UnConfigureAC97Control();

} // PowerDown()

void  HardwareContext::PowerUp()
{

    // Initialize GPIO and power up AC97 link
//    ConfigureAC97Control();

    // Clear DMA status
    ClearDmac(m_RecordingChannel);
    ClearDmac(m_PlaybackChannel);
    InterruptDone(m_SysIntrAudioDMA);

    if (TRUE == m_InPowerHandler)
    {
        m_Sleeping=FALSE;
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Wavedev:HardwareContext::PowerUp: Done\r\n")));

}

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

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// RecalcSpeakerEnable decides whether to enable the speaker or not.
// For now, it only looks at the m_bForceSpeaker variable, but it could
// also look at whether the headset is plugged in
// and/or whether we're in a voice call. Some mechanism would
// need to be implemented to inform the wave driver of changes in the state of
// these variables however.
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8

void HardwareContext::RecalcSpeakerEnable()
{
    SetSpeakerEnable(m_NumForcedSpeaker);
}

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// SetForceSpeaker is called from the device context to update the state of the
// m_bForceSpeaker variable.
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8

DWORD HardwareContext::ForceSpeaker( BOOL bForceSpeaker )
{
    // If m_NumForcedSpeaker is non-zero, audio should be routed to an
    // external speaker (if hw permits).
    if (bForceSpeaker)
    {
        m_NumForcedSpeaker++;
        if (m_NumForcedSpeaker==1)
        {
            RecalcSpeakerEnable();
        }
    }
    else
    {
        m_NumForcedSpeaker--;
        if (m_NumForcedSpeaker==0)
        {
            RecalcSpeakerEnable();
        }
    }

    return MMSYSERR_NOERROR;
}


short int HardwareContext::MsgWriteAC97(DWORD dwParam1,DWORD dwParam2)
{
    DEBUGMSG(ZONE_VERBOSE, (TEXT( "write %x %x \r\n" ),dwParam1,dwParam2)); 

    SafeWriteAC97((BYTE)dwParam1,(unsigned short int)dwParam2 );
    return (MMSYSERR_NOERROR);
}

short int HardwareContext::MsgReadAC97(DWORD dwParam1,DWORD dwParam2)
{
    unsigned short int MyData=0; 

    DEBUGMSG(ZONE_VERBOSE, (TEXT( "read %x %x \r\n" ),dwParam1,MyData ));

    SafeReadAC97((BYTE)dwParam1, &MyData);

    if (dwParam2 != (unsigned short int) NULL)
            * (unsigned short int *) dwParam2 =  MyData;

    return (MMSYSERR_NOERROR);
}


/*
#define RIL_AUDIO_NONE                              (0x00000000)      // @constdefine No audio devices
#define RIL_AUDIO_HANDSET                           (0x00000001)      // @constdefine Handset
#define RIL_AUDIO_SPEAKERPHONE                      (0x00000002)      // @constdefine Speakerphone
#define RIL_AUDIO_HEADSET                           (0x00000003)      // @constdefine Headset
#define RIL_AUDIO_CARKIT                            (0x00000004)      // @constdefine Carkit
*/

BOOL HardwareContext::SetCfgHeadSet()
{
        return TRUE;
}
BOOL HardwareContext::SetCfgHandSet()
{
        return TRUE;
}
BOOL HardwareContext::SetCfgSpeakerPhone()
{
        return TRUE;
}
BOOL HardwareContext::SetCfgCarKit()
{
        return TRUE;
}
BOOL HardwareContext::SetCfgNone()
{
        return TRUE;
}

//------------------------------------------------------------------------------------------------------------
// Function: MapDMADescriptors
//
// Purpose:  Map the physical DMA Descriptors into virtual space
//
// Returns:  TRUE indicates success. FALSE indicates failure
//
//-------------------------------------------------------------------------------------------------------------

⌨️ 快捷键说明

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