📄 videoecho.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.
$RCSfile: VideoEcho.c,v $
$Revision: 1.4 $
$Date: 2007/06/13 16:00:33 $
*********************************************************************************/
/*********************************************************************
Include files
*********************************************************************/
#include <services\services.h> // system services
#include <drivers\adi_dev.h> // device manager includes
#include <drivers\ppi\adi_ppi.h> // PPI driver includes
#include "ezkitutilities.h" // EZ-Kit utilities
#include "adi_itu656.h" // ITU656 utilities
/*********************************************************************
ADSP-BF533/537 have only 1 PPI called PPI0
ADSP-BF561 has 2, PPI0 connected to video decoder, PPI1 to video encoder
*********************************************************************/
#if defined(__ADSPBF561__)
#define ENCODER_PPI (1)
#define DECODER_PPI (0)
#else
#define ENCODER_PPI (0)
#define DECODER_PPI (0)
#endif
/*********************************************************************
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.
*********************************************************************/
//#define USE_DEFERRED_CALLBACKS
/*********************************************************************
Static data
*********************************************************************/
// Interrupt Manager data (need 1 secondary handler for each DMA channel used)
static u8 InterruptManagerStorage[ADI_INT_SECONDARY_MEMORY * 1];
// 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)];
// define a chunk of SDRAM to hold a single NTSC video frame
// For single-core processors, we can define the frame right here but
// for dual-core processors, we need to declare it here but define
// it in the sml3 project so that they get placed in SDRAM properly
#if defined(__ADSPBF561__)
extern u8 Frame[];
#else
static u8 Frame[ADI_ITU656_NTSC_LINE_WIDTH * ADI_ITU656_NTSC_HEIGHT];
#endif
/*********************************************************************
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
{
ezErrorCheck(1);
return(ADI_INT_RESULT_PROCESSED);
}
static ADI_INT_HANDLER(HWErrorHandler) // hardware error handler
{
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 input buffer. We
don't really need the callback function as the main
code uses the ProcessedFlag field of the buffer to
determine when the inbound buffer has completed
processing, but it's included here for illustrative
purposes.
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 the example,
the CallbackParameter is set to be the address of the
buffer itself. That allows the callback function to
determine which buffer was processed. Often the
CallbackParameter value is set to NULL for every buffer
except the last buffer in a chain. That technique causes
the callback function to get called only when the last
buffer in the chain has been processed.
*********************************************************************/
static void Callback(
void *AppHandle,
u32 Event,
void *pArg)
{
static unsigned int Counter = 0; // count the number of input buffers processed
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:
// point to the buffer
pBuffer = (ADI_DEV_BUFFER *)pArg;
// increment our counter
Counter++;
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
}
// return
}
/*********************************************************************
Function: CaptureFrame
Description: This function is called to capture a frame of video
data. This function first enables the AD7183 video
decoder and gives it time to sync. The buffer that
is passed to the device driver, given to this function
by the calling function, is modified so as to generate
a callback when the buffer is processed by the PPI
driver. The PPI driver is then opened for input,
configured according to the parameters in the
configuration table, and then dataflow is enabled.
After the buffer has been processed, meaning the
frame of video data has been captured in SDRAM, the
PPI driver is closed and the function returns to the
caller.
The first LED is lit when this function is executing.
*********************************************************************/
void CaptureFrame(
ADI_DCB_HANDLE DCBManagerHandle,
ADI_DMA_MANAGER_HANDLE DMAManagerHandle,
ADI_DEV_MANAGER_HANDLE DeviceManagerHandle,
ADI_DEV_2D_BUFFER *pBuffer2D
){
// table of configuration values for the PPI on input
ADI_DEV_CMD_VALUE_PAIR InboundConfigurationTable [] = {
{ ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED },
{ ADI_PPI_CMD_SET_CONTROL_REG, (void *)0x0084 },
{ ADI_PPI_CMD_SET_LINES_PER_FRAME_REG, (void *)ADI_ITU656_NTSC_HEIGHT },
{ ADI_DEV_CMD_END, NULL },
};
ADI_DEV_DEVICE_HANDLE DeviceHandle; // handle to the device driver
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -