📄 wmxscaledmatest.c
字号:
WM_WAVEGEN_CTX wavegenCtxRight = WM_START_OF_WAVE;
const WM_TEST_SOUND *pTestSound = WMTestAudio_GetSound();
#if VERIFY_DMA_TIMING
unsigned int timestampArray[TEST_BUFFER_TIMESTAMPS] = {0};
#endif
WM_XSCALE_DEVICE_CONTEXT *pDeviceContext =
(WM_XSCALE_DEVICE_CONTEXT *) hDevice;
VOLATILE_DMAC_T *v_pDmaReg =
pDeviceContext->v_pDmaReg;
VOLATILE_AC97_T *v_pAC97Regs =
pDeviceContext->v_pAC97Regs;
/*
* The following values are put into variables so they can be
* altered in a debugger.
*/
int loopForever = CONTINUAL_MONO;
WM_SAMPLE_RATE sampleRate = TEST_SAMPLE_RATE_MONO;
unsigned short frequency = pTestSound->frequency;
unsigned short amplitude = pTestSound->amplitude;
unsigned int duration = pTestSound->duration;
if ( !WM_HAS_MONO_DAC( hDevice ) )
{
WMTEST_SKIP();
}
/*
* Setup the DMA so that it is ready to run.
*/
WMTEST_BOOLEAN( private_MapDMAMemory( hDevice ) );
private_FillDescriptors( hDevice, channel );
/*
* Work out the number of repeats to get our duration.
* One buffer contains WMAUDIO_MAX_BUFFER_SIZE bytes.
*/
samplesPerBuffer = WMAUDIO_MAX_BUFFER_SIZE/sizeof(WM_AUDIO_STEREO_SAMPLE);
repeats = WM_TEST_REPEATS( duration,
sampleRate,
samplesPerBuffer
);
#if VERIFY_DMA_TIMING
WM_ASSERT( hDevice, repeats <= TEST_BUFFER_TIMESTAMPS );
#endif
/*
* Power up, enable and unmute the Mono output path.
*/
WMTEST_CALL( WMAudioPowerUp( hDevice,WM_POWER_AUDIO_PLAYBACK ) );
WMTEST_CALL( WMAudioEnableOutputPaths( hDevice, WM_STREAM_MONO_OUT, TRUE ) );
WMTEST_CALL( WMAudioMuteAllOutputs( hDevice, FALSE ) );
/*
* Set the sample rate for the Mono.
*/
WMTEST_CALL( WMAudioSetSampleRate( hDevice,
WM_STREAM_MONO_OUT,
sampleRate
)
);
/* Make sure our buffers are cleared */
private_ClearDMABuffers();
/* Fill the first buffer and set up our "next" pointer */
WMGenerateSineWave( v_pDMABufXmitA_Virtual,
samplesPerBuffer,
sampleRate,
frequency,
amplitude,
WM_WAVEGEN_LEFT,
&wavegenCtxLeft
);
WMGenerateSineWave( v_pDMABufXmitA_Virtual,
samplesPerBuffer,
sampleRate,
frequency * 2,
amplitude,
WM_WAVEGEN_RIGHT,
&wavegenCtxRight
);
pNextBuffer = v_pDMABufXmitB_Virtual;
/* Initialise the DMA */
private_InitDMA( hDevice, channel, channelId );
/*
* Clear any interrupts, and any output FIFO errors.
*/
v_pDmaReg->DCSR[channel] |= DCSR_DMA_INT_MASK;
v_pAC97Regs->MOSR = 0x10;
/*
* Work out how long it should take:
* 4 bytes per (stereo) sample = WMAUDIO_MAX_BUFFER_SIZE/4 samples per buffer.
* repeats buffers.
* sampleRate samples per second =>
* 1000/sampleRate milliseconds per sample
*/
expectedDuration = ( samplesPerBuffer * repeats * 1000 ) /
sampleRate;
/*
* Start the DMA on the channel.
*/
v_pDmaReg->DCSR[channel] |= DCSR_RUN; /* set the RUN bit */
do
{
/* Get our start time for this loop */
startTime = GetMillisecondTimestamp( hDevice );
/* Send the buffer the requested number of times */
for ( repeat = 0; repeat < repeats; repeat++ )
{
/* Get the start time for this buffer */
bufferStartTime = GetMillisecondTimestamp( hDevice );
/* Fill the next buffer */
WMGenerateSineWave( pNextBuffer,
samplesPerBuffer,
sampleRate,
frequency,
amplitude,
WM_WAVEGEN_LEFT,
&wavegenCtxLeft
);
WMGenerateSineWave( pNextBuffer,
samplesPerBuffer,
sampleRate,
frequency * 2,
amplitude,
WM_WAVEGEN_RIGHT,
&wavegenCtxRight
);
if ( v_pDMABufXmitA_Virtual == pNextBuffer )
pNextBuffer = v_pDMABufXmitB_Virtual;
else
pNextBuffer = v_pDMABufXmitA_Virtual;
/*
* Wait for the current buffer to finish.
*/
status = private_WaitForBuffer( hDevice, channel );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, ( "Timed out waiting for DMA to finish - skipping test" ) );
WMTEST_SKIP();
}
#if VERIFY_DMA_TIMING
/* Remember how long this buffer took */
timestampArray[repeat] = GetMillisecondTimestamp( hDevice ) - bufferStartTime;
#endif
/*
* Check the DMA status is correct - end interrupt and no errors.
*/
WMTEST_BOOLEAN( DCSR_ENDINTR == ( v_pDmaReg->DCSR[channel] & DCSR_DMA_INT_MASK ) );
WMTEST_BOOLEAN( v_pDmaReg->DINT & ( 1U << channel ) );
/*
* Clear the DMA interrupts
*/
v_pDmaReg->DCSR[channel] |= DCSR_DMA_INT_MASK;
}
/* Now work out how long it all took */
endTime = GetMillisecondTimestamp( hDevice );
duration = endTime - startTime;
WMTEST_TRACE(( "%d buffers of %d samples took %d ms (expected %dms)\n",
repeats,
samplesPerBuffer,
duration,
expectedDuration
));
#if VERIFY_DMA_TIMING
/* Make sure it's reasonably close to what we expect */
WMTEST_GREATER( duration, expectedDuration - TEST_MILLISECOND_SLOP );
WMTEST_LESS( duration, expectedDuration + TEST_MILLISECOND_SLOP );
#endif /* VERIFY_DMA_TIMING */
}
while ( loopForever );
/*
* Mute, disable and power down the Mono output path.
*/
WMTEST_CALL( WMAudioMuteAllOutputs( hDevice, TRUE ) );
WMTEST_CALL( WMAudioEnableOutputPaths( hDevice, WM_STREAM_MONO_OUT, FALSE ) );
WMTEST_CALL( WMAudioPowerDown( hDevice,WM_POWER_AUDIO_PLAYBACK ) );
/*
* Clean up the DMA now that the test is finished.
*/
private_CleanupDMA( hDevice, channel, channelId );
#else /* WM_MONODAC */
WMTEST_SKIP();
#endif /* WM_MONODAC */
}
WMTEST_END
/*-----------------------------------------------------------------------------
* Function: WMTestVoiceDACDMADirect
*
* Plays a sound directly to the Voice DAC, using direct control of the
* DMA buffers.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
*
* Returns: WM_BOOL
* TRUE if it passed, FALSE if it failed in a way it could detect.
*---------------------------------------------------------------------------*/
WMTEST_START( WMTestVoiceDACDMADirect( WM_DEVICE_HANDLE hDevice ) )
{
#if WM_VOICE
WMSTATUS status;
unsigned int repeat;
unsigned int repeats;
unsigned int samplesPerBuffer;
unsigned int startTime, endTime, bufferStartTime;
unsigned int expectedDuration;
WM_AUDIO_STEREO_SAMPLE *pNextBuffer;
int channel = WMDMA_VOICE_OUT;
int channelId = DMA_CHAN_VOICE_OUT;
WM_WAVEGEN_CTX wavegenCtxMono = WM_START_OF_WAVE;
const WM_TEST_SOUND *pTestSound = WMTestAudio_GetSound();
#if VERIFY_DMA_TIMING
unsigned int timestampArray[TEST_BUFFER_TIMESTAMPS] = {0};
#endif
WM_XSCALE_DEVICE_CONTEXT *pDeviceContext =
(WM_XSCALE_DEVICE_CONTEXT *) hDevice;
VOLATILE_DMAC_T *v_pDmaReg =
pDeviceContext->v_pDmaReg;
VOLATILE_SSP_T *v_pSSP2Regs =
pDeviceContext->v_pSSP2Regs;
/*
* The following values are put into variables so they can be
* altered in a debugger.
*/
int loopForever = CONTINUAL_VOICE;
WM_SAMPLE_RATE sampleRate = TEST_SAMPLE_RATE_VOICE;
unsigned short frequency = pTestSound->frequency;
unsigned short amplitude = pTestSound->amplitude;
unsigned int duration = pTestSound->duration;
if ( !WM_HAS_VOICE_DAC( hDevice ) )
{
WMTEST_SKIP();
}
/*
* Setup the DMA so that it is ready to run.
*/
WMTEST_BOOLEAN( private_MapDMAMemory( hDevice ) );
private_FillDescriptors( hDevice, channel );
/*
* Power up, enable and unmute the Voice output path.
*/
WMTEST_CALL( WMAudioPowerUp( hDevice,WM_POWER_AUDIO_PLAYBACK ) );
WMTEST_CALL( WMAudioEnableOutputPaths( hDevice, WM_STREAM_VOICE_OUT, TRUE ) );
WMTEST_CALL( WMAudioMuteAllOutputs( hDevice, FALSE ) );
/*
* Set the sample rate for the VoiceDAC.
*/
WMTEST_CALL( WMAudioSetSampleRate( hDevice,
WM_STREAM_VOICE_OUT,
sampleRate
)
);
/* Make sure our buffers are cleared */
private_ClearDMABuffers();
/*
* Work out the number of repeats to get our duration.
* One buffer contains WMAUDIO_MAX_BUFFER_SIZE bytes.
*/
samplesPerBuffer = WMAUDIO_MAX_BUFFER_SIZE/sizeof(WM_AUDIO_STEREO_SAMPLE);
repeats = WM_TEST_REPEATS( duration,
sampleRate,
samplesPerBuffer
);
#if VERIFY_DMA_TIMING
WM_ASSERT( hDevice, repeats <= TEST_BUFFER_TIMESTAMPS );
#endif
/* Fill the first buffer */
WMGenerateSineWave( v_pDMABufXmitA_Virtual,
samplesPerBuffer,
sampleRate,
frequency,
amplitude,
WM_WAVEGEN_MONO,
&wavegenCtxMono
);
pNextBuffer = v_pDMABufXmitB_Virtual;
/* Initialise the DMA */
private_InitDMA( hDevice, channel, channelId );
/*
* Work out how long it should take:
* 2 bytes per (mono) sample = WMAUDIO_MAX_BUFFER_SIZE/2 samples per buffer.
* TEST_BUFFER_REPEATS buffers.
* sampleRate samples per second =>
* 1000/sampleRate milliseconds per sample
*/
expectedDuration = ( samplesPerBuffer * repeats * 1000 ) /
sampleRate;
/*
* Enable the Voice DAC Interface.
*/
WMTEST_CALL( WMAudioEnableStream( hDevice, WM_STREAM_VOICE_OUT ) );
/*
* Clear any interrupts, and any output FIFO errors.
*/
v_pDmaReg->DCSR[channel] |= DCSR_DMA_INT_MASK;
v_pSSP2Regs->ssr = XLLP_SSSP_TUR;
/* And set it going */
WMVoiceStart( hDevice );
v_pDmaReg->DCSR[channel] |= DCSR_RUN; /* set the RUN bit */
do
{
/* Get our start time for this loop */
startTime = GetMillisecondTimestamp( hDevice );
/* Send the buffer the requested number of times */
for ( repeat = 0; repeat < repeats; repeat++ )
{
/* Get the start time for this buffer */
bufferStartTime = GetMillisecondTimestamp( hDevice );
/* Fill the next buffer */
WMGenerateSineWave( pNextBuffer,
samplesPerBuffer,
sampleRate,
frequency,
amplitude,
WM_WAVEGEN_MONO,
&wavegenCtxMono
);
if ( v_pDMABufXmitA_Virtual == pNextBuffer )
pNextBuffer = v_pDMABufXmitB_Virtual;
else
pNextBuffer = v_pDMABufXmitA_Virtual;
/*
* Wait for the current buffer to finish.
*/
status = private_WaitForBuffer( hDevice, channel );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, ( "Timed out waiting for DMA to finish - skipping test" ) );
WMTEST_SKIP();
}
#if VERIFY_DMA_TIMING
/* Remember how long this buffer took */
timestampArray[repeat] = GetMillisecondTimestamp( hDevice ) - bufferStartTime;
#endif
/*
* Check the DMA status is correct - end interrupt and no errors.
*/
WMTEST_BOOLEAN( DCSR_ENDINTR == ( v_pDmaReg->DCSR[channel] & DCSR_DMA_INT_MASK ) );
WMTEST_BOOLEAN( v_pDmaReg->DINT & ( 1U << channel ) );
/*
* Clear the DMA interrupts
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -