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

📄 hwctxt.cpp

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    switch(SampleRate)
    {
        case 8000:
            value = XLLP_AC97_U14_DR_8000;
            break;
        case 11025:
            value = XLLP_AC97_U14_DR_11025;
            break;
        case 16000:
            value = XLLP_AC97_U14_DR_16000;
            break;
    
        case 22050:
            value = XLLP_AC97_U14_DR_22050;
            break;
    
        case 32000:
            value = XLLP_AC97_U14_DR_32000;
            break;
    
        case 44100:
             value = XLLP_AC97_U14_DR_44100;
             break;
    
        case 48000:
             value = XLLP_AC97_U14_DR_48000;
         break;
        default:
            DEBUGCHK(0);  //we sent a bad rate
            RetVal=FALSE;
            return (RetVal);
    }
    
    if (apidir == WAPI_IN)
            RetVal=SafeWriteAC97((XLLP_UINT16_T)AUDIO_ADC_RATE,value , DEV_AUDIO); //set the input sample rate
    else
            RetVal=SafeWriteAC97((XLLP_UINT16_T)AUDIO_DAC_RATE,value , DEV_AUDIO); //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")));

     //Get vendor ID to identify chipset first
    if(VendorId == 0)
    {
        SafeReadAC97(VENDOR_ID1, &VidTemp, DEV_AUDIO);

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

        SafeReadAC97(VENDOR_ID2, &VidTemp, DEV_AUDIO);

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

    //vendor specific 
    switch (VendorId)
    {
      case 0x574D4C10: //For Wolfson WM9712L chipset

        //
        // 1. Configure GPIO pins for AC'97
        //
        //Pin 4 is output, active low, sticky (/AC97_AMPSD)
        //Pin 1 is active low. (For Jack insert detection)

        //Set GPIO pin direction
        Ac97RegisterData = 0xFFEF;
        SafeWriteAC97(AUGPIO_PIN_DIR,Ac97RegisterData, DEV_AUDIO);

        //Set GPIO pin polarity
        Ac97RegisterData = 0xFFED;
        SafeWriteAC97(AUGPIO_PIN_POL,Ac97RegisterData, DEV_AUDIO);

        //Set GPIO pins sticky
        Ac97RegisterData = 0x10;
        SafeWriteAC97(AUGPIO_PIN_STICK,Ac97RegisterData, DEV_AUDIO);

        //
        // 2. Configure Jack insertion and auto-switching between headphone and ear speaker
        //
        SafeReadAC97(AUADD_FUNC1,&Ac97RegisterData, DEV_AUDIO);
        Ac97RegisterData = Ac97RegisterData | 0x1000;
        Ac97RegisterData = Ac97RegisterData & 0xF7FF;
        SafeWriteAC97(AUADD_FUNC1, Ac97RegisterData, DEV_AUDIO);

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

        //
        // 4. Set Record selector and Record gain/volume(18dB w/20db Boost)
        //
        SafeWriteAC97(RECORD_SELECT, 0x7000, DEV_AUDIO); // 0x7000 for phone mic and 0x7707 for AEC mic
        SafeWriteAC97(RECORD_GAIN, 0x0C0C, DEV_AUDIO);

        //
        // 4.5 Set inputs
        //
        SafeWriteAC97(MIC_VOLUME, 0x6008, DEV_AUDIO);       // 0dB MICVOL, single ended mono (MIC1),  0x6040 for AEC mic 
        SafeWriteAC97(PHONE_VOLUME, 0xC008, DEV_AUDIO);     //0dB PHONEVOL
        SafeWriteAC97(LINE_IN_VOLUME,0xE006,DEV_AUDIO);     // Line-in not used

        //
        //5. Mute every output that is not used
        //
        SafeWriteAC97(MASTER_VOLUME, 0x8000, DEV_AUDIO);    // LOUT/ROUT - not used

        //
        //6. Open DAC path for headphone, speaker and phone mixer. 
        //
        SafeWriteAC97(PCM_OUT_VOL, 0x0808, DEV_AUDIO); // 0dB DAC volume

        //
        //7. Set outputs: headphone, ear speaker and loudspeaker volume to max
        //
        SafeWriteAC97(HEADPHONE_VOLUME, 0x0000, DEV_AUDIO);     // R/LHeadphone volume 0dB
        SafeWriteAC97(AUX_VOLUME, 0x0000, DEV_AUDIO);           // Set OUT3 (ear speaker) volume 0dB
        SafeWriteAC97(MASTER_VOLUME_MONO, 0x0000, DEV_AUDIO);   // PHONE output (loudspeaker thru AEC chip) volume 0dB

        //
        // 7.5 Tone control  
        //
        SafeWriteAC97(MASTER_TONE_R_L, 0x9444, DEV_AUDIO);  // Adaptive bassboost, -6db attn, bass & treble boost

        //
        //8. Power down everything except the ACLink and oscillator by default. Things will be turned on as needed
        //
        SafeWriteAC97(ADDTL_POWERDOWN_CTRL_STAT, 0x7FFF, DEV_AUDIO);

        //
        //9. Misc config
        //
        // Enable DAC auto-mute and ADC High Pass Filter
        SafeReadAC97(AUADD_FUNC2, &Ac97RegisterData, DEV_AUDIO);
        Ac97RegisterData = Ac97RegisterData | 0x80; // DAC Auto-Mute
        Ac97RegisterData = Ac97RegisterData | 0x08; // ADC High-Pass
        Ac97RegisterData = Ac97RegisterData &= 0xFEFF;
        SafeWriteAC97(AUADD_FUNC2, Ac97RegisterData, DEV_AUDIO);

        // Disable AUXDAC for power conservation        
        SafeReadAC97(CD_VOLUME, &Ac97RegisterData, DEV_AUDIO);
        Ac97RegisterData = Ac97RegisterData & 0xFFFE;
        SafeWriteAC97(CD_VOLUME, Ac97RegisterData, DEV_AUDIO);

        break;

      default:
        DEBUGMSG(ZONE_ERROR, (TEXT( "Error: Unknown codec.\r\n")));    
        break;
    }

    return;
}

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

    // Power down Codec
    // SafeWriteAC97(XLLP_AC97_CR_POWERDOWN_CTRL_STAT, 0x1000, DEV_AUDIO);

    return;
}

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

    DEBUGMSG(ZONE_FUNCTION | ZONE_VERBOSE, (TEXT("WaveDev2: PowerDown\r\n")));
   
    // Power down Codec
    SafeWriteAC97(AUADD_FUNC1, 0x0400, DEV_AUDIO); // set SVD=1 just to make sure VREF is off
    SafeWriteAC97(ADDTL_POWERDOWN_CTRL_STAT, 0xFFFF, DEV_AUDIO);
    SafeWriteAC97(POWERDOWN_CTRL_STAT, 0x7F00, DEV_AUDIO);

    // Power down AC97 link
    UnConfigureAC97Control();

} // PowerDown()

