📄 hwctxt.cpp
字号:
}
}
for(i=0; i<(sizeof(WM8580_Codec_Init_Table)/2); i++)
{
WriteCodecRegister(WM8580_Codec_Init_Table[i][0], WM8580_Codec_Init_Table[i][1]);
}
Codec_channel(); // ADC/DAC power down // Jin, 071221
RETAILMSG(DBG_ON, (TEXT("-IIS InitCodec\r\n")));
#endif
return(TRUE);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: InitOutputDMA()
Description: Initializes the DMA channel for output.
Notes: DMA Channel 2 is used for transmitting output sound
data from system memory to the I2S controller.
Returns: Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::InitOutputDMA()
{
RETAILMSG(DBG_AUDIO,(TEXT("+++InitOutputDMA\n")));
//----- 1. Initialize the DMA channel for output mode and use the first output DMA buffer -----
g_pDMAregs->DISRC2 = (int)(g_PhysDMABufferAddr.LowPart);
g_pDMAregs->DISRCC2 &= ~(SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); // Source is system bus, increment addr
//----- 2. Initialize the DMA channel to send data over the I2S bus -----
g_pDMAregs->DIDST2 = IISFIFTX_PHYS;
g_pDMAregs->DIDSTC2 = (DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); // Dest is periperal bus, fixed addr
//----- 3. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
// single tx, single service, I2SSDO, I2S request, no auto-reload, half-word, tx count
g_pDMAregs->DCON2 = ( HANDSHAKE_MODE | GENERATE_INTERRUPT
#if DMA_FLAG
// | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2 ) );
| TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4 ) );
#else
| NO_DMA_AUTO_RELOAD | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2) );
// | NO_DMA_AUTO_RELOAD | TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4 ) );
#endif
g_pDMAregs->DMAREQSEL2 = (DMAREQSEL_I2SSDO) |(1<<0); // HW_SEL
//----- 4. Reset the playback pointers -----
AUDIO_RESET_PLAYBACK_POINTER();
RETAILMSG(DBG_AUDIO,(TEXT("---InitOutputDMA\n")));
return TRUE;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: StartOutputDMA()
Description: Starts outputting the sound data to the audio codec
chip via DMA.
Notes: Currently, both playback and record share the same
DMA channel. Consequently, we can only start this
operation if the input channel isn't using DMA.
Returns: Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::StartOutputDMA()
{
volatile int i=0;
static int tmp=0;
g_ForCount=1;
RETAILMSG(DBG_ON, (TEXT("StartOutputDMA\n")));
//RETAILMSG(1, (TEXT("#####Start OUTPUT DMA.\r\n")));
#if (BSP_TYPE == BSP_SMDK2443)
if(!m_OutputDMARunning)
#elif (BSP_TYPE == BSP_SMDK2450)
if(!m_OutputDMARunning && (m_Dx == D0) )
#endif
{
//RETAILMSG(1, (TEXT("### it's the first time\r\n")));
//----- 1. Initialize our buffer counters -----
m_OutputDMARunning=TRUE;
Codec_channel();
//--------------------------- for short length audio file hsjang 060518 ------------------------------
if (g_NeedtoSleep)
{
Sleep(15);
}
// -------------------------------------------------------------------------------------------
m_OutBytes[OUT_BUFFER_A]=m_OutBytes[OUT_BUFFER_B]=0;
//----- 2. Prime the output buffer with sound data -----
m_OutputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;
ULONG OutputTransferred = TransferOutputBuffers(m_OutputDMAStatus);
RETAILMSG(DBG_ON,(TEXT("OutputTransferred=%d\n"), OutputTransferred));
// Turn ON output channel
//----- 3. If we did transfer any data to the DMA buffers, go ahead and enable DMA -----
if(OutputTransferred)
{
//RETAILMSG(1, (TEXT("### it's the first time ########\r\n")));
//----- 4. Configure the DMA channel for playback -----
if(!InitOutputDMA())
{
RETAILMSG(DBG_AUDIO, (TEXT("HardwareContext::StartOutputDMA() - Unable to initialize output DMA channel!\r\n")));
goto START_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
// To correct left/right channel on ouput stream,
// You should reset IISCON[0] bit.
Lock();
/*
g_pIISregs->IISCON &= ~IIS_INTERFACE_ENABLE; // interface disable
g_pIISregs->IISCON |= TRANSMIT_DMA_REQUEST_ENABLE;
g_pIISregs->IISCON &= ~TRANSMIT_IDLE_CMD; // Not Idle.(channel no stop)
*/
//g_pIISregs->IISMOD &= ~(1<<9|1<<8); //IIS_TRANSMIT_MODE; // Transmit only mode
//----- 5. Make sure the audio isn't muted -----
AudioMute(DMA_CH_OUT, FALSE);
//----- 6. Start the DMA controller -----
AUDIO_RESET_PLAYBACK_POINTER();
SELECT_AUDIO_DMA_OUTPUT_BUFFER_A();
//Codec_channel(); // Turn ON output channel
//RETAILMSG(1,(TEXT("+")));
//RETAILMSG(1,(TEXT("-")));
AUDIO_OUT_DMA_ENABLE();
// wait for DMA to start.
delay_count = 0;
while((g_pDMAregs->DSTAT2&0xfffff)==0) // wait until DSTAT2 becomes zero
{
if( delay_count++ > DELAY_COUNT ) break; // if delay count is over DELAY_COUNT defined for TIMEOUT
}
if(delay_count>DELAY_COUNT) RETAILMSG(1, (TEXT("TimeOut!!!\n")));
//g_pIISregs->IISCON |= IIS_INTERFACE_ENABLE;
Unlock();
////////////////////////////////////////////////////////////////////////////////
// change the buffer pointer
SELECT_AUDIO_DMA_OUTPUT_BUFFER_B();
// Set DMA for B Buffer
}
else // We didn't transfer any data, so DMA wasn't enabled
{
RETAILMSG(DBG_AUDIO,(TEXT("<<<<m_OutputDMARunning=FALSE; >>>>>\n")));
m_OutputDMARunning=FALSE;
}
}
RETAILMSG(DBG_AUDIO,(TEXT("---StartOutputDMA\n")));
return TRUE;
START_ERROR:
return FALSE;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: StopOutputDMA()
Description: Stops any DMA activity on the output channel.
Returns: Boolean indicating success
-------------------------------------------------------------------*/
void HardwareContext::StopOutputDMA()
{
//RETAILMSG(DBG_ON, (TEXT("+StopOutputDMA\r\n")));
//----- 1. If the output DMA is running, stop it -----
if (m_OutputDMARunning)
{
m_OutputDMAStatus = DMA_CLEAR;
//StopI2SClock();
AUDIO_OUT_DMA_DISABLE();
AUDIO_OUT_CLEAR_INTERRUPTS();
/*
g_pIISregs->IISCON &= ~TRANSMIT_DMA_REQUEST_ENABLE; // Disable TX DMA
g_pIISregs->IISCON |= TRANSMIT_IDLE_CMD; // TXCHPAUSE
*/
//g_pIISregs->IISMOD &= ~IIS_TRANSMIT_MODE; // reserved
#if (BSP_TYPE == BSP_SMDK2443)
AudioMute(DMA_CH_OUT, TRUE);
#elif (BSP_TYPE == BSP_SMDK2450)
#endif
}
m_OutputDMARunning = FALSE;
#if (BSP_TYPE == BSP_SMDK2443)
#elif (BSP_TYPE == BSP_SMDK2450)
AudioMute(DMA_CH_OUT, TRUE);
#endif
Codec_channel();
g_ForCount=1;
//RETAILMSG(DBG_ON, (TEXT("-StopOutputDMA\r\n")));
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: InitInputDMA()
Description: Initializes the DMA channel for input.
Notes: ***** NOT IMPLEMENTED *****
The following routine is not implemented due to a
hardware bug in the revision of the Samsung SC2450
CPU this driver was developed on. See the header
at the top of this file for details.
Returns: Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::InitInputDMA()
{
RETAILMSG(DBG_AUDIO,(TEXT("+++InitInputDMA\r\n")));
//============================ Configure DMA Channel 1 ===========================
//------ On platforms with the revision of the Samsung SC2450 CPU with the IIS SLAVE bug fix, this -----
// code can be used to configure DMA channel 1 for input.
//----- 1. Initialize the DMA channel for input mode and use the first input DMA buffer -----
//g_pDMAregs->DISRC1 = (unsigned int)IISFIFRX_PHYS; // DonGo modified.
g_pDMAregs->DISRC1 = (unsigned int)0x55000014; // DonGo modified.
g_pDMAregs->DISRCC1 = (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); // Source is periperal bus, fixed addr
//----- 2. Initialize the DMA channel to receive data over the I2S bus -----
g_pDMAregs->DIDST1 = (int)(g_PhysDMABufferAddr.LowPart);
g_pDMAregs->DIDSTC1 &= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); // Destination is system bus, increment addr
//----- 3. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
// single tx, single service, I2SSDI, I2S request, no auto-reload, half-word, tx count
g_pDMAregs->DCON1 = ( HANDSHAKE_MODE | GENERATE_INTERRUPT
#if DMA_FLAG
// | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2) );
| TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4) );
#else
| NO_DMA_AUTO_RELOAD | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2) );
// | NO_DMA_AUTO_RELOAD | TRANSFER_WORD | (AUDIO_DMA_PAGE_SIZE / 4) );
#endif
g_pDMAregs->DMAREQSEL1 = (DMAREQSEL_I2SSDI) |(1) ;
RETAILMSG(DBG_AUDIO,(TEXT("---InitInputDMA\r\n")));
return(TRUE);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: StartInputDMA()
Description: Starts inputting the recorded sound data from the
audio codec chip via DMA.
Notes: ***** NOT IMPLEMENTED *****
The following routine is not implemented due to a
hardware bug in the revision of the Samsung SC2450
CPU this driver was developed on. See the header
at the top of this file for details.
Returns: Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::StartInputDMA()
{
//------ On platforms with the revsion of the Samsung SC2450 CPU with the IIS SLAVE bug fix, this -----
// code can be used to configure DMA channel 1 for input.
//RETAILMSG(1,(TEXT("+++StartInputDMA\n")));
if(!m_InputDMARunning)
{
//RETAILMSG(1,(TEXT("+++InputDMArunning first\r\n")));
//----- 1. Initialize our buffer counters -----
m_InputDMARunning=TRUE;
Codec_channel(); // Turn On Input channel
m_InBytes[IN_BUFFER_A]=m_InBytes[IN_BUFFER_B]=0;
//----- 2. Prime the output buffer with sound data -----
m_InputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;
//----- 3. Configure the DMA channel for record -----
if(!InitInputDMA())
{
RETAILMSG(1, (TEXT("HardwareContext::StartInputDMA() - Unable to initialize input DMA channel!\r\n")));
goto START_ERROR;
}
/*
g_pIISregs->IISCON &= ~(RECEIVE_DMA_PAUSE|RECEIVE_IDLE_CMD);
g_pIISregs->IISCON |= RECEIVE_DMA_REQUEST_ENABLE;
*/
//g_pIISregs->IISMOD |= (IIS_RECEIVE_MODE|MASTER_CLOCK_FREQ_384fs);
//----- 4. Make sure the audio isn't muted -----
AudioMute(DMA_CH_MIC, FALSE);
//----- 5. Start the input DMA -----
AUDIO_RESET_RECORD_POINTER();
SELECT_AUDIO_DMA_INPUT_BUFFER_A();
//Codec_channel(); // Turn On Input channel
//g_pDMAregs->DMASKTRIG1 = ENABLE_DMA_CHANNEL;
AUDIO_IN_DMA_ENABLE();
/*
#if DMA_FLAG
// wait for DMA to start.
RETAILMSG(DBG_AUDIO, (TEXT("Going into the DMA start loop")));
//while((g_pDMAregs->DSTAT1&0xfffff)!=0);
RETAILMSG(DBG_AUDIO, (TEXT("Out of the DMA start loop")));
// change the buffer pointer
SELECT_AUDIO_DMA_INPUT_BUFFER_B();
#endif
*/
}
// wait for DMA to start.
delay_count = 0;
while((g_pDMAregs->DSTAT1&0xfffff)==0)
{
if( delay_count++ > DELAY_COUNT ) break;
}
if(delay_count>DELAY_COUNT) RETAILMSG(1, (TEXT("TimeOut!!!\n")));
SELECT_AUDIO_DMA_INPUT_BUFFER_B();
//RETAILMSG(1,(TEXT("---StartInputDMA\n")));
return(TRUE);
START_ERROR:
return(FALSE);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: StopInputDMA()
Description: Stops any DMA activity on the input channel.
Notes: ***** IMPLEMENTED *****
Returns: Boolean indicating success
-------------------------------------------------------------------*/
void HardwareContext::StopInputDMA()
{
//------ On platforms with the revsion of the Samsung SC2450 CPU with the IIS SLAVE bug fix, this -----
// code can be used to configure DMA channel 1 for input.
//RETAILMSG(1,(TEXT("+++StopInputDMA\n")));
//----- 1. If the input DMA is running, stop it -----
if (m_InputDMARunning)
{
m_InputDMAStatus = DMA_CLEAR;
//StopI2SClock();
/*
g_pIISregs->IISCON &= ~RECEIVE_DMA_REQUEST_ENABLE;
g_pIISregs->IISCON |= RECEIVE_IDLE_CMD; // RXCHPAUSE
g_pDMAregs->DMASKTRIG1 |= STOP_DMA_TRANSFER;
g_pDMAregs->DMASKTRIG1 &= ~ENABLE_DMA_CHANNEL;
*/
AUDIO_IN_DMA_DISABLE();
//g_pIISregs->IISMOD |= IIS_TRANSMIT_MODE; // reserved
AUDIO_IN_CLEAR_INTERRUPTS();
#if (BSP_TYPE == BSP_SMDK2443)
AudioMute(DMA_CH_MIC, TRUE);
#elif (BSP_TYPE == BSP_SMDK2450)
#endif
}
m_InputDMARunning = FALSE;
#if (BSP_TYPE == BSP_SMDK2443)
#elif (BSP_TYPE == BSP_SMDK2450)
AudioMute(DMA_CH_MIC, TRUE);
#endif
Codec_channel();
//RETAILMSG(1,(TEXT("---StopInputDMA\n")));
}
DWORD HardwareContext::GetInterruptThreadPriority()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -