📄 analog_video.c
字号:
return result;
}
AV_RESULT av_setup_output( u32 BLANK_pin, u32 RESET_pin,
const AVStandard *pa_pStd, bool pa_bPAL_M )
{
if( pa_pStd == g_pInvalidStd )
return AV_RESULT_INVALID_STANDARD;
if( RESET_pin )
{
gpio_becomeOutput( RESET_pin );
gpio_set( RESET_pin );
}
I2CControl( ADV7171_HWID, adv7171_common, 4 );
if( pa_pStd == g_pPALstd )
{
if( pa_bPAL_M )
I2CControl( ADV7171_HWID, adv7171_pal_m, 1 );
else
I2CControl( ADV7171_HWID, adv7171_pal_bghid, 1 );
}
else if( pa_pStd == g_pNTSCstd )
I2CControl( ADV7171_HWID, adv7171_ntsc, 1 );
I2CControl( ADV7171_HWID, adv7171_reset_timing, 2 );
if( BLANK_pin )
{
gpio_becomeOutput( BLANK_pin );
gpio_set( BLANK_pin );
}
return AV_RESULT_OK;
}
AV_RESULT av_reset_output_timing()
{
I2CControl( ADV7171_HWID, adv7171_reset_timing, 2 );
return AV_RESULT_OK;
}
#define DECLARE_DMA_HANDLER( ppi_index )\
static void DMAhandler ## ppi_index ( void );
#define DEFINE_DMA_HANDLER( ppi_index ) \
static void DMAhandler ## ppi_index ( void )\
{ *( g_aPPIspec[ ppi_index ].pDMAirqStat ) = 1;\
if( g_aPPIstat[ ppi_index ].frame_handler )\
g_aPPIstat[ ppi_index ].frame_handler( AV_EVENT_FRAME_FINISHED ); }
#define DMA_HANDLER( ppi_index ) DMAhandler ## ppi_index
extern T_PPI_SPEC g_aPPIspec[];
extern unsigned int g_nPPIcount;
typedef struct
{
int opened; // true if ppi is currently opened
int output; // true if ppi is output
ADI_INT_PERIPHERAL_ID ppi_err_int_id; // adi_int peripheral id for PPI_ERR
int ppi_err_shared; // PPI_ERR shared with other peripherals
T_PPI_CALLBACK dma_handler; // adi_int peripheral id for according DMA channel
AV_EVENT_HANDLER_FN error_handler; // (ppi-) error handler function
AV_EVENT_HANDLER_FN frame_handler; // per frame handler function
void *target_buffer; // target image buffer
const AVStandard *std; // video standard descriptor
int buffer_matrix; // true if target buffer is a itu656 matrix
int double_buffer; // true if target buffer is a double buffer
DMAListDescriptor dma_desc[4];
} PPIStat;
/*************** Cross-platform support ****************/
#if defined( __ADSPBF533__ )
#undef __AV32__
DECLARE_DMA_HANDLER( 0 );
static PPIStat g_aPPIstat[] =
{
{
0,
0,
ADI_INT_PPI_ERROR,
0,
DMA_HANDLER( 0 ),
0,
0,
0
}
};
DEFINE_DMA_HANDLER( 0 );
#elif defined( __ADSPBF537__ )
#undef __AV32__
DECLARE_DMA_HANDLER( 0 );
static PPIStat g_aPPIstat[] =
{
{
0,
0,
ADI_INT_PERIPHERAL_ERROR,
1,
DMA_HANDLER( 0 ),
0,
0,
0
}
};
DEFINE_DMA_HANDLER( 0 );
#elif defined( __ADSPBF561__ )
#define __AV32__
DECLARE_DMA_HANDLER( 0 );
DECLARE_DMA_HANDLER( 1 );
static PPIStat g_aPPIstat[] =
{
{
0,
0,
ADI_INT_PPI0_ERROR,
0,
DMA_HANDLER( 0 ),
0,
0,
0
},
{
0,
0,
ADI_INT_PPI1_ERROR,
0,
DMA_HANDLER( 1 ),
0,
0,
0
}
};
DEFINE_DMA_HANDLER( 0 );
DEFINE_DMA_HANDLER( 1 );
#endif
/*******************************************************/
static ADI_INT_HANDLER( PPIerrorHandler )
{
int i;
u16 ppi_status[g_nPPIcount];
int err_occurred;
for( i = 0; i < g_nPPIcount; i++ )
{
ppi_status[i] = *( g_aPPIspec[i].pPPIstatus );
}
err_occurred = 0;
for( i = 0; i < g_nPPIcount; i++ )
{
if( ppi_status[i] & 0xf800 )
{
err_occurred = 1;
if( ( ppi_status[i] & FT_ERR ) && g_aPPIstat[i].error_handler )
g_aPPIstat[i].error_handler( AV_EVENT_PPI_FT_ERR );
}
}
if( err_occurred )
return ADI_INT_RESULT_PROCESSED;
else
return ADI_INT_RESULT_NOT_PROCESSED;
}
int g_nDMAIVG, g_nPPIerrorIVG;
AV_RESULT av_base_init( int pa_nDMAIVG, int pa_nPPIerrorIVG )
{
g_nDMAIVG = pa_nDMAIVG;
g_nPPIerrorIVG = pa_nPPIerrorIVG;
if( adi_int_CECHook( g_nPPIerrorIVG, PPIerrorHandler, 0, 1 ) )
return AV_RESULT_ADI_INT_ERROR;
/* int i;
for( i = 0; i < g_nPPIcount; i++ )
{
g_aPPIstat[i].
}
*/
return AV_RESULT_OK;
}
AV_RESULT av_open( u8 pa_nPPIindex,
void *pa_pTargetBuffer,
const AVStandard *pa_pStd,
bool pa_bBufferMatrix,
bool pa_bOutput,
bool pa_bDoubleBuffer,
AV_EVENT_HANDLER_FN pa_fFrameHandler,
AV_EVENT_HANDLER_FN pa_fErrorHandler,
bool pa_bStart )
{
if( pa_nPPIindex >= g_nPPIcount )
return AV_RESULT_WRONG_PPI_INDEX;
if( pa_pStd == g_pInvalidStd )
return AV_RESULT_INVALID_STANDARD;
PPIStat *stat = g_aPPIstat + pa_nPPIindex;
void *critical_arg = adi_int_EnterCriticalRegion( NULL );
if( stat->opened )
return AV_RESULT_PPI_ALREADY_OPENED;
stat->opened = 1;
adi_int_ExitCriticalRegion( critical_arg );
stat->output = pa_bOutput;
stat->error_handler = pa_fErrorHandler;
stat->frame_handler = pa_fFrameHandler;
stat->target_buffer = pa_pTargetBuffer;
stat->std = pa_pStd;
stat->buffer_matrix = pa_bBufferMatrix;
stat->double_buffer = pa_bDoubleBuffer;
if( pa_bStart )
av_start( pa_nPPIindex );
return AV_RESULT_OK;
}
AV_RESULT av_close( int pa_nPPIindex )
{
if( pa_nPPIindex >= g_nPPIcount )
return AV_RESULT_WRONG_PPI_INDEX;
PPIStat *stat = g_aPPIstat + pa_nPPIindex;
if( ! stat->opened )
return AV_RESULT_PPI_NOT_OPENED;
av_stop( pa_nPPIindex );
stat->error_handler = 0;
stat->frame_handler = 0;
stat->opened = 0;
return AV_RESULT_OK;
}
AV_RESULT av_start( int pa_nPPIindex )
{
if( pa_nPPIindex >= g_nPPIcount )
return AV_RESULT_WRONG_PPI_INDEX;
PPIStat *stat = g_aPPIstat + pa_nPPIindex;
if( ! stat->opened )
return AV_RESULT_PPI_NOT_OPENED;
if( stat->output )
{
if( ! stat->buffer_matrix )
return AV_RESULT_NEED_BUFFER_MATRIX;
if( ppi_setup_gp( pa_nPPIindex,
(u32)stat->target_buffer,
PORT_EN |
#if defined( __AV32__ )
DMA32 |
#endif
DLEN_8 | PACK_EN | PORT_DIR,
0,
0,
0,
FLOW_AUTOBUFFER |
#if defined( __AV32__ )
WDSIZE_32 |
#else
WDSIZE_16 |
#endif
DMA2D | DI_EN | DMAEN,
#if defined( __AV32__ )
stat->std->line_stride / 4,
4,
stat->std->total_lines,
4,
#else
stat->std->line_stride / 2,
2,
stat->std->total_lines,
2,
#endif
0,
stat->dma_handler ) )
return AV_RESULT_PPI_CONFIG_ERROR;
}
else
{
#if defined( __AV32__ )
#define STRIDE 4
#define XCOUNT ( stat->std->width >> 1 )
#define CFG ( FLOW_DESC_LIST | NDSIZE( 9 ) | WDSIZE_32 | DMA2D | WNR | DMAEN )
#else
#define STRIDE 2
#define XCOUNT ( stat->std->width )
#define CFG ( FLOW_DESC_LIST | NDSIZE( 9 ) | WDSIZE_16 | DMA2D | WNR | DMAEN )
#endif
adi_int_SICSetIVG( stat->ppi_err_int_id, g_nPPIerrorIVG );
adi_int_SICEnable( stat->ppi_err_int_id );
if( stat->buffer_matrix )
{
stat->dma_desc[0].next_desc = stat->dma_desc + 1;
stat->dma_desc[0].start_addr = (void *)( (unsigned long)stat->target_buffer + stat->std->active_video1_offset );
stat->dma_desc[0].x_count = XCOUNT;
stat->dma_desc[0].x_modify = STRIDE;
stat->dma_desc[0].y_count = (stat->std->height >> 1) + (stat->std->height & 1);
stat->dma_desc[0].y_modify = stat->std->line_stride - 2 * stat->std->width + STRIDE;
stat->dma_desc[0].dmacfg = CFG;
stat->dma_desc[1].next_desc = stat->dma_desc;
stat->dma_desc[1].start_addr = (void *)( (unsigned long)stat->target_buffer + stat->std->active_video2_offset );
stat->dma_desc[1].x_count = XCOUNT;
stat->dma_desc[1].x_modify = STRIDE;
stat->dma_desc[1].y_count = stat->std->height >> 1;
stat->dma_desc[1].y_modify = stat->std->line_stride - 2 * stat->std->width + STRIDE;
stat->dma_desc[1].dmacfg = CFG;
}
else
{
stat->dma_desc[0].next_desc = stat->dma_desc + 1;
stat->dma_desc[1].start_addr = (void *)( (unsigned long)stat->target_buffer + 2 * stat->std->width );
stat->dma_desc[0].x_count = XCOUNT;
stat->dma_desc[0].x_modify = STRIDE;
stat->dma_desc[0].y_count = (stat->std->height >> 1) + (stat->std->height & 1);
stat->dma_desc[0].y_modify = 2 * stat->std->width + STRIDE;
stat->dma_desc[0].dmacfg = CFG;
stat->dma_desc[1].next_desc = stat->dma_desc + 2;
stat->dma_desc[0].start_addr = stat->target_buffer;
stat->dma_desc[1].x_count = XCOUNT;
stat->dma_desc[1].x_modify = STRIDE;
stat->dma_desc[1].y_count = stat->std->height >> 1;
stat->dma_desc[1].y_modify = 2 * stat->std->width + STRIDE;
stat->dma_desc[1].dmacfg = CFG;
if( stat->double_buffer )
{
stat->dma_desc[2].next_desc = stat->dma_desc + 3;
stat->dma_desc[3].start_addr = (void *)( (unsigned long)stat->target_buffer + ( 2 * stat->std->width * stat->std->height ) + 2 * stat->std->width );
stat->dma_desc[2].x_count = XCOUNT;
stat->dma_desc[2].x_modify = STRIDE;
stat->dma_desc[2].y_count = (stat->std->height >> 1) + (stat->std->height & 1);
stat->dma_desc[2].y_modify = 2 * stat->std->width + STRIDE;
stat->dma_desc[2].dmacfg = CFG;
stat->dma_desc[3].next_desc = stat->dma_desc;
stat->dma_desc[2].start_addr = (void *)( (unsigned long)stat->target_buffer + ( 2 * stat->std->width * stat->std->height ) );
stat->dma_desc[3].x_count = XCOUNT;
stat->dma_desc[3].x_modify = STRIDE;
stat->dma_desc[3].y_count = stat->std->height >> 1;
stat->dma_desc[3].y_modify = 2 * stat->std->width + STRIDE;
stat->dma_desc[3].dmacfg = CFG;
}
else
stat->dma_desc[1].next_desc = stat->dma_desc;
}
if( ppi_setup_gp( pa_nPPIindex,
0,
PACK_EN |
#if defined( __AV32__ )
DMA32 |
#endif
FLD_SEL | PORT_EN,
stat->std->total_lines,
stat->std->active_video_line_size - 1,
0,
FLOW_DESC_LIST | NDSIZE( 9 ) | DMAEN,
0,
0,
0,
0,
(unsigned long)stat->dma_desc,
0 ) )
return AV_RESULT_PPI_CONFIG_ERROR;
}
return AV_RESULT_OK;
}
AV_RESULT av_stop( int pa_nPPIindex )
{
T_ERROR_CODE ppi_result;
if( pa_nPPIindex >= g_nPPIcount )
return AV_RESULT_WRONG_PPI_INDEX;
PPIStat *stat = g_aPPIstat + pa_nPPIindex;
if( ! stat->opened )
return AV_RESULT_PPI_NOT_OPENED;
ppi_result = ppi_close( pa_nPPIindex );
// if( ppi_result )
// return AV_RESULT_PPI_CONFIG_ERROR;
if( adi_int_SICDisable( stat->ppi_err_int_id ) )
return AV_RESULT_ADI_INT_ERROR;
*(g_aPPIspec[pa_nPPIindex].pPPIcontrol) = 0;
*(g_aPPIspec[pa_nPPIindex].pDMAconfig) = 0;
*(g_aPPIspec[pa_nPPIindex].pDMAirqStat) = 1;
return AV_RESULT_OK;
}
AV_RESULT av_restart( int pa_nPPIindex )
{
AV_RESULT result;
if( result = av_stop( pa_nPPIindex ) )
return result;
if( result = av_start( pa_nPPIindex ) )
return result;
return AV_RESULT_OK;
}
AV_RESULT av_tell( int pa_nPPIindex, int *which )
{
if( pa_nPPIindex >= g_nPPIcount )
return AV_RESULT_WRONG_PPI_INDEX;
*which = ( *(g_aPPIspec[pa_nPPIindex].pDMAnextDescrPtr) == &( g_aPPIstat[pa_nPPIindex].dma_desc[3] ) ||
*(g_aPPIspec[pa_nPPIindex].pDMAnextDescrPtr) == &( g_aPPIstat[pa_nPPIindex].dma_desc[0] ) );
return AV_RESULT_OK;
}
AV_RESULT av_init_matrix( void *pa_pBufferAddr, BLTBufferDesc *pa_pBufferDesc,
const AVStandard *pa_pStd )
{
if( pa_pStd == g_pInvalidStd )
return AV_RESULT_INVALID_STANDARD;
unsigned short blank = 0x1080;
u32 sav, eav;
char *iterator;
unsigned short line;
long i;
for( i = 0; i < pa_pStd->line_stride * pa_pStd->total_lines; i++ )
{
*( (u16*)pa_pBufferAddr + i ) = blank;
}
line = 0;
iterator = pa_pBufferAddr;
int flagno = 0;
long matchln;
matchln = pa_pStd->flags[flagno].line;
do
{
if( line == matchln )
{
sav = SAV( pa_pStd->flags[flagno].flags );
eav = EAV( pa_pStd->flags[flagno].flags );
flagno++;
matchln = pa_pStd->flags[flagno].line;
}
*(unsigned long *)iterator = eav;
*(unsigned long *)( iterator + pa_pStd->blank_line_size - 4 ) = sav;
iterator += pa_pStd->line_stride;
line++;
}
while( line < pa_pStd->total_lines );
*pa_pBufferDesc = (BLTBufferDesc){ pa_pBufferAddr,
pa_pStd->active_video_line_size / 2,
pa_pStd->height,
pa_pStd->active_video1_offset,
4,
pa_pStd->line_stride,
pa_pStd->field_stride + pa_pStd->line_stride,
1 };
return AV_RESULT_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -