📄 framecapture.c
字号:
/********** MACROS ************************************************************************/
#define USE_CIRCULAR_BUFFER
//#define PAL_FRAME
/*********************************************************************
Include files
*********************************************************************/
#include <drivers/adi_dev.h> // Device manager includes
#include <drivers/decoder/adi_adv7183.h> // AD7183 device driver includes
#include <drivers/twi/adi_twi.h> // TWI device driver includes
#include <SDK-ezkitutilities.h>
#include <adi_ssl_Init.h>
#include <stdio.h>
/*****************************************************************************
Static data
*****************************************************************************/
#define PAL 1
#define NTSC 0
#if defined(PAL_FRAME)
#define FRAME_DATA_LEN 1728 // Data length per line for PAL video format
#define NUM_LINES 625 // Number of lines per frame
#define ACTIVE_FIELD1 22 // Line number of first active field1
#define ACTIVE_FIELD2 335 // Line number of first active field2
#define HORIZONTAL_BLANKING 72 // Width (32bits) of horizontal blanking
#define NUM_LINES_ACTIVE 288 // Number of active lines per frame
#else // its NTSC Frame
#define FRAME_DATA_LEN 1716 // Data length per line for NTSC format
#define NUM_LINES 525 // Number of lines per frame
#define ACTIVE_FIELD1 19 // Line number of first active field1
#define ACTIVE_FIELD2 282 // Line number of first active field2
#define HORIZONTAL_BLANKING 69 // Width (32bits) of horizontal blanking
#define NUM_LINES_ACTIVE 240 // Number of active lines per frame
#endif
#define FRAME_SIZE FRAME_DATA_LEN*NUM_LINES
#define FRAME_DATA_LEN_32BIT FRAME_DATA_LEN/4
// Define the DMA buffer for one video frame.
section("sdram0") static char sFrame0[FRAME_SIZE];
#ifdef USE_CIRCULAR_BUFFER
// buffer for input/output.
static ADI_DEV_CIRCULAR_BUFFER CircBuffer;
#else
ADI_DEV_2D_BUFFER Buffer2D;
#endif
// storage for critical region
static ADI_INT_CRITICAL_REGION_DATA CriticalRegionData;
/*********************************************************************
handles to device drivers
*********************************************************************/
ADI_DEV_DEVICE_HANDLE AD7183DriverHandle;// handle to the ad7183 driver
ADI_DEV_DEVICE_HANDLE EncoderDriverHandle;// handle to the ad7171 driver
/*********************************************************************
static function prototypes
*********************************************************************/
static void InitSystemServices(void);
static void SetEncoderMode(ADI_DEV_DEVICE_HANDLE EncoderDevHandle, u32 mode);
static void Read7183StatusReg(ADI_DEV_DEVICE_HANDLE AD7183DevHandler);
static void ReadEncoderRegs(ADI_DEV_DEVICE_HANDLE EncoderDevHandler);
static void DisplayVideoFrame(
ADI_DEV_MANAGER_HANDLE DeviceManagerHandle,
ADI_DMA_MANAGER_HANDLE DMAManagerHandle );
static void CaptureVideoFrame(
ADI_DEV_MANAGER_HANDLE DeviceManagerHandle,
ADI_DMA_MANAGER_HANDLE DMAManagerHandle );
static void PrepareBuffer(void);
static ADI_INT_HANDLER(ExceptionHandler); // exception handler
static ADI_INT_HANDLER(HWErrorHandler); // hardware error handler
static void ClientCallback(void *AppHandle,u32 Event,void *pArg);
static void CopyField2ToField1(void);
volatile bool FrameReady = FALSE;
/*********************************************************************
*
* Function: main
* Description: Using the AD7183 and AD7179 device drivers,this
program demonstrates a simple video display program.
A single frame video data is captured into SDRAM from the AD7183 decoder,
then output through AD7179 encoder continuosly.
When first push button is pressed, a new video data is captured.
In this example,no processing is done on the video data.
*********************************************************************/
void main(void)
{
unsigned int i;
// initialize the system services
InitSystemServices();
// enable all LED's
for(i=0;i<EZ_NUM_LEDS;i++){
ezInitLED(i);
}
// enable the first push button(SW4)
ezInitButton(EZ_FIRST_BUTTON);
// enable the last push button(SW7)
ezInitButton(EZ_LAST_BUTTON);
ezTurnOffAllLEDs();
// prepare input/output buffers
PrepareBuffer();
// capture the first video frame
CaptureVideoFrame(adi_dev_ManagerHandle, adi_dma_ManagerHandle);
// keep going ..........
// to exit this program push last button(SW7)
while (ezIsButtonPushed(EZ_LAST_BUTTON) == FALSE){
// capture a new frame of video if first button(SW4) is push
if(ezIsButtonPushed(EZ_FIRST_BUTTON) == TRUE){
ezTurnOffLED(0);
// capture a new video frame
CaptureVideoFrame(adi_dev_ManagerHandle, adi_dma_ManagerHandle);
}
}
ezTurnOnAllLEDs();
adi_ssl_Terminate();
}
/*********************************************************************
Function: InitSystemServices
Description: Initializes the necessary system services.
*********************************************************************/
static void InitSystemServices(void) {
u32 i;
u32 Result;
ezInit(1);
adi_ssl_Init();
// hook the exception and hardware error interrupts
ezErrorCheck( adi_int_CECHook(3, ExceptionHandler, NULL, FALSE));
ezErrorCheck( adi_int_CECHook(5, HWErrorHandler, NULL, FALSE));
// return
}
/*********************************************************************
Function: PrepareBuffer
Description: Prepares Video-In buffer for ADV7183 and
Video-Out buffer for ADV7171(BF533) or ADV7179(BF561)
*********************************************************************/
static void PrepareBuffer(void){
CircBuffer.Data = (void*)sFrame0;
CircBuffer.SubBufferCount = NUM_LINES;
CircBuffer.SubBufferElementCount = (FRAME_DATA_LEN/2);
CircBuffer.ElementWidth = 2;
CircBuffer.CallbackType = ADI_DEV_CIRC_FULL_BUFFER;
CircBuffer.pAdditionalInfo = NULL;
}
/*********************************************************************
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
{
// turn on all LEDs and wait for help
ezTurnOnAllLEDs();
return(ADI_INT_RESULT_PROCESSED);
}
static ADI_INT_HANDLER(HWErrorHandler) // hardware error handler
{
// turn on all LEDs and wait for help
ezTurnOnAllLEDs();
return(ADI_INT_RESULT_PROCESSED);
}
/*********************************************************************
Function: ClientCallback
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.
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.
*********************************************************************/
static void ClientCallback(
void *AppHandle,
u32 Event,
void *pArg)
{
switch (Event)
{
// CASE (DMA buffer processed)
case ADI_DEV_EVENT_BUFFER_PROCESSED:
if (AppHandle == (void *)0x7183) {
FrameReady = TRUE;
}
break;
}
}
/*********************************************************************
Function: CaptureVideoFrame
Description: This function is called to capture a frame of video
data using ADV7183 device driver.
This function first enables the AD7183 video
decoder and gives it time to sync.
After the buffer has been processed, meaning the
frame of video data has been captured in SDRAM, the
ADV7183 driver is closed and the function returns to the
caller.
*********************************************************************/
static void CaptureVideoFrame(
ADI_DEV_MANAGER_HANDLE DeviceManagerHandle,
ADI_DMA_MANAGER_HANDLE DMAManagerHandle
){
FrameReady = FALSE;
// turn on last LED
ezTurnOnLED(5);
ezEnableVideoDecoder();// enable the video decoder (7183)
/********************** AD7183 driver *************************************************************/
// open the ad7183 driver
ezErrorCheck( adi_dev_Open( DeviceManagerHandle, // DevMgr handle
&ADIADV7183EntryPoint, // pdd entry point
0, // device instance
(void*)0x7183, // client handle callback identifier
&AD7183DriverHandle, // DevMgr handle for this device
ADI_DEV_DIRECTION_INBOUND, // data direction for this device
DMAManagerHandle, // handle to DmaMgr for this device
NULL, // handle to deferred callback service
ClientCallback)); // client's callback function
// Hardware TWI Configuration table for BF537 to access regs
// Run TWI clock at 100MHz & 50% Duty Cycle
adi_twi_bit_rate rate={100,50};
ADI_DEV_CMD_VALUE_PAIR TWIConfig[]={
{ ADI_TWI_CMD_SET_HARDWARE, (void *)ADI_INT_TWI },
{ ADI_TWI_CMD_SET_FIFO, (void *)0x0000 },
{ ADI_TWI_CMD_SET_LOSTARB, (void *)1 },
{ ADI_TWI_CMD_SET_RATE, (void *)(&rate) },
{ ADI_TWI_CMD_SET_ANAK, (void *)0 },
{ ADI_TWI_CMD_SET_DNAK, (void *)0 },
{ ADI_DEV_CMD_END, NULL }
};
// Send TWI Configuration table to AD7183 if register configuratian is needed
ezErrorCheck(adi_dev_Control(AD7183DriverHandle,ADI_AD7183_CMD_SET_TWI_CONFIG_TABLE,(void*)TWIConfig));
// do the register read/write here if needed.
//Read7183StatusReg(AD7183DriverHandle);
// open the AD7183-PPI device 0 (see Schematic)
ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_OPEN_PPI, (void *)0));
// command PPI to work in NTSC or PAL mode
#if defined(PAL_FRAME)
ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)PAL));
#else
ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)NTSC));
#endif
// configure the ad7183 dataflow method to circular
ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void*)ADI_DEV_MODE_CIRCULAR));
// give the PPI driver the buffer to process
ezErrorCheck( adi_dev_Read(AD7183DriverHandle, ADI_DEV_CIRC, (ADI_DEV_BUFFER *)&CircBuffer));
/***********************************************************************************/
// start capturing the input data
ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)TRUE));
// wait till the buffer has been processed
while (FrameReady == FALSE) ;
// close the PPI driver
ezErrorCheck(adi_dev_Close(AD7183DriverHandle));
// turn off LED
ezTurnOffLED(5);
CopyField2ToField1();
}
/**********************************************************************
* read ADV7183 status registers
**********************************************************************/
static void Read7183StatusReg(ADI_DEV_DEVICE_HANDLE AD7183DevHandler)
{
u32 Result = 0, i;
// array to hold the read AD7183 subaddress register value
u16 Read_data[4] ={0};
ADI_DEV_ACCESS_REGISTER Regs[] =
{{ ADV7183_STATUS1_RO, 0 }, // Register address to access, corresponding register data
{ ADV7183_IDENT_RO, 0 },
{ ADV7183_STATUS2_RO, 0 },
{ ADV7183_STATUS3_RO, 0 },
{ ADI_DEV_REGEND, 0 }}; // Register access delimiter (indicates end of register access)
//To read list of registers in DevRegs
Result = adi_dev_Control(AD7183DevHandler, ADI_DEV_CMD_REGISTER_TABLE_READ, (void *)&Regs);
if (Result != 0) printf("CMD_SELECTIVE_REGISTER_READ failed(error:%x)\n",Result);
else {
// print the values
printf("AD7183: STATUS1 IDENT STATUS2 STATUS3\n ");
for (i=0; i<4; i++){
printf("0x%02X ",Regs[i].Data);
}
printf("\n");
}
}
/*********************************************************************
Function: Copy Odd to Even Frame
Description: This functions copies video field 2 over
the video field 1 in the 7183 input buffer
This is necessary to reduce the video output
flicker caused when the odd and even video field
contain different video frames
*********************************************************************/
static void CopyField2ToField1(void)
{
u32 i,j;
u32 *ipF, *opF;
// Field1, 1st active line number * line length(in 32 bit) + horizontal blanking length
ipF =((u32 *)sFrame0)+ ACTIVE_FIELD2*FRAME_DATA_LEN_32BIT + HORIZONTAL_BLANKING; // pointer to field1
// Field2, 1st active line number * line length(in 32 bit) + horizontal blanking length
opF= ((u32 *)sFrame0)+ ACTIVE_FIELD1*FRAME_DATA_LEN_32BIT + HORIZONTAL_BLANKING; // pointer to field2
for(j=0;j<NUM_LINES_ACTIVE;ipF+=HORIZONTAL_BLANKING,opF+=HORIZONTAL_BLANKING,j++)
for(i=0;i<360;ipF+=1,opF+=1,i++)
*opF=*ipF; //copy field1 to field 2
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -