📄 hwctxt.cpp
字号:
{
ERRORMSG(1, (_T("MapRegisters: MmMapIoSpace failed for Audio ")
_T("MUX!\r\n")));
goto cleanUp;
}
// We need to configure the CKO signal to output CKIH for the MC13783 CLI
// clock input.
DDKClockSetCKO(TRUE, DDK_CLOCK_CKO_SRC_CKIH, DDK_CLOCK_CKO_DIV_2);
// We now have the ability to access all of the hardware components that
// are needed to perform audio recording and playback.
rc = TRUE;
cleanUp:
if (!rc) BSPAudioDeinit();
DEBUGMSG(ZONE_FUNCTION, (_T("-HardwareContext::BSPAudioInit\n")));
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: BSPAudioDeinit
//
// This function unmaps the peripheral registers previously mapped with
// the MapRegisters function.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::BSPAudioDeinit()
{
DEBUGMSG(ZONE_FUNCTION, (_T("+HardwareContext::BSPAudioDeinit\n")));
// Unmap SSI1 peripheral registers
if (m_pSSI1)
{
MmUnmapIoSpace(m_pSSI1, sizeof(CSP_SSI_REG));
m_pSSI1 = NULL;
}
// Unmap SSI2 peripheral registers
if (m_pSSI2)
{
MmUnmapIoSpace(m_pSSI2, sizeof(CSP_SSI_REG));
m_pSSI2 = NULL;
}
// Unmap AUDMUX peripheral registers
if (m_pAUDMUX)
{
MmUnmapIoSpace(m_pAUDMUX, sizeof(CSP_AUDMUX_REG));
m_pAUDMUX = NULL;
}
if (hStDAC != NULL)
{
PmicAudioClose(hStDAC);
hStDAC = NULL;
}
#ifdef AUDIO_RECORDING_ENABLED
if (hVoiceCODEC != NULL)
{
PmicAudioClose(hVoiceCODEC);
hVoiceCODEC = NULL;
}
#endif
DEBUGMSG(ZONE_FUNCTION, (_T("-HardwareContext::BSPAudioDeinit\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: BSPAudioAllocDMABuffers
//
// Allocate the audio DMA buffers.
//
// Parameters:
// pAddress - returns physical address of allocated DMA buffers
//
// Returns:
// PBYTE virtual address of allocated memory region (NULL if error)
//
//-----------------------------------------------------------------------------
PBYTE HardwareContext::BSPAudioAllocDMABuffers(PHYSICAL_ADDRESS *pAddress)
{
#ifdef BSP_AUDIO_DMA_BUF_ADDR
PBYTE pBuf;
// Use a statically defined memory region for the audio DMA buffers. This
// may be either internal or external memory depending upon the address
// region that is selected.
pAddress->HighPart = 0;
pAddress->LowPart = BSP_AUDIO_DMA_BUF_ADDR;
pBuf = (PBYTE)MmMapIoSpace(*pAddress, BSP_AUDIO_DMA_BUF_SIZE, FALSE);
// If virtual mapping succeeded and buffer is being allocated from IRAM
if ((pBuf) && (pAddress->LowPart >= IMAGE_SHARE_IRAM_PA_START) &&
(pAddress->LowPart < (IMAGE_SHARE_IRAM_PA_START+IMAGE_SHARE_IRAM_SIZE)))
{
// Hardware constraints require IRAM to be accessed with PAHB or
// we can incur errors on subsequent accesses to DRAM. Update
// the MMU attributes to use backwards-compatible extended
// small page format. This format allows us to set the TEX bits
// to mark the IRAM region for non-shared device (directs
// access to PAHB)
//
// Extended Small Page Format
// --------------------------
// BITS[31:12] = ADDRESS (preserved)
// BITS[11:9] = SBZ (write as zero)
// BITS[8:6] = TEX (010b used for non-shared device)
// BITS[5:4] = AP (preserved)
// BITS[3:2] = CB (00b used for non-shared device)
// BITS[1:0] = must be 11b for extended small page
//
// VAL = (0x0 << 9) | (0x2 << 6) | (0x0 << 2) | (0x3 << 0) = 0x083
// MASK = (0x7 << 9) | (0x7 << 6) | (0x3 << 2) | (0x3 << 0) = 0xFCF
if (!VirtualSetAttributes(pBuf, BSP_AUDIO_DMA_BUF_SIZE,
0x083, 0xFCF, NULL))
{
ERRORMSG(1, (_T("VirtualSetAttributes failed!\r\n")));
goto cleanUp;
}
// Flush the TLB since we directly updated the page tables
CacheRangeFlush(0, 0, CACHE_SYNC_FLUSH_TLB);
}
cleanUp:
return pBuf;
#else // #ifdef BSP_AUDIO_DMA_BUF_ADDR
// Use dynamically allocated memory for the audio DMA buffers.
#ifdef AUDIO_RECORDING_ENABLED
// Allocate 2 DMA buffers each for audio playback and recording.
static const DMA_BUFFER_REGION_SIZE_NBYTES = AUDIO_DMA_PAGE_SIZE * 4;
#else
// Only allocate 2 DMA buffers for audio playback.
static const DMA_BUFFER_REGION_SIZE_NBYTES = AUDIO_DMA_PAGE_SIZE * 2;
#endif
DMA_ADAPTER_OBJECT Adapter;
memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
Adapter.InterfaceType = Internal;
Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
// Allocate DMA buffers from external memory.
return (PBYTE)HalAllocateCommonBuffer(&Adapter,
DMA_BUFFER_REGION_SIZE_NBYTES,
pAddress,
FALSE);
#endif // #ifdef BSP_AUDIO_DMA_BUF_ADDR
}
//-----------------------------------------------------------------------------
//
// Function: BSPAudioDeallocDMABuffers
//
// Deallocate the audio DMA buffers that were previously allocated by calling
// BSPAudioAllocDMABuffers().
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioDeallocDMABuffers(PVOID virtualAddress)
{
#ifndef BSP_AUDIO_DMA_BUF_ADDR
// Only deallocate the audio DMA buffer memory if it was previously
// dynamically allocated.
PHYSICAL_ADDRESS phyAddr;
// Logical address parameter is ignored
phyAddr.QuadPart = 0;
HalFreeCommonBuffer(NULL, 0, phyAddr, virtualAddress, FALSE);
#endif // #ifndef BSP_AUDIO_DMA_BUF_ADDR
}
//-----------------------------------------------------------------------------
//
// Function: BSPAudioPowerUp
//
// This function powers up the SSI, AUDMUX, and external audio chip.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioPowerUp(const BOOL fullPowerUp)
{
if (!fullPowerUp)
{
PmicAudioPowerUp();
}
else
{
BSPAudioSetCodecPower(AUDIO_PWR_STATE_STANDBY);
}
}
//-----------------------------------------------------------------------------
//
// Function: BSPAudioPowerDown
//
// This function powers down the SSI, AUDMUX, and external audio chip.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void HardwareContext::BSPAudioPowerDown(const BOOL fullPowerOff)
{
if (!fullPowerOff)
{
PmicAudioPowerDown();
}
else
{
BSPAudioSetCodecPower(AUDIO_PWR_STATE_OFF);
}
}
//-----------------------------------------------------------------------------
//
// Function: BSPAudioGetStDACSSI
//
// Returns the SSI that is currently connected to the PMIC Stereo DAC.
//
// Parameters:
// None.
//
// Returns:
// The SSI that is connected to the PMIC Stereo DAC.
//
//-----------------------------------------------------------------------------
PCSP_SSI_REG HardwareContext::BSPAudioGetStDACSSI()
{
return STEREO_DAC_SSI;
}
#ifdef AUDIO_RECORDING_ENABLED
//-----------------------------------------------------------------------------
//
// Function: BSPAudioGetVCodecSSI
//
// Returns the SSI that is currently connected to the PMIC Voice CODEC.
//
// Parameters:
// None.
//
// Returns:
// The SSI that is connected to the PMIC Voice CODEC.
//
//-----------------------------------------------------------------------------
PCSP_SSI_REG HardwareContext::BSPAudioGetVCodecSSI()
{
return VOICE_CODEC_SSI;
}
#endif // #ifdef AUDIO_RECORDING_ENABLED
//-----------------------------------------------------------------------------
//
// Function: BSPAudioInitOutput
//
// This function initializes the DMA, SSI, and AUDMUX to support audio
// output.
//
// Parameters:
// The SSI configuration to be used.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
BOOL HardwareContext::BSPAudioInitOutput(AUDIO_BUS bus)
{
BOOL rc = FALSE;
switch (bus)
{
case AUDIO_BUS_STEREO_OUT:
// Configure the SSI to function as the audio output channel.
BSPAudioInitSsi(bus, STEREO_DAC_SSI);
// Configure the PMIC Stereo DAC.
BSPAudioInitCodec(bus);
// Configure the AUDMUX to route the SSI to the PMIC Stereo DAC.
//
// We need to do this last (and only after both the SSI and PMIC
// has been properly configured) to avoid any possible signal
// conflicts due to any previous SSI and/or PMIC configuration
// settings.
BSPAudioRoute((STEREO_DAC_SSI == m_pSSI1) ? SSI1_AUDMUX_PORT :
SSI2_AUDMUX_PORT,
STEREO_DAC_AUDMUX_PORT,
(STEREO_DAC_SSI == m_pSSI1) ? BSP_SSI1_MASTER_BOOL :
BSP_SSI2_MASTER_BOOL);
// Configure the output DMA watermark level. This value defines
// the number of empty slots in the SSI transmit FIFO before a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -