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

📄 wmxscaledmatest.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 3 页
字号:
			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 %dms (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 );

	/* 
	 * Stop, mute, disable and power down the Voice DAC Interface.
	 */
	WMVoiceStop( hDevice );

    WMTEST_CALL( WMAudioMuteAllOutputs( hDevice, TRUE ) );

    WMTEST_CALL( WMAudioEnableOutputPaths( hDevice, WM_STREAM_VOICE_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_VOICE */
	WMTEST_SKIP();	
#endif /* WM_VOICE */
}
WMTEST_END

/*-----------------------------------------------------------------------------
 * Function:    private_InitDMA
 *
 * Initialise the DMA.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      channel	    The DMA channel to stop.
 *      channelId   The DMA DRCMR channel ID.
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void private_InitDMA(  WM_DEVICE_HANDLE hDevice, int channel, int channelId )
{
    WM_XSCALE_DEVICE_CONTEXT	*pDeviceContext =
                                        (WM_XSCALE_DEVICE_CONTEXT *) hDevice;
    VOLATILE_DMAC_T				*v_pDmaReg		= pDeviceContext->v_pDmaReg;
	
    /* 
     * Disable the DMA Interrupts until we have finished.
     * NOTE: At this point the DMA IST may already be running.
     *       If it is, it will interfere with this function
     *       as we need to be able to poll the dcsr to see
     *       if any DMA interrupts have occured.
     */
    WMAudioDisableDMAInterrupts( hDevice );

    /*
     * Set up the DMA so it's ready to run on this channel.
     */
    v_pDmaReg->DDG[channel].DDADR = (unsigned int)v_pAudioXmitA_Physical;
    v_pDmaReg->DRCMR1[channelId] = DMA_MAP_VALID_MASK | channel;
}

/*-----------------------------------------------------------------------------
 * Function:    private_CleanupDMA
 *
 * Clean up the DMA descriptors and buffers.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      channel	    The DMA channel to stop.
 *      channelId   The DMA DRCMR channel ID.
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void private_CleanupDMA( WM_DEVICE_HANDLE hDevice, int channel, int channelId )
{
    WM_XSCALE_DEVICE_CONTEXT	*pDeviceContext =
									(WM_XSCALE_DEVICE_CONTEXT *) hDevice;
    VOLATILE_DMAC_T				*v_pDmaReg		= pDeviceContext->v_pDmaReg;

    /* Fill the DMA buffers with silence */
    private_ClearDMABuffers();

    /* Stop the DMA from running */
    v_pDmaReg->DCSR[channel] &=  ~DCSR_RUN;          /* clear the RUN bit */

    /* Clear the DRCMR */
    v_pDmaReg->DRCMR1[channelId] = 0;

    /* Clear the descriptors */
    private_ClearDescriptors();

    /* Free the virtual memory */
    private_ReleaseDMAMemory();

    /*
     * Enable the DMA Interrupts now we have finished.
     */
    WMAudioEnableDMAInterrupts( hDevice );
}

/*-----------------------------------------------------------------------------
 * Function:    private_MapDMAMemory
 *
 * Maps the DMA descriptors and buffers in to virtual memory.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *
 * Returns:     TRUE on success, FALSE on error
 *---------------------------------------------------------------------------*/
WM_BOOL private_MapDMAMemory( WM_DEVICE_HANDLE hDevice )
{
    /* Don't map in twice */
    if ( s_Initialised )
    {
        goto done;
    }

    /*
     * The DMA descriptors
     */
    v_pAudioXmitA_Virtual = ALLOC_OR_MAP_BUFFER( hDevice,
                                                 volatile XLLP_DMAC_DESCRIPTOR_T,
                                                 WMDMA_DESCRIPTOR_BASE_PHYSICAL,
                                                 WMAUDIO_DMA_DESC_SIZE * WMDMA_DESCRIPTORS_PER_CHANNEL, 
                                                 &v_pAudioXmitA_Physical,
                                                 "private_MapDMAMemory: ALLOC_OR_MAP_BUFFER failed to allocate DMA descriptors"
                                               );
    if ( !v_pAudioXmitA_Virtual )
    {
        v_pAudioXmitA_Physical = NULL;
        WM_TRACE( hDevice, ( "private_MapDMAMemory: ALLOC_OR_MAP_BUFFER failed to allocate DMA descriptors" ) );
        goto error;
    }

    v_pAudioXmitB_Virtual  = (volatile XLLP_DMAC_DESCRIPTOR_T *)((unsigned long)v_pAudioXmitA_Virtual  + WMAUDIO_DMA_DESC_SIZE);
    v_pAudioXmitB_Physical = (volatile XLLP_DMAC_DESCRIPTOR_T *)((unsigned long)v_pAudioXmitA_Physical + WMAUDIO_DMA_DESC_SIZE);
    
    /*
     * The DMA buffers
     */
    v_pDMABufXmitA_Virtual = ALLOC_OR_MAP_BUFFER( hDevice,
                                                  WM_AUDIO_STEREO_SAMPLE,
                                                  WMDMA_BUFFER_BASE_PHYSICAL,
                                                  WMAUDIO_MAX_BUFFER_SIZE * WMDMA_BUFFERS_PER_CHANNEL, 
                                                  &v_pDMABufXmitA_Physical,
                                                  "private_MapDMAMemory: ALLOC_OR_MAP_BUFFER failed to allocate DMA buffers"
                                               );
    if ( !v_pDMABufXmitA_Virtual )
    {
        v_pDMABufXmitA_Physical = NULL;
        WM_TRACE( hDevice, ( "private_MapDMAMemory: ALLOC_OR_MAP_BUFFER failed to allocate DMA buffers" ) );
        goto error;
    }

    v_pDMABufXmitB_Virtual  = (WM_AUDIO_STEREO_SAMPLE *)((unsigned long)v_pDMABufXmitA_Virtual  + WMAUDIO_MAX_BUFFER_SIZE);
    v_pDMABufXmitB_Physical = (WM_AUDIO_STEREO_SAMPLE *)((unsigned long)v_pDMABufXmitA_Physical  + WMAUDIO_MAX_BUFFER_SIZE);

    /*
     * All well and good.
     */
done:
    s_Initialised = TRUE;
    return TRUE;
    
    /*
     * Clean up on error
     */
error:
	private_ReleaseDMAMemory();
    return FALSE;
}
 
/*-----------------------------------------------------------------------------
 * Function:    private_ReleaseDMAMemory
 *
 * Releases the virtual memory used by the DMA descriptors and buffers.
 *
 * Parameters:
 *      none
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void private_ReleaseDMAMemory()
{
	if ( v_pAudioXmitA_Virtual )
	{
	    FREE_BUFFER_MEMORY( v_pAudioXmitA_Virtual,
    					    v_pAudioXmitA_Physical,
    					    WMAUDIO_DMA_DESC_SIZE * WMDMA_DESCRIPTORS_PER_CHANNEL
    				      );
		v_pAudioXmitA_Virtual  = NULL;
		v_pAudioXmitA_Physical = NULL;
		v_pAudioXmitB_Virtual  = NULL;
		v_pAudioXmitB_Physical = NULL;
	}

	if ( v_pDMABufXmitA_Virtual )
	{
		FREE_BUFFER_MEMORY( v_pDMABufXmitA_Virtual,
							v_pDMABufXmitA_Physical,
							WMAUDIO_MAX_BUFFER_SIZE * WMDMA_BUFFERS_PER_CHANNEL
						  );
		v_pDMABufXmitA_Virtual  = NULL;
		v_pDMABufXmitA_Physical	= NULL;
		v_pDMABufXmitB_Virtual  = NULL;
		v_pDMABufXmitB_Physical	= NULL;
	}

    s_Initialised = FALSE;
}
 
/*-----------------------------------------------------------------------------
 * Function:    private_ClearDescriptors
 *
 * Clears the DMA descriptors.
 *
 * Parameters:
 *      none
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void private_ClearDescriptors( void )
{
    union DmaCmdReg CmdBuff = {0};

    /*
     * Clear XmitA Descriptor
     */
    v_pAudioXmitA_Virtual->DDADR = (DMAC_DESC_FIELD_T)NULL;	/* address of the next (XmitB) descriptor */
    v_pAudioXmitA_Virtual->DTADR = (DMAC_DESC_FIELD_T)NULL;	/* source address of the AC97 XmitA buffer */
    v_pAudioXmitA_Virtual->DSADR = (DMAC_DESC_FIELD_T)NULL;	/* destination address of the XmitA buffer */
    v_pAudioXmitA_Virtual->DCMD  = CmdBuff.DcmdDword;		/* size and cmd values of the XmitA buffer */

    /*
     * Clear XmitB Descriptor
     */
    v_pAudioXmitB_Virtual->DDADR = (DMAC_DESC_FIELD_T)NULL;	/* address of the next (XmitA) descriptor */
    v_pAudioXmitB_Virtual->DTADR = (DMAC_DESC_FIELD_T)NULL;	/* source address of the AC97 XmitB buffer */
    v_pAudioXmitB_Virtual->DSADR = (DMAC_DESC_FIELD_T)NULL;	/* destination address of the XmitB buffer */
    v_pAudioXmitB_Virtual->DCMD  = CmdBuff.DcmdDword;		/* size and cmd values of the XmitB buffer */

}

/*-----------------------------------------------------------------------------
 * Function:    private_ClearDMABuffers
 *
 * Fill the DMA buffers with silence.
 *
 * Parameters:
 *      none
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void private_ClearDMABuffers( void )
{
    /* 
     * Set the the whole of the DMA buffers to zero.
     */ 
	memset( v_pDMABufXmitA_Virtual, 0, WMAUDIO_MAX_BUFFER_SIZE );
	memset( v_pDMABufXmitB_Virtual, 0, WMAUDIO_MAX_BUFFER_SIZE );
}

/*-----------------------------------------------------------------------------
 * Function:    private_FillDescriptors
 *
 * Sets up the DMA descriptors.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      channel     the channel to set the descriptors up for.
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void private_FillDescriptors( WM_DEVICE_HANDLE hDevice, int channel )
{
    union DmaCmdReg CmdBuff = {0};
    unsigned long channelAddr;
    
    switch ( channel )
    {
        case WMDMA_STEREO_OUT:
#	if WM_AC97
            if ( WM_IS_AC97( hDevice ) )
            {
                channelAddr = DMAC_AC97_AUDIO_XMIT_FIFO;
            }
#	endif
#	if WM_I2S
    		if ( WM_IS_I2S( hDevice ) )
    		{
                channelAddr = DMAC_I2S_AUDIO_XMIT_FIFO;
    		}
#	endif           
 			break;
            
        case WMDMA_MONO_OUT:
            channelAddr = DMAC_AC97_MONO_XMIT_FIFO;
            break;
            
        case WMDMA_VOICE_OUT:
            channelAddr = DMAC_SSP2_AUDIO_XMIT_FIFO;
            break;
    }

    /* set values with bit fields */
    CmdBuff.DcmdReg.len = WMAUDIO_MAX_BUFFER_SIZE;  /*length of memory buffer */
    CmdBuff.DcmdReg.width = 0x3;    /* 4 bytes per sample */
    CmdBuff.DcmdReg.size = 0x3;     /* 32 byte burst size */
    CmdBuff.DcmdReg.endian = 0;     /* little endian */
    CmdBuff.DcmdReg.flybyt = 0;     /* Flowthrough */
    CmdBuff.DcmdReg.flybys = 0;     /* Flowthrough */
    CmdBuff.DcmdReg.endirqen = 1;   /* 1 means Interrupt when decrement length = 0; */
    CmdBuff.DcmdReg.startirqen = 0; /* 1 means Interrupt when the desc is loaded */
    CmdBuff.DcmdReg.flowtrg = 1;    /* 1 means the target is an external peripheral */
    CmdBuff.DcmdReg.flowsrc = 0;    /* 1 means the source is an external peripheral (and needs flow con */
    CmdBuff.DcmdReg.inctrgadd = 0;  /* 1 means increment the target address (since it's memory) */
    CmdBuff.DcmdReg.incsrcadd = 1;  /* 1 means increment the source address (since it's a peripheral) */

    /*
     * set up XmitA Descriptor
     */
    v_pAudioXmitA_Virtual->DDADR = (DMAC_DESC_FIELD_T)v_pAudioXmitB_Physical; /* address of the next (XmitB) descriptor */
    v_pAudioXmitA_Virtual->DTADR = channelAddr;                               /* source address of the XmitA buffer */ 
    v_pAudioXmitA_Virtual->DSADR = (DMAC_DESC_FIELD_T)v_pDMABufXmitA_Physical;/* destination address of the XmitA buffer */
    v_pAudioXmitA_Virtual->DCMD  = CmdBuff.DcmdDword;                         /* size and cmd values of the XmitA buffer */

    /*
     * set up XmitB Descriptor
     */
    v_pAudioXmitB_Virtual->DDADR = (DMAC_DESC_FIELD_T)v_pAudioXmitA_Physical; /* address of the next (XmitA) descriptor */
    v_pAudioXmitB_Virtual->DTADR = channelAddr;                               /* source address of the XmitB buffer */
    v_pAudioXmitB_Virtual->DSADR = (DMAC_DESC_FIELD_T)v_pDMABufXmitB_Physical;/* destination address of the XmitB buffer */
    v_pAudioXmitB_Virtual->DCMD  = CmdBuff.DcmdDword;                         /* size and cmd values of the XmitB buffer */
}

/*-----------------------------------------------------------------------------
 * Function:    private_WaitForBuffer
 *
 * Waits for the DMA buffer to finish.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      channel     DMA channel to wait for
 *
 * Returns:     WM_STATUS
 *      WMS_SUCCESS         - succeeded
 *      WMS_DATA_TIMED_OUT  - couldn't do write
 *---------------------------------------------------------------------------*/
static WM_STATUS private_WaitForBuffer( WM_DEVICE_HANDLE hDevice,
                                        unsigned int channel
                                      )
{
    WM_XSCALE_DEVICE_CONTEXT *pDeviceContext = (WM_XSCALE_DEVICE_CONTEXT*) hDevice;
    VOLATILE_DMAC_T          *v_pDmaReg      = pDeviceContext->v_pDmaReg;
    unsigned int startTime = GetMillisecondTimestamp( hDevice );
    unsigned int endTime;

    while ( !(v_pDmaReg->DCSR[channel] & DCSR_DMA_INT_MASK) )
    {
        MilliSleep( hDevice, 1 );
        endTime = GetMillisecondTimestamp( hDevice );
        if ( ( endTime - startTime ) >= MAX_PATIENCE )
            return WMS_DATA_TIMED_OUT;
    }

    return WMS_SUCCESS;
}
#endif  /* WM_AUDIO_STREAM && WM_TESTING */

/*------------------------------ END OF FILE ---------------------------------*/

⌨️ 快捷键说明

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