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

📄 analog_video.c

📁 BlackFin处理器视频演示代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    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 + -