📄 vportcap.c
字号:
//clear BLKCAP in VCA_CTL to enable capture DMA events
VP_FSETH(vpCaptureHandle2, VCACTL, BLKCAP,VP_VCACTL_BLKCAP_CLEAR);
VP_FSETH(vpCaptureHandle2, VCBCTL, BLKCAP,VP_VCBCTL_BLKCAP_CLEAR);
return (vpCaptureHandle2);
}
/*******************************************************************/
/* Function : bt656_capture_start */
/* Input(s) : VP_handle */
/* Description : Configures given video port for 8.bit BT.656 non. */
/* continuos frame capture on channel A. */
/*******************************************************************/
void bt656_capture_start(VP_Handle videoHandle)
{
volatile Uint32 *p;
p=(Uint32 *)0x01c40020;//PFUNC
*p=0x00300000;
p=(Uint32 *)0x01c40024;//PDIR
*p=0x00300000;
p=(Uint32 *)0x01c4002c;//PDOUT
*p=0x00300000;
p=(Uint32 *)0x01c48020;//PFUNC
*p=0x00300000;
p=(Uint32 *)0x01c48024;//PDIR
*p=0x00300000;
p=(Uint32 *)0x01c4802c;//PDOUT
*p=0x00300000;
}
/*................................................................ */
/* Function : VPCapChaAIsr */
/* Description : This capture ISR clears FRMC to continue capture */
/* in this non.continuous mode and also clears other */
/* status bits. */
/*................................................................ */
interrupt void VPCapChaAIsr(void)
{
Uint32 vpis = 0;
/* Get video port status register value */
vpis = VP_RGETH(vpCaptureHandle, VPIS);
if(vpis & _VP_VPIS_CCMPA_MASK) /* capture complete */
{
/* Clear frame complete bit in VCX_CTL to continue capture in non-continuous mode*/
VP_FSETH(vpCaptureHandle, VCASTAT, FRMC,VP_VCASTAT_FRMC_CLEAR);
/* Clear CCMPA to enable next frame complete interrupts*/
VP_FSETH(vpCaptureHandle, VPIS, CCMPA,VP_VPIS_CCMPA_CLEAR);
capChaAFrameCount++; /* increment captured frame count */
// capNewFrame += 1;
}
if(vpis & _VP_VPIS_COVRA_MASK) /* overrun error */
{
capChaAOverrun++;
VP_FSETH(vpCaptureHandle, VPIS, COVRA,VP_VPIS_COVRA_CLEAR);
}
if(vpis & _VP_VPIS_SERRA_MASK) /* synchronization error */
{
capChaASyncError++;
VP_FSETH(vpCaptureHandle, VPIS, SERRA,VP_VPIS_SERRA_CLEAR);
}
if(vpis & _VP_VPIS_SFDA_MASK) /* short field detect */
{
capChaAShortFieldDetect++;
VP_FSETH(vpCaptureHandle, VPIS, SFDA, VP_VPIS_SFDA_CLEAR);
}
if(vpis & _VP_VPIS_LFDA_MASK) /* long field detect */
{
capChaALongFieldDetect++;
VP_FSETH(vpCaptureHandle, VPIS, LFDA, VP_VPIS_LFDA_CLEAR);
}
}
//VP2中断
interrupt void VPCapChaAIsr2(void)
{
Uint32 vpis = 0;
vpis = VP_RGETH(vpCaptureHandle2, VPIS);
if(vpis & _VP_VPIS_CCMPA_MASK)
{
VP_FSETH(vpCaptureHandle2, VCASTAT, FRMC,VP_VCASTAT_FRMC_CLEAR);
VP_FSETH(vpCaptureHandle2, VPIS, CCMPA,VP_VPIS_CCMPA_CLEAR);
capChaAFrameCount++;
//capNewFrame += 1;
}
if(vpis & _VP_VPIS_COVRA_MASK)
{
capChaAOverrun++;
VP_FSETH(vpCaptureHandle2, VPIS, COVRA,VP_VPIS_COVRA_CLEAR);
}
if(vpis & _VP_VPIS_SERRA_MASK)
{
capChaASyncError++;
VP_FSETH(vpCaptureHandle2, VPIS, SERRA,VP_VPIS_SERRA_CLEAR);
}
if(vpis & _VP_VPIS_SFDA_MASK)
{
capChaAShortFieldDetect++;
VP_FSETH(vpCaptureHandle2, VPIS, SFDA, VP_VPIS_SFDA_CLEAR);
}
if(vpis & _VP_VPIS_LFDA_MASK)
{
capChaALongFieldDetect++;
VP_FSETH(vpCaptureHandle2, VPIS, LFDA, VP_VPIS_LFDA_CLEAR);
}
if(vpis & _VP_VPIS_CCMPB_MASK)
{
VP_FSETH(vpCaptureHandle2, VCBSTAT, FRMC,VP_VCBSTAT_FRMC_CLEAR);
// Clear CCMPA to enable next frame complete interrupts
VP_FSETH(vpCaptureHandle2, VPIS, CCMPB,VP_VPIS_CCMPB_CLEAR);
capChaAFrameCount++; // increment captured frame count
//capNewFrame+=1;
}
if(vpis & _VP_VPIS_COVRB_MASK) //overrun error
{
capChaAOverrun++;
VP_FSETH(vpCaptureHandle2, VPIS, COVRB,VP_VPIS_COVRB_CLEAR);
}
if(vpis & _VP_VPIS_SERRB_MASK) // synchronization error
{
capChaASyncError++;
VP_FSETH(vpCaptureHandle2, VPIS, SERRB,VP_VPIS_SERRB_CLEAR);
}
if(vpis & _VP_VPIS_SFDB_MASK) //short field detect
{
capChaAShortFieldDetect++;
VP_FSETH(vpCaptureHandle2, VPIS, SFDB, VP_VPIS_SFDB_CLEAR);
}
if(vpis & _VP_VPIS_LFDB_MASK) // long field detect
{
capChaALongFieldDetect++;
VP_FSETH(vpCaptureHandle2, VPIS, LFDB, VP_VPIS_LFDB_CLEAR);
}
}
void setupVPCapChaAEDMA2(int portNumber)
{
Int32 YEvent, UEvent, VEvent;
Int32 YEventb, UEventb, VEventb;
/* get channelA Y, U, V EDMA event numbers,选择触发事件 */
switch(portNumber)
{
/*确定相应的DMA通路*/
case VP_DEV0:
YEvent = EDMA_CHA_VP0EVTYA;
UEvent = EDMA_CHA_VP0EVTUA;
VEvent = EDMA_CHA_VP0EVTVA;
YEventb = EDMA_CHA_VP0EVTYB;
UEventb= EDMA_CHA_VP0EVTUB;
VEventb = EDMA_CHA_VP0EVTVB;
break;
case VP_DEV1:
YEvent = EDMA_CHA_VP1EVTYA;
UEvent = EDMA_CHA_VP1EVTUA;
VEvent = EDMA_CHA_VP1EVTVA;
break;
case VP_DEV2:
YEvent = EDMA_CHA_VP2EVTYA;
UEvent = EDMA_CHA_VP2EVTUA;
VEvent = EDMA_CHA_VP2EVTVA;
YEventb = EDMA_CHA_VP2EVTYB;
UEventb = EDMA_CHA_VP2EVTUB;
VEventb = EDMA_CHA_VP2EVTVB;
break;
}
//VP2 DMA CONFIG
configVPCapEDMAChannel( &hEdmaVPCapChaA2Yb, YEventb,
&edmaCapChaAYTccNum2,
vpCaptureHandle2->ysrcbAddr,
(Uint32)capChaAYSpaced,
VCB_Y_EDMA_FRMCNT2,
VCB_Y_EDMA_ELECNT2);
configVPCapEDMAChannel( &hEdmaVPCapChaA2Y, YEvent,
&edmaCapChaAYTccNum2,
vpCaptureHandle2->ysrcaAddr,
(Uint32)capChaAYSpacec,
VCA_Y_EDMA_FRMCNT2,
VCA_Y_EDMA_ELECNT2);
// Configure Cb EDMA channel to move data from CbSRCA
// (FIFO) to Cb.data buffer, capChaACbSpace
configVPCapEDMAChannel( &hEdmaVPCapChaA2Cb, UEvent,
&edmaCapChaACbTccNum2,
vpCaptureHandle2->cbsrcaAddr,
(Uint32)capChaACbSpacec,
VCA_Y_EDMA_FRMCNT2,
VCA_Y_EDMA_ELECNT2/2); //(1/2) of Y.samples
configVPCapEDMAChannel( &hEdmaVPCapChaA2Cbb, UEventb,
&edmaCapChaACbTccNum2,
vpCaptureHandle2->cbsrcbAddr,
(Uint32)capChaACbSpaced,
VCB_Y_EDMA_FRMCNT2,
VCB_Y_EDMA_ELECNT2/2);
// Configure Cr EDMA channel to move data from CrSRCA
// (FIFO) to Cr.data buffer, capChaACrSpace
configVPCapEDMAChannel( &hEdmaVPCapChaA2Cr, VEvent,
&edmaCapChaACrTccNum2,
vpCaptureHandle2->crsrcaAddr,
(Uint32)capChaACrSpacec,
VCA_Y_EDMA_FRMCNT2,
VCA_Y_EDMA_ELECNT2/2); //(1/2) of Y.samples
configVPCapEDMAChannel( &hEdmaVPCapChaA2Crb, VEventb,
&edmaCapChaACrTccNum2,
vpCaptureHandle2->crsrcbAddr,
(Uint32)capChaACrSpaced,
VCB_Y_EDMA_FRMCNT2,
VCB_Y_EDMA_ELECNT2/2);
//VP2
EDMA_enableChannel(hEdmaVPCapChaA2Y);
EDMA_enableChannel(hEdmaVPCapChaA2Cb);
EDMA_enableChannel(hEdmaVPCapChaA2Cr);
EDMA_enableChannel(hEdmaVPCapChaA2Yb);
EDMA_enableChannel(hEdmaVPCapChaA2Cbb);
EDMA_enableChannel(hEdmaVPCapChaA2Crb);
}
/*................................................................ */
/* Function : configVPCapEDMAChannel */
/* */
/* Input(s) : edmaHandle . pointer to EDMA handle. */
/* eventId . EDMA eventId. */
/* tccNum . pointer to transfer complete number. */
/* srcAddr . source address for EDMA transfer. */
/* dstAddr . destination address for EDMA transfer */
/* frameCount . frame count. */
/* elementCount . element count(32.bit element size). */
/* */
/* Output(s): edmaHandle . edma Handle of the given event. */
/* tccNum . transfer complete code for the given */
/* event. */
/* */
/* Description : Configures the given VP capture EDMA channel. */
/* The source address update is fixed address mode */
/* because the captured data is read from the FIFO. */
/* In this example, the destination address mode is */
/* auto.increment. But, in real.time applications */
/* there is lot of flexibility in the way capture */
/* buffers can be managed like ping.pong and round */
/* robin,…etc. */
/*................................................................ */
void configVPCapEDMAChannel(EDMA_Handle *edmaHandle,
Int32 eventId,
Int32 *tccNum,
Uint32 srcAddr,
Uint32 dstAddr,
Uint32 frameCount,
Uint32 elementCount)
{
Int32 tcc = 0;
EDMA_Handle hEdmaTable;
/* Open Y EVT EDMA channel */
*edmaHandle = EDMA_open(eventId, EDMA_OPEN_RESET);
if(*edmaHandle == EDMA_HINV)
{
for(;;){}
}
/* allocate TCC for Y event */
if((tcc = EDMA_intAlloc(-1)) == -1)
{
for(;;){}
}
/*打开一个新的EDMA链接*/
hEdmaTable = EDMA_allocTable(-1);
/* Configure EDMA parameters */
EDMA_configArgs(
*edmaHandle,
EDMA_OPT_RMK(EDMA_OPT_PRI_MEDIUM, /* medium priority 设置优先级为中*/
EDMA_OPT_ESIZE_32BIT, /* Element size 32 bits 元素的长度为4个Byte*/
EDMA_OPT_2DS_NO, /* 1.dimensional source(FIFO) 源采用固定的方试*/
EDMA_OPT_SUM_NONE, /* fixed src address mode(FIFO) 源地址不变*/
EDMA_OPT_2DD_YES, /* 2.dimensional destination 目的采用2维空间的组成*/
EDMA_OPT_DUM_INC, /* destination increment 目的采用增长的方式*/
EDMA_OPT_TCINT_YES, /* Enable transfer complete indication,使能传送结束指示*/
EDMA_OPT_TCC_OF(tcc & 0xF),/*设置完成标志CIP0的低位*/
EDMA_OPT_TCCM_OF(((tcc & 0x30) >> 4)),/*设置完成标志CIP0的高位*/
EDMA_OPT_ATCINT_NO, /* Disable Alternate Transfers 禁止交替传送 */
EDMA_OPT_ATCC_OF(0),/* Complete Interrupt 未使用交替完标志 */
EDMA_OPT_PDTS_DISABLE, /* disable PDT(peripheral device transfer) mode for source */
EDMA_OPT_PDTD_DISABLE, /* disable PDT mode for dest */
EDMA_OPT_LINK_YES, /* Disable linking */
EDMA_OPT_FS_NO), /* Array synchronization 阵列同步*/
EDMA_SRC_RMK(srcAddr),/*源地址*/
EDMA_CNT_RMK(EDMA_CNT_FRMCNT_OF((frameCount-1)),/*陈列的行数*/
EDMA_CNT_ELECNT_OF(elementCount)),/*每行的像素数*/
EDMA_DST_RMK(dstAddr),/*目的地址*/
EDMA_IDX_RMK(EDMA_IDX_FRMIDX_OF((elementCount * 4)),/*每行的增量*/
EDMA_IDX_ELEIDX_OF(0)), /* note: 32-bit element size */
/* no RLD in 2D and no linking */
EDMA_RLD_RMK(EDMA_RLD_ELERLD_OF(0), EDMA_RLD_LINK_OF(0))
);
EDMA_configArgs(
hEdmaTable,/*配置表的句柄*/
EDMA_OPT_RMK(EDMA_OPT_PRI_MEDIUM, /* medium priority 设置优先级为中*/
EDMA_OPT_ESIZE_32BIT, /* Element size 32 bits 元素的长度为4个Byte*/
EDMA_OPT_2DS_NO, /* 1.dimensional source(FIFO) 源采用固定的方试*/
EDMA_OPT_SUM_NONE, /* fixed src address mode(FIFO) 源地址不变*/
EDMA_OPT_2DD_YES, /* 2.dimensional destination 目的采用2维空间的组成*/
EDMA_OPT_DUM_INC, /* destination increment 目的采用增长的方式*/
EDMA_OPT_TCINT_YES, /* Enable transfer complete indication,使能传送结束指示*/
EDMA_OPT_TCC_OF(tcc & 0xF),/*设置完成标志CIP0的低位*/
EDMA_OPT_TCCM_OF(((tcc & 0x30) >> 4)),/*设置完成标志CIP0的高位*/
EDMA_OPT_ATCINT_NO, /* Disable Alternate Transfers 禁止交替传送 */
EDMA_OPT_ATCC_OF(0),/* Complete Interrupt 未使用交替完标志 */
EDMA_OPT_PDTS_DISABLE, /* disable PDT(peripheral device transfer) mode for source */
EDMA_OPT_PDTD_DISABLE, /* disable PDT mode for dest */
EDMA_OPT_LINK_YES, /* Disable linking */
EDMA_OPT_FS_NO), /* Array synchronization 阵列同步*/
EDMA_SRC_RMK(srcAddr),/*源地址*/
EDMA_CNT_RMK(EDMA_CNT_FRMCNT_OF((frameCount-1)),/*陈列的行数*/
EDMA_CNT_ELECNT_OF(elementCount)),/*每行的像素数*/
EDMA_DST_RMK(dstAddr),/*目的地址*/
EDMA_IDX_RMK(EDMA_IDX_FRMIDX_OF((elementCount * 4)),/*每行的增量*/
EDMA_IDX_ELEIDX_OF(0)), /* note: 32.bit element size */
/* no RLD in 2D and no linking */
EDMA_RLD_RMK(EDMA_RLD_ELERLD_OF(0), EDMA_RLD_LINK_OF(0))
);
/*连接两个DMA*/
EDMA_link(*edmaHandle,hEdmaTable);
/*使EDMA循环起来*/
EDMA_link(hEdmaTable,hEdmaTable);
*tccNum = tcc;/*返回中断完成标志*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -