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

📄 buffer.c

📁 自己实现的一个DMA链的源码
💻 C
字号:
//buffer_init
#include "Buffer.h"
#include <services/services.h>
#include "ImgTool4BFx.h"

/*********************************************************************
*Functions defined in this file have similar functionality. 
*But for easy understanding of the dataflow different functions 
*are created
**********************************************************************/

/************************************************************************
	Function:BufferSDtoL1
	
	Description: 
************************************************************************/
/*
extern enum {
	waiting_for_callback_to_happen,
	callback_happened
} Callback_Flag[2];
*/
extern ADI_DMA_DESCRIPTOR_LARGE	gDst0Buffers[5];		// descriptors where data is written to
extern ADI_DMA_DESCRIPTOR_LARGE	gSrc0Buffers[5];		// descriptors where data is written from
extern ADI_DMA_DESCRIPTOR_LARGE	gDst1Buffers[5];		// descriptors where data is written to
extern ADI_DMA_DESCRIPTOR_LARGE	gSrc1Buffers[5];		// descriptors where data is written from

extern ADI_DMA_CHANNEL_HANDLE		dma_s0_chan_handle;					// source DMA channel handle
extern ADI_DMA_CHANNEL_HANDLE		dma_d0_chan_handle;					// destination DMA channel handle
extern ADI_DMA_CHANNEL_HANDLE		dma_s1_chan_handle;					// source DMA channel handle
extern ADI_DMA_CHANNEL_HANDLE		dma_d1_chan_handle;					// destination DMA channel handle

extern volatile int gDesDmaDoneFlag[2];

extern ADI_DCB_HANDLE	Callback_Handle;
extern ADI_DMA_MANAGER_HANDLE gDMAManagerHandle;	// handle to the DMA Manager

/*
void ConfigDst2DTransPara(ADI_DMA_2D_TRANSFER *transDst2D, void *addr, u16 XCount, s16 XModify, u16 YCount, s16 YModify )
{
	transDst2D->StartAddress = addr;
	transDst2D->XCount       = XCount;
	transDst2D->XModify      = XModify;
	transDst2D->YCount       = YCount;
	transDst2D->YModify      = YModify;
}

void FastConfigDst2DAddr(ADI_DMA_2D_TRANSFER *transDst2D, void *addr)
{
	transDst2D->StartAddress = addr;
}


void ConfigSrc2DTransPara(ADI_DMA_2D_TRANSFER *transSrc2D, void *addr, u16 XCount, s16 XModify, u16 YCount, s16 YModify )
{
	transSrc2D->StartAddress = addr;
	transSrc2D->XCount       = XCount;
	transSrc2D->XModify      = XModify;
	transSrc2D->YCount       = YCount;
	transSrc2D->YModify      = YModify;
}

void FastConfigSrc2DAddr(ADI_DMA_2D_TRANSFER *transSrc2D, void *addr)
{
	transSrc2D->StartAddress = addr;
}


//  This is the callback function for the DMA.
void Memory_Callback0(void *AppHandle, u32  Event, void *pArg)
{
	
	// watch for errors
	if (Event == ADI_DMA_EVENT_ERROR_INTERRUPT) {
	//	ezErrorCheck(1);
		return;
	}

	Callback_Flag[0] = callback_happened;
}

void Memory_Callback1(void *AppHandle,	u32  Event,	void *pArg)
{
	
	// watch for errors
	if (Event == ADI_DMA_EVENT_ERROR_INTERRUPT) {
	//	ezErrorCheck(1);
		return;
	}

	Callback_Flag[1] = callback_happened;
}
*/

// callback function called by DCB
void Descriptor_Callback0(	void *AppHandle, u32 Event,	void *pArg)
{
	switch(Event) {
		
		case ADI_DMA_EVENT_DESCRIPTOR_PROCESSED:
			gDesDmaDoneFlag[0] = 1;								// Tell main() that the DMA is done.
			break;
		
		case ADI_DMA_EVENT_INNER_LOOP_PROCESSED:			// this is only used with 2-D DMA
			break;
			
		case ADI_DMA_EVENT_OUTER_LOOP_PROCESSED:			// we're not using this feature of DMA
			break;
			
		case ADI_DMA_EVENT_ERROR_INTERRUPT:					// this is a common error when debugging DMA applications
			break;
		
		default:											// unexpected events
//			ezErrorCheck(1);
			break;
	}
}

void Descriptor_Callback1(	void *AppHandle, u32 Event,	void *pArg)
{
	switch(Event) {
		
		case ADI_DMA_EVENT_DESCRIPTOR_PROCESSED:
			gDesDmaDoneFlag[1] = 1;								// Tell main() that the DMA is done.
			break;
		
		case ADI_DMA_EVENT_INNER_LOOP_PROCESSED:			// this is only used with 2-D DMA
			break;
			
		case ADI_DMA_EVENT_OUTER_LOOP_PROCESSED:			// we're not using this feature of DMA
			break;
			
		case ADI_DMA_EVENT_ERROR_INTERRUPT:					// this is a common error when debugging DMA applications
			break;
		
		default:											// unexpected events
//			ezErrorCheck(1);
			break;
	}
}

void Descriptor_Start(int handleId)
{
	if(handleId==0)
	{
		gDesDmaDoneFlag[0] = 0;
		adi_dma_Queue( dma_s0_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gSrc0Buffers[0]);
		adi_dma_Queue( dma_d0_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gDst0Buffers[0]);
		adi_dma_Control( dma_s0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
		adi_dma_Control( dma_d0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
	}
	else
	{
		gDesDmaDoneFlag[1] = 0;
		adi_dma_Queue( dma_s1_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gSrc1Buffers[0]);
		adi_dma_Queue( dma_d1_chan_handle, (ADI_DMA_DESCRIPTOR_HANDLE)&gDst1Buffers[0]);
		adi_dma_Control( dma_s1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
		adi_dma_Control( dma_d1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)TRUE);
	}
}

void Descriptor_Wait(int handleId)
{
	if(handleId==0)
	{
		while(gDesDmaDoneFlag[0] == 0);			// Wait for the DMA to finish
		adi_dma_Control( dma_s0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
		adi_dma_Control( dma_d0_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
	}
	else
	{
		while(gDesDmaDoneFlag[1] == 0);			// Wait for the DMA to finish
		adi_dma_Control( dma_s1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
		adi_dma_Control( dma_d1_chan_handle, ADI_DMA_CMD_SET_DATAFLOW, (void *)FALSE);
	}
}

void DesBufferSetup(
	int handleId,
	int buffsNum,						// number of buffers (descriptors) to use in each direction
	int Read0Write1,
	int Dma1D02D1,					    // 0 = 1-dimensional DMA,  1 = 2-dimensional DMA
	int XCount,	int XModify,			// number of elements in each buffer (descriptor)
	int YCount,	int YModify,
	int bytes_per_element)				// number of bytes in each element (1, 2, or 4)
{
	ADI_DMA_CONFIG_REG	config;
	int i, j, k;

	// careful not to confuse 0,1,2 values with 1, 2, and 4 bytes
	if(bytes_per_element == 1) 	      config.b_WDSIZE		= 0; 	// 0=8bits (1 byte)
	else if(bytes_per_element == 2)   config.b_WDSIZE		= 1;	// 1=16bits (2 bytes)
	else if(bytes_per_element == 4)   config.b_WDSIZE		= 2;	// 2=32bits (4 bytes)
	config.b_DMA2D	= Dma1D02D1;	// 0 = 1-dimensional DMA,  1 = 2-dimensional DMA

	if(Read0Write1==1)
	{
		config.b_WNR	= 1;	// 0 = memory read,  1 = memory write
	}
	else
	{
		// The source uses slightly different config register settings
		config.b_WNR		= 0;	// 0=memory read, 1=memory write
		config.b_DI_EN		= 0;	// don't interrupt on outbound data
	}
	
	if(handleId==0)
	{
		if(Read0Write1==1)
		{
			for (i = 0; i < buffsNum; i++) 
			{		// set up all the buffers (descriptors) for writing TO memory
		//		DestinationBuffers[i].StartAddress = ;	// SDRAM
				gDst0Buffers[i].Config  = config;				// the config register we set up earlier
				gDst0Buffers[i].XCount  = XCount;
				gDst0Buffers[i].XModify = XModify;
				gDst0Buffers[i].YCount  = YCount;					// this is for 2-dimensional DMA only
				gDst0Buffers[i].YModify = YModify;					// this is for 2-dimensional DMA only
				if (i == (buffsNum-1)) 
				{
					gDst0Buffers[i].CallbackFlag = TRUE;		// interrupt on the last descriptor only
					gDst0Buffers[i].pNext = NULL;				// the last descriptor always points to zero!
				} else 
				{
					gDst0Buffers[i].CallbackFlag = FALSE;		// don't interrupt on intermediate descriptors
					gDst0Buffers[i].pNext = &gDst0Buffers[i+1];		// point to the next buffer in the chain
				}
			}
		}
		else
		{
			for (i = 0; i < buffsNum; i++) 
			{		// set up all the buffers (descriptors) for writing FROM memory
				//SourceBuffers[i].StartAddress = (void *)(SOURCE_DATA_START * i * ELEMENTS * BYTES_PER_ELEMENT);			//SDRAM
				gSrc0Buffers[i].Config  = config;					// the config register we set up earlier
				gSrc0Buffers[i].XCount  = XCount;
				gSrc0Buffers[i].XModify = XModify;
				gSrc0Buffers[i].YCount  = YCount;						// this is for 2-dimensional DMA only
				gSrc0Buffers[i].YModify = YModify;						// this is for 2-dimensional DMA only
				if (i == (buffsNum-1))									// Notice we only use interrupts in the destination DMA
					gSrc0Buffers[i].pNext = NULL;					// the last descriptor always points to zero!!
				else
					gSrc0Buffers[i].pNext = &gSrc0Buffers[i+1];	// point to the next buffer in the chain
			}
		}
	} // if handleId==0
	else
	{
		if(Read0Write1==1)
		{
			for (i = 0; i < buffsNum; i++) 
			{		// set up all the buffers (descriptors) for writing TO memory
		//		DestinationBuffers[i].StartAddress = ;	// SDRAM
				gDst1Buffers[i].Config  = config;				// the config register we set up earlier
				gDst1Buffers[i].XCount  = XCount;
				gDst1Buffers[i].XModify = XModify;
				gDst1Buffers[i].YCount  = YCount;					// this is for 2-dimensional DMA only
				gDst1Buffers[i].YModify = YModify;					// this is for 2-dimensional DMA only
				if (i == (buffsNum-1)) 
				{
					gDst1Buffers[i].CallbackFlag = TRUE;		// interrupt on the last descriptor only
					gDst1Buffers[i].pNext = NULL;				// the last descriptor always points to zero!
				} else 
				{
					gDst1Buffers[i].CallbackFlag = FALSE;		// don't interrupt on intermediate descriptors
					gDst1Buffers[i].pNext = &gDst1Buffers[i+1];		// point to the next buffer in the chain
				}
			}
		}
		else
		{
			for (i = 0; i < buffsNum; i++) 
			{		// set up all the buffers (descriptors) for writing FROM memory
				//SourceBuffers[i].StartAddress = (void *)(SOURCE_DATA_START * i * ELEMENTS * BYTES_PER_ELEMENT);			//SDRAM
				gSrc1Buffers[i].Config  = config;					// the config register we set up earlier
				gSrc1Buffers[i].XCount  = XCount;
				gSrc1Buffers[i].XModify = XModify;
				gSrc1Buffers[i].YCount  = YCount;						// this is for 2-dimensional DMA only
				gSrc1Buffers[i].YModify = YModify;						// this is for 2-dimensional DMA only
				if (i == (buffsNum-1))									// Notice we only use interrupts in the destination DMA
					gSrc1Buffers[i].pNext = NULL;					// the last descriptor always points to zero!!
				else
					gSrc1Buffers[i].pNext = &gSrc1Buffers[i+1];	// point to the next buffer in the chain
			}
		}
	}
}

void DesDmaSetAddr(int handleId, int Src0Dst1, int arrId, void *addr)
{
	if(handleId==0)
	{
		if(Src0Dst1==0)
		{
			gSrc0Buffers[arrId].StartAddress = addr;
		}
		else
		{
			gDst0Buffers[arrId].StartAddress = addr;
		}
	}
	else
	{
		if(Src0Dst1==0)
		{
			gSrc1Buffers[arrId].StartAddress = addr;
		}
		else
		{
			gDst1Buffers[arrId].StartAddress = addr;
		}
	}
}

⌨️ 快捷键说明

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