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

📄 memdma_2d.c

📁 ADI公司blackfin DSP开发板BF533 EZ-KIT LITE附带的全部原代码
💻 C
字号:
/*********************************************************************************
 
Copyright(c) 2004 Analog Devices, Inc. All Rights Reserved. 

This software is proprietary and confidential.  By using this software you agree
to the terms of the associated Analog Devices License Agreement.  

$RCSfile: memdma_2D.c,v $
$Revision: 1.3 $
$Date: 2007/06/25 15:31:17 $

***********************************************************************************

Please refer to the 'readme.txt' file for a description of the Interrupt Manager Examples.


*********************************************************************

Include files

*********************************************************************/

#include <services/services.h>
#include "ezkitutilities.h"

/*********************************************************************

Enumerations and defines

*********************************************************************/


#define MEMORY_COPY_SIZE_X		256			// number of bytes in X direction
#define MEMORY_COPY_SIZE_Y		128			// number of bytes in Y direction

#define SQUARE_MATRIX_SIZE		128			// dimensions for a square matrix


#define CALLBACK_QUEUE_SIZE		4

#define OUR_CLIENT_ID			54321		// this is for whatever this application wants, pick any number

/*********************************************************************

Data Structures 

*********************************************************************/


// These are placed in SDRAM
section("sdram0") static u8 memory_buffer_source[MEMORY_COPY_SIZE_X][MEMORY_COPY_SIZE_Y];
section("sdram0") static u8 memory_buffer_destination[MEMORY_COPY_SIZE_X][MEMORY_COPY_SIZE_Y];
section("sdram0") static u8 memory_buffer_column[MEMORY_COPY_SIZE_X];

ADI_DMA_MANAGER_HANDLE DMA_Handle;
void *Channel_Handle;


/*********************************************************************

Static data

*********************************************************************/
// Callback manager necessary stuff
static ADI_DCB_HANDLE	Callback_Handle;
static u8				Callback_Manager_Storage[ADI_DCB_QUEUE_SIZE];
static u8				Callback_Queue[ADI_DCB_ENTRY_SIZE * CALLBACK_QUEUE_SIZE];

// DMA manager necessary stuff (always need 2 channels for a memory copy)
static u8 DMA_Manager_Storage[ADI_DMA_BASE_MEMORY + ADI_DMA_CHANNEL_MEMORY*2];


// storage for interrupt manager data
static u8 IntMgrData[(2*ADI_INT_SECONDARY_MEMORY)];	


// flag between main and the callback routine
// to indicate when the DMA is completed
volatile enum {
	waiting_for_callback_to_happen,
	callback_happened
} Callback_Flag;

/*********************************************************************

prototypes

*********************************************************************/

u32 CheckMemory(void);
void SetupMemory(void);


/*********************************************************************

test code

*********************************************************************/


static ADI_INT_HANDLER(Simple_Exception_Handler) {
	ezErrorCheck(1);
	return(ADI_INT_RESULT_PROCESSED);
}
		
	
static ADI_INT_HANDLER(Simple_Hardware_Error_Handler) {
	ezErrorCheck(1);
	return(ADI_INT_RESULT_PROCESSED);
}


void set_up_error_handling (void) {
	
	// hook the exception interrupt
	ezErrorCheck( adi_int_CECHook(3, Simple_Exception_Handler, NULL, FALSE) != ADI_INT_RESULT_SUCCESS);
	
	// hook the hardware error
	ezErrorCheck( adi_int_CECHook(5, Simple_Hardware_Error_Handler, NULL, FALSE) != ADI_INT_RESULT_SUCCESS);
}


/*********************************************************************

Static functions

*********************************************************************/



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

	Callback_Flag = callback_happened;
}


//
//  Initializes the source memory with a psuedo-random pattern.
//  Also zeros out the destination memory.
static void SetupMemory() {
	u32 x, y;
	
	// set source buffer to our pseudo-random pattern...
	// ...and set destination buffer to all zeros.
	for( x=0; x<MEMORY_COPY_SIZE_X; x++) {
		for( y=0; y<MEMORY_COPY_SIZE_Y; y++) {
			memory_buffer_source[x][y] = rand()>>24;		// get an 8-bit random number
			memory_buffer_destination[x][y] = 0;
		}
	}
	
	// clear out the column buffer in case we want to use it
	for( x=0; x<MEMORY_COPY_SIZE_X; x++) {
		memory_buffer_column[x] = 0;
	}
}


//
//  Check if the source memory was correctly copied to the destination.
//  Return the result.
static u32 CheckMemory() {
	u32 x, y;
	
	for( x=0; x<MEMORY_COPY_SIZE_X; x++) {
		for( y=0; y<MEMORY_COPY_SIZE_Y; y++) {
			if( memory_buffer_source[x][y] != memory_buffer_destination[x][y]) {
				return(1);
			}
		}
	}
	return(0);
}




/*********************************************************************
*
*	Function:	main
*
*********************************************************************/


void main(void) {
	
	ADI_DMA_2D_TRANSFER		src_info, dst_info;
	u32 x, y;
	
	int Result;			// location to store result from system services calls
	u32 Response_Count;		// location to store result from system services calls
	volatile u32 i;			// "volatile" is used to avoid optimizing out a delay loop below.


	// initialize the interrupt manager
	ezErrorCheck(adi_int_Init(IntMgrData, sizeof(IntMgrData), &Response_Count, NULL));
	
	// initialize EZ-Kit; power and EBIU services	
	ezInit(1);
	

	// set up exception and error handlers
	set_up_error_handling();
	
	// initialize DMA
	ezErrorCheck( adi_dma_Init(DMA_Manager_Storage, sizeof(DMA_Manager_Storage), &Response_Count, &DMA_Handle, NULL));

	//Initialize the flag service, memory is not passed because callbacks are not being used
	ezErrorCheck(adi_flag_Init(NULL, 0, &Response_Count, NULL));
	
	//Initialize all LEDS
	for (i = EZ_FIRST_LED; i < EZ_NUM_LEDS; i++){
        ezInitLED(i);
	}

//  Dual core processors actually have different names for the memory DMA channels
//  so we need to look at which processor we are using.
#if defined(__ADSPBF561__)
	// dual core processors: use different streams for each core, which one to use for each core is arbitrary.
	if( adi_core_id() == 0) {
		ezErrorCheck( adi_dma_MemoryOpen(DMA_Handle, ADI_DMA_MDMA1_0, (void *)OUR_CLIENT_ID, &Channel_Handle, Callback_Handle));
	} else {
		ezErrorCheck( adi_dma_MemoryOpen(DMA_Handle, ADI_DMA_MDMA2_0, (void *)OUR_CLIENT_ID, &Channel_Handle, Callback_Handle));
	}
#else
	// single core processors
	ezErrorCheck( adi_dma_MemoryOpen(DMA_Handle, ADI_DMA_MDMA_0, main, &Channel_Handle, Callback_Handle));
#endif		




//
// First, copy a 1-byte wide, simple 2-D array without using callbacks
//
	SetupMemory();
	
	src_info.StartAddress = &memory_buffer_source[0][0];
	src_info.XCount  = MEMORY_COPY_SIZE_X;
	src_info.XModify = 1;					// typically the same as element width
	src_info.YCount  = MEMORY_COPY_SIZE_Y;
	src_info.YModify = 1;					// typically the same as element width
	
	dst_info.StartAddress = &memory_buffer_destination[0][0];
	dst_info.XCount  = MEMORY_COPY_SIZE_X;
	dst_info.XModify = 1;					// typically the same as element width
	dst_info.YCount  = MEMORY_COPY_SIZE_Y;
	dst_info.YModify = 1;					// typically the same as element width
	
	ezErrorCheck( adi_dma_MemoryCopy2D(Channel_Handle, &dst_info, &src_info, 1, NULL));
	ezErrorCheck( CheckMemory() );
	
	

//
// Next, try it with 4-byte wide, simple 2-D array without using callbacks
//
	SetupMemory();

	// The Count variable specifies bytes, not elements!  That's why it's the same as above.	
	src_info.StartAddress = &memory_buffer_source[0][0];
	src_info.XCount  = MEMORY_COPY_SIZE_X;	// Notice that we still specify the same count
	src_info.XModify = 4;					// typically the same as element width
	src_info.YCount  = MEMORY_COPY_SIZE_Y;	// Notice that we still specify the same count
	src_info.YModify = 4;					// typically the same as element width
	
	dst_info.StartAddress = &memory_buffer_destination[0][0];
	dst_info.XCount  = MEMORY_COPY_SIZE_X;	// Notice that we still specify the same count
	dst_info.XModify = 4;					// typically the same as element width
	dst_info.YCount  = MEMORY_COPY_SIZE_Y;	// Notice that we still specify the same count
	dst_info.YModify = 4;					// typically the same as element width
	
	// Make sure to use 4 bytes in the call below instead of 1 byte.
	ezErrorCheck( adi_dma_MemoryCopy2D(Channel_Handle, &dst_info, &src_info, 4, NULL));
	ezErrorCheck( CheckMemory() );
	
	
//
// Next, this is how to pull a column out of a 2-D matrix, without callbacks
//
	SetupMemory();
	
	// Get column 3 from the 2-D source array into a 1-D destination array.
	src_info.StartAddress = &memory_buffer_source[0][3];
	src_info.XCount  = MEMORY_COPY_SIZE_X;	// go through all rows of the 2-D source
	src_info.XModify = MEMORY_COPY_SIZE_Y;	// hop down to the next row after every fetch
	src_info.YCount  = 1;					// since we just want 1 column, use 1
	src_info.YModify = 1;					// we just want 1 column
	
	dst_info.StartAddress = &memory_buffer_column[0];
	dst_info.XCount  = MEMORY_COPY_SIZE_X;	// for the destination, make it act like a 1-D copy
	dst_info.XModify = 1;					// for the destination, make it act like a 1-D copy
	dst_info.YCount  = 1;					// for the destination, make it act like a 1-D copy
	dst_info.YModify = 1;					// for the destination, make it act like a 1-D copy
	
	ezErrorCheck( adi_dma_MemoryCopy2D(Channel_Handle, &dst_info, &src_info, 1, NULL));
	
	// Now verify the memory
	for(i=0; i<MEMORY_COPY_SIZE_X; i++) {
		if( memory_buffer_source[i][3] != memory_buffer_column[i] ) {
			ezErrorCheck(1);				// there was a mismatch, light all the LEDs
		}
	}
	
//
// From this point on, start using callbacks
//

	// initialize callbacks
	ezErrorCheck( adi_dcb_Init(Callback_Manager_Storage, sizeof(Callback_Manager_Storage), &Response_Count, NULL));
	// open a callback queue
	ezErrorCheck( adi_dcb_Open(ik_ivg14, Callback_Queue, sizeof(Callback_Queue), &Response_Count, &Callback_Handle));	


//
// Next, show how to transpose a square 2-D matrix, with callbacks
//
	
	SetupMemory();
	
	// Assume a matrix with dimensions SQUARE_MATRIX_SIZE x SQUARE_MATRIX_SIZE
	src_info.StartAddress = &memory_buffer_source[0][0];
	src_info.XCount  = SQUARE_MATRIX_SIZE;
	src_info.XModify = SQUARE_MATRIX_SIZE;	// hop down to the next row after every fetch
	src_info.YCount  = SQUARE_MATRIX_SIZE;	// do all of the columns
	//
	//  The next statement is the tricky part.  After doing the Nth element of all rows, move to the next column
	//  by DECREMENTING by one less than the size of the matrix with one row missing.
	//
	// here's a 3x3 example:
	//
	// a b c
	// d e f
	// g h i
	//
	// a b c  d e f  g h i
	//          we want to do: a, d, g, b, e, h, c, f, i
	// which means we move by:    3, 3,-5, 3, 3,-5, 3, 3 
	// note that -5 == -(( 3 * (3 - 1) ) - 1)
	src_info.YModify = -((SQUARE_MATRIX_SIZE * (SQUARE_MATRIX_SIZE - 1) ) - 1);		// note it's a negative modify value
	
	// The destination just takes that stream of elements and constructs an ordinary matrix
	dst_info.StartAddress = &memory_buffer_destination[0][0];
	dst_info.XCount  = SQUARE_MATRIX_SIZE;	// just like the destination of a normal matrix copy
	dst_info.XModify = 1;					// just like the destination of a normal matrix copy
	dst_info.YCount  = SQUARE_MATRIX_SIZE;	// just like the destination of a normal matrix copy
	dst_info.YModify = 1;					// just like the destination of a normal matrix copy
	
	Callback_Flag = waiting_for_callback_to_happen;
	ezErrorCheck( adi_dma_MemoryCopy2D(Channel_Handle, &dst_info, &src_info, 1, &Memory_Callback));
	

	// Wait for the DMA to finish.
	// If the program is stuck here, the callback never happened and the DMA did not work.
	while(Callback_Flag != callback_happened);

	// Now check if the result is transposed
	for(x=0; x<SQUARE_MATRIX_SIZE; x++) {
		for(y=0; y<SQUARE_MATRIX_SIZE; y++) {
			if( memory_buffer_source[x][y] != memory_buffer_destination[y][x] ) {
				ezErrorCheck(1);			// The matrix was not transposed correctly
			}
		}
	}
	
	
	// All done, success
	while(1) {
		for(i=0; i<0x00FFFFFF; i++);		// delay for a little while
		ezCycleLEDs();
	}
}

⌨️ 快捷键说明

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