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

📄 memdma_1d.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_1D.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		32768

#define CALLBACK_QUEUE_SIZE		4

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

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

Data Structures 

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


// memory locations to be DMA'ed... They're placed in SDRAM
section("sdram0") static u8 memory_buffer_source[MEMORY_COPY_SIZE];
section("sdram0") static u8 memory_buffer_destination[MEMORY_COPY_SIZE];

ADI_DMA_MANAGER_HANDLE DMA_Handle;
void *Channel_Handle;



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

Static data

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

// 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];

// 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];


// 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 i;
	
	// set source buffer to our pseudo-random pattern...
	// ...and set destination buffer to all zeros.
	for( i=0; i<MEMORY_COPY_SIZE; i++) {
		memory_buffer_source[i] = rand()>>24;				// get an 8-bit random number
		memory_buffer_destination[i] = 0;
	}
}


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




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


void main(void) {
	
	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 now.
#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, try it with 1-byte width and without using callbacks
//
	SetupMemory();
	ezErrorCheck( adi_dma_MemoryCopy(Channel_Handle, &memory_buffer_destination[0], &memory_buffer_source[0], 1, MEMORY_COPY_SIZE, NULL));
	ezErrorCheck( CheckMemory() );

//
// Next, try it with 4-byte width and without using callbacks
//
	SetupMemory();
	ezErrorCheck( adi_dma_MemoryCopy(Channel_Handle, &memory_buffer_destination[0], &memory_buffer_source[0], 4, MEMORY_COPY_SIZE/4, NULL));
	ezErrorCheck( CheckMemory() );
	
//
// Next, use callbacks and 2-byte wide transfers
//
	
	// 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));	

	SetupMemory();
	Callback_Flag = waiting_for_callback_to_happen;
	ezErrorCheck( adi_dma_MemoryCopy(Channel_Handle, &memory_buffer_destination[0], &memory_buffer_source[0], 2, MEMORY_COPY_SIZE/2, 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);
	ezErrorCheck( CheckMemory() );

	
	// 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 + -