📄 memdma_1d.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 + -