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

📄 hwctxt.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            //       = 7  (for 16 bits/word)
            //       = 11 (for 24 bits/word)
            //
            OUTREG32(&pSSI->STCCR,
                CSP_BITFVAL(SSI_STCCR_DIV2, SSI_STCCR_DIV2_BYPASS)    |
                CSP_BITFVAL(SSI_STCCR_PSR, SSI_STCCR_PSR_DIV8_BYPASS) |
                CSP_BITFVAL(SSI_STCCR_WL, ssi_stccr_wl)               |
                CSP_BITFVAL(SSI_STCCR_DC, ssi_stccr_dc_mode)          |
                CSP_BITFVAL(SSI_STCCR_PM, 2));
        }
        else if (pSSI == STEREO_DAC_SSI)
        {
            // We want a 44.1 kHz sampling rate from the SSI for the Stereo DAC.
            //
            // The calculation of the appropriate SSI clock divider constants
            // is done as follows:
            //
            //    Ideal Sampling Rate  = 44.1 kHz
            //    Oversampling Rate    = 384
            //    Ideal MCLK Frequency = 44.1 kHz * 384 = 16.9344 MHz
            //    Serial PLL Frequency = 220.1472 MHz
            //
            //    SSI Divider = 220.1472 / 16.9344 = 13
            //
            // So that means we can set the predivider to divide-by-one (by
            // just writing 0) and the postdivider to divide-by-thirteen
            // (which actually means writing a 12 to the postdivider control
            // register).
            //
            // This will produce the exact 16.9344 MHz clock that we need
            // as the input to the SSI.
            DDKClockConfigBaud((pSSI == m_pSSI1) ? DDK_CLOCK_SIGNAL_SSI1 :
                                                   DDK_CLOCK_SIGNAL_SSI2,
                               (pSSI == m_pSSI1) ? SSI1_MASTER_CLOCK_SOURCE :
                                                   SSI2_MASTER_CLOCK_SOURCE,
                               0, 12);

            // The associated SSI internal clock divider constants are
            // calculated as follows:
            //
            //    Ideal Sampling Rate              = 44.1 kHz
            //
            //    For NETWORK mode only:
            //        Bits/Word                    = 16
            //        Words/Frame                  = 4
            //        Ideal Bit Clock Frequency    = 44.1 kHz * 16 * 4
            //                                     = 2.8224 MHz
            //        SSI Internal Clock Frequency = 16.9344 MHz (from above)
            //        SSI Internal Divider         = 16.9344 / 2.8224 = 6
            //
            //    For I2S mode only:
            //        Bits/Word                    = 32
            //        Words/Frame                  = 2
            //        Ideal Bit Clock Frequency    = 44.1 kHz * 32 * 2
            //                                     = 2.8224 MHz
            //        SSI Internal Clock Frequency = 16.9344 MHz (from above)
            //        SSI Internal Divider         = 16.9344 / 2.8224 = 6
            //
            // The corresponding SSI internal divider settings are as follows:
            //
            //    For both NETWORK and I2S modes:
            //        DIV2 = 0
            //        PSR  = 0
            //        PM   = 2
            //
            // We also set the following to configure for bits/word and
            // either 4 or 2 words/frame:
            //
            //    DC = 3 (for network mode with 4 words/frame)
            //       = 1 (for I2S mode 2 words/frame)
            //    WL = 3  (for 8 bits/word)
            //       = 7  (for 16 bits/word)
            //       = 11 (for 24 bits/word)
            //
            // Note that for the I2S mode, the word length is fixed at 32
            // bits/word and the WL value only serves to indicate how many
            // out of the 32 bits/word are actually valid.
            OUTREG32(&pSSI->STCCR,
                CSP_BITFVAL(SSI_STCCR_DIV2, SSI_STCCR_DIV2_BYPASS)    |
                CSP_BITFVAL(SSI_STCCR_PSR, SSI_STCCR_PSR_DIV8_BYPASS) |
                CSP_BITFVAL(SSI_STCCR_WL, ssi_stccr_wl)               |
                CSP_BITFVAL(SSI_STCCR_DC, ssi_stccr_dc_mode)          |
                CSP_BITFVAL(SSI_STCCR_PM, 2));
        }

        // Also set the SSI transmitter to use it's internal clock source to
        // generate the bit clock and framesync signals for master mode.
        SETREG32(&pSSI->STCR, CSP_BITFMASK(SSI_STCR_TXDIR));
        SETREG32(&pSSI->STCR, CSP_BITFMASK(SSI_STCR_TFDIR));
    }
    else
    {
        // Configure the SSI transmit clock for slave mode operation where
        // the internal divider and prescaler parameters are irrelevant. The
        // key settings are DC to select words/frame and WL for bits/word to
        // match the PMIC's configuration.
        OUTREG32(&pSSI->STCCR,
            CSP_BITFVAL(SSI_STCCR_DIV2, SSI_STCCR_DIV2_BYPASS)    |
            CSP_BITFVAL(SSI_STCCR_PSR, SSI_STCCR_PSR_DIV8_BYPASS) |
            CSP_BITFVAL(SSI_STCCR_WL, ssi_stccr_wl)               |
            CSP_BITFVAL(SSI_STCCR_DC, ssi_stccr_dc_mode)          |
            CSP_BITFVAL(SSI_STCCR_PM, 0));

        // We have already configured the SSI transmitter to use an external
        // clock and framesync so nothing needs to be done here.
    }

    // Leave the SSI in a disabled state until we are actually ready to perform
    // audio playback or recording.
    //
    // Also note that we leave all of the transmit and receive timeslots masked
    // at this time and only unmask the required timeslots when we call either
    // BSPAudioStartSsiOutput() or BSPAudioStartSsiInput().

    // Disable SSI clocks to minimize power consumption.
    DDKClockSetGatingMode((pSSI == m_pSSI1) ? DDK_CLOCK_GATE_INDEX_SSI1 :
                                              DDK_CLOCK_GATE_INDEX_SSI2,
                          DDK_CLOCK_GATE_MODE_DISABLED);
}


//-----------------------------------------------------------------------------
//
//  Function: BSPAudioStartSsiOutput
//
//  This function configures SSI to start audio output.
//
//  Parameters:
//      pSSI 
//          [in] Points to SSI to be configured.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioStartSsiOutput(PCSP_SSI_REG pSSI,
                                             const HWSAMPLE *const ssiFifoPrefill,
                                             const unsigned nSsiFifoPrefill)
{
    // Enable SSI clocks before we access the SSI registers.
    DDKClockSetGatingMode((pSSI == m_pSSI1) ? DDK_CLOCK_GATE_INDEX_SSI1 :
                                              DDK_CLOCK_GATE_INDEX_SSI2,
                          DDK_CLOCK_GATE_MODE_ENABLED_ALL);

    // Enable the SSI and the transmit FIFO0 so that we can fill it up before
    // we enable the transmitter later.
    SETREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_SSIEN));
    SETREG32(&pSSI->STCR, CSP_BITFMASK(SSI_STCR_TFEN0));

    // Prefill the transmit FIFO so that there is something ready to go when
    // we enable the transmitter in the next step.
    for (unsigned i = 0; i < nSsiFifoPrefill; i++)
    {
        OUTREG32(&pSSI->STX0, *(ssiFifoPrefill + i));
    }

    // Enable only the first two transmit timeslots (for the left+right audio
    // channels).
    OUTREG32(&pSSI->STMSK, ~0x3);

    // The SSI has already been properly configured, we just need to enable
    // the SSI transmitter DMA request and the transmitter to begin the
    // audio output/playback process.
    SETREG32(&pSSI->SIER, CSP_BITFMASK(SSI_SIER_TDMAE));
    SETREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_TE));
}


//-----------------------------------------------------------------------------
//
//  Function: BSPAudioStopSsiOutput
//
//  This function configures SSI to stop audio output.
//
//  Parameters:
//      pSSI 
//          [in] Points to SSI to be configured.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioStopSsiOutput(PCSP_SSI_REG pSSI)
{
    UINT32 scr;

    // Start by disabling the SSI transmitter.
    CLRREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_TE));
    
    // Disable the SSI transmit DMA request.
    CLRREG32(&pSSI->SIER, CSP_BITFMASK(SSI_SIER_TDMAE));

    // Disable the transmit FIFO0 and mask all transmit timeslots.
    CLRREG32(&pSSI->STCR, CSP_BITFMASK(SSI_STCR_TFEN0));
    OUTREG32(&pSSI->STMSK, 0xffffffff);

    // If the SSI receiver is also disabled, then turn off the entire SSI.
    scr = INREG32(&pSSI->SCR);
    if (!(scr & CSP_BITFMASK(SSI_SCR_RE)))
    {
        // Completely disable the SSI.
        CLRREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_SSIEN));

        // Disable SSI clocks to minimize power consumption.
        DDKClockSetGatingMode((pSSI == m_pSSI1) ? DDK_CLOCK_GATE_INDEX_SSI1 :
                                                  DDK_CLOCK_GATE_INDEX_SSI2,
                              DDK_CLOCK_GATE_MODE_DISABLED);
    }
}


#ifdef AUDIO_RECORDING_ENABLED

//-----------------------------------------------------------------------------
//
//  Function: BSPAudioStartSsiInput
//
//  This function configures SSI to start audio input.
//
//  Parameters:
//      pSSI 
//          [in] Points to SSI to be configured.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioStartSsiInput(PCSP_SSI_REG pSSI)
{
    // Enable SSI clocks before we access the SSI registers.
    DDKClockSetGatingMode((pSSI == m_pSSI1) ? DDK_CLOCK_GATE_INDEX_SSI1 :
                                              DDK_CLOCK_GATE_INDEX_SSI2,
                          DDK_CLOCK_GATE_MODE_ENABLED_ALL);

    // Start off by enabling the SSI. This must be done first.
    SETREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_SSIEN));

    // Next, enable the SSI receiver DMA request and RX FIFO0.
    OUTREG32(&pSSI->SIER, CSP_BITFVAL(SSI_SIER_RFF0_EN, TRUE));
    SETREG32(&pSSI->SRCR, CSP_BITFMASK(SSI_SRCR_RFEN0));

    // Unmask only the first two receive timeslots (for the primary and
    // secondary audio recording channels).
    OUTREG32(&pSSI->SRMSK, ~0x3);

    // The SSI has already been properly configured, we just need to enable
    // the SSI receiver DMA request and the receiver to begin the audio
    // input/recording process.
    SETREG32(&pSSI->SIER, CSP_BITFMASK(SSI_SIER_RDMAE));
    SETREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_RE));
}


//-----------------------------------------------------------------------------
//
//  Function: BSPAudioStopSsiInput
//
//  This function configures SSI to stop audio input.
//
//  Parameters:
//      pSSI 
//          [in] Points to SSI to be configured.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioStopSsiInput(PCSP_SSI_REG pSSI)
{
    UINT32 scr;

    // Start by disabling the SSI receiver.
    CLRREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_RE));
    
    // Disable the SSI receive DMA request
    CLRREG32(&pSSI->SIER, CSP_BITFMASK(SSI_SIER_RDMAE));

    // Disable the receive FIFO0 and mask all receive timeslots.
    CLRREG32(&pSSI->SRCR, CSP_BITFMASK(SSI_SRCR_RFEN0));
    OUTREG32(&pSSI->SRMSK, 0xffffffff);

    // If the transmitter is also disabled, then turn off the entire SSI.
    scr = INREG32(&pSSI->SCR);
    if (!(scr & CSP_BITFMASK(SSI_SCR_TE)))
    {
        // Completely disable the SSI.
        CLRREG32(&pSSI->SCR, CSP_BITFMASK(SSI_SCR_SSIEN));

        // Disable SSI clocks to minimize power consumption.
        DDKClockSetGatingMode((pSSI == m_pSSI1) ? DDK_CLOCK_GATE_INDEX_SSI1 :
                                                  DDK_CLOCK_GATE_INDEX_SSI2,
                              DDK_CLOCK_GATE_MODE_DISABLED);
    }
}

#endif // #ifdef AUDIO_RECORDING_ENABLED


//-----------------------------------------------------------------------------
//
//  Function: BSPAudioSetCodecPower
//
//  This function sets the power state of the external audio chip.
//
//  Parameters:
//      state
//          [in] - Specifies the desired power state.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioSetCodecPower(AUDIO_PWR_STATE state)
{
    UINT32 regMode0, audRx0, mask;

    // Check if power state transition is required
    if (state == m_CodecPwrState) return;
    
    switch (state) 
    {
        case AUDIO_PWR_STATE_OFF:

            regMode0 = CSP_BITFVAL(MC13783_REG_MODE0_VAUDIOEN, FALSE)  |
                       CSP_BITFVAL(MC13783_REG_MODE0_VAUDIOSTBY, TRUE) |
                       CSP_BITFVAL(MC13783_REG_MODE0_VAUDIOMODE, FALSE);

            audRx0 = CSP_BITFVAL(MC13783_AUD_RX0_VAUDIOON,
                                 MC13783_AUD_RX0_VAUDIOON_DISABLE) |
                     CSP_BITFVAL(MC13783_AUD_RX0_BIASEN,
                                 MC13783_AUD_RX0_BIASEN_DISABLE)   |
                     CSP_BITFVAL(MC13783_AUD_RX0_BIASSPEED,
                                 MC13783_AUD_RX0_BIASSPEED_ENABLE);

            break;
            
        case AUDIO_PWR_STATE_STANDBY:
#ifdef AUDIO_RECORDING_ENABLED
            // Only allow transition to standby state if both input
            // and output are ina

⌨️ 快捷键说明

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