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

📄 coreb_main.c

📁 BlackFin LCD 显示, 简单GUI图形显示
💻 C
字号:
/*********************************************************************************

Copyright(c) 2005 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.  


Please refer to the "README.txt" file for a description of this example.

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


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

Include files

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

#include <services/services.h>
#include <drivers/adi_dev.h>
#include <drivers/adi_ppi.h>
#include <ezkitutilities.h>
#include "main.h"


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

User configurations:

Callbacks can be either "live" meaning they happen at hardware interrupt
time, or "deferred" meaning that the Deferred Callback Service is used
to make callbacks at a lower priority interrupt level.  Deferred 
callbacks usually allow the system to process data more efficiently with
lower interrupt latencies.  

The macro below can be used to toggle between "live" and "deferred"
callbacks.  All drivers and system services that make callbacks into an 
application are passed a handle to a callback service.  If that handle
is NULL, then live callbacks are used.  If that handle is non-NULL, 
meaning the handle is a real handle into a deferred callback service, 
then callbacks are deferred using the given callback service.  

The other user controlled macro is the USE_LOOPBACK macro.  When enabled
the example will setup the buffer chains to use the chained with loopback
mode rather than the chained mode.  When loopback is enabled, buffers
are continually reused and never have to be requeued.  When loopback
is disabled, buffers must be requeued by the application or else the 
driver will starve for data.  

*********************************************************************/
#define USE_LOOPBACK			// enabled chained with loopback

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

Enumerations and defines

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

#define NUM_BUFFERS (30)		// frame change rate = (NUM_BUFFERS/30)/second

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

Static data

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

// variable for synchronizing cores
extern testset_t adi_pwr_lockvar;

// Two areas in external memory that will each hold an frame that will be
// sent out to the LCD, defined in sml3.dlb
extern char PingFrame[];
extern char PongFrame[];

// Area in memory which holds the 24-bit BMP file
extern char Image_BMP[];

// Create two buffer chains.  One chain will be used for one of the frames,
// the other chain for the other frame.
ADI_DEV_2D_BUFFER PingBuffer[NUM_BUFFERS];
ADI_DEV_2D_BUFFER PongBuffer[NUM_BUFFERS];

// DMA Manager data (base memory + memory for 1 DMA channel)
static u8 DMAMgrData[ADI_DMA_BASE_MEMORY + (ADI_DMA_CHANNEL_MEMORY * 1)];

// Deferred Callback Manager data (memory for 1 service plus 4 posted callbacks)
#if defined(USE_DEFERRED_CALLBACKS)
static u8 DCBMgrData[ADI_DCB_QUEUE_SIZE + (ADI_DCB_ENTRY_SIZE)*4];
#endif

// Device Manager data (base memory + memory for 1 device)
static u8 DevMgrData[ADI_DEV_BASE_MEMORY + (ADI_DEV_DEVICE_MEMORY * 1)];

// Handle to the PPI driver
static ADI_DEV_DEVICE_HANDLE 	DriverHandle;


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

	Function:	ExceptionHandler
			HWErrorHandler

	Description:	We should never get an exception or hardware error, 
			but just in case we'll catch them and simply turn 
			on all the LEDS should one ever occur.

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

static ADI_INT_HANDLER(ExceptionHandler)	// exception handler
{
	// passing a 1 to ezErrorCheck forces the LED's to indicate an error condition
	ezErrorCheck(1);
	return(ADI_INT_RESULT_PROCESSED);
}
		
	
static ADI_INT_HANDLER(HWErrorHandler)		// hardware error handler
{
	// passing a 1 to ezErrorCheck forces the LED's to indicate an error condition
	ezErrorCheck(1);
	return(ADI_INT_RESULT_PROCESSED);
}



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

	Function:	Callback

	Description:	Each type of callback event has it's own unique ID 
			so we can use a single callback function for all 
			callback events.  The switch statement tells us 
			which event has occurred.
					
			In the example, we'll get a callback when the PPI 
			has completed processing of the last buffer in the 
			Ping and Pong buffer chains.  If loopback is enabled, 
			the device driver will automatically reuse the buffer 
			chains so there's really nothing to do, in fact, 
			generating the callback	in the first place is 
			unnecessary.  However, if loopback is not used, the 
			callback function must requeue the chain that just 
			finished in order to keep the device driver saturated 
			with data.  
										
			Note that in the device driver model, in order to 
			generate a callback for buffer completion, the 
			CallbackParameter of the buffer must be set to a non-NULL 
			value.  That non-NULL value is then passed to the 
			callback function as the pArg parameter.  In this example,
			the CallbackParameter is set to be the address of the 
			first buffer in the chain.  That allows	the callback 
			function to requeue the whole chain since even though 
			the callback was generated by the last buffer in the chain,
			the pArg parameter contains the address of the first buffer
			in the chain.  See the code in the "main()" function 
			below for more information.  

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


static void Callback(
	void *AppHandle,
	u32  Event,
	void *pArg)
{
	
	ADI_DEV_BUFFER *pBuffer;			// pointer to the buffer that was processed
	
	// CASEOF (event type)
	switch (Event) {
		
		// CASE (buffer processed)
		case ADI_DEV_EVENT_BUFFER_PROCESSED:
		
			// when the buffer chain was created, the CallbackParameter value for the buffer
			// that was generating the callback was set to be the address of the first buffer
			// in the chain.  So here in the callback that value is passed in as the pArg
			// parameter.  
			pBuffer = (ADI_DEV_BUFFER *)pArg;
			
			// if loopback is enabled, the driver will continually reuse the buffers so there's
			// really nothing to do.  in fact, we really don't need to generate callbacks at all
			// if loopback is enabled.  if loopback is disabled though, we need to requeue the 
			// the buffer chain that just finished
#if defined(USE_LOOPBACK)
#else
			ezErrorCheck(adi_dev_Write(DriverHandle, ADI_DEV_2D, pArg));
#endif
			break;
			
		// CASE (an error)
		case ADI_DEV_EVENT_DMA_ERROR_INTERRUPT:
		case ADI_PPI_EVENT_ERROR_INTERRUPT:
		
			// turn on all LEDs and wait for help
			ezTurnOnAllLEDs();
			while (1) ;
			
	// ENDCASE
	}
	
}

/****************************************************************************
  Function:	Init_Timers	
				
  Set up timers for PWM mode to control HSYNC and VSYNC.  Do notenale them here.
******************************************************************************/

void InitTimers(void)
{
	//HSYNC
	//Setting up command table for Timer 10
	ADI_TMR_GP_CMD_VALUE_PAIR Timer10ConfigurationTable [] = {
		{ ADI_TMR_GP_CMD_SET_TIMER_MODE,			(void *)0x01			},
		{ ADI_TMR_GP_CMD_SET_COUNT_METHOD,			(void *)TRUE			},
		{ ADI_TMR_GP_CMD_SET_INPUT_SELECT,			(void *)TRUE			},
		{ ADI_TMR_GP_CMD_SET_CLOCK_SELECT,			(void *)TRUE			},
		{ ADI_TMR_GP_CMD_RUN_DURING_EMULATION,		(void *)TRUE			},
		{ ADI_TMR_GP_CMD_SET_PERIOD,				(void *)800				},
		{ ADI_TMR_GP_CMD_SET_WIDTH, 				(void *)96				},
		{ ADI_TMR_GP_CMD_END,						NULL					}, 
	};
	//VSYNC	
	//Setting up command table for Timer 11
	ADI_TMR_GP_CMD_VALUE_PAIR Timer11ConfigurationTable [] = {
		{ ADI_TMR_GP_CMD_SET_TIMER_MODE,			(void *)0x01			},
		{ ADI_TMR_GP_CMD_SET_COUNT_METHOD,			(void *)TRUE			},
		{ ADI_TMR_GP_CMD_SET_INPUT_SELECT,			(void *)TRUE			},
		{ ADI_TMR_GP_CMD_SET_CLOCK_SELECT,			(void *)TRUE			},
		{ ADI_TMR_GP_CMD_RUN_DURING_EMULATION,		(void *)TRUE			},
		{ ADI_TMR_GP_CMD_SET_PERIOD,				(void *)420000			},
		{ ADI_TMR_GP_CMD_SET_WIDTH, 				(void *)1600 			},
		{ ADI_TMR_GP_CMD_END,						NULL					}, 
	};
	//Open Timer 10 for access
	adi_tmr_Open(ADI_TMR_GP_TIMER_10);
	//Program timer 10 with Timer 10 table
	adi_tmr_GPControl(ADI_TMR_GP_TIMER_10, ADI_TMR_GP_CMD_TABLE, Timer10ConfigurationTable);
	//Open Timer 11 for access
	adi_tmr_Open(ADI_TMR_GP_TIMER_11);
	//Program timer 11 with Timer 11 table
	adi_tmr_GPControl(ADI_TMR_GP_TIMER_11, ADI_TMR_GP_CMD_TABLE, Timer11ConfigurationTable);
}


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


void main(void) {
	
	ADI_DEV_CMD_VALUE_PAIR ConfigurationTable [] = {	// table of PPI driver configuration values
		{ ADI_DEV_CMD_SET_DATAFLOW_METHOD, 		(void *)ADI_DEV_MODE_CHAINED_LOOPBACK },
		{ ADI_PPI_CMD_SET_CONTROL_REG,			(void *)0xB81E		},
		{ ADI_PPI_CMD_SET_DELAY_COUNT_REG,		(void *)143			},
		{ ADI_PPI_CMD_SET_TRANSFER_COUNT_REG,	(void *)639			},
		{ ADI_DEV_CMD_SET_STREAMING,			(void *)TRUE		},
		{ ADI_DEV_CMD_END,						NULL				},
	};

	ADI_DCB_HANDLE			DCBManagerHandle;	// handle to the callback service
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle;	// handle to the DMA Manager
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle;	// handle to the Device Manager
	ADI_DEV_2D_BUFFER 		Buffer2D;			// buffer to be sent to PPI Driver
	u32 					ResponseCount;		// response counter
	int						i;					// counter
	
	// Initialize the power management module
	ADI_PWR_COMMAND_PAIR pwrConfig[] = {
		{ ADI_PWR_CMD_SET_EZKIT,   (void*)ADI_PWR_EZKIT_BF561_600MHZ },
		{ ADI_PWR_CMD_SET_AUTO_SYNC_ENABLED, NULL },								
		{ ADI_PWR_CMD_SET_SYNC_LOCK_VARIABLE, (void*)&adi_pwr_lockvar },
		{ ADI_PWR_CMD_END, 0}
	};
	ezErrorCheck(adi_pwr_Init(pwrConfig));
	
	// Initialize buttons and LED's
	ezInit();
	ezTurnOnAllLEDs();

	// initialize the Interrupt Manager and hook the exception and hardware error interrupts
	ezErrorCheck(adi_int_Init(NULL, 0, &ResponseCount, NULL));

	ezErrorCheck(adi_int_CECHook(3, ExceptionHandler, NULL, FALSE));
	ezErrorCheck(adi_int_CECHook(5, HWErrorHandler, NULL, FALSE));
	
	DCBManagerHandle = NULL;

	// initialize the DMA Manager
	ezErrorCheck(adi_dma_Init(DMAMgrData, sizeof(DMAMgrData), &ResponseCount, &DMAManagerHandle, NULL));
	
	// initialize the Device Manager
	ezErrorCheck(adi_dev_Init(DevMgrData, sizeof(DevMgrData), &ResponseCount, &DeviceManagerHandle, NULL));
	
	// initialize the two frames and fill them with 16-bit versions of the 24-bit BMP image
	ezErrorCheck(Create_Data(PingFrame,Image_BMP));
	ezErrorCheck(Create_Data(PongFrame,Image_BMP));
	// create a buffer chain that points to the PingFrame.  Each buffer points to the same PingFrame
	// so the PingFrame will be displayed NUM_BUFFERS times.  NUM_BUFFERS is sized to 
	// keep the display busy for 1 second.  Place a callback on only the last buffer
	// in the chain.  Make the CallbackParameter (the value that gets passed to the callback
	// function as the pArg parameter) point to the first buffer in the chain.  This way, when
	// the callback goes off, the callback function can requeue the whole chain if the loopback
	// mode is off.  
	for (i = 0; i < NUM_BUFFERS; i++) {
		PingBuffer[i].Data = PingFrame;
		PingBuffer[i].ElementWidth = 2;
		PingBuffer[i].XCount = 640;
		PingBuffer[i].XModify = 2;
		PingBuffer[i].YCount = 525;
		PingBuffer[i].YModify = 2;
		PingBuffer[i].CallbackParameter = NULL;
		PingBuffer[i].pNext = &PingBuffer[i + 1];
	}
	PingBuffer[NUM_BUFFERS - 1].CallbackParameter = &PingBuffer[0];
	PingBuffer[NUM_BUFFERS - 1].pNext = NULL;
	
	// now do the same for the Pong buffers
	for (i = 0; i < NUM_BUFFERS; i++) {
		PongBuffer[i].Data = PongFrame;
		PongBuffer[i].ElementWidth = 2;
		PongBuffer[i].XCount = 640;
		PongBuffer[i].XModify = 2;
		PongBuffer[i].YCount = 525;
		PongBuffer[i].YModify = 2;
		PongBuffer[i].CallbackParameter = NULL;
		PongBuffer[i].pNext = &PongBuffer[i + 1];
	}
	PongBuffer[NUM_BUFFERS - 1].CallbackParameter = &PongBuffer[0];
	PongBuffer[NUM_BUFFERS - 1].pNext = NULL;
	
	// initialize the Timer manager
	InitTimers();
	
	// open the PPI driver for output
	ezErrorCheck(adi_dev_Open(DeviceManagerHandle, &ADIPPIEntryPoint, 1, NULL, &DriverHandle, ADI_DEV_DIRECTION_OUTBOUND, DMAManagerHandle, DCBManagerHandle, Callback));
		
	// configure the PPI driver with the values from the configuration table
   	ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_TABLE, ConfigurationTable));
		
	// give the device the Ping and Pong buffer chains
	ezErrorCheck(adi_dev_Write(DriverHandle, ADI_DEV_2D, (ADI_DEV_BUFFER *)PingBuffer));
	ezErrorCheck(adi_dev_Write(DriverHandle, ADI_DEV_2D, (ADI_DEV_BUFFER *)PongBuffer));
	
	// enable data flow
	ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void *)TRUE));
	
	//enable timer 10 and timer 11
	adi_tmr_GPGroupEnable(ADI_TMR_GP_TIMER_10 | ADI_TMR_GP_TIMER_11,TRUE);		
	
	// keep going until the last push button is pressed
	while (ezIsButtonPushed(EZ_LAST_BUTTON) == FALSE){
		idle();
	}
		
	// close the Device Manager
	ezErrorCheck(adi_dev_Terminate(DeviceManagerHandle));
	
	// close down the DMA Manager
	ezErrorCheck(adi_dma_Terminate(DMAManagerHandle));
	
	while(1);
}






⌨️ 快捷键说明

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