void  HardwareContext::PowerUp()
{
    // Initialize GPIO and power up AC97 link
    ConfigureAC97Control();

    // Initialize the codec
    InitCodec();

    //Initialize AEC chipset
    AecAudioInit();

    // Power up the AEC if it was previously powered
    if (m_AECStatus)
    {
        PowerUpAEC();
    }

    // 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)
{
    unsigned short int Ac97RegisterData=0;
    BOOL fAECStatus = FALSE;
    
    // Switch the power on or off to the audio amp that controls the speaker
    if (bEnable)
    {
        RETAILMSG(1,(TEXT("Turning speaker on...\r\n")));

        // power up the buffers and the speaker mixer
        SafeReadAC97(ADDTL_POWERDOWN_CTRL_STAT,&Ac97RegisterData, DEV_AUDIO);
        Ac97RegisterData = Ac97RegisterData & 0xFF3F;
        SafeWriteAC97(ADDTL_POWERDOWN_CTRL_STAT, Ac97RegisterData, DEV_AUDIO);

        // power up the amp
        SafeReadAC97(AUGPIO_PIN_STATUS, &Ac97RegisterData, DEV_AUDIO);
        Ac97RegisterData = Ac97RegisterData | 0x20;
        SafeWriteAC97(AUGPIO_PIN_STATUS, Ac97RegisterData, DEV_AUDIO);

        // Speaker output comes through the AEC chip. So power it up!
        fAECStatus = TRUE;
        SetAECStatus(&fAECStatus);
    }
    else
    {
        RETAILMSG(1,(TEXT("Turning speaker off...\r\n")));

        // power down the buffers and the speaker mixer
        SafeReadAC97(ADDTL_POWERDOWN_CTRL_STAT,&Ac97RegisterData, DEV_AUDIO);
        Ac97RegisterData = Ac97RegisterData | 0x00C0;
        SafeWriteAC97(ADDTL_POWERDOWN_CTRL_STAT, Ac97RegisterData, DEV_AUDIO);

        //power down the amp
        SafeReadAC97(AUGPIO_PIN_STATUS, &Ac97RegisterData, DEV_AUDIO);
        Ac97RegisterData = Ac97RegisterData & 0xFFDF;
        SafeWriteAC97(AUGPIO_PIN_STATUS, Ac97RegisterData, DEV_AUDIO);

        // AEC is not needed if the speaker output is disabled. Power it down to reduce power consumption
        fAECStatus = FALSE;
        SetAECStatus(&fAECStatus);
    }
    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;
}


void HardwareContext::SetAECStatus(LPVOID pvStatus)
{
    if (m_AECStatus != *((BOOL*)pvStatus))
    {
        m_AECStatus = *((BOOL*)pvStatus);
        if (m_AECStatus)
        {
            // turn on AEC
            if (!PowerUpAEC())
            {
                DEBUGMSG(ZONE_ERROR, (TEXT( "Failed to power up the AEC chip.\r\n" ))); 
            }
        }
        else
        {
            // turn off AEC
            if (!PowerDownAEC())
            {
                DEBUGMSG(ZONE_ERROR, (TEXT( "Failed to power down the AEC chip.\r\n" ))); 
            }

        }
    }
}

void HardwareContext::GetAECStatus(LPVOID pvStatus)
{
    *((BOOL*)pvStatus) = m_AECStatus;
}


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, DEV_AUDIO );
    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, DEV_AUDIO);

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

    return (MMSYSERR_NOERROR);
}


//------------------------------------------------------------------------------------------------------------

⌨️ 快捷键说明

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