📄 analog_video.c
字号:
/**
* @author Zlatan Stanojevic
*/
#include "analog_video.h"
#include "../../i2c/src/i2c_framing_layer.h"
#include "../../misc/clock_query.h"
#include "../../PPIConfig.h"
#include "../../GPIOconfig.h"
#include <stdio.h>
//#include <services/adi_dma.h>
#include <services/services.h>
#include "dma.h"
#include "itu-r-656.h"
#include "blt.h"
AVStandard pal_std = {
720,
576,
2,
1728,
539136,
1080000,
38304,
579168,
1440,
288,
625,
{
{ 0, FIELD_1 | VERTICAL_BLANK },
{ 22, FIELD_1 },
{ 310, FIELD_1 | VERTICAL_BLANK },
{ 312, FIELD_2 | VERTICAL_BLANK },
{ 335, FIELD_2 },
{ 623, FIELD_2 | VERTICAL_BLANK },
{ -1, 0 }
}
};
AVStandard ntsc_std = {
720,
507,
2,
1716,
449592,
900900,
5424,
456732,
1440,
276,
525,
{
{ 0, FIELD_2 | VERTICAL_BLANK },
{ 3, FIELD_1 | VERTICAL_BLANK },
{ 19, FIELD_1 },
{ 263, FIELD_1 | VERTICAL_BLANK },
{ 265, FIELD_2 | VERTICAL_BLANK },
{ 282, FIELD_2 },
{ -1, 0 }
}
};
const AVStandard *g_pInvalidStd = 0;
const AVStandard *g_pPALstd = &pal_std;
const AVStandard *g_pNTSCstd = &ntsc_std;
const AVStandard *g_pInputStd = 0;
#define AV_DEBUG
/****************** Encoder part *********************/
#define ADV7171_HWID 0x2A
static I2CConfig adv7171_reset_timing [] =
{
{ 0x07, 0x80 }, //reset timing unit
{ 0x07, 0x08 }, //set timing mode and remove reset
};
static I2CConfig adv7171_common [] =
{
{ 0x01, 0x00 },
{ 0x02, 0x00 },
{ 0x03, 0x80 },
{ 0x04, 0x00 },
}; ///<Setup commands common to all modes.
static I2CConfig adv7171_pal_bghid [] =
{
{ 0x00, 0x05 },
}; ///<Specific command for PAL-BGHID mode
static I2CConfig adv7171_pal_m [] =
{
{ 0x00, 0x06 },
}; ///<Specific command for PAL-M mode
static I2CConfig adv7171_ntsc [] =
{
{ 0x00, 0x00 },
}; ///<Specific command for NTSC mode
//static I2CConfig adv7171_pwr
/*****************************************************/
/****************** Decoder part *********************/
#define ADV7183_HWID 0x20
//////////////////////CONTROL//////////////////////////
/*
static I2CConfig adv7183_common [] =
{
}; ///<Setup common to all types and modes
*/
static I2CConfig adv7183_typeA [] =
{
{ 0x04, 0x75 }, //DATA drive strength to high
{ 0x0e, 0x48 }, //CLOCK three-stated and drive strength to high
}; ///<Specific settings for type A chip
static I2CConfig adv7183_typeB [] =
{
{ 0x1d, 0x80 }, //CLOCK three-stated
{ 0xf4, 0x3c }, //DATA and CLOCK drive strength to high
}; ///<Specific settings for type B chip
static I2CConfig adv7183_reset [] =
{
{ 0x0f, 0x01 },
}; ///<Reset command
static I2CConfig adv7183_pwr_CVBS [] =
{
{ 0x3a, 0x06 },
}; ///<Power down mode for CVBS input
static I2CConfig adv7183_pwr_YC [] =
{
{ 0x3a, 0x02 },
}; ///<Power down mode for S-Video input
static I2CConfig adv7183_pwr_YPrPb [] =
{
{ 0x3a, 0x00 },
}; ///<All ADC's powered up
static I2CConfig adv7183_pwr_off [] =
{
{ 0x3a, 0x0e },
}; ///<All ADC's powered down
//////////////////////STATUS///////////////////////////
static I2CConfig adv7183_IDENT [] =
{
{ 0x11, 0x00 },
}; ///<Part identification register
static I2CConfig adv7183_STATUS1 [] =
{
{ 0x10, 0x00 },
}; ///<STATUS1 register: lock state, autodetect result
static I2CConfig adv7183_STATUS3 [] =
{
{ 0x13, 0x00 },
}; ///<STATUS3 register: interlaced video
/*****************************************************/
static enum
{
ADV7183A,
ADV7183B,
UNKNOWN_DECODER,
} decoder_part;
static enum
{
ADV7171KST,
UNKNOWN_ENCODER,
} encoder_part;
//AV_SRC_FIELD video_source = 0;
//AV_SRC_FIELD video_detection_mask = AV_YC_AIN14 | AV_CVBS_AIN2 | AV_CVBS_AIN3 | AV_CVBS_AIN5 | AV_CVBS_AIN6;
static AV_RESULT av_cycle_inputs( s16 tries,
AV_SRC_FIELD *video_detection_result,
AV_SRC_FIELD video_detection_mask )
{
AV_SRC_FIELD video_source;
long loops = querySystemClock() / 20;
long i;
short j;
//I2CControl( ADV7183_HWID, adv7183_reset, 1 );
adv7183_STATUS1[0].value = 0;
for( ; tries; tries-- )
{
video_source = 0;
for( j = 0; j < 16; j++ )
{
I2CConfig input_mode = { 0x00, (u8)j };
AV_SRC_FIELD bit = 1 << j;
if( video_detection_mask & bit )
{
I2CControl( ADV7183_HWID, &input_mode, 1 );
for( i = 0; i < loops; i++ )
asm( "ssync;" );
I2CStatus( ADV7183_HWID, adv7183_STATUS1, 1 );
if( adv7183_STATUS1[0].value & 0x01 )
{
video_source |= 1 << j;
}
}
}
u16 ones; //get number of bits set
asm( "%0 = 0; %0.l = ones %1;" : "=d"(ones) : "d"(video_source) );
if( ones )
{
*video_detection_result = video_source;
if( ones > 1 )
return AV_RESULT_AMBIGUOUS_INPUT_SELECTION;
else
return AV_RESULT_OK;
}
if( tries < 0 )
tries = -1;
}
return AV_RESULT_NO_INPUT;
}
int av_input_locked(void)
{
I2CStatus( ADV7183_HWID, adv7183_STATUS1, 1 );
return adv7183_STATUS1[0].value & 0x01;
}
static inline AV_RESULT av_adjust_power( AV_SRC_FIELD video_source )
{
if( video_source & ~AV_CVBS_ALL == 0 )
I2CControl( ADV7183_HWID, adv7183_pwr_CVBS, 1 );
if( video_source & ~AV_YC_ALL == 0 )
I2CControl( ADV7183_HWID, adv7183_pwr_YC, 1 );
if( video_source & ~AV_YPrPb_ALL == 0 )
I2CControl( ADV7183_HWID, adv7183_pwr_YPrPb, 1 );
return AV_RESULT_OK;
}
AV_RESULT av_configure_input( AV_SRC_FIELD video_source, AV_INPUT_TYPE pa_input_type )
{
u16 ones; //get number of bits set
asm( "%0 = 0; %0.l = ones %1;" : "=d"(ones) : "d"(video_source) );
if( ones )
{
if( ones > 1 )
return AV_RESULT_AMBIGUOUS_INPUT_SELECTION;
else
{
u16 signbits;
asm( "%0 = 0; %0.l = signbits %1;"
: "=d"(signbits)
: "d"(video_source) );
I2CConfig input = { 0x00, (u8)( 30 - signbits ) };
I2CControl( ADV7183_HWID, &input, 1 );
#ifdef AV_DEBUG
printf( "---------------------------------------------\n" );
#endif
I2CStatus( ADV7183_HWID, adv7183_STATUS3, 1 );
switch( pa_input_type == AUTODETECT ? adv7183_STATUS1[0].value & 0x70 : pa_input_type )
{
case NTSC_MJ:
g_pInputStd = g_pNTSCstd;
#ifdef AV_DEBUG
printf( "NTSC-MJ video standard\n" );
#endif
break;
case NTSC_443:
g_pInputStd = g_pNTSCstd;
#ifdef AV_DEBUG
printf( "NTSC-443 video standard\n" );
#endif
break;
case PAL_M:
g_pInputStd = g_pPALstd;
#ifdef AV_DEBUG
printf( "PAL-M video standard\n" );
#endif
break;
case PAL_60:
g_pInputStd = g_pPALstd;
#ifdef AV_DEBUG
printf( "PAL-60 video standard\n" );
#endif
break;
case PAL_BGHID:
g_pInputStd = g_pPALstd;
#ifdef AV_DEBUG
printf( "PAL-BGHID video standard\n" );
#endif
break;
case SECAM:
g_pInputStd = g_pInvalidStd;
#ifdef AV_DEBUG
printf( "SECAM video standard\n" );
#endif
break;
case PAL_N:
g_pInputStd = g_pPALstd;
#ifdef AV_DEBUG
printf( "PAL-Combination N video standard\n" );
#endif
break;
case SECAM_525:
g_pInputStd = g_pInvalidStd;
#ifdef AV_DEBUG
printf( "SECAM 525 video standard\n" );
#endif
break;
}
if( adv7183_STATUS3[0].value & ( 1 << 6 ) )
printf( "Interlaced video\n" );
#ifdef AV_DEBUG
printf( "---------------------------------------------\n" );
#endif
av_adjust_power( video_source );
return AV_RESULT_OK;
}
}
else
return AV_RESULT_NO_INPUT;
}
static AV_RESULT av_enable_decoder_clock( void )
{
I2CConfig pin_control [1];
switch( decoder_part )
{
case ADV7183A:
pin_control[0] = adv7183_typeA[1];
I2CStatus( ADV7183_HWID, pin_control, 1 );
pin_control[0].value &= ~0x40;
break;
case ADV7183B:
pin_control[0] = adv7183_typeB[0];
I2CStatus( ADV7183_HWID, pin_control, 1 );
pin_control[0].value &= ~0x80;
break;
}
I2CControl( ADV7183_HWID, pin_control, 1 );
return AV_RESULT_OK;
}
AV_RESULT av_init_input( u32 OE_pin, u32 RESET_pin, bool pa_bDisable )
{
AV_RESULT result = AV_RESULT_OK;
if( RESET_pin )
{
gpio_becomeOutput( RESET_pin );
gpio_set( RESET_pin );
}
I2CStatus( ADV7183_HWID, adv7183_IDENT, 1 );
switch( adv7183_IDENT[0].value )
{
case 0x13:
decoder_part = ADV7183B;
I2CControl( ADV7183_HWID, adv7183_typeB, 2 );
break;
case 0x0d:
case 0x0e:
case 0x0f:
case 0x10:
case 0x11:
decoder_part = ADV7183A;
I2CControl( ADV7183_HWID, adv7183_typeA, 2 );
break;
default:
decoder_part = UNKNOWN_DECODER;
result = AV_RESULT_UNKNOWN_DECODER_DEVICE;
break;
}
if( decoder_part != UNKNOWN_DECODER && OE_pin )
{
gpio_becomeOutput( OE_pin );
if( pa_bDisable )
gpio_set( OE_pin );
else
{
gpio_clear( OE_pin );
av_enable_decoder_clock();
}
}
#ifdef AV_DEBUG
switch( decoder_part )
{
case ADV7183B:
printf( "Type B device detected\n" );
break;
case ADV7183A:
printf( "Type A device detected, IDENT = 0x%2X\n", adv7183_IDENT[0].value );
break;
case UNKNOWN_DECODER:
printf( "Detected device is of unknown type\n" );
break;
}
#endif
return result;
}
AV_RESULT av_find_input( s16 pa_nTries,
AV_SRC_FIELD *pa_video_detection_result,
AV_SRC_FIELD pa_video_detection_mask,
AV_INPUT_TYPE pa_input_type )
{
AV_RESULT result;
if( decoder_part == UNKNOWN_DECODER )
return AV_RESULT_UNKNOWN_DECODER_DEVICE;
I2CControl( ADV7183_HWID, adv7183_pwr_YPrPb, 1 );
result = av_cycle_inputs( pa_nTries, pa_video_detection_result,
pa_video_detection_mask );
#ifdef AV_DEBUG
printf( "== Autodetection result =====================\n" );
#endif
if( result == AV_RESULT_NO_INPUT )
{
#ifdef AV_DEBUG
printf( "No input signal\n" );
#endif
}
else if( result == AV_RESULT_AMBIGUOUS_INPUT_SELECTION )
{
#ifdef AV_DEBUG
printf( "Ambiguous input selection. Either \nadjust the input mask, or disconnect\nsome video inputs from the board.\n" );
#endif
}
else
{
#ifdef AV_DEBUG
if( *pa_video_detection_result & AV_CVBS_AIN1 )
printf( "CVBS input at AIN1 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN2 )
printf( "CVBS input at AIN2 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN3 )
printf( "CVBS input at AIN3 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN4 )
printf( "CVBS input at AIN4 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN5 )
printf( "CVBS input at AIN5 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN6 )
printf( "CVBS input at AIN6 detected\n" );
if( *pa_video_detection_result & AV_YC_AIN14 )
printf( "YC input at AIN1 and AIN4 detected\n" );
if( *pa_video_detection_result & AV_YC_AIN25 )
printf( "YC input at AIN2 and AIN5 detected\n" );
if( *pa_video_detection_result & AV_YC_AIN36 )
printf( "YC input at AIN3 and AIN6 detected\n" );
if( *pa_video_detection_result & AV_YPrPb_AIN145 )
printf( "YPrPb input at AIN1, AIN4 and AIN5 detected\n" );
if( *pa_video_detection_result & AV_YPrPb_AIN236 )
printf( "YPrPb input at AIN2, AIN3 and AIN6 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN7 )
printf( "CVBS input at AIN7 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN8 )
printf( "CVBS input at AIN8 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN9 )
printf( "CVBS input at AIN9 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN10 )
printf( "CVBS input at AIN10 detected\n" );
if( *pa_video_detection_result & AV_CVBS_AIN11 )
printf( "CVBS input at AIN11 detected\n" );
#endif
}
if( result == AV_RESULT_OK )
result = av_configure_input( *pa_video_detection_result, pa_input_type );
// if( result ==AV_RESULT_OK )
// result = av_adjust_power( *pa_video_detection_result );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -